MAX32625PICO LP0 mode

Dependencies:   SX1276GenericLib USBDevice

Fork of PICO_LP0 by Walter Luu

Revision:
0:664d9df11a00
Child:
2:f6ae69f3bfce
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Aug 07 00:50:01 2020 +0000
@@ -0,0 +1,566 @@
+#include "mbed.h"
+#include "PinMap.h"
+
+//#include "BufferedSerial.h"
+
+//#ifdef FEATURE_USBSERIAL
+//#include "USBSerialBuffered.h"
+//#endif
+//
+//#ifdef FEATURE_USBSERIAL
+//extern USBSerialBuffered *usb;
+//#endif
+
+#include "GenericPingPong.h"
+ 
+#define FEATURE_LORA
+#include "sx1276-mbed-hal.h"
+#include "main.h"
+
+
+//#if defined(TARGET_MAX32630FTHR) // using the RFM95 board
+#include "max32630fthr.h"
+MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
+//#endif
+
+#include "USBSerial.h"  // for virtual COM
+
+#define BS          8       // ASCII Back Space
+#define CR          13      // ASCII Carriage Return
+
+// Virtual serial port over USB TODO NEW VID PID NEEDED!!
+USBSerial pc(0x0B6A, 0x0042, 0x0001, false);
+
+DigitalOut myled(LED2);          // LED = LED2 green
+DigitalOut rLED(LED1);          // red LED
+DigitalOut bLED(LED3);          // blue LED
+
+
+/*
+LoRa initialization
+*/
+
+/* Set this flag to '1' to display debug messages on the console */
+#define DEBUG_MESSAGE   1
+
+/* 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 TX_OUTPUT_POWER         14                  // 14 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
+    
+#elif USE_MODEM_FSK == 1
+
+#define FSK_FDEV                25000     // Hz
+#define FSK_DATARATE            19200     // bps
+#define FSK_BANDWIDTH           50000     // Hz
+#define FSK_AFC_BANDWIDTH       83333     // Hz
+#define FSK_PREAMBLE_LENGTH     5         // Same for Tx and Rx
+#define FSK_FIX_LENGTH_PAYLOAD_ON   false
+#define FSK_CRC_ENABLED         true
+    
+#else
+    #error "Please define a modem in the compiler options."
+#endif 
+
+
+#define RX_TIMEOUT_VALUE    3500    // in ms
+
+//#define BUFFER_SIZE       32        // Define the payload size here
+#define BUFFER_SIZE         64        // Define the payload size here
+
+/*
+ *  Global variables declarations
+ */
+typedef enum
+{
+    LOWPOWER = 0,
+    IDLE,
+    
+    RX,
+    RX_TIMEOUT,
+    RX_ERROR,
+    
+    TX,
+    TX_TIMEOUT,
+    
+    CAD,
+    CAD_DONE
+} AppStates_t;
+
+volatile AppStates_t State = LOWPOWER;
+
+/*!
+ * Radio events function pointer
+ */
+static RadioEvents_t RadioEvents;
+
+/*
+ *  Global variables declarations
+ */
+SX1276Generic *Radio;
+
+
+const uint8_t PingMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'I', 'N', 'G'};// "PING";
+const uint8_t PongMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'O', 'N', 'G'};// "PONG";
+
+uint16_t BufferSize = BUFFER_SIZE;
+uint8_t *Buffer;
+
+DigitalOut *led3;
+
+int main() {
+
+// This mbed-os is copied from Joey's PICO_I2C_FW_Virtual_COM project: FTHR becomes a virtual serial port.
+    
+myled = 0;                      // green led off
+rLED = 0;                       // red led off
+bLED = 0;                       // blue led off
+
+/************ Testing purpose ************
+*/
+//pc.printf("Hello World\n");
+//bLED = 1;
+//wait(3); 
+//bLED = 0;
+//
+//while (1) {
+//    pc.printf("Testing\n");
+//    pc.printf("Haha\n");
+//    wait(1);
+//    myled = !myled;
+//    }    
+    
+    pc.printf("Starting LoRa Example\n");
+//    GenericPingPong.SX1276PingPong();
+    SX1276PingPong();
+}
+
+int SX1276PingPong(void) 
+{
+//    dprintf("TEST" );
+    pc.printf("TEST");
+#if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
+    DigitalOut *led = new DigitalOut(LED2);
+#elif defined(TARGET_NUCLEO_L073RZ) || defined(TARGET_DISCO_L072CZ_LRWAN1)
+    DigitalOut *led = new DigitalOut(LED4);   // RX red
+    led3 = new DigitalOut(LED3);  // TX blue
+#else
+    DigitalOut *led = new DigitalOut(LED1);             // led = LED1 red  FTHR board
+    led3 = led;                                         // led3 = led red  FTHR board
+#endif
+    
+    Buffer = new  uint8_t[BUFFER_SIZE];
+    *led3 = 1;                                          // red LED on
+
+#ifdef B_L072Z_LRWAN1_LORA
+    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);
+#else // RFM95
+    Radio = new SX1276Generic(NULL, RFM95_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);
+
+#endif
+    
+    uint8_t i;
+    bool isMaster = true;
+    
+//    dprintf("SX1276 Ping Pong Demo Application" );
+    pc.printf("SX1276 Ping Pong Demo Application");
+//    dprintf("Freqency: %.1f", (double)RF_FREQUENCY/1000000.0);
+    pc.printf("Freqency: %.1f", (double)RF_FREQUENCY/1000000.0);
+//    dprintf("TXPower: %d dBm",  TX_OUTPUT_POWER);
+    pc.printf("TXPower: %d dBm",  TX_OUTPUT_POWER);
+#if USE_MODEM_LORA == 1
+//    dprintf("Bandwidth: %d Hz", LORA_BANDWIDTH);
+    pc.printf("Bandwidth: %d Hz", LORA_BANDWIDTH);
+//    dprintf("Spreading factor: SF%d", LORA_SPREADING_FACTOR);
+    pc.printf("Spreading factor: SF%d", LORA_SPREADING_FACTOR);
+#elif USE_MODEM_FSK == 1
+//    dprintf("Bandwidth: %d kHz",  FSK_BANDWIDTH);
+    pc.printf("Bandwidth: %d kHz",  FSK_BANDWIDTH);
+//    dprintf("Baudrate: %d", FSK_DATARATE);
+    pc.printf("Baudrate: %d", FSK_DATARATE);
+#endif
+    // Initialize Radio driver
+    RadioEvents.TxDone = OnTxDone;
+    RadioEvents.RxDone = OnRxDone;
+    RadioEvents.RxError = OnRxError;
+    RadioEvents.TxTimeout = OnTxTimeout;
+    RadioEvents.RxTimeout = OnRxTimeout;    
+    if (Radio->Init( &RadioEvents ) == false) {
+        while(1) {
+//            dprintf("Radio could not be detected!");
+            pc.printf("Radio could not be detected!");
+            wait( 1 );
+        }
+    }
+
+    
+    switch(Radio->DetectBoardType()) {            // check where DetectBoardType is!!
+        case SX1276MB1LAS:
+            if (DEBUG_MESSAGE)
+//                dprintf(" > Board Type: SX1276MB1LAS <");
+                pc.printf(" > Board Type: SX1276MB1LAS <");
+            break;
+        case SX1276MB1MAS:
+            if (DEBUG_MESSAGE)
+//                dprintf(" > Board Type: SX1276MB1LAS <");
+                pc.printf(" > Board Type: SX1276MB1LAS <");
+        case MURATA_SX1276:
+            if (DEBUG_MESSAGE)
+//                dprintf(" > Board Type: MURATA_SX1276_STM32L0 <");
+                pc.printf(" > Board Type: MURATA_SX1276_STM32L0 <");
+            break;
+        case RFM95_SX1276:
+            if (DEBUG_MESSAGE)
+//                dprintf(" > HopeRF RFM95xx <");
+                pc.printf(" > HopeRF RFM95xx <");
+            break;
+        default:
+//            dprintf(" > Board Type: unknown <");
+            pc.printf(" > Board Type: unknown <");
+    }
+
+    Radio->SetChannel(RF_FREQUENCY ); 
+
+#if USE_MODEM_LORA == 1
+    
+    if (LORA_FHSS_ENABLED)
+//        dprintf("             > LORA FHSS Mode <");
+        pc.printf("             > LORA FHSS Mode <");
+    if (!LORA_FHSS_ENABLED)
+//        dprintf("             > LORA Mode <");
+        pc.printf("             > LORA Mode <");
+
+    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 );
+    
+    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 );
+                         
+#elif USE_MODEM_FSK == 1
+
+//    dprintf("              > FSK Mode <");
+    pc.printf("              > FSK Mode <");
+    Radio->SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
+                         FSK_DATARATE, 0,
+                         FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
+                         FSK_CRC_ENABLED, 0, 0, 0, 2000 );
+    
+    Radio->SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
+                         0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
+                         0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
+                         0, 0, false, true );
+                         
+#else
+
+#error "Please define a modem in the compiler options."
+
+#endif
+     
+    if (DEBUG_MESSAGE)
+        pc.printf("Starting Ping-Pong loop"); 
+//        dprintf("Starting Ping-Pong loop"); 
+
+        
+    Radio->Rx( RX_TIMEOUT_VALUE );
+    
+    while( 1 )
+    {
+#ifdef TARGET_STM32L4
+    //     WatchDogUpdate();
+#endif
+        
+        switch( State )
+        {
+        case RX:
+            *led3 = 0;
+            if( isMaster == true )
+            {
+                if( BufferSize > 0 )
+                {
+                    if( memcmp(Buffer, PongMsg, sizeof(PongMsg)) == 0 )
+                    {
+                        *led = !*led;
+//                        dprintf( "...Pong" );
+                        pc.printf( "...Pong" );
+                        // Send the next PING frame            
+                        memcpy(Buffer, PingMsg, sizeof(PingMsg));
+                        // We fill the buffer with numbers for the payload 
+                        for( i = sizeof(PingMsg); i < BufferSize; i++ )
+                        {
+                            Buffer[i] = i - sizeof(PingMsg);
+                        }
+                        wait_ms( 10 ); 
+                        Radio->Send( Buffer, BufferSize );
+                    }
+                    else if( memcmp(Buffer, PingMsg, sizeof(PingMsg)) == 0 )
+                    { // A master already exists then become a slave
+//                        dprintf( "...Ping" );
+                        pc.printf( "...Ping" );
+                        *led = !*led;
+                        isMaster = false;
+                        // Send the next PONG frame
+                        memcpy(Buffer, PongMsg, sizeof(PongMsg));        
+                        // We fill the buffer with numbers for the payload 
+                        for( i = sizeof(PongMsg); i < BufferSize; i++ )
+                        {
+                            Buffer[i] = i - sizeof(PongMsg);
+                        }
+                        wait_ms( 10 ); 
+                        Radio->Send( Buffer, BufferSize );
+                    }
+                    else // valid reception but neither a PING or a PONG message
+                    {    // Set device as master ans start again
+                        isMaster = true;
+                        Radio->Rx( RX_TIMEOUT_VALUE );
+                    }    
+                }
+            }
+            else
+            {
+                if( BufferSize > 0 )
+                {
+                    if( memcmp(Buffer, PingMsg, sizeof(PingMsg)) == 0 )
+                    {
+                        *led = !*led;
+//                        dprintf( "...Ping" );
+                        pc.printf( "...Ping" );
+                        // Send the reply to the PING string
+                        memcpy(Buffer, PongMsg, sizeof(PongMsg));
+                        // We fill the buffer with numbers for the payload 
+                        for( i = sizeof(PongMsg); i < BufferSize; i++ )
+                        {
+                            Buffer[i] = i - sizeof(PongMsg);
+                        }
+                        wait_ms( 10 );  
+                        Radio->Send( Buffer, BufferSize );
+                    }
+                    else // valid reception but not a PING as expected
+                    {    // Set device as master and start again
+                        isMaster = true;
+                        Radio->Rx( RX_TIMEOUT_VALUE );
+                    }    
+                }
+            }
+            State = LOWPOWER;
+            break;
+        case TX:    
+            *led3 = 1;
+            if( isMaster == true )  
+            {
+//                dprintf("Ping..." );
+                pc.printf("Ping..." );
+            }
+            else
+            {
+//                dprintf("Pong..." );
+                pc.printf("Pong..." );
+            }
+            Radio->Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        case RX_TIMEOUT:
+            if( isMaster == true )
+            {
+                // Send the next PING frame
+                memcpy(Buffer, PingMsg, sizeof(PingMsg));
+                for( i = sizeof(PingMsg); i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - sizeof(PingMsg);
+                }
+                wait_ms( 10 ); 
+                Radio->Send( Buffer, BufferSize );
+            }
+            else
+            {
+                Radio->Rx( RX_TIMEOUT_VALUE );  
+            }             
+            State = LOWPOWER;
+            break;
+        case RX_ERROR:
+            // We have received a Packet with a CRC error, send reply as if packet was correct
+            if( isMaster == true )
+            {
+                // Send the next PING frame
+                memcpy(Buffer, PingMsg, sizeof(PingMsg));
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                wait_ms( 10 );  
+                Radio->Send( Buffer, BufferSize );
+            }
+            else
+            {
+                // Send the next PONG frame
+                memcpy(Buffer, PongMsg, sizeof(PongMsg));
+                for( i = sizeof(PongMsg); i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - sizeof(PongMsg);
+                }
+                wait_ms( 10 );  
+                Radio->Send( Buffer, BufferSize );
+            }
+            State = LOWPOWER;
+            break;
+        case TX_TIMEOUT:
+            Radio->Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        case LOWPOWER:
+            sleep();
+            break;
+        default:
+            State = LOWPOWER;
+            break;
+        }    
+    }
+}
+
+void dump(const char *title, const void *data, int len, bool dwords)
+{
+//    dprintf("dump(\"%s\", 0x%x, %d bytes)", title, data, len);
+    pc.printf("dump(\"%s\", 0x%x, %d bytes)", title, data, len);
+
+    int i, j, cnt;
+    unsigned char *u;
+    const int width = 16;
+    const int seppos = 7;
+
+    cnt = 0;
+    u = (unsigned char *)data;
+    while (len > 0) {
+//        rprintf("%08x: ", (unsigned int)data + cnt);
+        pc.printf("%08x: ", (unsigned int)data + cnt);
+        if (dwords) {
+            unsigned int *ip = ( unsigned int *)u;
+//            rprintf(" 0x%08x\r\n", *ip);
+            pc.printf(" 0x%08x\r\n", *ip);
+            u+= 4;
+            len -= 4;
+            cnt += 4;
+            continue;
+        }
+        cnt += width;
+        j = len < width ? len : width;
+        for (i = 0; i < j; i++) {
+//            rprintf("%2.2x ", *(u + i));
+            pc.printf("%2.2x ", *(u + i));
+            if (i == seppos)
+//                rprintf(" ");
+                pc.printf(" ");
+        }
+//        rprintf(" ");
+        pc.printf(" ");
+        if (j < width) {
+            i = width - j;
+            if (i > seppos + 1)
+//                rprintf(" ");
+                pc.printf(" ");
+            while (i--) {
+//                rprintf("%s", "   ");
+                pc.printf("%s", "   ");
+            }
+        }
+        for (i = 0; i < j; i++) {
+            int c = *(u + i);
+            if (c >= ' ' && c <= '~')
+//                rprintf("%c", c);
+                pc.printf("%c", c);
+            else
+//                rprintf(".");
+                pc.printf(".");
+            if (i == seppos)
+//                rprintf(" ");
+                pc.printf(" ");
+        }
+        len -= width;
+        u += width;
+//        rprintf("\r\n");
+        pc.printf("\r\n");
+    }
+//    rprintf("--\r\n");
+    pc.printf("--\r\n");
+}
+
+
+void OnTxDone(void *radio, void *userThisPtr, void *userData)
+{
+    Radio->Sleep( );
+    State = TX;
+    if (DEBUG_MESSAGE)
+        //dprintf("> OnTxDone");
+        pc.printf("> OnTxDone");
+}
+
+void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    Radio->Sleep( );
+    BufferSize = size;
+    memcpy( Buffer, payload, BufferSize );
+    State = RX;
+    if (DEBUG_MESSAGE)
+        pc.printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d", rssi, snr);
+//        dprintf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d", rssi, snr);
+//    dump("Data:", payload, size);
+    dump("Data:", payload, size, false);
+}
+
+void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
+{
+    *led3 = 0;
+    Radio->Sleep( );
+    State = TX_TIMEOUT;
+    if(DEBUG_MESSAGE)
+        pc.printf("> OnTxTimeout");
+//        dprintf("> OnTxTimeout");
+}
+
+void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
+{
+    *led3 = 0;
+    Radio->Sleep( );
+    Buffer[BufferSize-1] = 0;
+    State = RX_TIMEOUT;
+    if (DEBUG_MESSAGE)
+        pc.printf("> OnRxTimeout");
+//        dprintf("> OnRxTimeout");
+}
+
+void OnRxError(void *radio, void *userThisPtr, void *userData)
+{
+    Radio->Sleep( );
+    State = RX_ERROR;
+    if (DEBUG_MESSAGE)
+        pc.printf("> OnRxError");
+//        dprintf("> OnRxError");
+}
+
+
+
+//#endif