Version FC

Dependencies:   DmTftLibrary eeprom SX1280Lib filesystem mbed

Fork of MSNV2-Terminal_V1-5 by Francis CHATAIN

main.cpp

Committer:
FCH_31
Date:
2017-08-02
Revision:
2:57f098de07c7
Parent:
1:22e02d1cfbca
Child:
3:3adb454ba1d2

File content as of revision 2:57f098de07c7:

#include "mbed.h"
#include "radio.h"
#include "sx1280-hal.h"


#define FIRMWARE_VERSION ( ( char* )"Firmware Version: 01" )    // display firmware version on RS232
#define MODE_LORA                                               // Lora modulation 
#define RF_FREQUENCY     2400000000UL                           // HzNominal frequency
#define TX_OUTPUT_POWER  13                                     // Output power in dBm [-18..+13] dBm

typedef enum         // States of the application
{
    APP_LOWPOWER,
    APP_RX,
    APP_RX_TIMEOUT,
    APP_RX_ERROR,
    APP_TX,
    APP_TX_TIMEOUT,
}AppStates_t;

#define BUFFER_SIZE     16          // Payload size
//#define BUFFER_SIZE                                 34

/*!
 * Message type for this application
 */
//const uint8_t PingMsg[] = "DATA IOT TERMINAL";
//const uint8_t PongMsg[] = "RESPONSE GATEWAY ";
const uint8_t PingMsg[] = "PING DATA IOT TERMINAL";
const uint8_t PongMsg[] = "PONG";

/*!
 * \brief Defines the size of the token defining message type in the payload
 */
#define PINGPONGSIZE                    4

uint8_t BufferSize = BUFFER_SIZE;           // Size of the buffer
uint8_t Buffer[BUFFER_SIZE];                // Buffer 

AppStates_t AppState = APP_LOWPOWER;        // State of the application

int8_t RssiValue = 0;
int8_t SnrValue = 0;

void OnTxDone       ( void );               // Function to be executed on Radio Tx Done event
void OnRxDone       ( void );               // Function to be executed on Radio Rx Done event
void OnTxTimeout    ( void );               // Function executed on Radio Tx Timeout event
void OnRxTimeout    ( void );               // Function executed on Radio Rx Timeout event
void OnRxError      ( IrqErrorCode_t );     // Function executed on Radio Rx Error event

RadioCallbacks_t callbacks =                // All the callbacks are stored in a structure
{
    &OnTxDone,        // txDone
    &OnRxDone,        // rxDone
    NULL,             // syncWordDone
    NULL,             // headerDone
    &OnTxTimeout,     // txTimeout
    &OnRxTimeout,     // rxTimeout
    &OnRxError,       // rxError
    NULL,             // rangingDone
    NULL,             // cadDone
};

//                    mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks...
SX1280Hal Radio     ( D11 , D12 , D13 , D7 , D3  , D5  , NC  , NC  , A0 , &callbacks );

DigitalOut ANT_SW   ( A3 );
DigitalOut TxLed    ( A4 );
DigitalOut RxLed    ( A5 );

/*!
 * Define IO for Unused Pin
 */
DigitalOut F_CS     ( D6 );     // MBED description of pin
DigitalOut SD_CS    ( D8 );     // MBED description of pin

#define TX_TIMEOUT_VALUE        100         // ms   Number of tick size steps for tx timeout
#define RX_TIMEOUT_VALUE        100         // ms Number of tick size steps for rx timeout
#define RX_TIMEOUT_TICK_SIZE    RADIO_TICK_SIZE_1000_US   // Size of ticks (used for Tx and Rx timeout)

uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in rx mode
uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in tx mode

PacketParams_t PacketParams;        // Locals parameters and status for radio API
PacketStatus_t PacketStatus;        // NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING

bool isMaster       = true;
ModulationParams_t modulationParams;


/* Specify serial datarate for UART debug output */
void baud   ( int baudrate )    { Serial s( USBTX, USBRX ); s.baud( baudrate );}

void setup () {
    baud    (115200);
    
    printf( "\n\n\r     SX1280 Terminal IoT LORA MODULATION 2.4GHz (%s)\n\n\r", FIRMWARE_VERSION );

    F_CS   = 1  ;
    SD_CS  = 1  ;
    RxLed  = 1  ;
    TxLed  = 1  ;
    ANT_SW = 1  ;

    wait_ms( 500 ); // wait for on board DC/DC start-up time

    Radio.Init              ( );
    
    Radio.SetRegulatorMode  ( USE_DCDC ); // Can also be set in LDO mode but consume more power

    memset  ( &Buffer, 0x00, BufferSize );

 
    RxLed = 0;
    TxLed = 0;
    
    modulationParams.PacketType                     =   PACKET_TYPE_LORA        ;
    modulationParams.Params.LoRa.SpreadingFactor    =   LORA_SF7                ;
    modulationParams.Params.LoRa.Bandwidth          =   LORA_BW_0400            ;
    modulationParams.Params.LoRa.CodingRate         =   LORA_CR_4_5             ;

    PacketParams.PacketType                         =   PACKET_TYPE_LORA        ;
    PacketParams.Params.LoRa.PreambleLength         =   0x08                    ;
    PacketParams.Params.LoRa.HeaderType             =   LORA_PACKET_VARIABLE_LENGTH;
    PacketParams.Params.LoRa.PayloadLength          =   15                      ;
    PacketParams.Params.LoRa.CrcMode        = LORA_CRC_ON;
    PacketParams.Params.LoRa.InvertIQ       = LORA_IQ_INVERTED;


    Radio.SetStandby                ( STDBY_RC );
    Radio.SetPacketType             ( modulationParams.PacketType );
    Radio.SetModulationParams       ( &modulationParams );
    Radio.SetPacketParams           ( &PacketParams );

    Radio.SetRfFrequency            ( RF_FREQUENCY );
    Radio.SetBufferBaseAddresses    ( 0x00, 0x00 );
    Radio.SetTxParams               ( TX_OUTPUT_POWER, RADIO_RAMP_20_US );

    Radio.SetDioIrqParams           ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
    Radio.SetRx                     ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );

    AppState = APP_LOWPOWER;   
    
    }

