RX
Dependencies: mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2
Revision 0:674f1e460248, committed 2019-06-05
- Comitter:
- TMRL123
- Date:
- Wed Jun 05 00:23:37 2019 +0000
- Commit message:
- Commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BufferedSerial.lib Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/sam_grove/code/BufferedSerial/#a0d37088b405
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinMap.h Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Helmut Tschemernjak + * 30826 Garbsen (Hannover) Germany + * Licensed under the Apache License, Version 2.0); + */ + + + +#ifdef TARGET_NUCLEO_L476RG + #define FEATURE_LORA 1 +#elif TARGET_DISCO_L072CZ_LRWAN1 +#define FEATURE_LORA 1 +#endif + + + +#if defined(TARGET_DISCO_L072CZ_LRWAN1) + +#define LORA_SPI_MOSI PA_7 +#define LORA_SPI_MISO PA_6 +#define LORA_SPI_SCLK PB_3 +#define LORA_CS PA_15 +#define LORA_RESET PC_0 +#define LORA_DIO0 PB_4 +#define LORA_DIO1 PB_1 +#define LORA_DIO2 PB_0 +#define LORA_DIO3 PC_13 +#define LORA_DIO4 PA_5 +#define LORA_DIO5 PA_4 +#define LORA_ANT_RX PA_1 +#define LORA_ANT_TX PC_2 +#define LORA_ANT_BOOST PC_1 +#define LORA_TCXO PA_12 // 32 MHz + + + +#elif defined(TARGET_NUCLEO_L476RG) // using the RFM95 board + +#define LORA_SPI_MOSI PC_12 +#define LORA_SPI_MISO PC_11 +#define LORA_SPI_SCLK PC_10 +#define LORA_CS PA_0 +#define LORA_RESET PA_1 +#define LORA_DIO0 PD_2 // DIO0=TxDone/RXDone +#define LORA_DIO1 PB_7 // +#define LORA_DIO2 PC_14 // DIO2=FhssChangeChannel +#define LORA_DIO3 PC_15 // DIO3=CADDone +#define LORA_DIO4 PH_0 // ???? +#define LORA_DIO5 NC // unused? + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDCard_Y.cpp Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,244 @@ +#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 Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,30 @@ +#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/SX1276GenericLib.lib Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/TMRL123/code/SX1276GenericLib/#3e66a98f60fe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UbxGpsNavSol.cpp Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,427 @@ +#include "UbxGpsNavSol.hh" +#include "mbed.h" + +UbxGpsNavSol::UbxGpsNavSol(PinName tx, PinName rx, int baud):UARTSerial(tx, rx, baud){ + this->carriagePosition = 0; + // this->setLength(52); + this->offsetClassProperties = 8; + this->offsetHeaders = 4; +} + +UbxGpsNavSol::~UbxGpsNavSol(){} + +bool UbxGpsNavSol::ready(){ + //unsigned char buffer[60]; + + if(this->readable()){ + for(int k = 0; k < 60; k++) + this->buffer[k] = 0; + + this->read(this->buffer, 60); + } + + if(this->buffer[0] != UBX_NAV_SOL_HEADER_1 || this->buffer[1] != UBX_NAV_SOL_HEADER_2) + return false; + + if(this->buffer[2] != UBX_NAV_SOL_CLASS || this->buffer[3] != UBX_NAV_SOL_ID) + return false; + + payload_length = this->buffer[5]; + payload_length = payload_length << 8; + payload_length = this->buffer[4]; + + if(payload_length != UBX_NAV_SOL_PAYLOAD_LENGTH) + return false; + + if(calculateChecksum(buffer) == false) + return false; + + iTOW = this->buffer[9] << 8; + iTOW |= this->buffer[8]; + iTOW <<= 8; + iTOW |= this->buffer[7]; + iTOW <<= 8; + iTOW |= this->buffer[6]; + + fTOW = this->buffer[13] << 8; + fTOW |= this->buffer[12]; + fTOW <<= 8; + fTOW |= this->buffer[11]; + fTOW <<= 8; + fTOW |= this->buffer[10]; + + week = this->buffer[15] << 8; + week |= this->buffer[14]; + + gpsFix = this->buffer[16]; + + flags = this->buffer[17]; + + ecefX = this->buffer[21] << 8; + ecefX |= this->buffer[20]; + ecefX <<= 8; + ecefX |= this->buffer[19]; + ecefX <<= 8; + ecefX |= this->buffer[18]; + + ecefY = this->buffer[25] << 8; + ecefY |= this->buffer[24]; + ecefY <<= 8; + ecefY |= this->buffer[23]; + ecefY <<= 8; + ecefY |= this->buffer[22]; + + ecefZ = this->buffer[29] << 8; + ecefZ |= this->buffer[28]; + ecefZ <<= 8; + ecefZ |= this->buffer[27]; + ecefZ <<= 8; + ecefZ |= this->buffer[26]; + + pAcc = this->buffer[33] << 8; + pAcc |= this->buffer[32]; + pAcc <<= 8; + pAcc |= this->buffer[31]; + pAcc <<= 8; + pAcc |= this->buffer[30]; + + ecefVX = this->buffer[37] << 8; + ecefVX |= this->buffer[36]; + ecefVX <<= 8; + ecefVX |= this->buffer[35]; + ecefVX <<= 8; + ecefVX |= this->buffer[34]; + + ecefVY = this->buffer[41] << 8; + ecefVY |= this->buffer[40]; + ecefVY <<= 8; + ecefVY |= this->buffer[39]; + ecefVY <<= 8; + ecefVY |= this->buffer[38]; + + ecefVZ = this->buffer[45] << 8; + ecefVZ |= this->buffer[44]; + ecefVZ <<= 8; + ecefVZ |= this->buffer[43]; + ecefVZ <<= 8; + ecefVZ |= this->buffer[42]; + + sAcc = this->buffer[49] << 8; + sAcc |= this->buffer[48]; + sAcc <<= 8; + sAcc |= this->buffer[47]; + sAcc <<= 8; + sAcc |= this->buffer[46]; + + pDOP = this->buffer[51] << 8; + pDOP |= this->buffer[50]; + + reserved1 = this->buffer[52]; + + numSV = this->buffer[53]; + + reserved2 = this->buffer[57] << 8; + reserved2 |= this->buffer[56]; + reserved2 <<= 8; + reserved2 |= this->buffer[55]; + reserved2 <<= 8; + reserved2 |= this->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 1 + 0x62, // sync char 2 2 + 0x06, // class 3 + 0x01, // id 4 + 0x02, // length 5 + 0x00, // length 6 + 0x01, // payload 7 + 0x06, // payload 8 + 0x10,//CKA + 0x39,//CKB + + }; + if(this->writable()){ + this->write(buffer, 10); + 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 + 0x20, // length + 0x00, // length + 0x02, // payload - portID + 0x00, // payload - reserved0 + 0x00, // payload - txReady + 0x00, // payload - txReady + 0xD0, // payload - mode + 0x08, // payload - mode + 0x00, // payload - mode + 0x00, // payload - mode + 0x00, // payload - reserved3 + 0xC2, // payload - reserved3 + 0x01, // payload - reserved3 + 0x00, // payload - reserved3 + 0x07, // payload - inProtoMask + 0x00, // payload - inProtoMask + 0x03, // payload - outProtoMask --> activate NMEA??? + 0x00, // payload - outProtoMask + 0x00, // payload - flags + 0x00, // payload - flags + 0x00, // payload - reserved5 + 0x00, // payload - reserved5 + 0xCC, // CK_A + 0xBA, // 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); +} + +bool UbxGpsNavSol::saveConfiguration() { + const uint8_t packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x09, // id + 0x0D, // length + 0x00, // length + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0xFF, // payload + 0xFF, // payload + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0x00, // payload + 0x17, // payload + 0x31, // CK_A + 0xBF, // CK_B + }; + + if(this->writable()){ + this->write(packet, sizeof(packet)); + return true; + } + + return false; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UbxGpsNavSol.hh Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,66 @@ +#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); + virtual ~UbxGpsNavSol(); + + uint8_t buffer [60]; + bool ready(); + void disableNmea(); + bool enableNAVSOL(); + bool changeFrequency(); + bool changeBaudrate(); + bool disableUnnecessaryChannels(); + bool disableGNSS(); + bool restoreDefaults(); + void baud(int baud); + bool saveConfiguration(); + // 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 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/X_NUCLEO_IKS01A2.lib Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/TMRL123/code/X_NUCLEO_IKS01A2/#d8d170e96e23
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,399 @@ +#/* Includes */ +#include "mbed.h" /* Mbed include */ + +/* Lora includes */ +#include "PinMap.h" +#include "sx1276-mbed-hal.h" + +/* Serial communication include */ +#include "BufferedSerial.h" + +/* SD card includes */ +#include "SDCard_Y.hh" + +/* Set this flag to display debug messages on the console */ +#define DEBUG_MESSAGE + + +/* Definition of the SD card */ +#define SPI_FREQUENCY 1000000 + +/* Definition of the SD card */ +//#define SD_EN + +/* LoRa definitions */ + +/* Set this flag to display debug messages on the console */ +#define DEBUG_MESSAGE + +/* Set this flag to '1' to use the LoRa modulation */ +#define USE_MODEM_LORA 1 +#define USE_MODEM_FSK !USE_MODEM_LORA +#define RF_FREQUENCY RF_FREQUENCY_915_0 // Hz +#define TX_OUTPUT_POWER 14 // 20 dBm + +#if USE_MODEM_LORA == 1 + +#define LORA_BANDWIDTH 125000 // LoRa default, details in SX1276::BandwidthMap +#define LORA_SPREADING_FACTOR LORA_SF7 +#define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5 + +#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx +#define LORA_SYMBOL_TIMEOUT 5 // Symbols +#define LORA_FIX_LENGTH_PAYLOAD_ON false +#define LORA_FHSS_ENABLED false +#define LORA_NB_SYMB_HOP 4 +#define LORA_IQ_INVERSION_ON false +#define LORA_CRC_ENABLED true + +#endif + + +#define RX_TIMEOUT_VALUE 0 // In ms +#define TX_TIMEOUT_VALUE 1000000 // In ms + +typedef struct { + /* Header for identification of updated informations */ + bool header [8]; + int time; // Time between transmissions + 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 + float p; // Pressure of LPS22HB + float temperatureLPS22HB; // Temperature from LPS22HB + float humidity; // Humidity of HTS221 + float temperatureHTS221; // Temperature from HTS221 + 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 + bool drogueStatus; // Drogue parachute status provided by Avionics + bool mainStatus; //Main parachute status provided by Avionics + float pressureBar; // Pressure by COTS Altimeter + float temperature; // Temperature by COTS Altimeter + bool mainStatusCOTS; // Main parachute status provided by COTS Altimeter + bool drogueStatusCOTS; // Drogue status provided 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 +}Data; // Data struct + +Data data; + +/* LoRa modem instances and configurations */ + +static RadioEvents_t RadioEvents; // Calback functions struct + +SX1276Generic *Radio; // Definition of a Radio object + +/* Configuration function */ +void SystemClock_Config(void); + +bool received = false; // Flag to indicate the end of reception + + +/* 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); + +#ifdef DEBUG_MESSAGE +/* Serial communication to debug program */ +BufferedSerial *ser; +#endif + +int main() { + data.header [0] = 0; + data.header [1] = 0; + data.header [2] = 0; + data.header [3] = 0; + data.header [4] = 0; + data.header [5] = 0; + data.header [6] = 0; + data.header [7] = 0; + data.time = 0; + data.ag[0] = 0; + data.ag[1] = 0; + data.ag[2] = 0; + data.w[0] = 0; + data.w[1] = 0; + data.w[2] = 0; + data.a[0] = 0; + data.a[1] = 0; + data.a[2] = 0; + data.m [0] = 0; + data.m [1] = 0; + data.m [2] = 0; + data.p = 0; + data.temperatureLPS22HB = 0; + data.humidity = 0; + data.temperatureHTS221 = 0; + data.timeOfWeek = 0; + data.timeOfWeekFracPart = 0; + data.gpsFix = 0; + data.ecefx = 0; + data.ecefy = 0; + data.ecefz = 0; + data.positionAcc3D = 0; + data.ecefvx = 0; + data.ecefvy = 0; + data.ecefvz = 0; + data.speedAcc = 0; + data.numbSat = 0; + data.drogueStatus = 0; + data.mainStatus = 0; + data.pressureBar = 0; + data.temperature = 0; + data.mainStatusCOTS = 0; + data.drogueStatusCOTS = 0; + data.timeStamp = 0; + data.aglAlt = 0; + data.battery = 0; + + SystemClock_Config(); /* Synchronize clock for TX and RX boards */ + + /* Serial configuration */ + #ifdef DEBUG_MESSAGE + ser = new BufferedSerial(USBTX, USBRX); + ser->baud(115200); + ser->format(8); + #endif + + /* General Header*/ + #ifdef DEBUG_MESSAGE + ser->printf ("Telemetry Rx inicial version program\r\n\r\n"); + #endif + + /* Radio setup */ + #ifdef DEBUG_MESSAGE + ser->printf("\r\n--- Starting the modem LoRa ---\r\n"); + #endif + 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); + #ifdef DEBUG_MESSAGE + ser->printf("SX1276 Simple transmission 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); + #endif + + // Initialize Radio driver + RadioEvents.TxDone = OnTxDone; + RadioEvents.RxDone = OnRxDone; + RadioEvents.RxError = OnRxError; + RadioEvents.TxTimeout = OnTxTimeout; + RadioEvents.RxTimeout = OnRxTimeout; + + for (int i = 0; Radio->Init( &RadioEvents ) == false && i < 40; i++) { + #ifdef DEBUG_MESSAGE + ser->printf("Radio could not be detected!\r\n"); + #endif + wait_ms(500); + } + + // Display the board type + #ifdef DEBUG_MESSAGE + switch(Radio->DetectBoardType()) { + case SX1276MB1LAS: + ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); + break; + case SX1276MB1MAS: + ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); + break; + case MURATA_SX1276: + ser->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n"); + break; + case RFM95_SX1276: + ser->printf(" > HopeRF RFM95xx <\r\n"); + break; + default: + ser->printf(" > Board Type: unknown <\r\n"); + } + #endif + Radio->SetChannel(RF_FREQUENCY ); // Sets the frequency of the communication + + // Debug message of the state of fhss + #ifdef DEBUG_MESSAGE + if (LORA_FHSS_ENABLED) { + ser->printf(" > LORA FHSS Mode <\r\n"); + } + if (!LORA_FHSS_ENABLED) { + ser->printf(" > LORA Mode <\r\n"); + } + #endif + // 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 ); + + #ifdef SD_EN + SPI spi (PA_7, PA_6, PA_5); + spi.frequency (SPI_FREQUENCY); + SDCard sdCard (&spi, PB_10); + uint8_t sdData[sizeof(data)]; + int block = 0; + #endif + + 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) { + #ifdef SD_EN + // Saving the data on SD Card + memcpy (sdData, &data, sizeof(data)); + while(sdCard.write(&sdData[0],block) == 0); + block ++; + while (sdCard.write (&sdData[64],block) == 0); + block++; + while (sdCard.write(&sdData[128],block) == 0); + block++; + #endif + #ifdef DEBUG_MESSAGE + ser->printf("I received %d mg, %d mg, %d mg, %d mg, %d mg, %d mg, %d mdps, %d mdps, %d mdps\r\n", data.a[0], data.a[1], data.a[2], data.ag[0], data.ag[1], data.ag[2], data.w[0], data.w[1], data.w[2]); + ser->printf("and %d mG, %d mG, %d mG, %g %%, %g C, %g C, %g mBar\r\n", data.m[0], data.m[1], data.m[2], data.humidity, data.temperatureHTS221, data.temperatureLPS22HB, data.p); + ser->printf("and time - %d ms, time of the week - %d ms, time of week frac part - %d ns\r\n",data.time, data.timeOfWeek, data.timeOfWeekFracPart); + ser->printf("and GPS fix %c, ECEFX %d cm, ECEFY %d cm, ECEFZ %d cm\r\n", data.gpsFix, data.ecefx, data.ecefy, data.ecefz); + ser->printf("and 3D Position accuracy %d cm, ECEFVX %d cm/s, ECEFVY %d cm/s, ECEFVZ %d cm/s, Speed accuracy %d cm/s\r\n", data.positionAcc3D, data.ecefvx, data.ecefvy, data.ecefvz, data.speedAcc); + ser->printf("and Number of satelites %x, Drogue Status %x, Main status %x, BMP280 %f bar, temperature %f C\r\n", data.numbSat, data.drogueStatus, data.mainStatus, data.pressureBar, data.temperature); + ser->printf("Main Status COTS %x, Drogue Status COTS %x, Time Stamp %d s, AGL altitude %d m, Battery voltage %d V\r\n",data.mainStatusCOTS, data.drogueStatusCOTS, data.timeStamp, data.aglAlt, data.battery); + ser->printf("Header: %d, %d, %d, %d, %d, %d, %d, %d\r\n",data.header[0], data.header[1], data.header[2], data.header[3], data.header[4], data.header[5], data.header[6], data.header[7]); + #endif + received = false; + Radio->Rx(RX_TIMEOUT_VALUE); + } + } +} + + +void SystemClock_Config(void) +{ +#ifdef B_L072Z_LRWAN1_LORA + /* + * The L072Z_LRWAN1_LORA clock setup is somewhat differnt from the Nucleo board. + * It has no LSE. + */ + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + + /* Enable HSE Oscillator and Activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSEState = RCC_HSE_OFF; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6; + RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3; + + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + // Error_Handler(); + } + + /* Set Voltage scale1 as MCU will run at 32MHz */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */ + while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {}; + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { + // Error_Handler(); + } +#endif +} + +void OnTxDone(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + #ifdef DEBUG_MESSAGE + ser->printf("> OnTxDone\r\n"); + #endif +} + +void OnTxTimeout(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + #ifdef DEBUG_MESSAGE + ser->printf("> OnTxTimeout\r\n"); + #endif +} + +void OnRxTimeout(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + #ifdef DEBUG_MESSAGE + ser->printf("> OnRxTimeout\r\n"); + #endif +} + +void OnRxError(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + received = true; + #ifdef DEBUG_MESSAGE + ser->printf("> OnRxError\r\n"); + #endif +} + +void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) +{ + Radio->Sleep( ); + received = true; + memcpy(&data, payload, sizeof(data)); + /* #ifdef DEBUG_MESSAGE + ser->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\r\n", rssi, snr); + ser->printf("I received %d mg, %d mg, %d mg, %d mg, %d mg, %d mg, %d mdps, %d mdps, %d mdps\r\n", data.a[0], data.a[1], data.a[2], data.ag[0], data.ag[1], data.ag[2], data.w[0], data.w[1], data.w[2]); + ser->printf("and %d mG, %d mG, %d mG, %g %%, %g C, %g C, %g mBar\r\n", data.m[0], data.m[1], data.m[2], data.humidity, data.temperatureHTS221, data.temperatureLPS22HB, data.p); + ser->printf("and time - %d ms, time of the week - %d ms, time of week frac part - %d ns\r\n",data.time, data.timeOfWeek, data.timeOfWeekFracPart); + ser->printf("and GPS fix %c, ECEFX %d cm, ECEFY %d cm, ECEFZ %d cm\r\n", data.gpsFix, data.ecefx, data.ecefy, data.ecefz); + ser->printf("and 3D Position accuracy %d cm, ECEFVX %d cm/s, ECEFVY %d cm/s, ECEFVZ %d cm/s, Speed accuracy %d cm/s\r\n", data.positionAcc3D, data.ecefvx, data.ecefvy, data.ecefvz, data.speedAcc); + ser->printf("and Number of satelites %x, Drogue Status %x, Main status %x, BMP280 %f bar, temperature %f C\r\n", data.numbSat, data.drogueStatus, data.mainStatus, data.pressureBar, data.temperature); + ser->printf("Main Status COTS %x, Drogue Status COTS %x, Time Stamp %d s, AGL altitude %d m, Battery voltage %d V\r\n",data.mainStatusCOTS, data.drogueStatusCOTS, data.timeStamp, data.aglAlt, data.battery); + ser->printf("Header: %d, %d, %d, %d, %d, %d, %d, %d\r\n",data.header[0], data.header[1], data.header[2], data.header[3], data.header[4], data.header[5], data.header[6], data.header[7]); + #endif */ +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jun 05 00:23:37 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file