Basic MAC data interface for LoRa transceiver

Dependencies:   L2Frame crc

Dependents:   LoRaBaseStation LoRaTerminal

Revision:
0:e2ccabf3f30c
Child:
2:fa264e48d5f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AlohaTransceiver.cpp	Thu Jul 14 04:48:17 2016 +0000
@@ -0,0 +1,254 @@
+#include "AlohaTransceiver.h"
+#include "mbed.h"
+#include "radio.h"
+#include "AlohaFrame.h"
+
+// declear the type of radio state
+typedef enum
+{
+    LOWPOWER = 0,
+    IDLE,
+
+    RX,
+    RX_TIMEOUT,
+    RX_ERROR,
+
+    TX,
+    TX_TIMEOUT,
+
+    CAD,
+    CAD_DONE
+}AppStates_t;
+
+// radio driver related variables
+static uint16_t BufferSize;
+static uint8_t Buffer[BUFFER_SIZE];
+
+static int16_t RssiValue;
+static int8_t SnrValue;
+
+static volatile AppStates_t State;
+static RadioEvents_t RadioEvents;
+
+// callback functions for radio driver
+void OnTxDone();
+void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
+void OnTxTimeout();
+void OnRxTimeout();
+void OnRxError();
+void OnFhssChangeChannel( uint8_t channelIndex );
+void OnCadDone();
+
+// radio driver
+#ifdef BUILD_FOR_BS
+SX1276MB1xAS Radio( NULL );
+#endif
+
+#ifdef BUILD_FOR_TERMINAL
+SX1276inAir Radio( NULL );
+#endif
+
+
+/*
+ * Abstract interface for accessing radio driver
+ */
+
+AlohaTransceiver::AlohaTransceiver()
+{
+    // configure properties
+#if USE_MODEM_LORA == 1
+    Settings.Power = TX_OUTPUT_POWER;
+    Settings.Bandwidth = LORA_BANDWIDTH;
+    Settings.Datarate = LORA_SPREADING_FACTOR;
+    Settings.Coderate = LORA_CODINGRATE;
+    Settings.PreambleLen = LORA_PREAMBLE_LENGTH;
+    Settings.SymbolTimeout = LORA_SYMBOL_TIMEOUT;
+    Settings.FixLen = LORA_FIX_LENGTH_PAYLOAD_ON;
+    Settings.PayloadLen = 0;
+    Settings.CrcOn = LORA_CRC_ENABLED;
+    Settings.FreqHopOn = LORA_FHSS_ENABLED;
+    Settings.HopPeriod = LORA_NB_SYMB_HOP;
+    Settings.IqInverted = LORA_IQ_INVERSION_ON;
+    Settings.RxContinuous = true;
+    Settings.TxTimeout = TX_TIMEOUT_VALUE;
+
+#elif USE_MODEM_FSK == 1
+    // TODO: Complete settings for FSK mode
+    #error "FSK not implemented"
+#else
+    #error "Please define a modem in the compiler options."
+#endif
+}
+
+AlohaTransceiver::~AlohaTransceiver()
+{
+
+}
+
+void AlohaTransceiver::BoardInit()
+{
+    // configure callback functions
+    RadioEvents.TxDone = OnTxDone;
+    RadioEvents.RxDone = OnRxDone;
+    RadioEvents.RxError = OnRxError;
+    RadioEvents.TxTimeout = OnTxTimeout;
+    RadioEvents.RxTimeout = OnRxTimeout;
+    Radio.Init( &RadioEvents );
+
+    // verify the connection with the board
+    while( Radio.Read( REG_VERSION ) == 0x00  )
+    {
+        printf( "Radio could not be detected!\n\r" );
+        wait( 1 );
+    }
+    printf("RadioRegVersion: %d\r\n", Radio.Read( REG_VERSION ));
+
+    // select operating channel
+    Radio.SetChannel( RF_FREQUENCY );
+
+    // configure radio tx and rx properties
+    updateSettings();
+
+    // entering passive receiver mode by default
+    Radio.Rx( RX_TIMEOUT_VALUE );
+}
+
+void AlohaTransceiver::updateSettings()
+{
+#if USE_MODEM_LORA == 1
+
+    Radio.SetTxConfig( MODEM_LORA, Settings.Power, 0, Settings.Bandwidth,
+                         Settings.Datarate, Settings.Coderate,
+                         Settings.PreambleLen, Settings.FixLen,
+                         Settings.CrcOn, Settings.FreqHopOn, Settings.HopPeriod,
+                         Settings.IqInverted, Settings.TxTimeout );
+
+    Radio.SetRxConfig( MODEM_LORA, Settings.Bandwidth, Settings.Datarate,
+                         Settings.Coderate, 0, Settings.PreambleLen,
+                         Settings.SymbolTimeout, Settings.FixLen, Settings.PayloadLen,
+                         Settings.CrcOn, Settings.FreqHopOn, Settings.HopPeriod,
+                         Settings.IqInverted, Settings.RxContinuous );
+
+#elif USE_MODEM_FSK == 1
+    #error "FSK not implemented"
+#else
+    #error "Please define a modem in the compiler options."
+#endif
+}
+
+void AlohaTransceiver::poll()
+{
+    switch( State )
+    {
+        case RX:
+        {
+            printf("RX::rssi = %d snr = %d\r\n", RssiValue, SnrValue);
+            
+            // create new frame instance
+            AlohaFrame frame(Buffer, BufferSize);
+            
+            // execute callback functions
+            if (AlohaTypeCallbackTable[frame.getType()] != NULL)
+            {
+                AlohaTypeCallbackTable[frame.getType()](&frame);
+            }
+
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        }
+        case TX:
+        {
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        }
+        case RX_TIMEOUT:
+        {
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        }
+        case RX_ERROR:
+        {
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        }
+        case TX_TIMEOUT:
+        {
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        }
+        case LOWPOWER:
+        {
+            break;
+        }
+        default:
+        {
+            State = LOWPOWER;
+            break;
+        }
+    }
+}
+
+void AlohaTransceiver::send(uint8_t *buffer, int length)
+{
+    Radio.Rx( 0 );
+    Radio.Send(buffer, length);
+    Radio.Rx( RX_TIMEOUT_VALUE );
+}
+
+void AlohaTransceiver::registerType(AlohaFrame::AlohaType_t type, aloha_callback_func f)
+{
+    AlohaTypeCallbackTable[type] = f;
+}
+
+void AlohaTransceiver::deRegisterType(AlohaFrame::AlohaType_t type, aloha_callback_func f)
+{
+    AlohaTypeCallbackTable[type] = NULL;
+}
+
+void OnTxDone( void )
+{
+    Radio.Sleep( );
+    State = TX;
+    printf( "> OnTxDone\n\r" );
+}
+
+void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    Radio.Sleep( );
+
+    // safeguard: if size exceeded maximum buffer size, it will cause memory overflow
+    BufferSize = size ? BUFFER_SIZE : size <= BUFFER_SIZE;
+
+    memcpy( Buffer, payload, BufferSize );
+    RssiValue = rssi;
+    SnrValue = snr;
+    State = RX;
+    printf( "> OnRxDone\n\r" );
+}
+
+void OnTxTimeout( void )
+{
+    Radio.Sleep( );
+    State = TX_TIMEOUT;
+    printf( "> OnTxTimeout\n\r" );
+}
+
+void OnRxTimeout( void )
+{
+    Radio.Sleep( );
+    Buffer[ BufferSize ] = 0;
+    State = RX_TIMEOUT;
+    printf( "> OnRxTimeout\n\r" );
+}
+
+void OnRxError( void )
+{
+    Radio.Sleep( );
+    State = RX_ERROR;
+    printf( "> OnRxError\n\r" );
+}