SX1272Lib updated in order to be RTOS aware

Fork of SX1272Lib by Semtech

Since Semtech original SX1272 library used InterruptIn and Timout mbed-os classes, whose ISRs are not allowed to lock RTOS mutexes, any SPI-related operation was doomed to fail. Indeed, SPI transactions functions are always nested inside a spi-level mutex lock/unlock pair in order to provide for thread access safety. A typical case occurs for example when radio is set to sleep state after a RX timeout.

This fork solves such problems by mean of a EventQueue/Thread pair, where any InterruptIn and Timeout ISRs actually enqueue callback calls.

Take a look at usage example at https://github.com/maiorfi/mbedos_lablet_lora_1

Files at this revision

API Documentation at this revision

Comitter:
Lorenzo Maiorfi
Date:
Sat Feb 24 08:47:30 2018 +0100
Parent:
9:a9a2d4937e88
Child:
11:866b939cf709
Commit message:
Radio Events event queue and related thread should now be passed externally (e.g. by main()) as pointers. This frees user code from locking/unlocking through mutex in order to implement an async state machine interlaced with radio events

Changed in this revision

sx1272/sx1272.cpp Show annotated file Show diff for this revision Revisions of this file
sx1272/sx1272.h Show annotated file Show diff for this revision Revisions of this file
--- a/sx1272/sx1272.cpp	Sat Feb 10 08:59:58 2018 +0100
+++ b/sx1272/sx1272.cpp	Sat Feb 24 08:47:30 2018 +0100
@@ -79,7 +79,7 @@
     this->RadioEvents = events;
 
     // <RTOS>
-    _thread_events_queue.start(callback(&_eq_events, &EventQueue::dispatch_forever));
+    //_thread_events_queue->start(callback(_eq_events, &EventQueue::dispatch_forever));
     // </RTOS>
 }
 
@@ -1412,7 +1412,7 @@
 
 void SX1272::enqueueOnTimeoutIrq()
 {
-    _eq_events.call(this, &SX1272::OnTimeoutIrq);
+    _eq_events->call(this, &SX1272::OnTimeoutIrq);
 }
 
 void SX1272::radioEvent_RxTimeout()
@@ -1422,7 +1422,7 @@
 
 void SX1272::enqueueRadioEvent_RxTimeout()
 {
-     _eq_events.call(this, &SX1272::radioEvent_RxTimeout);
+     _eq_events->call(this, &SX1272::radioEvent_RxTimeout);
 }
 
 void SX1272::radioEvent_TxTimeout()
@@ -1432,7 +1432,7 @@
 
 void SX1272::enqueueRadioEvent_TxTimeout()
 {
-     _eq_events.call(this, &SX1272::radioEvent_TxTimeout);
+     _eq_events->call(this, &SX1272::radioEvent_TxTimeout);
 }
 
 void SX1272::radioEvent_RxError()
@@ -1442,7 +1442,7 @@
 
 void SX1272::enqueueRadioEvent_RxError()
 {
-     _eq_events.call(this, &SX1272::radioEvent_RxError);
+     _eq_events->call(this, &SX1272::radioEvent_RxError);
 }
 
 void SX1272::radioEvent_RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
@@ -1452,7 +1452,7 @@
 
 void SX1272::enqueueRadioEvent_RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
 {
-     _eq_events.call(this, &SX1272::radioEvent_RxDone, payload, size, rssi, snr);
+     _eq_events->call(this, &SX1272::radioEvent_RxDone, payload, size, rssi, snr);
 }
 
 void SX1272::radioEvent_TxDone()
@@ -1462,7 +1462,7 @@
 
 void SX1272::enqueueRadioEvent_TxDone()
 {
-     _eq_events.call(this, &SX1272::radioEvent_TxDone);
+     _eq_events->call(this, &SX1272::radioEvent_TxDone);
 }
 
 void SX1272::radioEvent_FhssChangeChannel(uint8_t currentChannel)
@@ -1472,7 +1472,7 @@
 
 void SX1272::enqueueRadioEvent_FhssChangeChannel(uint8_t currentChannel)
 {
-    _eq_events.call(this, &SX1272::radioEvent_FhssChangeChannel, currentChannel);
+    _eq_events->call(this, &SX1272::radioEvent_FhssChangeChannel, currentChannel);
 }
 
 void SX1272::radioEvent_CadDone(bool channelActivityDetected)
@@ -1482,32 +1482,32 @@
 
 void SX1272::enqueueRadioEvent_CadDone(bool channelActivityDetected)
 {
-    _eq_events.call(this, &SX1272::radioEvent_CadDone, channelActivityDetected);
+    _eq_events->call(this, &SX1272::radioEvent_CadDone, channelActivityDetected);
 }
 
 void SX1272::enqueueOnDio0Irq()
 {
-    _eq_events.call(this, &SX1272::OnDio0Irq);
+    _eq_events->call(this, &SX1272::OnDio0Irq);
 }
 
 void SX1272::enqueueOnDio1Irq()
 {
-    _eq_events.call(this, &SX1272::OnDio1Irq);
+    _eq_events->call(this, &SX1272::OnDio1Irq);
 }
 
 void SX1272::enqueueOnDio2Irq()
 {
-    _eq_events.call(this, &SX1272::OnDio2Irq);
+    _eq_events->call(this, &SX1272::OnDio2Irq);
 }
 
 void SX1272::enqueueOnDio3Irq()
 {
-    _eq_events.call(this, &SX1272::OnDio3Irq);
+    _eq_events->call(this, &SX1272::OnDio3Irq);
 }
 
 void SX1272::enqueueOnDio4Irq()
 {
-    _eq_events.call(this, &SX1272::OnDio4Irq);
+    _eq_events->call(this, &SX1272::OnDio4Irq);
 }
 
 void SX1272::enqueueOnDio5Irq()
--- a/sx1272/sx1272.h	Sat Feb 10 08:59:58 2018 +0100
+++ b/sx1272/sx1272.h	Sat Feb 24 08:47:30 2018 +0100
@@ -99,8 +99,8 @@
     static const FskBandwidth_t FskBandwidths[];
 
     // <RTOS>
-    Thread _thread_events_queue;
-    EventQueue _eq_events;
+    Thread* _thread_events_queue;
+    EventQueue* _eq_events;
     // </RTOS>
 
 protected:
@@ -118,6 +118,11 @@
             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 );
     SX1272( RadioEvents_t *events );
     virtual ~SX1272( );
+
+    // <RTOS>
+    void assign_events_queue_thread(Thread* thread) {_thread_events_queue=thread;}
+    void assign_events_queue(EventQueue* event_queue) {_eq_events=event_queue;}
+    // </RTOS>
     
     //-------------------------------------------------------------------------
     //                        Redefined Radio functions