mbed_controller / Mbed 2 deprecated CC1101_Transceiver_STM32F4

Dependencies:   mbed

Revision:
1:e96096a7b90b
Parent:
0:9df942ea84f4
Child:
2:54c832c68208
--- a/main.cpp	Sun Nov 21 11:37:56 2010 +0000
+++ b/main.cpp	Tue Mar 31 07:48:52 2015 +0000
@@ -1,22 +1,63 @@
+/**
+ * This program prints input text to serial port of each other side.
+ * Test result: TX, RX work well with 433MHz on STM32-F407 platform.
+ * Two features are improved from the original source code.
+ * - Synchronous implementation of CC1101::SendPacket()
+ *   For subsequent packet transmission, now this function returns after packet transmission.
+ * - FIFO checking routine changed.
+ *   Original code uses timer to check FIFO, it may cause resource corruption by timer interrupt.
+ */
 #include "mbed.h"
 #include "CC1101.h"
 #include "RingBuffer.h"
- 
+
+#if 0
+#define PRINTF pc.printf
+#else
+#define PRINTF(...)
+#endif
+
+#define FIFO_CHECK_INTERVAL_US	500000
+
 ///////////////////////////////////////////////////
-Ticker timer;
-CC1101 cc1101(p5, p6, p7, p8, p10);
-DigitalIn gdo0(p9);     // pin connected to gdo0 pin of CC1101 for checking that received a new packet
+const PinName mosi = PB_5;
+const PinName miso = PB_4;
+const PinName clk = PB_3;
+const PinName csn = PA_15;
+// RDmiso --> pin to detect MISO low.
+const PinName RDmiso = PD_7;
 
-DigitalOut led1(LED1);  // timer blink led
+// pin connected to GDO0 pin of CC1101 for checking that received a new packet
+// It related with CC1101 IOCFG0 register.
+const PinName gdo0 = PE_0;
+
+// pin for checking that sent a packet
+// It related with CC1101 IOCFG01register.
+const PinName gdo1 = PE_1;
+
+CC1101 cc1101(mosi, miso, clk, csn, RDmiso, gdo0, gdo1);
+
+Serial pc(USBTX, USBRX);
+DigitalOut led1(LED1);  // FIFO led
 DigitalOut led2(LED2);  // RX led
 DigitalOut led3(LED3);  // TX led
-Serial pc(USBTX, USBRX); // tx, rx
+
 RingBuffer pcRX(512);   // ring buffer for the pc RX data
 RingBuffer pcTX(512);   // ring buffer for the pc TX data
 Timeout pcRXtimeout;
 Timeout led2timeout;
 Timeout led3timeout;
