Skip to content

Instantly share code, notes, and snippets.

@Krelyx
Created January 16, 2015 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Krelyx/5ddf3732bb9d185da23a to your computer and use it in GitHub Desktop.
Save Krelyx/5ddf3732bb9d185da23a to your computer and use it in GitHub Desktop.
Version modifée
// Ydle.cpp
//
// Ydle implementation for Arduino
// See the README file in this directory for documentation
// For changes, look at Ydle.h
//
// Authors:
// Fabrice Scheider AKA Denia,
// Manuel Esteban AKA Yaug
// Matthieu Desgardin AKA Zescientist
// Yargol AKA Yargol
// Xylerk
//
// WebPage: http://www.ydle.fr/index.php
// Contact: http://forum.ydle.fr/index.php
// Licence: CC by sa (http://creativecommons.org/licenses/by-sa/3.0/fr/)
// Pll function inspired on VirtualWire library
#include <TimerOne.h>
#include "Ydle.h"
#include <avr/eeprom.h>
#include "Float.h"
#include "dataStructures.h"
const PROGMEM prog_uchar _atm_crc8_table[256] = {
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
};
static Frame_t g_m_receivedframe; // received frame
static Frame_t g_frameBuffer[YDLE_MAX_FRAME];
static Frame_t g_sendFrameBuffer; // Une seule pour le moment
static uint8_t m_data[YDLE_MAX_SIZE_FRAME]; // data + crc
static uint8_t pinRx = 12; // Le numéro de la broche IO utilisée pour le module récepteur
static uint8_t pinTx = 10; // Le numéro de la broche IO utilisée pour le module émetteur
static uint8_t pinLed = 13; // Le numéro de la broche IO utilisée pour la Led de statut
static uint8_t pinCop = 8; // Permet la recopie du signal sur une sortie pour vérification à l'oscilloscope
static uint8_t start_bit2 = 0b01000010; // Octet de start
volatile uint8_t sample_value = 0; // Disponibilité d'un sample
volatile uint8_t sample_count = 1; // Nombre de samples sur la période en cours
volatile uint8_t last_sample_value = 0; // La valeur du dernier sample reéu
// La rampe PLL, varie entre 0 et 159 sur les 8 samples de chaque période de bit
// Quand la PLL est synchronisée, la transition de bit arrive quand la rampe vaut 0
static uint8_t pll_ramp = 0;
// La somme des valeurs des samples. si inférieur à 5 "1" samples dans le cycle de PLL
// le bit est déclaré comme 0, sinon à 1
static uint8_t sample_sum = 0;
static uint16_t rx_bits = 0; // Les 16 derniers bits reçus, pour repérer l'octet de start
volatile unsigned long t_start = 0; // Temps du premier sample de chaque bit
static uint8_t rx_active = 0; // Flag pour indiquer la bonne réception du message de start
#define YDLE_SPEED 1000
// Le débit de transfert en bits/secondes
#define YDLE_TPER 1000000/YDLE_SPEED // La période d'un bit en microseconds
#define YDLE_FBIT YDLE_TPER/8 // La fréquence de prise de samples
static uint8_t bit_value = 0; // La valeur du dernier bit récupéré
static uint8_t bit_count = 0; // Le nombre de bits récupérés
static uint8_t sender = 0; // Id sender reçue
static uint8_t receptor = 0; // Id receptor reçue
static uint8_t type = 0; // Info type reçue
static uint8_t parite = false; // Info parité reçue
static uint8_t taille = 0; // Info taille reçue
static int rx_bytes_count = 0; // Nombre d'octets reçus
static uint8_t length_ok = 0; // Disponibilité de la taille de trame
volatile uint8_t wait_ack = 0;
volatile uint8_t last_check = 0;
volatile uint8_t retry = 0;
static uint8_t rx_done = 0; // Si le message est complet
static uint8_t frameReadyToBeRead = false;
static uint8_t pFrame = 0;
volatile uint8_t transmission_on = false;
static int tx_sample =0;
static int tx_bit =7;
static int tx_index =0;
static bool bit_test = false;
volatile uint8_t frameToSend[40];
volatile uint8_t frameToSendLength = 0;
// Catch function for interrupt the reset button
void reset(){
#ifdef _YDLE_DEBUG
Serial.println("Interrupt catched");
#endif
ydle::resetNode();
}
void ydle::resetNode(){
memset((void*)&m_Config, 0x0, sizeof(Config_t));
eeprom_write_block((void*)&m_Config,0, sizeof(m_Config));
m_initializedState = false;
m_bLnkSignalReceived = false;
}
// Initialisation des IO avec des valeurs entrées par l'utilisateur
ydle::ydle(int rx, int tx)
{
m_bLnkSignalReceived = false;
m_initializedState = false;
this->_callback_set = false;
readEEProm();
pinMode(rx, INPUT);
pinRx = rx;
pinMode(tx, OUTPUT);
pinTx = tx;
pinMode(pinLed, OUTPUT);
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
}
// Initialisation des IO avec les valeurs par défaut
ydle::ydle()
{
m_bLnkSignalReceived = false;
m_initializedState = false;
this->_callback_set = false;
readEEProm();
pinMode(pinRx, INPUT);
pinMode(pinTx, OUTPUT);
pinMode(pinLed, OUTPUT);
}
void ydle::init_timer(){
Timer1.initialize(YDLE_FBIT); // set a timer of length YDLE_FBIT microseconds
Timer1.attachInterrupt( timerInterrupt ); // attach the service routine here
}
void timerInterrupt(){
if(!transmission_on){
if(rx_done)
{
rx_done = false;
}
sample_value = (PINB & (1<<PB4));
pll();
}
if(transmission_on){
if(tx_sample == 0){
if (bit_test ==0){
digitalWrite(pinTx, frameToSend[tx_index]& 1<<tx_bit);
bit_test = true;
}
else {
digitalWrite(pinTx, !(frameToSend[tx_index]& 1<<tx_bit));
bit_test = false;
tx_bit--;
}
}
if (tx_bit < 0){
tx_index++;
tx_bit = 7;
}
tx_sample++;
if(tx_sample > 7){
tx_sample = 0 ;
}
if(tx_index > frameToSendLength && tx_sample == 0){
PORTB &= ~(1<<PB2);//digitalWrite(pinTx, LOW);
digitalWrite(pinLed, LOW);
PORTD |= (1<<PD5);//digitalWrite(5, HIGH);
transmission_on=false;
}
}
}
void ydle::attach(ydleCallbackFunction function){
this->callback = function;
this->_callback_set = true;
}
// Used to read the configuration
void ydle::ReadConfig()
{
readEEProm();
}
// lire en mémoire EEProm du signal de référence
void ydle::readEEProm()
{
memset((void*)&m_Config,0x0,sizeof(m_Config));
eeprom_read_block ((void*)&m_Config, 0, sizeof(Config_t));
if((m_Config.IdMaster!=0)&&(m_Config.IdNode!=0)){
m_initializedState = true;
#ifdef _YDLE_DEBUG
log("Config find in eeprom");
log("Config.IdMaster : ", m_Config.IdMaster);
log("Config.IdNode :", m_Config.IdNode);
#endif
}
else{
#ifdef _YDLE_DEBUG
log("NODE IS NOT INIT");
log("No config in EEprom");
#endif
m_initializedState = false;
memset((void*)&m_Config,0,sizeof(m_Config));
}
}
// Ecriture en mémoire EEProm du signal de référence
void ydle::writeEEProm()
{
eeprom_write_block((void*)&m_Config,0, sizeof(m_Config));
#ifdef _YDLE_DEBUG
log("Enregistrement du signal reçu comme signal de réference");
#endif
}
uint8_t ydle::crc8(const uint8_t* buf, uint8_t length) {
// The inital and final constants as used in the ATM HEC.
const uint8_t initial = 0x00;
const uint8_t final = 0x55;
uint8_t crc = initial;
while (length) {
crc = pgm_read_byte_near(_atm_crc8_table + (*buf ^ crc));
buf++;
length--;
}
return crc ^ final;
}
unsigned char ydle::computeCrc(Frame_t* frame){
unsigned char *buf, crc;
int a,j;
buf = (unsigned char*)malloc(frame->taille+3);
memset(buf, 0x0, frame->taille+3);
buf[0] = frame->sender;
buf[1] = frame->receptor;
buf[2] = frame->type;
buf[2] = buf[2] << 5;
buf[2] |= frame->taille;
for(a=3, j=0 ;j < frame->taille - 1;a++, j++){
buf[a] = frame->data[j];
}
crc = crc8(buf,frame->taille+2);
free(buf);
return crc;
}
uint8_t ydle::receive(){
unsigned char crc_p;
if(frameReadyToBeRead){
for(int i = 0; i < (int)pFrame; i++){
crc_p = computeCrc(&g_frameBuffer[i]);
if(crc_p != g_frameBuffer[i].crc)
{
#ifdef _YDLE_DEBUG
printFrame(&g_frameBuffer[i]);
log("crc error!!!!!!!!!");
#endif // _YDLE_DEBUG
}
else
{
#ifdef _YDLE_DEBUG
Serial.println("Frame ready to be handled");
#endif // _YDLE_DEBUG
// We receive a CMD so trait it
if(g_frameBuffer[i].type == YDLE_TYPE_CMD)
{
handleReceivedFrame(&g_frameBuffer[i]);
#ifdef _YDLE_DEBUG
printFrame(&g_frameBuffer[i]);
#endif // _YDLE_DEBUG
}else if(g_frameBuffer[i].type == YDLE_TYPE_ACK){
#ifdef _YDLE_DEBUG
Serial.println("ACK received");
#endif // _YDLE_DEBUG
if(g_frameBuffer[i].sender == g_sendFrameBuffer.receptor
&& g_frameBuffer[i].receptor == g_sendFrameBuffer.sender){
wait_ack = 0;
retry = 0;
last_check = 0;
return 1;
}
}else{
#ifdef _YDLE_DEBUG
printFrame(&g_frameBuffer[i]);
#endif
// Send the frame to the callback function
if(this->_callback_set)
this->callback(&g_frameBuffer[i]);
}
// Frame handled
}
}
// Peut poser un probléme si une interruption se produit et
// que la pll termine de traiter un paquet et la pose sur la pile exactement à ce moment là
pFrame = 0;
frameReadyToBeRead = false;
if(wait_ack == 1){
if(retry <= 3){
uint8_t curt = millis();
if(curt - last_check >= YDLE_ACK_TIMEOUT){
last_check = curt;
this->send(&g_sendFrameBuffer);
#ifdef _YDLE_DEBUG
Serial.println("Timeout, resending frame");
#endif
}
retry++;
}else{
// Lost packet... sorry dude !
wait_ack = 0;
retry = 0;
last_check = 0;
return 0;
#ifdef _YDLE_DEBUG
Serial.println("Lost packet... sorry dude !");
#endif
}
}
}
}
// Do something with a received Command
void ydle::handleReceivedFrame(Frame_t *frame)
{
uint8_t * pData = frame->data ;
sReceivedCommand * p = (sReceivedCommand *)pData ;
uint8_t receivedCommand = p->cmd ;
uint8_t receivednid = p->nid;
if(checkSignal(frame))
{
delay(1000);
#ifdef _YDLE_DEBUG
log("**************Send ACK********************");
#endif
Frame_t response;
memset(&response, 0x0, sizeof(response));
dataToFrame(&response, YDLE_TYPE_ACK); // Create a new ACK Frame
#ifdef _YDLE_DEBUG
printFrame(&response);
Serial.println("End send ack");
#endif
send(&response);
}
if (receivedCommand == YDLE_CMD_LINK){
#ifdef _YDLE_DEBUG
log("Link received ",receivedCommand);
#endif
// we are not already linked
if(!m_initializedState)
{
m_Config.IdNode = frame->receptor;
m_Config.IdMaster = frame->sender;
m_initializedState = true;
writeEEProm();
}
}
else if(receivedCommand == YDLE_CMD_ON && checkSignal(frame))
{
#ifdef _YDLE_DEBUG
Serial.println("YDLE_CMD_ON");
#endif
cmd_ON(receivednid);
}
else if(receivedCommand == YDLE_CMD_OFF && checkSignal(frame))
{
#ifdef _YDLE_DEBUG
Serial.println("YDLE_CMD_OFF");
#endif
cmd_OFF(receivednid);
}
else if(receivedCommand == YDLE_CMD_RESET && checkSignal(frame))
{
#ifdef _YDLE_DEBUG
Serial.println("YDLE_CMD_RESET");
#endif
#ifdef _YDLE_DEBUG
log("Reset received ",litype);
#endif
m_Config.IdNode = 0;
m_Config.IdMaster = 0;
writeEEProm();
m_initializedState = false;
}
else if (receivedCommand == YDLE_CMD_ASKDATA && checkSignal(frame))
{
#ifdef _YDLE_DEBUG
Serial.println("YDLE_CMD_ASKDATA");
#endif
askData();
}
}
// Synchronise l'AGC, envoie l'octet de start puis transmet la trame
uint8_t ydle::send(Frame_t *frame)
{
int i = 0,j = 0;
//PORTB |= (1<<PB5);
digitalWrite(pinLed, HIGH); // on allume la Led pour indiquer une émission
if(frame->type == YDLE_TYPE_STATE_ACK){
if(wait_ack != 1){
memcpy(&g_sendFrameBuffer, &frame, sizeof(Frame_t));
wait_ack = 1;
}
}
#ifdef _YDLE_DEBUG
printFrame(frame);
#endif
// From now, we are ready to transmit the frame
while(rx_active){
// Wait that the current transmission finish
delay(2*YDLE_TPER);
#ifdef _YDLE_DEBUG
Serial.println("The ligne is occuped");
#endif
}
memset((void*)&frameToSend, 0x0, 40);
// add crc BYTE
frame->taille++;
// calcul crc
frame->crc = computeCrc(frame);
uint8_t index =0;
frameToSendLength =7+frame->taille;
frameToSend[index++] = 0xFF;
frameToSend[index++] = 0xFF;
frameToSend[index++] = 0xFF;
frameToSend[index++] = 0xFF;
frameToSend[index++] = start_bit2;
frameToSend[index++] = frame->receptor;
frameToSend[index++] = frame->sender;
frameToSend[index++] = (frame->type << 5)+ frame->taille;
for (int j=0; j<frame->taille-1;j++)
{
frameToSend[index++] = frame->data[j];
}
frameToSend[index++] = frame->crc;
tx_index = 0;
tx_bit = 7;
PORTB &= ~(1<<PB5);
digitalWrite(5, LOW);
transmission_on = true;
}
// Comparaison du signal reçu et du signal de référence
bool ydle::checkSignal(Frame_t *frame)
{
if(frame->sender==m_Config.IdMaster && frame->receptor==m_Config.IdNode)
return true;
else
return false;
}
void pll()
{
sample_count ++;
// On additionne chaque sample et on incrémente le nombre du prochain sample
if (sample_value){
sample_sum++;
}
// On vérifie s'il y a eu une transition de bit
if (sample_value != last_sample_value){
// Transition, en avance si la rampe > 40, en retard si < 40
if(pll_ramp < 80){
pll_ramp += 11;
}
else{
pll_ramp += 29;
}
last_sample_value = sample_value;
}
else{
// Si pas de transition, on avance la rampe de 20 (= 80/4 samples)
pll_ramp += 20;
}
// On vérifie si la rampe é atteint son maximum de 80
if (pll_ramp >= 160)
{
//t_start = micros();
// On ajoute aux 16 derniers bits reéus rx_bits, MSB first
// On stock les 16 derniers bits
rx_bits <<= 1;
// On vérifie la somme des samples sur la période pour savoir combien était é l'état haut
// S'ils étaient < 2, on déclare un 0, sinon un 1;
if (sample_sum >= 5){
rx_bits |= 0x1;
bit_value = 1;
}
else{
rx_bits |= 0x0;
bit_value = 0;
}
pll_ramp -= 160; // On soustrait la taille maximale de la rampe é sa valeur actuelle
sample_sum = 0; // On remet la somme des samples é 0 pour le prochain cycle
sample_count = 1; // On ré-initialise le nombre de sample
// Si l'on est dans le message, c'est ici qu'on traite les données
if (rx_active){
bit_count ++;
// On récupére les bits et on les places dans des variables
// 1 bit sur 2 avec Manchester
if (bit_count % 2 == 1){
if (bit_count < 16){
// Les 8 premiers bits de données
receptor <<= 1;
receptor |= bit_value;
}
else if (bit_count < 32){
// Les 8 bits suivants
sender <<= 1;
sender |= bit_value;
}
else if (bit_count < 38){
// Les 3 bits de type
type <<= 1;
type |= bit_value;
}
else if (bit_count < 48){
// Les 5 bits de longueur de trame
rx_bytes_count <<= 1;
rx_bytes_count |= bit_value;
}
else if ((bit_count-48) < (rx_bytes_count * 16)){
// les données
length_ok = 1;
m_data[(bit_count-48)/16] <<= 1;
m_data[(bit_count-48)/16]|= bit_value;
}
}
// Quand on a reéu les 24 premiers bits, on connait la longueur de la trame
// On vérifie alors que la longueur semble logique
if (bit_count >= 48)
{
// Les bits 19 é 24 informent de la taille de la trame
// On les vérifie car leur valeur ne peuvent étre < é 1 et > é 30 + 1 pour le CRC
if (rx_bytes_count < 1 || rx_bytes_count > 30)
{
#ifdef _YDLE_DEBUG
Serial.println("error!");
#endif
// Mauvaise taille de message, on ré-initialise la lecture
rx_active = false;
sample_count = 1;
bit_count = 0;
length_ok = 0;
sender = 0;
receptor = 0;
type = 0;
parite = 0;
taille = 0;
memset(m_data,0,sizeof(m_data));
//t_start = micros();
return;
}
}
// On vérifie si l'on a reçu tout le message
if ((bit_count-48) >= (rx_bytes_count*16) && (length_ok == 1))
{
#ifdef _YDLE_DEBUG
Serial.println("complete");
#endif
rx_active = false;
g_m_receivedframe.sender = sender;
g_m_receivedframe.receptor = receptor;
g_m_receivedframe.type = type;
g_m_receivedframe.taille = rx_bytes_count; // data + crc
memcpy(g_m_receivedframe.data,m_data,rx_bytes_count-1); // copy data len - crc
g_m_receivedframe.crc=m_data[rx_bytes_count-1];
// May be an array ?
if(pFrame == YDLE_MAX_FRAME){
pFrame = 0;
}
memcpy(&g_frameBuffer[pFrame], &g_m_receivedframe, sizeof(Frame_t));
pFrame++;
frameReadyToBeRead = true;
length_ok = 0;
sender = 0;
receptor = 0;
type = 0;
taille = 0;
memset(m_data,0,sizeof(m_data));
}
}
// Pas dans le message, on recherche l'octet de start
else if (rx_bits == 0x6559)
{
#ifdef _YDLE_DEBUG
Serial.println("start");
#endif
// Octet de start, on commence é collecter les données
rx_active = true;
bit_count = 0;
rx_bytes_count = 0;
}
}
}
// Fonction qui crée une trame avec les infos fournies
void ydle::dataToFrame(Frame_t *frame, unsigned long destination, unsigned long sender, unsigned long type)
{
frame->sender = sender;
frame->receptor = destination;
frame->type = type;
frame->taille = 0;
frame->crc = 0;
memset(frame->data,0,sizeof(frame->data));
}
// Fonction qui crée une trame avec un type fournie
void ydle::dataToFrame(Frame_t *frame, unsigned long type)
{
frame->sender = m_Config.IdNode;
frame->receptor = m_Config.IdMaster;
frame->type = type;
frame->taille = 0;
frame->crc = 0;
memset(frame->data, 0x0, sizeof(frame->data));
}
// Fonction qui retourne "true" si la Node est initialisée
bool ydle::initialized()
{
return m_initializedState;
}
int ydle::isSignal()
{
return rx_active;
}
// ----------------------------------------------------------------------------
/**
Function: addCmd
Inputs: int type type of data
int data
Outputs:
*/
// ----------------------------------------------------------------------------
/*void ydle::addCmd(Frame_t *frame, int type, int data)
{
frame->data[frame->taille]=type<<4;
frame->data[frame->taille+1]=data;
frame->taille+=2;
}
union _FP16 ydle::floatToHalf(float number){
union _FP16 o = { 0 };
union _FP32 f;
f.f = number;
// Based on ISPC reference code (with minor modifications)
if (f.Exponent == 0) // Signed zero/denormal (which will underflow)
o.Exponent = 0;
else if (f.Exponent == 255) // Inf or NaN (all exponent bits set)
{
o.Exponent = 31;
o.Mantissa = f.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
}
else // Normalized number
{
// Exponent unbias the single, then bias the halfp
int newexp = f.Exponent - 127 + 15;
if (newexp >= 31) // Overflow, return signed infinity
o.Exponent = 31;
else if (newexp <= 0) // Underflow
{
if ((14 - newexp) <= 24) // Mantissa might be non-zero
{
uint16_t mant = f.Mantissa | 0x800000; // Hidden 1 bit
o.Mantissa = mant >> (14 - newexp);
if ((mant >> (13 - newexp)) & 1) // Check for rounding
o.u++; // Round, might overflow into exp bit, but this is OK
}
}
else
{
o.Exponent = newexp;
o.Mantissa = f.Mantissa >> 13;
if (f.Mantissa & 0x1000) // Check for rounding
o.u++; // Round, might overflow to inf, this is OK
}
}
o.Sign = f.Sign;
return o;
}
// Affiche les logs sur la console série
void ydle::log(String msg)
{
#if not defined( __AVR_ATtiny85__ ) or defined(_YDLE_DEBUG)
Serial.println(msg);
#endif
}
// Affiche les logs sur la console série
void ydle::log(String msg,int i)
{
#if not defined( __AVR_ATtiny85__ ) or defined(_YDLE_DEBUG)
Serial.print(msg);
Serial.println(i);
#endif
}
// ----------------------------------------------------------------------------
/**
Function: printFrame
Inputs: Frame_t trame frame to log
int data
Outputs:
Log a frame if debug activated
*/
// ----------------------------------------------------------------------------
void ydle::printFrame(Frame_t *trame)
{
#if not defined( __AVR_ATtiny85__ ) or defined (_YDLE_DEBUG)
// if debug
char sztmp[255];
log("-----------------------------------------------");
sprintf(sztmp,"Emetteur :%d",trame->sender);
log(sztmp);
sprintf(sztmp,"Recepteur :%d",trame->receptor);
log(sztmp);
sprintf(sztmp,"Type :%d",trame->type);
log(sztmp);
sprintf(sztmp,"Taille :%d",trame->taille);
log(sztmp);
sprintf(sztmp,"CRC :%d",trame->crc);
log(sztmp);
sprintf(sztmp,"Data Hex: ");
for (int a=0;a<trame->taille-1;a++)
sprintf(sztmp,"%s 0x%02X",sztmp,trame->data[a]);
log(sztmp);
sprintf(sztmp,"Data Dec: ");
for (int a=0;a<trame->taille-1;a++)
sprintf(sztmp,"%s %d",sztmp,trame->data[a]);
log(sztmp);
log("-----------------------------------------------");
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment