Updated Nov. 18th.

Dependencies:   SX1276Lib_modtronix

Fork of SX1276PingPong by Semtech

main.cpp

Committer:
AMNoll
Date:
2017-11-19
Revision:
16:4051b7c16410
Parent:
15:8b35dd7c1436

File content as of revision 16:4051b7c16410:

#include "mbed.h"
#include "sx1276Regs-LoRa.h"
#include "sx1276-inAir.h"
 
#define DEBUG                           1
 
#define RF_FREQUENCY                    915000000           // 915MHz
#define TX_OUTPUT_POWER                 14                  // 14 dBm for inAir9
#define LORA_BANDWIDTH                  7                   // 0: 7.8 kHz,  1: 10.4 kHz, 2: 15.6kHz, 3: 20.8kHz,
                                                            // 4: 31.25kHz, 5: 41.7 kHz, 6: 62.5 kHz,
                                                            // 7: 125 kHz,  8: 250 kHz,  9: 500 kHz
#define LORA_SPREADING_FACTOR           12                  // SF7..SF12
#define LORA_CODINGRATE                 1                   // 1=4/5, 2=4/6, 3=4/7, 4=4/8
#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
 
#define TX_TIMEOUT_VALUE                2000000
#define RX_TIMEOUT_VALUE                3500000     // in us
#define BUFFER_SIZE                     32          // Define the payload size here
 
 
void OnTxDone(void);
void OnTxTimeout(void);
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
void OnRxTimeout(void);
void OnRxError(void);
 
Serial      pc(USBTX, USBRX);   //Use default TX and RX. Available via USB Com port when using PGM-NUCLEO programmer
SX1276inAir radio(OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, NULL, NULL);
DigitalOut led(LED1);
 
uint8_t Buffer[BUFFER_SIZE];
uint16_t BufferSize = BUFFER_SIZE;
int16_t LoRaRssi;
int8_t LoRaSNR;
volatile RadioState State = LOWPOWER;

const uint8_t PingMsg[] = "PING";
const uint8_t PongMsg[] = "PONG";
 
