Version FC

Dependencies:   DmTftLibrary eeprom SX1280Lib filesystem mbed

Fork of MSNV2-Terminal_V1-5 by Francis CHATAIN

Radio.cpp

Committer:
FCH_31
Date:
2018-10-22
Revision:
41:5a436163dddf

File content as of revision 41:5a436163dddf:

/*
 *  MISNet
 *
 *  TERMINAL Radio module
 *
 *  Created on: September 19, 2018    Author: Francis CHATAIN
 *
 */

// ================================================================= INCLUDES

#include "mbed.h"
#include "main.h"
#include "Radio.h"
#include "sx1280-hal.h"
#include <string.h>


// ================================================================= VARIABLE & DEFINE

extern "C"{
  int _getpid       ()                  { return -1;}
  int _kill         (int pid, int sig)  { return -1; }
  extern int _write ()  ;   //{return -1;}
}

//DigitalOut  ledReceive      (PA_8)  ;
//DigitalOut  ledSend         (PB_13) ;
DigitalOut  ledReceive      (A5)  ;
DigitalOut  ledSend         (A4) ;


/******************************************************************************
 * Declaration of RADIO variables and function
 *****************************************************************************/

// FEM      TxEN:PB3 RxEN:PB9
//DigitalOut  femTx   (PB_3);
//DigitalOut  femRx   (PB_9);

#define     BUFFER_SIZE   100
uint8_t     BufferSize  = BUFFER_SIZE;
uint8_t     Buffer[BUFFER_SIZE];

int8_t      RssiValue   = 0 ;
int8_t      SnrValue    = 0 ;

typedef enum { APP_IDLE=0, APP_LOWPOWER, APP_RX, APP_RX_TIMEOUT, APP_RX_ERROR, APP_TX, APP_TX_TIMEOUT,} AppStates_t;
AppStates_t AppState = APP_LOWPOWER ;

ModulationParams_t  ModulationParams ;
ModulationParams_t  ModulationParamsEmitter ;
ModulationParams_t  ModulationParamsReceiver;

PacketParams_t      PacketParamsReceiver ;
PacketStatus_t      PacketStatusReceiver ;

PacketParams_t      PacketParamsEmitter  ;


// Radio Callback event
void OnTxDone       (void)                      { AppState = APP_TX         ; }
void OnRxDone       (void)                      { AppState = APP_RX         ; }
void OnTxTimeout    (void)                      { AppState = APP_TX_TIMEOUT ; }
void OnRxTimeout    (void)                      { AppState = APP_RX_TIMEOUT ; }
void OnRxError      (IrqErrorCode_t errorCode)  { AppState = APP_RX_ERROR   ; }
void OnRangingDone  (IrqRangingCode_t val)      { }
void OnCadDone      (bool channelActivityDetected){}

RadioCallbacks_t callbacks ={
    &OnTxDone       , &OnRxDone     ,       // tx / rx Done
    NULL            , NULL          ,       // syncWordDone headerDone
    &OnTxTimeout    , &OnRxTimeout  ,       // txTimeout rxTimeout
    &OnRxError      ,                       // rxError
    NULL            , NULL          ,       // rangingDone / cadDone
};

//  Timeout callback
#define         TX_TIMEOUT_VALUE                100                 // ms
#define         RX_TIMEOUT_VALUE                0x00000000          //   or 100    (ms)
#define         RX_TIMEOUT_TICK_SIZE            RADIO_TICK_SIZE_1000_US

uint16_t        RxIrqMask           = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT   ;
uint16_t        TxIrqMask           = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT   ;


int8_t          rssi=0, snr=0;

// SX1280   MOSI:PA7 MISO:PA6 CLK:PA5  CS:PA4  BSY:PB7  DIO1:PB6  DIO2:PB5  DIO3:PB4  RST:PB8
// SX1280Hal   Radio   (PA_7, PA_6, PA_5, PA_4, PB_7, PB_6, PB_5, PB_4, PB_8, &callbacks);//mosi miso clk cs bsy dio1 dio2 dio3 rst   [DONGLE]
SX1280Hal   Radio   ( D11 , D12 , D13 , D7 , D3  , D5  , NC  , NC  , A0 , &callbacks );     //   [NUCLEO] 