-unsigned char buffer[128];
+unsigned char buffer[64];
+
+///////////////////////////////////////////////////
+static uint32_t compute_elapse_us(uint32_t prev_tick, uint32_t cur_tick)
+{
+    if (prev_tick <= cur_tick)
+        return cur_tick - prev_tick;
+
+    // tick wrap around happens, it assumes tick start from 0.
+    return cur_tick;
+}
 ///////////////////////////////////////////////////
 void led2timeout_func()
 {
@@ -33,66 +74,81 @@
 void pcRXtimeout_func()         // function for transmiting the RF packets - empty the pcRX ring buffer
 {
     unsigned char txlength;
-    
+
     txlength = 0;
-    while(pcRX.use() > 0)
-    {
-      led2 = 1;
-      buffer[txlength] = pcRX.getc();
-      txlength++;
-      led2timeout.attach(&led2timeout_func, 0.050);  // for switch off the led
+    while(pcRX.use() > 0) {
+        led2 = 1;
+        buffer[txlength] = pcRX.getc();
+        txlength++;
+        led2timeout.attach(&led2timeout_func, 0.050);  // for switch off the led
     }
-    if (txlength)
-      cc1101.SendPacket(buffer, txlength);    // tx packet
-    
+    if (txlength) {
+        cc1101.SendPacket(buffer, txlength);    // tx packet
+    }
+
     pcRXtimeout.detach();
 }
 ///////////////////////////////////////////////////
-void timer_func()           // check the status of the CC1101 every 100ms
-{    
+void check_FIFO()           // check the status of the CC1101 to see FIFO error
+{
     unsigned char chip_status_rx, chip_status_tx;
-    
+
     led1 = !led1;
-    chip_status_rx = cc1101.ReadChipStatusRX();  // check the rx status 
-    if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_RXFIFO_OVERFLOW)   // if rx overflow flush the rx fifo
-      cc1101.FlushRX();  
-    if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_IDLE)              // if state is idle go to rx state again
-      cc1101.RXMode();  
-    chip_status_tx = cc1101.ReadChipStatusTX();  // check the tx sttus
-    if ((chip_status_tx & CHIP_STATE_MASK) == CHIP_STATE_TXFIFO_UNDERFLOW)  // if tx underflow flush the tx fifo
-      cc1101.FlushTX();
+    chip_status_rx = cc1101.ReadChipStatusRX();  // check the rx status
+    if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_RXFIFO_OVERFLOW)  { // if rx overflow flush the rx fifo
+        PRINTF("*RXFIFO_OVERFLOW->Flush\r\n");
+        cc1101.FlushRX();
+    }
+    if ((chip_status_rx & CHIP_STATE_MASK) == CHIP_STATE_IDLE) {             // if state is idle go to rx state again
+        // Basically we don't need to set RXMode here because RXOFF_MODE and TXOFF_MODE of CC1101 are RX mode.
+        // But we still need to check IDLE because it can be IDEL by flushing FIFO.
+        PRINTF("*RX MODE\r\n");
+        cc1101.RXMode();
+    }
+    chip_status_tx = cc1101.ReadChipStatusTX();  // check the tx status
+    if ((chip_status_tx & CHIP_STATE_MASK) == CHIP_STATE_TXFIFO_UNDERFLOW) { // if tx underflow flush the tx fifo
+        PRINTF("*XFIFO_UNDERFLOW->Flush\r\n");
+        cc1101.FlushTX();
+    }
+    PRINTF("[%8u]Chip RX=%02x TX=%02x\r\n", us_ticker_read()/1000, chip_status_rx, chip_status_tx);
 }
 ///////////////////////////////////////////////////
-int main() 
+int main()
 {
     unsigned char rxlength, i;
-    
+    uint32_t saved_tick = 0, cur_tick;
+
+    pc.baud(115200);
+    printf("build at " __TIME__ "\r\n");
     pcRX.clear();
     pcTX.clear();
     cc1101.init();
-    timer.attach(&timer_func, 0.1);
-    while(1)
-    {
-        if(gdo0)      // rx finished and CRC OK read the new packet
-        {
+    while(1) {
+        cur_tick = us_ticker_read();
+        if (compute_elapse_us(saved_tick, cur_tick) > FIFO_CHECK_INTERVAL_US) {
+            check_FIFO();
+            saved_tick = cur_tick;
+        }
+
+        if(cc1101.GetGDO0()) {    // rx finished and CRC OK read the new packet
             rxlength = sizeof(buffer);
-            if (cc1101.ReceivePacket(buffer, &rxlength) == 1)   // read the rx packet
-            {
+            if (cc1101.ReceivePacket(buffer, &rxlength) == 1) { // read the rx packet
                 led3 = 1;
                 for (i = 0; i < rxlength; i++)
-                    pcTX.putc(buffer[i]);                       // store the packet to the pcTX ring buffer 
+                    pcTX.putc(buffer[i]);                       // store the packet to the pcTX ring buffer
                 led3timeout.attach(&led3timeout_func, 0.050);   // for switch off the led
             }
         }
         if (pcTX.use() > 0)         // check if we have data to transmit to pc
             pc.putc(pcTX.getc());   // get the data from the ring buffer and transmit it to the pc
-        if (pc.readable())          // check if we received new data from the pc
-        {
+        if (pc.readable()) {        // check if we received new data from the pc
             pcRX.putc(pc.getc());   // put the data to the pcRX buffer and wait until 20ms passed till the last byte before tx the packet in RF
-            pcRXtimeout.attach(&pcRXtimeout_func, 0.020);
+            if (pcRX.use() > 20)        // if more than 20 bytes received then tx the packet in RF
+                pcRXtimeout_func();
+            else
+                pcRXtimeout.attach(&pcRXtimeout_func, 0.020);
         }
-        if (pcRX.use() > 20)        // if more than 20 bytes received then tx the packet in RF
-            pcRXtimeout_func();
-    }     
+    }
 }
 ///////////////////////////////////////////////////
+