This is modified program from original CC1101_Transceiver. CC1101 Test succeeded STM32-F407 platform. Feature are improved little bit.

Dependencies:   mbed

TI CC1101 chip is embedded along with STM32-F407 MCU. /media/uploads/hillkim7/cc1101-test.png

main.cpp

Committer:
hillkim7
Date:
2015-03-31
Revision:
2:54c832c68208
Parent:
1:e96096a7b90b

File content as of revision 2:54c832c68208:

/**
 * 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 IOCFG02register.
const PinName gdo2 = PE_1;

CC1101 cc1101(mosi, miso, clk, csn, RDmiso, gdo0, gdo2);

#if 1
Serial pc(PD_8, PD_9); // tx, rx
DigitalOut led1(PD_12);  // FIFO led
DigitalOut led2(PD_13);  // RX led
DigitalOut led3(PD_14);  // TX led
#else
Serial pc(USBTX, USBRX);
DigitalOut led1(LED1);  // FIFO led
DigitalOut led2(LED2);  // RX led
DigitalOut led3(LED3);  // TX led
#endif
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);
        }
    }
}
///////////////////////////////////////////////////