//Radio Factory Parameter Sender and Receiver    only diff the Central Frequency emetter are shited by 800 Mhz
uint8_t         _modulation         =   PACKET_TYPE_LORA;
int             _spreadingFactor    =   2               ;
int             _bandWidth          =   1               ;
int             _codingRate         =   0               ;
unsigned long   _frequencySend      =   2400000000UL    ;
unsigned long   _frequencyReceive   =   2400000000UL    ;
int             _outputPower        =   13              ;   // -18 to +13 dBm
int             _size               =   10              ;

int             _iq                 =   1               ;
int             _crc                =   0               ;
uint8_t         _ar[]               =   { 0xDD, 0xA0, 0x96, 0x69, 0xDD  }       ;  // only used in GENERIC and BLE mode
uint8_t         _crcSeedLocal[3]    =   { 0x00, 0x45, 0x67              }       ;  // only used in GFSK, FLRC


// Futur use with FLRC modulation
//int           _mode               =   4               ;
//int           _modeShape          =   1               ;
//int           _modeIndex          =   2               ;
//int           _whitening          =   1               ;
//int           _bitrateBandwidth   =   12              ;

//  ============================================================================================ Declaration Internal function

RadioLoRaCodingRates_t      returnCrLORA    (int index) ;
RadioLoRaSpreadingFactors_t returnSfLORA    (int index) ;
RadioLoRaBandwidths_t       returnBwLORA    (int index) ;

void                        setFemTxRx      (bool tx)   ;   // only if FEM HW 

/* Evolution FLRC
 * RadioCrcTypes_t          returnCrcLen    (int index) ;
 * RadioFlrcBitrates_t      returnBrbwFLRC  (int index) ;
 * RadioFlrcCodingRates_t   returnCrFLRC    (int index) ;
 * RadioModShapings_t       returnMs        (int index) ;
 */

// ============================================================================================ EXTERNAL FUNCTION


// ============================================================================================ Radio Self Test

bool radioSelfTest  (uint16_t *rev) {
  Radio.Init();
  *rev = Radio.GetFirmwareVersion () ;
  // printf("*** RAD_ ***  Selftest : Firmware R%u\r\n", rev);
  wait(0.2);
  //printf((rev==0xffff?"Self test FAIL\r\n":"Self test PASS\r\n"));
  if    (*rev==0xffff)  return false ;
  else                  return true  ;
}

// ============================================================================================ Radio Initialisation


void radioInitReceiver          (RadioParameter radioParameter ) {
    _modulation         = radioParameter.modulation         ;
    _spreadingFactor    = radioParameter.spreadingFactor    ;
    _bandWidth          = radioParameter.bandWidth          ;
    _codingRate         = radioParameter.codingRate         ;
    _frequencyReceive   = radioParameter.frequency          ;

    if( _modulation == PACKET_TYPE_LORA ) {
        ModulationParamsReceiver.PacketType                  =  PACKET_TYPE_LORA;
        ModulationParamsReceiver.Params.LoRa.SpreadingFactor =  returnSfLORA    (_spreadingFactor)  ;
        ModulationParamsReceiver.Params.LoRa.Bandwidth       =  returnBwLORA    (_bandWidth)        ;
        ModulationParamsReceiver.Params.LoRa.CodingRate      =  returnCrLORA    (_codingRate)       ;
        PacketParamsReceiver.PacketType                    =    PACKET_TYPE_LORA;
        PacketParamsReceiver.Params.LoRa.PreambleLength    =    0x08;
        PacketParamsReceiver.Params.LoRa.HeaderType        =    LORA_PACKET_VARIABLE_LENGTH;
        PacketParamsReceiver.Params.LoRa.PayloadLength     =    7   ;
        PacketParamsReceiver.Params.LoRa.Crc               =    _crc==1?LORA_CRC_ON:LORA_CRC_OFF;
        PacketParamsReceiver.Params.LoRa.InvertIQ          =    _iq==1?LORA_IQ_INVERTED:LORA_IQ_NORMAL;
         //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength;
     }
}

