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
main.cpp
- Committer:
- hillkim7
- Date:
- 2015-03-31
- Revision:
- 1:e96096a7b90b
- Parent:
- 0:9df942ea84f4
- Child:
- 2:54c832c68208
File content as of revision 1:e96096a7b90b:
/**
* 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
///////////////////////////////////////////////////
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;
// 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
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[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()
{
led2 = 0;
led2timeout.detach();
}
///////////////////////////////////////////////////
void led3timeout_func()
{
led3 = 0;
led3timeout.detach();
}
///////////////////////////////////////////////////
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
}
if (txlength) {
cc1101.SendPacket(buffer, txlength); // tx packet
}
pcRXtimeout.detach();
}
///////////////////////////////////////////////////
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
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()
{
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();
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
led3 = 1;
for (i = 0; i < rxlength; i++)
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
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
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);
}
}
}
///////////////////////////////////////////////////