int main() { 
    wait_ms(500); // start delay
 
    // configure uart port
    pc.baud(9600);
    pc.format(8, SerialBase::None, 1);
    pc.printf("PC printing enabled\n\r");
    wait(2);
    // configure radio
    radio.SetBoardType(BOARD_INAIR9); // the correct hardware for our own board
    pc.printf("Board type set\n\r");
    
    /*
    while (true) {
        led = !led;
        pc.printf("loop reached\n\r");
        wait(2);
    }*/
    
    led = 0;
    while (radio.Read(REG_VERSION) == 0x00)
    {
        pc.printf("Trying to connect to radio device\r\n");
        wait_ms(200);
    }
    led = 1;
 
    pc.printf("%u",radio.Read(REG_VERSION));
    pc.printf("Radio is initialized\r\n");
 
    // set radio frequency
    radio.SetChannel(RF_FREQUENCY);
 
    pc.printf("Freq set to 915 MHz\r\n");
 
    // setup the modern
    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,
            TX_TIMEOUT_VALUE
    );
    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
    );
    pc.printf("TX and RX configured\r\n");
 
    uint8_t i;
    bool isMaster = true;
 
    pc.printf("before .Rx\r\n");
    radio.Rx(RX_TIMEOUT_VALUE);
    pc.printf("RX_TIMEOUT_VALUE RX set\r\n");
 
    State = RX_TIMEOUT;
    
    while (1)
    {
        // Check for connection to radio module
        while (radio.Read(REG_VERSION) == 0x00)
        {
            led = !led;
            pc.printf("Reconnecting...\r\n");
            wait_ms(200);
        }
        led = 1;
    
        pc.printf("%s\r\n",State );
        //pc.printf("About to check State value\r\n");
        
        switch(State)
        {
        case RX_DONE:
            if (isMaster)
            {
                if (BufferSize > 0)
                {
                    if (strncmp((const char *)Buffer, (const char *)PongMsg, 4) == 0)
                    {
                        pc.printf("...Pong\r\n");
                        // send next ping frame
                        strcpy((char *)Buffer, (char *)PingMsg);
                        // fill the buffer with numbers for the payload
                        for( i = 4; i < BufferSize; i++ )
                        {
                            Buffer[i] = i - 4;
                        }
                        wait_ms( 10 );
                        radio.Send( Buffer, BufferSize );
                    }
                    else if (strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
                    {
                        // A master already exists then become a slave
                        pc.printf("...Ping\r\n");
                        isMaster = false;
                        // send the next pong frame
                        strcpy( ( char* )Buffer, ( char* )PongMsg );
                        // We fill the buffer with numbers for the payload
                        for( i = 4; i < BufferSize; i++ )
                        {
                            Buffer[i] = i - 4;
                        }
                        wait_ms( 10 );
                        radio.Send( Buffer, BufferSize );
                    }
                    else
                    {
                        isMaster = true;
                        radio.Rx(RX_TIMEOUT_VALUE);
                    }
                }
            }
            else
            {
                if (BufferSize > 0)
                {
                    if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
                    {
                        pc.printf( "...Ping\r\n");
                        // Send the reply to the PING string
                        strcpy( ( char* )Buffer, ( char* )PongMsg );
                        // We fill the buffer with numbers for the payload
                        for( i = 4; i < BufferSize; i++ )
                        {
                            Buffer[i] = i - 4;
                        }
                        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;
            pc.printf( "\r\n");
            break;
 
        case TX_DONE:
            if (isMaster)
            {
                pc.printf("Ping...\r\n");
            }
            else
            {
                pc.printf("Pong...\r\n");
            }
            radio.Rx(RX_TIMEOUT_VALUE);
            State = LOWPOWER;
            break;
 
        case RX_TIMEOUT:
            if( isMaster == true )
            {
                pc.printf("trying to send ping\r\n");
                // Send the next PING frame
                strcpy( ( char* )Buffer, ( char* )PingMsg );
                for( i = 4; i < BufferSize; i++ )
                {
                    Buffer[i] = i - 4;
                }
                wait_ms( 10 );
                radio.Send( Buffer, BufferSize );
            }
            else
            {
                radio.Rx( RX_TIMEOUT_VALUE );
            }
            State = LOWPOWER;
            break;
 
        case TX_TIMEOUT:
            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
                strcpy( ( char* )Buffer, ( char* )PingMsg );
                for( i = 4; i < BufferSize; i++ )
                {
                    Buffer[i] = i - 4;
                }
                wait_ms( 10 );
                radio.Send( Buffer, BufferSize );
            }
            else
            {
                // Send the next PONG frame
                strcpy( ( char* )Buffer, ( char* )PongMsg );
                for( i = 4; i < BufferSize; i++ )
                {
                    Buffer[i] = i - 4;
                }
                wait_ms( 10 );
                radio.Send( Buffer, BufferSize );
            }
            State = LOWPOWER;
            break;
 
        case LOWPOWER:
            break;
 
        default:
            State = LOWPOWER;
            break;
        }
    }
} 


void OnTxDone(void)
{
    radio.Sleep();
    State = TX_DONE;
 
#if DEBUG == 1
    pc.printf("OnTxDone\r\n");
#endif
}
 
void OnTxTimeout(void)
{
    radio.Sleep();
    State = TX_TIMEOUT;
 
#if DEBUG == 1
    pc.printf("OnTxTimeout\r\n");
#endif
}
 
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
    radio.Sleep();
    BufferSize = size;
    memcpy(Buffer, payload, BufferSize);
    LoRaRssi = rssi;
    LoRaSNR = snr;
    State = RX_DONE;
 
#if DEBUG == 1
    pc.printf("OnRxDone\r\n");
#endif
}
 
void OnRxTimeout(void)
{
    radio.Sleep();
    Buffer[BufferSize] = 0;
    State = RX_TIMEOUT;
 
#if DEBUG == 1
    pc.printf("OnRxTimeout\r\n");
#endif
}
 
void OnRxError(void)
{
    radio.Sleep();
    State = RX_ERROR;
 
#if DEBUG == 1
    pc.printf("OnRxError\r\n");
#endif
}