void radioInitEmitter           (RadioParameter radioParameter ) {
    _modulation         = radioParameter.modulation         ;
    _spreadingFactor    = radioParameter.spreadingFactor    ;
    _bandWidth          = radioParameter.bandWidth          ;
    _codingRate         = radioParameter.codingRate         ;
    _size               = radioParameter.size               ;
    _frequencySend      = radioParameter.frequency          ;

    if( _modulation == PACKET_TYPE_LORA ) {
        ModulationParamsEmitter.PacketType                  =   PACKET_TYPE_LORA                    ;
        ModulationParamsEmitter.Params.LoRa.SpreadingFactor =   returnSfLORA    (_spreadingFactor)  ;
        ModulationParamsEmitter.Params.LoRa.Bandwidth       =   returnBwLORA    (_bandWidth)        ;
        ModulationParamsEmitter.Params.LoRa.CodingRate      =   returnCrLORA    (_codingRate)       ;
        PacketParamsEmitter.PacketType                    =     PACKET_TYPE_LORA                    ;
        PacketParamsEmitter.Params.LoRa.PreambleLength    =     0x08                                ;
        PacketParamsEmitter.Params.LoRa.HeaderType        =     LORA_PACKET_VARIABLE_LENGTH         ;
        PacketParamsEmitter.Params.LoRa.PayloadLength     =     _size                               ;
        PacketParamsEmitter.Params.LoRa.Crc               =     _crc==1?LORA_CRC_ON:LORA_CRC_OFF    ;
        PacketParamsEmitter.Params.LoRa.InvertIQ          =     _iq==1?LORA_IQ_INVERTED:LORA_IQ_NORMAL;
         //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength;
     }
}


void radioInitRadio () {
     Radio.SetStandby               ( STDBY_RC )        ;
     Radio.SetCrcSeed               ( _crcSeedLocal )   ;
     Radio.SetCrcPolynomial         ( 0x0123 )          ;
     Radio.SetPollingMode           ( )                 ;
     Radio.SetBufferBaseAddresses   ( 0x00, 0x00 )      ;
     Radio.SetSyncWord              ( 1, _ar )          ;
}

void radioStartReceive (RadioParameter radioParameter) {
    _frequencyReceive   = radioParameter.frequency          ;
    _outputPower        = radioParameter.outputPower        ;

//    setFemTxRx                  (0) ;
    ledSend             =       0   ;
    ledReceive          =       0   ;

    Radio.SetPacketType         ( ModulationParamsReceiver.PacketType )     ;
    Radio.SetModulationParams   ( &ModulationParamsReceiver )               ;
    Radio.SetPacketParams       ( &PacketParamsReceiver )                   ;
    Radio.SetRfFrequency        ( _frequencyReceive )                       ;
    Radio.SetDioIrqParams       ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE )        ;
    Radio.SetRx                 ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } )   ;

    AppState        =           APP_LOWPOWER        ;
    memset                      ( &Buffer , 0x00, BufferSize )  ;
}


