RX

Dependencies:   mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2

Files at this revision

API Documentation at this revision

Comitter:
LucasKB
Date:
Mon Jun 17 00:10:40 2019 +0000
Parent:
1:bd8b9ad01400
Commit message:
RX;

Changed in this revision

BufferedSerial.lib Show annotated file Show diff for this revision Revisions of this file
SDCard_Y.cpp Show annotated file Show diff for this revision Revisions of this file
SDCard_Y.hh Show annotated file Show diff for this revision Revisions of this file
UbxGpsNavSol.cpp Show annotated file Show diff for this revision Revisions of this file
UbxGpsNavSol.hh Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial.lib	Mon Jun 17 00:10:40 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/sam_grove/code/BufferedSerial/#7e5e866edd3d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDCard_Y.cpp	Mon Jun 17 00:10:40 2019 +0000
@@ -0,0 +1,243 @@
+#include "SDCard_Y.hh"
+
+
+
+#define SD_COMMAND_TIMEOUT 5000
+
+#define R1_IDLE_STATE           (1 << 0)
+#define R1_ERASE_RESET          (1 << 1)
+#define R1_ILLEGAL_COMMAND      (1 << 2)
+#define R1_COM_CRC_ERROR        (1 << 3)
+#define R1_ERASE_SEQUENCE_ERROR (1 << 4)
+#define R1_ADDRESS_ERROR        (1 << 5)
+#define R1_PARAMETER_ERROR      (1 << 6)
+
+
+
+
+SDCard::SDCard(SPI *t_spi, PinName t_cs) : cs(t_cs)
+{
+  spi = t_spi;
+  cs = 1;
+}
+
+SDCard::~SDCard()
+{
+  delete spi;
+}
+
+int SDCard::init(void)
+{
+  spi->frequency(100000);
+  cs = 1;
+
+  for( int i=0 ; i<16 ; i++)
+    spi->write(0xFF);
+
+  if(cmd(0,0) != R1_IDLE_STATE)
+    return -1;
+
+  int r = cmd8();
+
+  if(r == R1_IDLE_STATE){
+    return init_card_v2();      
+  } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
+    return init_card_v1();
+  } else {
+    return -1;
+  }
+  
+  return 0;
+}
+
+int SDCard::init_card_v1()
+{
+  for (int i = 0; i < SD_COMMAND_TIMEOUT; i++)
+    {
+      cmd(55, 0);
+      if(cmd(41, 0) == 0)
+    {
+      cdv = 512;
+          return 1;
+        }
+    }
+
+  return -1;
+}
+
+
+int SDCard::init_card_v2()
+{
+  for (int i = 0; i < SD_COMMAND_TIMEOUT; i++)
+    {
+      wait_ms(50);
+      cmd58();
+      cmd(55, 0);
+      if (cmd(41, 0x40000000) == 0)
+    {
+      cmd58();
+          cdv = 1;
+          return 2;
+        }
+    }
+
+  return -1;
+}
+
+
+int SDCard::cmd(int cmd, int arg)
+{
+  cs = 0;
+  spi->write(0x40 | cmd);
+  spi->write(arg >> 24);
+  spi->write(arg >> 16);
+  spi->write(arg >> 8);
+  spi->write(arg >> 0);
+  spi->write(0x95);
+
+  for( int i=0 ; i<SD_COMMAND_TIMEOUT ; i++)
+    {
+      int respuesta = spi->write(0xFF);
+      if( !(respuesta & 0x80) )
+    {
+      cs = 1;
+      spi->write(0xFF);
+      return respuesta;
+    }
+    }
+
+  cs = 1;
+  spi->write(0xFF);
+  return -1;
+
+}
+
+
+int SDCard::cmd8()
+{
+  cs = 0;
+
+  spi->write(0x40 | 8); // CMD8
+  spi->write(0x00);     // reserved
+  spi->write(0x00);     // reserved
+  spi->write(0x01);     // 3.3v
+  spi->write(0xAA);     // check pattern
+  spi->write(0x87);     // crc
+
+  for( int i=0 ; i<SD_COMMAND_TIMEOUT * 1000 ; i++)
+    {
+      char respuesta[5];
+      respuesta[0] = spi->write(0xFF);
+      
+      if( !(respuesta[0] & 0x80))
+    {
+      for( int j=1; j<5 ; j++)
+        respuesta[i] = spi->write(0xFF);
+
+      cs = 1;
+      spi->write(0xFF);
+      return respuesta[0];
+    }
+    }
+
+  cs = 1;
+  spi->write(0xFF);
+  return -1;
+  
+}
+
+
+
+int SDCard::cmd58()
+{
+  cs = 0;
+  
+  int arg = 0;
+
+  spi->write(0x40 | 58);
+  spi->write(arg >> 24);
+  spi->write(arg >> 16);
+  spi->write(arg >> 8);
+  spi->write(arg >> 0);
+  spi->write(0x95);
+
+  // wait for the repsonse (response[7] == 0)
+  for(int i = 0; i < SD_COMMAND_TIMEOUT; i++)
+    {
+      int respuesta = spi->write(0xFF);
+
+      if( !(respuesta & 0x80) )
+    {
+      int ocr = spi->write(0xFF) << 24;
+          ocr |= spi->write(0xFF) << 16;
+          ocr |= spi->write(0xFF) << 8;
+          ocr |= spi->write(0xFF) << 0;
+          cs = 1;
+          spi->write(0xFF);
+          return respuesta;
+        }
+    }
+    cs = 1;
+    spi->write(0xFF);
+    
+    return -1; // timeout
+}
+
+
+
+bool SDCard::read(uint8_t *vect, int post)
+{
+  while( cmd(17,post*512) == -1);
+
+  cs = 0;
+
+  while (spi->write(0xFF) != 0xFE);
+
+  for (uint32_t i = 0; i < 512; i++)
+    *(vect+i) = spi->write(0xFF);
+
+  spi->write(0xFF); // checksum
+  spi->write(0xFF);
+
+  cs = 1;
+  spi->write(0xFF);
+
+  while(cmd(12,512) == -1);
+
+  return 1;
+}
+
+
+
+bool SDCard::write(uint8_t *vect, int post)
+{
+  
+  while( cmd(24,post*512) == -1 );
+  
+  cs = 0;
+  
+  spi->write(0xFE);
+  
+  for (uint32_t i = 0; i < 512; i++)
+    spi->write(*(vect+i));
+
+  spi->write(0xFF);
+  spi->write(0xFF);
+
+  if( (spi->write(0xFF) & 0x1F) != 0x05 )
+    {
+      cs = 1;
+      spi->write(0xFF);
+      return 0;
+    }
+
+  while(spi->write(0xFF) == 0);
+
+  cs = 1;
+  spi->write(0xFF);
+
+  while(cmd(12,512) == -1);
+
+  return 1;
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDCard_Y.hh	Mon Jun 17 00:10:40 2019 +0000
@@ -0,0 +1,29 @@
+#include "mbed.h"
+
+
+class SDCard
+{
+public:
+
+  SDCard(SPI *t_spi, PinName t_cs);
+  ~SDCard();
+
+  int init(void);
+  
+  bool read(uint8_t *vect, int post);  //Lextura de un bloque de 512
+  bool write(uint8_t *vect, int post); //Escritura de un bloque de 512
+
+private:
+
+  SPI *spi;
+  DigitalOut cs;
+  int cdv;
+
+  int init_card_v1();
+  int init_card_v2();
+  
+  int cmd(int cmd, int arg);
+  int cmd8();
+  int cmd58();
+  
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UbxGpsNavSol.cpp	Mon Jun 17 00:10:40 2019 +0000
@@ -0,0 +1,398 @@
+#include "UbxGpsNavSol.hh"
+#include "mbed.h"
+
+UbxGpsNavSol::UbxGpsNavSol(PinName tx, PinName rx, int baud):UARTSerial(tx, rx, baud){
+    this->carriagePosition = 0;
+    // this->setLength(52);
+    offsetClassProperties = 8;
+    offsetHeaders = 4;
+}
+
+UbxGpsNavSol::~UbxGpsNavSol(){}
+
+bool UbxGpsNavSol::ready(){
+    unsigned char buffer[60];
+
+    if(this->readable()){
+      for(int k = 0; k < 60; k++)
+        buffer[k] = 0;
+
+      this->read(buffer, 60);
+    }
+
+    if(buffer[0] != UBX_NAV_SOL_HEADER_1 || buffer[1] != UBX_NAV_SOL_HEADER_2)
+      return false;
+
+    if(buffer[2] != UBX_NAV_SOL_CLASS || buffer[3] != UBX_NAV_SOL_ID)
+      return false;
+
+    payload_length = buffer[5];
+    payload_length = payload_length << 8;
+    payload_length = buffer[4];
+
+    if(payload_length != UBX_NAV_SOL_PAYLOAD_LENGTH)
+      return false;
+
+    // if(calculateChecksum(buffer) == false)
+    //   return false;
+
+    iTOW = buffer[9] << 8;
+    iTOW |= buffer[8];
+    iTOW <<= 8;
+    iTOW |= buffer[7];
+    iTOW <<= 8;
+    iTOW |= buffer[6];
+
+    fTOW = buffer[13] << 8;
+    fTOW |= buffer[12];
+    fTOW <<= 8;
+    fTOW |= buffer[11];
+    fTOW <<= 8;
+    fTOW |= buffer[10];
+
+    week = buffer[15] << 8;
+    week |= buffer[14];
+
+    gpsFix = buffer[16];
+
+    flags = buffer[17];
+
+    ecefX = buffer[21] << 8;
+    ecefX |= buffer[20];
+    ecefX <<= 8;
+    ecefX |= buffer[19];
+    ecefX <<= 8;
+    ecefX |= buffer[18];
+
+    ecefY = buffer[25] << 8;
+    ecefY |= buffer[24];
+    ecefY <<= 8;
+    ecefY |= buffer[23];
+    ecefY <<= 8;
+    ecefY |= buffer[22];
+
+    ecefZ = buffer[29] << 8;
+    ecefZ |= buffer[28];
+    ecefZ <<= 8;
+    ecefZ |= buffer[27];
+    ecefZ <<= 8;
+    ecefZ |= buffer[26];
+
+    pAcc = buffer[33] << 8;
+    pAcc |= buffer[32];
+    pAcc <<= 8;
+    pAcc |= buffer[31];
+    pAcc <<= 8;
+    pAcc |= buffer[30];
+
+    ecefVX = buffer[37] << 8;
+    ecefVX |= buffer[36];
+    ecefVX <<= 8;
+    ecefVX |= buffer[35];
+    ecefVX <<= 8;
+    ecefVX |= buffer[34];
+
+    ecefVY = buffer[41] << 8;
+    ecefVY |= buffer[40];
+    ecefVY <<= 8;
+    ecefVY |= buffer[39];
+    ecefVY <<= 8;
+    ecefVY |= buffer[38];
+
+    ecefVZ = buffer[45] << 8;
+    ecefVZ |= buffer[44];
+    ecefVZ <<= 8;
+    ecefVZ |= buffer[43];
+    ecefVZ <<= 8;
+    ecefVZ |= buffer[42];
+
+    sAcc = buffer[49] << 8;
+    sAcc |= buffer[48];
+    sAcc <<= 8;
+    sAcc |= buffer[47];
+    sAcc <<= 8;
+    sAcc |= buffer[46];
+
+    pDOP = buffer[51] << 8;
+    pDOP |= buffer[50];
+
+    reserved1 = buffer[52];
+
+    numSV = buffer[53];
+
+    reserved2 = buffer[57] << 8;
+    reserved2 |= buffer[56];
+    reserved2 <<= 8;
+    reserved2 |= buffer[55];
+    reserved2 <<= 8;
+    reserved2 |= buffer[54];
+
+    return true;
+}
+
+bool UbxGpsNavSol::calculateChecksum(unsigned char *buffer){
+  uint8_t check_a, check_b;
+  check_a = check_b = 0;
+
+  for(int i = 2; i < 58; i++){
+    check_a += buffer[i];
+    check_b += check_a;
+  }
+
+  if(check_a == buffer[59] && check_b == buffer[58])
+    return true;
+
+  else
+    return false;
+}
+
+bool UbxGpsNavSol::enableNAVSOL(){
+  const uint8_t buffer[] = {
+    0xB5, // sync char 1
+    0x62, // sync char 2
+    0x06, // class
+    0x01, // id
+    0x08, // length
+    0x00, // length
+    0x01, // payload
+    0x06, // payload
+    0x00, // payload
+    0x00, // payload
+    0x01, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x17, // CK_A
+    0xD9, // CK_B
+  };
+  if(this->writable()){
+    this->write(buffer, 16);
+    return true;
+  }
+
+  return false;
+}
+
+bool UbxGpsNavSol::restoreDefaults(){
+  const uint8_t packet[] = {
+    0xB5, // sync char 1
+    0x62, // sync char 2
+    0x06, // class
+    0x09, // id
+    0x0D, // length
+    0x00, // length
+    0xFF, // payload
+    0xFF, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0xFF, // payload
+    0xFF, // payload
+    0x00, // payload
+    0x00, // payload
+    0x17, // payload
+    0x2F, // CK_A
+    0xAE, // CK_B
+  };
+
+  if(this->writable()){
+    this->write(packet, 21);
+    return true;
+  }
+
+  return false;
+}
+
+void UbxGpsNavSol::disableNmea(){
+  const uint8_t messages[][2] = {
+      {0xF0, 0x0A},
+      {0xF0, 0x09},
+      {0xF0, 0x00},
+      {0xF0, 0x01},
+      {0xF0, 0x0D},
+      {0xF0, 0x06},
+      {0xF0, 0x02},
+      {0xF0, 0x07},
+      {0xF0, 0x03},
+      {0xF0, 0x04},
+      {0xF0, 0x0E},
+      {0xF0, 0x0F},
+      {0xF0, 0x05},
+      {0xF0, 0x08},
+      {0xF1, 0x00},
+      {0xF1, 0x01},
+      {0xF1, 0x03},
+      {0xF1, 0x04},
+      {0xF1, 0x05},
+      {0xF1, 0x06},
+  };
+
+  // CFG-MSG packet buffer
+  uint8_t packet[] = {
+      0xB5, // sync char 1
+      0x62, // sync char 2
+      0x06, // class
+      0x01, // id
+      0x03, // length
+      0x00, // length
+      0x00, // payload (first byte from messages array element)
+      0x00, // payload (second byte from messages array element)
+      0x00, // payload (not changed in the case)
+      0x00, // CK_A
+      0x00, // CK_B
+  };
+
+  uint8_t packetSize = sizeof(packet);
+
+  // Offset to the place where payload starts
+  uint8_t payloadOffset = 6;
+
+  // Iterate over the messages array
+  for (uint8_t i = 0; i < sizeof(messages) / sizeof(*messages); i++)
+  {
+      // Copy two bytes of payload to the packet buffer
+      for (uint8_t j = 0; j < sizeof(*messages); j++)
+      {
+          packet[payloadOffset + j] = messages[i][j];
+      }
+
+      // Set checksum bytes to the null
+      packet[packetSize - 2] = 0x00;
+      packet[packetSize - 1] = 0x00;
+
+      // Calculate checksum over the packet buffer excluding sync (first two) and checksum chars (last two)
+      for (uint8_t j = 0; j < packetSize - 4; j++)
+      {
+          packet[packetSize - 2] += packet[2 + j];
+          packet[packetSize - 1] += packet[packetSize - 2];
+      }
+
+      if(this->writable()){
+        this->write(packet, packetSize);
+      }
+    }
+}
+
+bool UbxGpsNavSol::changeBaudrate(){
+  const uint8_t packet[] = {
+    0xB5, // sync char 1
+    0x62, // sync char 2
+    0x06, // class
+    0x00, // id
+    0x14, // length
+    0x00, // length
+    0x01, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0xD0, // payload
+    0x08, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0xC2, // payload
+    0x01, // payload
+    0x00, // payload
+    0x07, // payload
+    0x00, // payload
+    0x03, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0x00, // payload
+    0xC0, // CK_A
+    0x7E, // CK_B
+  };
+
+  if(this->writable()){
+    this->write(packet, sizeof(packet));
+    return true;
+  }
+
+  return false;
+}
+
+bool UbxGpsNavSol::disableUnnecessaryChannels(){
+  const uint8_t packet[] = {
+    0xB5, // sync char 1
+    0x62, // sync char 2
+    0x06, // class
+    0x3E, // id
+    0x24, // length
+    0x00, // length
+
+    0x00, 0x00, 0x16, 0x04, 0x00, 0x04, 0xFF, 0x00, // payload
+    0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x00, // payload
+    0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x03, 0x00, // payload
+    0x00, 0x00, 0x00, 0x01, 0x06, 0x08, 0xFF, 0x00, // payload
+    0x00, 0x00, 0x00, 0x01,                         // payload
+
+    0xA4, // CK_A
+    0x25, // CK_B
+  };
+
+  if(this->writable()){
+    this->write(packet, sizeof(packet));
+    return true;
+  }
+
+  return false;
+}
+
+bool UbxGpsNavSol::changeFrequency(){
+  const uint8_t packet[] = {
+        0xB5, // sync char 1
+        0x62, // sync char 2
+        0x06, // class
+        0x08, // id
+        0x06, // length
+        0x00, // length
+        0x64, // payload
+        0x00, // payload
+        0x01, // payload
+        0x00, // payload
+        0x01, // payload
+        0x00, // payload
+        0x7A, // CK_A
+        0x12, // CK_B
+    };
+
+    if(this->writable()){
+      this->write(packet, sizeof(packet));
+      return true;
+    }
+
+    return false;
+}
+
+bool UbxGpsNavSol::disableGNSS(){
+    const uint8_t packet[] = {
+      0xB5, 0x62, 0x06, 0x3E, 0x3C, 0x00,
+      0x00, 0x00, 0x20, 0x07, 0x00, 0x08,
+      0x10, 0x00, 0x01, 0x00, 0x01, 0x01,
+      0x01, 0x01, 0x03, 0x00, 0x00, 0x00,
+      0x01, 0x01, 0x02, 0x04, 0x08, 0x00,
+      0x00, 0x00, 0x01, 0x01, 0x03, 0x08,
+      0x10, 0x00, 0x00, 0x00, 0x01, 0x01,
+      0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+      0x01, 0x01, 0x05, 0x00, 0x03, 0x00,
+      0x00, 0x00, 0x01, 0x01, 0x06, 0x08,
+      0x0E, 0x00, 0x00, 0x00, 0x01, 0x01,
+      0x2C, 0x4D
+    };
+
+    if(this->writable()){
+      this->write(packet, sizeof(packet));
+      return true;
+    }
+
+    return false;
+}
+
+void UbxGpsNavSol::baud(int baud){
+  this->set_baud(baud);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UbxGpsNavSol.hh	Mon Jun 17 00:10:40 2019 +0000
@@ -0,0 +1,63 @@
+#ifndef UBXGPSNAVSOL_H_
+#define UBXGPSNAVSOL_H_
+
+#include "mbed.h"
+
+#define  UBX_NAV_SOL_HEADER_1          (0xB5)
+#define  UBX_NAV_SOL_HEADER_2          (0x62)
+#define  UBX_NAV_SOL_CLASS                (0x01)
+#define  UBX_NAV_SOL_ID             (0x06)
+#define  UBX_NAV_SOL_PAYLOAD_LENGTH    (52)
+
+class UbxGpsNavSol : public UARTSerial{
+  public:
+    UbxGpsNavSol(PinName tx, PinName rx, int baud);
+    ~UbxGpsNavSol();
+
+    bool ready();
+    void disableNmea();
+    bool enableNAVSOL();
+    bool changeFrequency();
+    bool changeBaudrate();
+    bool disableUnnecessaryChannels();
+    bool disableGNSS();
+    bool restoreDefaults();
+    void baud(int baud);
+    // void setLength(unsigned char length);
+    // Type         Name           Unit     Description (scaling)
+    unsigned long   iTOW;       // ms       GPS time of week of the navigation epoch. See the description of iTOW for
+                                //          details
+    long            fTOW;       // ns       Fractional part of iTOW (range: +/-500000). The precise GPS time of week in
+                                //          seconds is: (iTOW * 1e-3) + (fTOW * 1e-9)
+    short           week;       // weeks    GPS week number of the navigation epoch
+    unsigned char   gpsFix;     // -        GPSfix Type, range 0..5
+    char            flags;      // -        Fix Status Flags (see graphic below)
+    long            ecefX;      // cm       ECEF X coordinate
+    long            ecefY;      // cm       ECEF Y coordinate
+    long            ecefZ;      // cm       ECEF Z coordinate
+    unsigned long   pAcc;       // cm       3D Position Accuracy Estimate
+    long            ecefVX;     // cm/s     ECEF X velocity
+    long            ecefVY;     // cm/s     ECEF Y velocity
+    long            ecefVZ;     // cm/s     ECEF Z velocity
+    unsigned long   sAcc;       // cm/s     Speed Accuracy Estimate
+    unsigned short  pDOP;       // -        Position DOP (0.01)
+    unsigned char   reserved1;  // -        Reserved
+    unsigned char   numSV;      // -        Number of satellites used in Nav Solution
+    unsigned long   reserved2;  // -        Reserved
+
+  private:
+    bool calculateChecksum(unsigned char *data);
+    // Class properties
+    unsigned char offsetClassProperties;
+    unsigned char offsetHeaders;
+    unsigned char size;
+    unsigned char carriagePosition;
+    unsigned char checksum[2];
+
+    // Headers (common).
+    unsigned char headerClass;
+    unsigned char headerId;
+    unsigned short headerLength;
+    uint16_t payload_length;
+};
+#endif
--- a/main.cpp	Tue Jun 04 23:58:46 2019 +0000
+++ b/main.cpp	Mon Jun 17 00:10:40 2019 +0000
@@ -1,13 +1,12 @@
 /* Includes */
 #include "mbed.h" /* Mbed include */
 
-#include "XNucleoIKS01A2.h" /* Sensors include*/
+/* Lora includes */
+#include "PinMap.h"
+#include "sx1276-mbed-hal.h"
 
-/* LoRa includes */
-#include "PinMap.h" 
-#include "sx1276-mbed-hal.h" 
-
-/* LoRa definitions */
+/* Serial communication include */
+#include "BufferedSerial.h"
 
 /* Set this flag to '1' to display debug messages on the console */
 #define DEBUG_MESSAGE   1
@@ -15,7 +14,7 @@
 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
 #define USE_MODEM_LORA  1
 #define USE_MODEM_FSK   !USE_MODEM_LORA
-#define RF_FREQUENCY            RF_FREQUENCY_915_0  // Hz
+#define RF_FREQUENCY            RF_FREQUENCY_915_0 // Hz
 #define TX_OUTPUT_POWER         14                  // 14 dBm
 
 #if USE_MODEM_LORA == 1
@@ -34,206 +33,208 @@
     
 #endif 
 
-
-#define RX_TIMEOUT_VALUE    3500    // in ms
+#define RX_TIMEOUT_VALUE    0       // In ms
+#define TX_TIMEOUT_VALUE    1000000 // In ms
 
 //#define BUFFER_SIZE       32        // Define the payload size here
-#define BUFFER_SIZE         64        // Define the payload size here
-
-/* Sensors instances */
-
-/* Instantiate the expansion board */
-static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
+#define BUFFER_SIZE         64      // Define the payload size here
 
-/* Retrieve the composing elements of the expansion board */
-static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer;
-static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
-static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
-static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
-static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
+typedef struct {
+        uint8_t header; // Header for identification of updated informations - 0 0 p temp LSM6DSL LSM303AGR
+        int time; // Time between transmissions
+        float p;  // Pressure of LPS22HB
+        float temperatureLPS22HB; // Temperature from LPS22HB
+        int32_t ag[3]; // Acceleration of the accelerometer and gyroscope LSM6DSL 
+        int32_t w[3]; // Angular velocity of LSM6DSL
+        int32_t a[3]; // Acceleration of the accelerometer LSM303AGR
+        int32_t m[3]; // Heading of LSM303AGR
+}Pkg1;
 
-//uint32_t dados[16]; //data vector
+typedef struct {
+        uint8_t header; // Header for identification of updated informations - 0 1 InternalCommunication HTS221
+        int time; // Time between transmissions
+        bool drogueStatus; // Drogue parachute status provided by Avionics
+        bool mainStatus; //Main parachute status provided by Avionics
+        bool mainStatusCOTS; // Main parachute status provided by COTS Altimeter
+        bool drogueStatusCOTS; // Drogue status provided by COTS Altimeter
+        float pressureBar; // Pressure by COTS Altimeter
+        float temperature; // Temperature by COTS Altimeter
+        int16_t timeStamp; // Timestamp from COTS Altimeter
+        int16_t aglAlt; // AGL Altitude from COTS Altimeter
+        int8_t battery; // Battery voltage reading from COTS Altimeter
+        float humidity; // Humidity of HTS221
+        float temperatureHTS221; // Temperature from HTS221
+        //uint8_t filler[25];
+}Pkg2;
+
 typedef struct {
-            float p; //pressure
-            float temperatureHTS221; //temperature from HTS221
-            float humidity; //humidity
-            float temperatureLPS22HB; //temperature from LPS22HB
-            int32_t w[3]; //angular velocity
-            int32_t a[3]; //acceleration of the accelerometer LSM303AGR
-            int32_t ag[3]; //acceleration of the accelerometer and gyroscope LSM6DSL 
-            int32_t m [3]; //heading 
-}Dados;
-        
-Dados dados;
+        uint8_t header; // Header for identification of updated informations - 1 0 GPS 
+        int time; // Time between transmissions
+        unsigned long timeOfWeek; //GPS time of week
+        long timeOfWeekFracPart; // GPS time of week fractional part
+        unsigned char gpsFix; // GPS fix
+        long ecefx; // GPS X posiition
+        long ecefy; // GPS Y posistion
+        long ecefz; // GPS Z postion
+        unsigned long positionAcc3D; // GPS 3D position accuracy
+        long ecefvx; // GPS X velocity
+        long ecefvy; // GPS Y velocity
+        long ecefvz; // GPS Z velocity
+        unsigned long speedAcc; // GPS speed accuracy
+        unsigned char numbSat; // GPS number of satellites conected
+        //uint8_t filler[8];
+}Pkg3;
+
+
+union Data {
+    Pkg1 pkg1;
+    Pkg2 pkg2;
+    Pkg3 pkg3;
+};
+
+Data data;
 
 /* LoRa modem instances and configurations */
 
 static RadioEvents_t RadioEvents; // Calback functions struct
 
-SX1276Generic *Radio; //Defenition of a Radio object
+SX1276Generic *Radio; // Definition of a Radio object
 
-/*Configuration function*/
+bool received = false; // Flag to indicate the end of reception
+
+/* Configuration function */
 void SystemClock_Config(void);
 
- bool transmited = true;
+/* Callback functions prototypes */
 
-/* Callback functions prototypes */
+// Brief Function to be executed on Radio Tx Done event
 void OnTxDone(void *radio, void *userThisPtr, void *userData);
 
+// Brief Function to be executed on Radio Rx Done event
 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
 
+// Brief Function executed on Radio Tx Timeout event
 void OnTxTimeout(void *radio, void *userThisPtr, void *userData);
 
+// Brief Function executed on Radio Rx Timeout event
 void OnRxTimeout(void *radio, void *userThisPtr, void *userData);
 
+// Brief Function executed on Radio Rx Error event
 void OnRxError(void *radio, void *userThisPtr, void *userData);
 
+// Brief Function executed on Radio Fhss Change Channel event
 void OnFhssChangeChannel(void *radio, void *userThisPtr, void *userData, uint8_t channelIndex);
 
+// Brief Function executed on CAD Done event
 void OnCadDone(void *radio, void *userThisPtr, void *userData);
 
 /* Serial communication to debug program */
-
-Serial pc(USBTX,USBRX);
+BufferedSerial *ser;
 
 int main() {
-    /* General Header*/
-    
-    pc.printf("Telemetry Tx inicial version program\r\n\r\n");
-    
-    uint8_t id; //Sensor id parameter for debug purpose
-    
-    /* Enable all sensors */
-    hum_temp->enable();
-    press_temp->enable();
-    magnetometer->enable();
-    accelerometer->enable();
-    acc_gyro->enable_x();
-    acc_gyro->enable_g();
-      
-    pc.printf("\r\n--- Starting the sensors ---\r\n");
+    SystemClock_Config(); /* Synchronize clock for TX and RX boards */
     
-    hum_temp->read_id(&id);
-    pc.printf("HTS221  humidity & temperature    = 0x%X\r\n", id);
-    press_temp->read_id(&id);
-    pc.printf("LPS22HB  pressure & temperature   = 0x%X\r\n", id);
-    magnetometer->read_id(&id);
-    pc.printf("LSM303AGR magnetometer            = 0x%X\r\n", id);
-    accelerometer->read_id(&id);
-    pc.printf("LSM303AGR accelerometer           = 0x%X\r\n", id);
-    acc_gyro->read_id(&id);
-    pc.printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id);
+    /* Serial configuration */
+    if (DEBUG_MESSAGE) {
+        ser = new BufferedSerial(USBTX, USBRX);
+        ser->baud(115200);
+        ser->format(8);
+    }
     
-    pc.printf("\r\n");
-    
-        /* Radio setup */
-     pc.printf("\r\n--- Starting the modem LoRa ---\r\n");
+    /* General Header*/
+    if (DEBUG_MESSAGE)
+        ser->printf("Telemetry Rx inicial version program\r\n\r\n");
     
     Radio = new SX1276Generic(NULL, MURATA_SX1276,
             LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
             LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5,
             LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO);
-    pc.printf("SX1276 Simple transmission aplication\r\n" );
-    pc.printf("Frequency: %.1f\r\n", (double)RF_FREQUENCY/1000000.0);
-    pc.printf("TXPower: %d dBm\r\n",  TX_OUTPUT_POWER);
-    pc.printf("Bandwidth: %d Hz\r\n", LORA_BANDWIDTH);
-    pc.printf("Spreading factor: SF%d\r\n", LORA_SPREADING_FACTOR);
+    
+    if (DEBUG_MESSAGE) {        
+        ser->printf("SX1276 Simple receiver aplication\r\n" );
+        ser->printf("Frequency: %.1f\r\n", (double)RF_FREQUENCY/1000000.0);
+        ser->printf("TXPower: %d dBm\r\n",  TX_OUTPUT_POWER);
+        ser->printf("Bandwidth: %d Hz\r\n", LORA_BANDWIDTH);
+        ser->printf("Spreading factor: SF%d\r\n", LORA_SPREADING_FACTOR);
+    }
     
     // Initialize Radio driver
     RadioEvents.TxDone = OnTxDone;
     RadioEvents.RxDone = OnRxDone;
     RadioEvents.RxError = OnRxError;
     RadioEvents.TxTimeout = OnTxTimeout;
-    RadioEvents.RxTimeout = OnRxTimeout;    
+    RadioEvents.RxTimeout = OnRxTimeout; 
+    
+    // Initializes the radio    
     while (Radio->Init( &RadioEvents ) == false) {
-        pc.printf("Radio could not be detected!\r\n");
+        if (DEBUG_MESSAGE)
+            ser->printf("Radio could not be detected!\r\n");
         wait( 1 );
     }
     
+    // Display the board type
     switch(Radio->DetectBoardType()) {
         case SX1276MB1LAS:
             if (DEBUG_MESSAGE)
-                pc.printf(" > Board Type: SX1276MB1LAS <\r\n");
+                ser->printf(" > Board Type: SX1276MB1LAS <\r\n");
             break;
         case SX1276MB1MAS:
             if (DEBUG_MESSAGE)
-                pc.printf(" > Board Type: SX1276MB1LAS <\r\n");
+                ser->printf(" > Board Type: SX1276MB1LAS <\r\n");
         case MURATA_SX1276:
             if (DEBUG_MESSAGE)
-                pc.printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n");
+                ser->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n");
             break;
         case RFM95_SX1276:
-            if (DEBUG_MESSAGE)
-                pc.printf(" > HopeRF RFM95xx <\r\n");
+            if (DEBUG_MESSAGE) 
+                ser->printf(" > HopeRF RFM95xx <\r\n");
             break;
         default:
-            pc.printf(" > Board Type: unknown <\r\n");
+            if (DEBUG_MESSAGE)
+                ser->printf(" > Board Type: unknown <\r\n");
     }
     
-    Radio->SetChannel(RF_FREQUENCY );
+    Radio->SetChannel(RF_FREQUENCY ); // Sets the frequency of the communication
     
-    if (LORA_FHSS_ENABLED)
-        pc.printf("             > LORA FHSS Mode <\r\n");
-    if (!LORA_FHSS_ENABLED)
-        pc.printf("             > LORA Mode <\r\n");
-        
-    pc.printf("\r\n");
-        
+    // Debug message of the state of fhss
+    if (LORA_FHSS_ENABLED) {
+        if (DEBUG_MESSAGE)
+            ser->printf("             > LORA FHSS Mode <\r\n");
+    }    
+    if (!LORA_FHSS_ENABLED) {
+        if (DEBUG_MESSAGE)
+            ser->printf("             > LORA Mode <\r\n");
+    }
+    // Sets the configuration of the transmission     
     Radio->SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                          LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                          LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
                          LORA_IQ_INVERSION_ON, 2000 );
     
+    // Sets the configuration of the reception
     Radio->SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                          LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                          LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
                          LORA_IQ_INVERSION_ON, true );
