MAX32625PICO LP0 mode

Dependencies:   SX1276GenericLib USBDevice

Fork of PICO_LP0 by Walter Luu

main.cpp

Committer:
walterluu
Date:
2020-08-09
Revision:
2:f6ae69f3bfce
Parent:
0:664d9df11a00
Child:
3:85fc843a9d7d

File content as of revision 2:f6ae69f3bfce:

#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);          //comment out
        if (dwords) {
            unsigned int *ip = ( unsigned int *)u;
//            rprintf(" 0x%08x\r\n", *ip);
//            pc.printf(" 0x%08x\r\n", *ip);                         //comment out
            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));           //comment out
            if (i == seppos)
//                rprintf(" ");
                pc.printf(" ");                        //comment out
        }
//        rprintf(" ");
//        pc.printf(" ");                                 //comment out
        if (j < width) {
            i = width - j;
            if (i > seppos + 1)
//                rprintf(" ");
//                pc.printf(" ");                           //comment out
            while (i--) {
//                rprintf("%s", "   ");
//                pc.printf("%s", "   ");                      //comment out
            }
        }
        for (i = 0; i < j; i++) {
            int c = *(u + i);
            if (c >= ' ' && c <= '~')
//                rprintf("%c", c);
                pc.printf("%c", c);                              //comment out
            else
//                rprintf(".");
                pc.printf(".");                              //comment out
            if (i == seppos)
//                rprintf(" ");
                pc.printf(" ");                                 //comment out             
        }
        len -= width;
        u += width;
//        rprintf("\r\n");
//        pc.printf("\r\n");                                       //comment out
    }
//    rprintf("--\r\n");
//    pc.printf("--\r\n");                                         //comment out
}


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