void    radioSend                   (RadioParameter radioParameter, uint8_t  *frame, uint8_t len) {
        _frequencySend      = radioParameter.frequency          ;
        _outputPower        = radioParameter.outputPower        ;

        ledSend             =       1   ;
        ledReceive          =       0   ;
//        setFemTxRx(1);

        Radio.SetPacketType         ( ModulationParamsEmitter.PacketType )      ;
        Radio.SetModulationParams   ( &ModulationParamsEmitter )                ;
        Radio.SetPacketParams       ( &PacketParamsEmitter )                    ;
        Radio.SetRfFrequency        ( _frequencySend )                      ;
        Radio.SetTxParams           ( _outputPower, RADIO_RAMP_20_US )  ;
        Radio.SetDioIrqParams       ( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
        Radio.SendPayload           ( frame, len, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
}

// ============================================================================================ Radio Handler
bool radioHandler(uint8_t *frame, uint8_t *len, int8_t *rssi, int8_t *snr){

    bool event = false ;
    Radio.ProcessIrqs();
    switch( AppState )    {
      case APP_RX:
          printf ("*** RADIO ***  radioHandler   APP RX  \r\n"); 
          AppState = APP_LOWPOWER;
          memset    ( &Buffer , 0, BUFFER_SIZE )    ;
          ledReceive = !ledReceive;
          Radio.GetPayload( Buffer, len, BUFFER_SIZE );
          //cdc2->printf   ("APP-RX Buffer = %s\r\n", Buffer);
          //showRssiSnr () ;
          Radio.GetPacketStatus(&PacketStatusReceiver);
          *rssi =  PacketStatusReceiver.LoRa.RssiPkt;
          *snr  =  PacketStatusReceiver.LoRa.SnrPkt;
          memcpy (frame, Buffer, *len) ;
          event = true ;
          //printBytes (Buffer, 30) ;
          setFemTxRx(0);   
          Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
          Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
          ledReceive = !ledReceive;
      break;

      case APP_TX:
          printf ("*** RADIO ***  radioHandler   APP TX  \r\n"); 
          AppState = APP_LOWPOWER;
          //cdc2->printf   ("APP-TX \r\n");
          setFemTxRx(0);   // if fem 
          Radio.SetPacketType       ( ModulationParamsReceiver.PacketType )     ;
          Radio.SetModulationParams ( &ModulationParamsReceiver )               ;
          Radio.SetPacketParams     ( &PacketParamsReceiver )                   ;
          Radio.SetRfFrequency      ( _frequencyReceive )                       ;

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

      case APP_RX_TIMEOUT:
            printf ("*** RADIO ***  radioHandler   APP RX Timeout \r\n"); 
            AppState = APP_LOWPOWER;
            setFemTxRx(0);
            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:
          AppState = APP_LOWPOWER;
      break;

      case APP_TX_TIMEOUT:
          printf ("*** RADIO ***  radioHandler   APP TX Timeout \r\n"); 
          AppState = APP_LOWPOWER;
          //cdc2->printf   ("APP-TX \r\n");
          setFemTxRx(0);
          Radio.SetPacketType       ( ModulationParamsReceiver.PacketType )     ;
          Radio.SetModulationParams ( &ModulationParamsReceiver )               ;
          Radio.SetPacketParams     ( &PacketParamsReceiver )                   ;
          Radio.SetRfFrequency      ( _frequencyReceive )                       ;

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

      case APP_LOWPOWER:
      break;

      default:
      // Set low power
      break;
    }
    return event ;
}




// ======================================================================================================  INTERNAL FUNCTION

RadioLoRaCodingRates_t returnCrLORA (int index) {
  // coding rate for LoRa
  switch(index){
    case 0: return LORA_CR_4_5;
    case 1: return LORA_CR_4_6;
    case 2: return LORA_CR_4_7;
    case 3: return LORA_CR_4_8;
    case 4: return LORA_CR_LI_4_5;
    case 5: return LORA_CR_LI_4_6;
    case 6: return LORA_CR_LI_4_7;
    default :  return LORA_CR_4_5;
  }
}


// SF for LoRa
RadioLoRaSpreadingFactors_t returnSfLORA(int index) {
  switch(index){
    case 0:     return LORA_SF5 ;
    case 1:     return LORA_SF6 ;
    case 2:     return LORA_SF7 ;
    case 3:     return LORA_SF8 ;
    case 4:     return LORA_SF9 ;
    case 5:     return LORA_SF10;
    case 6:     return LORA_SF11;
    case 7:     return LORA_SF12;
    default :   return LORA_SF7 ;
  }
}
RadioModShapings_t returnMs(int index){
  // shaping for FLRC GFSK and BLE
  switch(index){
    case 0:     return RADIO_MOD_SHAPING_BT_OFF ;
    case 1:     return RADIO_MOD_SHAPING_BT_1_0 ;
    case 2:     return RADIO_MOD_SHAPING_BT_0_5 ;
    default :   return RADIO_MOD_SHAPING_BT_1_0 ;
  }
}
RadioLoRaBandwidths_t returnBwLORA(int index){
  // bandwidth for LoRa
  switch(index){
    case 0:     return LORA_BW_0200     ;
    case 1:     return LORA_BW_0400     ;
    case 2:     return LORA_BW_0800     ;
    case 3:     return LORA_BW_1600     ;
    default :   return LORA_BW_1600     ;
  }
}


void setFemTxRx(bool tx)    {
    /*   Hoel module 
    if      (tx) { femTx=1 ; femRx=0 ; }
    else         { femRx=1 ; femTx=0 ; }
    */
}


/*   Futur Use
 *
 *      else if( _modulation == PACKET_TYPE_FLRC )      {
       ModulationParams.PacketType                    =     PACKET_TYPE_FLRC;
       ModulationParams.Params.Flrc.BitrateBandwidth  =     returnBrbwFLRC  (_bitrateBandwidth);// FLRC_BR_0_260_BW_0_3;
       ModulationParams.Params.Flrc.CodingRate        =     returnCrFLRC    (codingRate);//FLRC_CR_1_2;
       ModulationParams.Params.Flrc.ModulationShaping =     returnMs        (_modeShape);//RADIO_MOD_SHAPING_BT_1_0;
       PacketParams.PacketType                        =     PACKET_TYPE_FLRC;
       PacketParams.Params.Flrc.PreambleLength        =     PREAMBLE_LENGTH_32_BITS;
       PacketParams.Params.Flrc.SyncWordLength        =     FLRC_SYNCWORD_LENGTH_4_BYTE;
       PacketParams.Params.Flrc.SyncWordMatch         =     RADIO_RX_MATCH_SYNCWORD_1;
       PacketParams.Params.Flrc.HeaderType            =     RADIO_PACKET_VARIABLE_LENGTH;
       PacketParams.Params.Flrc.PayloadLength         =     32  ;
       PacketParams.Params.Flrc.CrcLength             =     RADIO_CRC_3_BYTES;
       PacketParams.Params.Flrc.Whitening             =     _whitening==1?RADIO_WHITENING_ON:RADIO_WHITENING_OFF;//RADIO_WHITENING_OFF;
       //Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.Flrc.PayloadLength;
     }
 *
 *
 *
 *RadioFlrcBitrates_t returnBrbwFLRC(int index){
  // bitrate and bandwidth for FLRC
  switch(index){
    case 0: return FLRC_BR_1_300_BW_1_2;
    case 1: return FLRC_BR_1_040_BW_1_2;
    case 2: return FLRC_BR_0_650_BW_0_6;
    case 3: return FLRC_BR_0_520_BW_0_6;
    case 4: return FLRC_BR_0_325_BW_0_3;
    case 5: return FLRC_BR_0_260_BW_0_3;
    default : return FLRC_BR_1_300_BW_1_2;
  }
}
RadioFlrcCodingRates_t returnCrFLRC(int index){
  switch(index){
    case 0: return FLRC_CR_1_2;
    case 1: return FLRC_CR_3_4;
    case 2: return FLRC_CR_3_4;
    default : return FLRC_CR_1_2;
  }
}

RadioCrcTypes_t returnCrcLen(int index){
  // CRC length for GFSK and FLRC
  switch(index){
    case 0: return RADIO_CRC_OFF;
    case 1: return RADIO_CRC_1_BYTES;
    case 2: return RADIO_CRC_2_BYTES;
    case 3: return RADIO_CRC_3_BYTES;
    default : return RADIO_CRC_OFF;
  }
}
 *
 *
 *
 */