void loop () {   
        switch( AppState )
        {
            case APP_RX:
            printf( "*** TERM ***  APP_RX      \r\n" ); 
                AppState            =   APP_LOWPOWER;
                RxLed               =   !RxLed;
                Radio.GetPayload    ( Buffer, &BufferSize, BUFFER_SIZE );
                
                printf  ( "Message Received : %s \r\n", Buffer );
               
                if( isMaster == true )
                {
                    if( BufferSize > 0 )
                    {
                        if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, PINGPONGSIZE ) == 0 )
                        {
                            printf  ( "<Master> Recv ...Pong\r\n" );
                            wait_ms (2000) ; 
                            memcpy( Buffer, PingMsg, PINGPONGSIZE );
                            Radio.SetDioIrqParams       ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                            Radio.SendPayload           ( Buffer, BufferSize,( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
                        }
                                                
                        else // valid reception but neither a PING or a PONG message
                        {    // Set device as master ans start again
                            printf( "<Master> Unknown message \r\n" );
         
                            isMaster = true;
                            Radio.SetDioIrqParams   ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                            Radio.SetRx             ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
                        }
                    }
                }
                
                // Receiver 
                else
                {
                    if( BufferSize > 0 )
                    {
                        if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 )
                        {
                            printf                  ( "...Ping\r\n" );
                            memcpy                  ( Buffer, PongMsg, 4 );
                            Radio.SetDioIrqParams   ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                            Radio.SendPayload       ( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
                        }
                        else // valid reception but not a PING as expected
                        {
                            printf( "<Slave> Unknown message \r\n" );
                            isMaster = true;
                            Radio.SetDioIrqParams   ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                            Radio.SetRx             ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
                        }
                    }
                }
                break;

            case APP_TX:
            printf( "*** TERM ***  APP_TX      \r\n" ); 
                AppState = APP_LOWPOWER;
                TxLed = !TxLed;
                if( isMaster == true )          printf( "<Master> Send Ping...\r\n" );
                else                            printf( "<Slave>  Send Pong...\r\n" );

                Radio.SetDioIrqParams       ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                Radio.SetRx                 ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
                break;

            case APP_RX_TIMEOUT:
            printf( "*** TERM ***  APP_RX_TIMEOUT      \r\n" ); 
                AppState = APP_LOWPOWER;
                if( isMaster == true )
                {
                    // Send the next PING frame
                    memcpy                  ( Buffer, PingMsg, PINGPONGSIZE );
                    Radio.SetDioIrqParams   ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                    Radio.SendPayload       ( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
                }
                else
                {
                    Radio.SetDioIrqParams   ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                    Radio.SetRx             ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
                }
                break;

            case APP_RX_ERROR:
            printf( "*** TERM ***  APP_RX_ERROR      \r\n" ); 
                AppState = APP_LOWPOWER;
                // 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, PINGPONGSIZE );
                    Radio.SetDioIrqParams   ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                    Radio.SendPayload       ( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
                }
                else
                {
                    // Send the next PONG frame
                    memcpy                  ( Buffer, PongMsg, PINGPONGSIZE );
                    Radio.SetDioIrqParams   ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                    Radio.SendPayload       ( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
                }
                break;

            case APP_TX_TIMEOUT:
           printf( "*** TERM ***  APP_TX_TIMEOUT      \r\n" ); 
                AppState        = APP_LOWPOWER;
                Radio.SetDioIrqParams       ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
                Radio.SetRx                 ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
                break;

            case APP_LOWPOWER:
                break;

            default:
                // Set low power
                break;
        }
}
   
  
    

int main( )  { setup () ; while (1) loop () ; }

void OnTxDone       ( void )                            { printf( "*** TERM ***  OnTxDone      \r\n" ); AppState = APP_TX         ;   }
void OnRxDone       ( void )                            { printf( "*** TERM ***  OnRxDone      \r\n" ); AppState = APP_RX         ;   }
void OnTxTimeout    ( void )                            { printf( "*** TERM ***  OnTxTimeout   \r\n" ); AppState = APP_TX_TIMEOUT ;   }
void OnRxTimeout    ( void )                            { printf( "*** TERM ***  OnRxTimeout   \r\n" ); AppState = APP_RX_TIMEOUT ;   } 
void OnRxError      ( IrqErrorCode_t errorCode )        { printf( "*** TERM ***  OnRxError     \r\n" ); AppState = APP_RX_ERROR   ;   }
void OnRangingDone  ( IrqRangingCode_t val )            { printf( "*** TERM ***  OnRangingDone \r\n" ); }
void OnCadDone      ( bool channelActivityDetected )    { printf( "*** TERM ***  OnCadDone     \r\n" ); }

   /*
    Radio.GetPacketStatus(&packetStatus);
    RssiValue = packetStatus.Lr24.RssiPkt;
    SnrValue = packetStatus.Lr24.SnrPkt;
    printf("rssi: %d; snr: %d\n\r", RssiValue, SnrValue );
    */