Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Diff: main.cpp
- 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(); - } + } } /////////////////////////////////////////////////// +