-      
-    Radio->Tx(1000000);
-    
-    while(1) {   
-    
-        
-        press_temp->get_pressure(&dados.p); //get the pressure
-        press_temp->get_temperature(&dados.temperatureLPS22HB); //get temperature from LPS22HB
-        accelerometer->get_x_axes(dados.a);//get the acceleration
-        acc_gyro->get_x_axes(dados.ag);//get the acceleration
-        acc_gyro->get_g_axes(dados.w);//get the angular velocity
-        magnetometer->get_m_axes(dados.m); //get the magnetometer heading
-        hum_temp->get_temperature(&dados.temperatureHTS221); //get temperature from HTS221
-        hum_temp->get_humidity(&dados.humidity); //get humidity
-        
-        
-        //sensors data
+    if (DEBUG_MESSAGE)
+        ser->printf("Starting Receive loop\r\n"); 
         
-        /*dados[0] = a[0];
-        dados[1] = a[1];
-        dados[2] = a[2];
-        dados[3] = ag[0];
-        dados[4] = ag[1];
-        dados[5] = ag[2];
-        dados[6] = w[0];
-        dados[7] = w[1];
-        dados[8] = w[2];
-        dados[9] = m[0];
-        dados[10] = m[1];
-        dados[11] = m[2];
-        dados[12] = humidity;
-        dados[13] = temperatureHTS221;
-        dados[14] = temperatureLPS22HB;
-        dados[15] = p;*/
-         
-        
-        if (transmited==true) {
-            transmited = false;
-            wait_ms(10);
-            Radio->Send( &dados, sizeof(dados) );
+    Radio->Rx(RX_TIMEOUT_VALUE); // Puts the device in reception mode continuously
+    
+    while( 1 )
+    {   
+        //After the receiving, puts the device again in receive mode 
+        if (received == true) {
+            received = false;
+            Radio->Rx(RX_TIMEOUT_VALUE); 
         }
     }
+    
 }
 
+
 void SystemClock_Config(void)
 {
 #ifdef B_L072Z_LRWAN1_LORA
@@ -278,44 +279,62 @@
 #endif
 }
 
-/* Helper function for printing floats & doubles */
-
-
 void OnTxDone(void *radio, void *userThisPtr, void *userData)
-{   
+{
     Radio->Sleep( );
-    transmited = true;
-    if (DEBUG_MESSAGE) {
-        pc.printf("> OnTxDone\r\n");
-        pc.printf("I transmited %d mg, %d mg, %d mg, %d mg, %d mg, %d mg, %d mdps, %d mdps, %d mdps\r\n", dados.a[0], dados.a[1], dados.a[2], dados.ag[0], dados.ag[1], dados.ag[2], dados.w[0], dados.w[1], dados.w[2]);
-        pc.printf("and %d mG, %d mG, %d mG, %g %%, %g C, %g C, %g mBar\r\n", dados.m[0], dados.m[1], dados.m[2], dados.humidity, dados.temperatureHTS221, dados.temperatureLPS22HB, dados.p);
-    }    
+    if (DEBUG_MESSAGE)
+        ser->printf("> OnTxDone\r\n");
 }
 
 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
 {
     Radio->Sleep( );
-    if (DEBUG_MESSAGE)
-        pc.printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\r\n", rssi, snr);
+    received = true;
+    uint8_t state = payload[0] >> 6;
+    
+    //ser->printf("The state is %x\r\n", state);
+    ser->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d, State=%d\r\n", rssi, snr, state);
+    //for(int i = 0; i < BUFFER_SIZE; i++){
+    //    ser->printf("%x ", payload[i]);   
+    //}
+    ser->printf("\r\n");
+    if(state == 3){
+        memcpy(&data.pkg1, payload, BUFFER_SIZE);
+        //ser->printf("Header: %x, time: %d, p: %f, tempLPS22HB: %f, ag: %d; %d; %d, w: %d; %d; %d, a: %d; %d; %d, m: %d; %d; %d\r\n", pkg1.header, pkg1.time, pkg1.p, pkg1.temperatureLPS22HB, pkg1.ag[0], pkg1.ag[1], pkg1.ag[2], pkg1.w[0], pkg1.w[1], pkg1.w[2], pkg1.a[0], pkg1.a[1], pkg1.a[2], pkg1.m[0], pkg1.m[1], pkg1.m[2]);   
+        ser->printf("%x,%d,%f,%f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", data.pkg1.header, data.pkg1.time, data.pkg1.p, data.pkg1.temperatureLPS22HB, data.pkg1.ag[0], data.pkg1.ag[1], data.pkg1.ag[2], data.pkg1.w[0], data.pkg1.w[1], data.pkg1.w[2], data.pkg1.a[0], data.pkg1.a[1], data.pkg1.a[2], data.pkg1.m[0], data.pkg1.m[1], data.pkg1.m[2]);
+    }
+    else if(state == 1){
+        memcpy(&data.pkg2, payload, BUFFER_SIZE);
+        //ser->printf("Header: %x, time: %d, parachuteStatus: %d%d%d%d, pressureBar: %f, temperature: %f, timeStamp: %d, aglAlt: %d, battery: %d, humidity: %f, tempHTS221: %f\r\n", pkg2.header, pkg2.time, pkg2.drogueStatus, pkg2.mainStatus, pkg2.mainStatusCOTS, pkg2.drogueStatusCOTS, pkg2.pressureBar, pkg2.temperature, pkg2.timeStamp, pkg2.aglAlt, pkg2.battery, pkg2.humidity, pkg2.temperatureHTS221);
+        ser->printf("%x,%d,%d%d%d%d,%f,%f,%d,%d,%d,%f,%f\r\n", data.pkg2.header, data.pkg2.time, data.pkg2.drogueStatus, data.pkg2.mainStatus, data.pkg2.mainStatusCOTS, data.pkg2.drogueStatusCOTS, data.pkg2.pressureBar, data.pkg2.temperature, data.pkg2.timeStamp, data.pkg2.aglAlt, data.pkg2.battery, data.pkg2.humidity, data.pkg2.temperatureHTS221);
+    }
+    else if(state == 2){
+        memcpy(&data.pkg3, payload, BUFFER_SIZE);
+        //ser->printf("Header: %x, time: %d, timeOfWeek: %d, frac: %d, gpsFix: %d\r\n", pkg3.header, pkg3.time, pkg3.timeOfWeek, pkg3.timeOfWeekFracPart, pkg3.gpsFix);
+        //ser->printf("eceFx: %d, eceFy: %d, eceFz: %d, posAcc3D: %d, eceFvx: %d, eceFvy: %d, eceFvz: %d\r\n", pkg3.ecefx, pkg3.ecefy, pkg3.ecefz, pkg3.positionAcc3D, pkg3.ecefvx, pkg3.ecefvy, pkg3.ecefvz);
+        //ser->printf("speedAcc: %d, numbSat: %d\r\n", pkg3.speedAcc, pkg3.numbSat);
+        ser->printf("%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", data.pkg3.header, data.pkg3.time, data.pkg3.timeOfWeek, data.pkg3.timeOfWeekFracPart, data.pkg3.gpsFix, data.pkg3.ecefx, data.pkg3.ecefy, data.pkg3.ecefz, data.pkg3.positionAcc3D, data.pkg3.ecefvx, data.pkg3.ecefvy, data.pkg3.ecefvz, data.pkg3.speedAcc, data.pkg3.numbSat);
+    }
 }
 
 void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
 {
     Radio->Sleep( );
     if(DEBUG_MESSAGE)
-        pc.printf("> OnTxTimeout\r\n");
+        ser->printf("> OnTxTimeout\r\n");
 }
 
 void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
 {
     Radio->Sleep( );
     if (DEBUG_MESSAGE)
-        pc.printf("> OnRxTimeout\r\n");
+        ser->printf("> OnRxTimeout\r\n");
 }
 
 void OnRxError(void *radio, void *userThisPtr, void *userData)
 {
     Radio->Sleep( );
+    received = true;
     if (DEBUG_MESSAGE)
-        pc.printf("> OnRxError\r\n");
+        ser->printf("> OnRxError\r\n");
 }