Improve rx task.
2 files changed, 56 insertions(+), 24 deletions(-)

M nrf24.c
M nrf24.h
M nrf24.c +53 -23
@@ 61,10 61,11 @@ const struct rf24_settings rf24_defaults
 static CTL_SPI_DEVICE_t nrf24_device;
 static nrf24_pin_state nrf24_ce_fn;
 static nrf24_pin_state nrf24_cs_fn;
+static nrf24_payload_handler nrf24_payload_handler_fn;
+static bool nrf24_listening_task_running;
 
 static uint8_t rf24_addr_len = 0;
 
-
 static void rf24_select(struct CTL_SPI_DEVICE_s *self, int state)
 {
   if (nrf24_cs_fn) {

          
@@ 403,6 404,22 @@ void rf24_start_listening(void)
   rf24_ce(true);
 }
 
+#define STACKSIZE 128
+#define CALLSTACKSIZE 16
+static unsigned char listening_task_stack[1 + STACKSIZE + 1];
+static CTL_TASK_t rf24_receive_task;
+
+void rf24_start_listening_with_callback(nrf24_payload_handler payload_handler)
+{
+  rf24_start_listening();
+  if (!nrf24_listening_task_running) {
+    nrf24_listening_task_running = true;
+    memset(listening_task_stack, 0xcd, sizeof(listening_task_stack));
+    listening_task_stack[0] = listening_task_stack[1+STACKSIZE] = 0xfacefeed;
+    ctl_task_run(&listening_task, 1, rf24_receive_task, 0 , "nrf24", STACKSIZE, listening_task_stack+1, CALLSTACKSIZE);
+  }
+}
+
 void rf24_stop_listening(void)
 {
   rf24_ce(false);

          
@@ 449,6 466,8 @@ void rf24_init(const struct rf24_setting
 
   rf24_addr_len = 5;
 
+  nrf24_payload_handler_fn = NULL;
+  nrf24_listening_task_running = false;
 
   ctl_spi_attach_device(spi_bus, &nrf24_device);
   

          
@@ 482,6 501,9 @@ void rf24_init(const struct rf24_setting
 
 static CTL_EVENT_SET_t rf24_events;
 
+#define RX_PACKET_ARRIVED_EVENT (1 << 0)
+#define ERROR_EVENT (1 << 1)
+
 void rf24_interrupt_handler(void)
 {
   int i = 0;

          
@@ 490,9 512,6 @@ void rf24_interrupt_handler(void)
   ctl_events_set_clear(&rf24_events, RX_PACKET_ARRIVED_EVENT, 0);
 }
 
-#define RX_PACKET_ARRIVED_EVENT (1 << 0)
-#define ERROR_EVENT (1 << 1)
-
 void rf24_receive_task(void *p)
 {
   unsigned wait_status;

          
@@ 502,32 521,43 @@ void rf24_receive_task(void *p)
   uint8_t payload_len;
   uint8_t fifo_no;
 
+  payload[sizeof(payload) - 1] = 0;
+
   while(1) {
     ctl_events_set_clear(&rf24_events, 0, RX_PACKET_ARRIVED_EVENT|ERROR_EVENT);
 
     wait_status = ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,
       &rf24_events, RX_PACKET_ARRIVED_EVENT|ERROR_EVENT,
       CTL_TIMEOUT_INFINITE, 0);
-    
-  
-    
-    // read status
-    // read payload
-    // clear RX_DR
-    // read fifo status
+
+    if (wait_status & RX_PACKET_ARRIVED_EVENT) {
+      while (!out) {
+        // read status
+        // read payload
+        // clear RX_DR
+        // read fifo status
 
-    status = rf24_status();
-    if ((status & RF24_STATUS_RX_DR) == 0) {
-      continue;
+        status = rf24_status();
+        if ((status & RF24_STATUS_RX_DR) == 0) {
+          out = true;
+          break;
+        }
+
+        fifo_no = (status & 0b1110) >> 1;
+
+        payload_len = 0;
+        rf24_get_rx_payload(payload, 32, &payload_len);
+
+        status = RF24_STATUS_RX_DR;
+        rf24_set_status(status);
+
+        if (nrf24_payload_handler_fn) {
+          nrf24_payload_handler_fn(fifo_no, payload);
+        }
+      }
     }
 
-    fifo_no = (status & 0b1110) >> 1;
-
-    payload_len = 0;
-    rf24_get_rx_payload(payload, 32, &payload_len);
+  }
+}
 
-    status = RF24_STATUS_RX_DR;
-    rf24_set_status(status);
-
-  }
-}
  No newline at end of file
+// vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2

          
M nrf24.h +3 -1
@@ 16,6 16,7 @@ 
 #define RF24_ERROR -1
 
 typedef void (*nrf24_pin_state)(int state);
+typedef void (*nrf24_payload_handler)(uint8_t fifo_no, const char *payload);
 
 struct rf24_settings {
   bool data_received_interrupt;

          
@@ 41,9 42,10 @@ void rf24_enable_pipes(uint8_t pipe_mask
 void rf24_set_tx_addr(const uint8_t *addr, uint8_t addr_len);
 void rf24_send_payload(void);
 void rf24_start_listening(void);
+void rf24_start_listening_with_callback(nrf24_payload_handler payload_handler);
 void rf24_stop_listening(void);
 void rf24_flush_tx(void);
 void rf24_flush_rx(void);
 void rf24_interrupt_handler(void);
 
-#endif /* NRF24_H */
  No newline at end of file
+#endif /* NRF24_H */