RX

Dependencies:   mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2

Revision:
0:674f1e460248
--- /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 */    
+}
+