xmpl_trx_echo.c - Echo Frames

This example shows, how frames are received and retransmitted if their CRC was correct. This example is esentially a combination from xmpl_trx_tx.c - Transmitting Frames and xmpl_trx_rx.c - Receiving Frames. The retransmission of the frames is initiated within the transceiver interrupt routine without any CCA.

Note:
Use this example with care !!! You can mess up your sensor network easily.
Code Example
/* $Id: pgXmplTrxEcho.html,v 1.1.1.4 2013/04/09 21:11:37 awachtler Exp $ */
/* Example for echoing received frames */

#include "board.h"
#include "transceiver.h"
#include "ioutil.h"
#include  <util/crc16.h>
#include "xmpl.h"


static uint8_t rxfrm[MAX_FRAME_SIZE];
static volatile uint8_t rxcnt;
static uint8_t state;

int main(void)
{
trx_regval_t rval;

    /* This will stop the application before initializing the radio transceiver
     * (ISP issue with MISO pin, see FAQ)
     */
    trap_if_key_pressed();

    /* Step 0: init MCU peripherals */
    LED_INIT();
    trx_io_init(SPI_RATE_1_2);
    LED_SET_VALUE(LED_MAX_VALUE);
    LED_SET_VALUE(0);

    /* Step 1: initialize the transceiver */
    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    TRX_RESET_HIGH();
    trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
    DELAY_US(TRX_INIT_TIME_US);
    rval = trx_bit_read(SR_TRX_STATUS);
    ERR_CHECK(TRX_OFF!=rval);
    LED_SET_VALUE(1);

    /* Step 2: setup transmitter
     * - configure radio channel
     * - go into RX state,
     * - enable "receive end" IRQ
     */
    trx_bit_write(SR_CHANNEL,CHANNEL);
    trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
#if defined(TRX_IRQ_TRX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_RX_END) && defined(TRX_IRQ_TX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_RX_END | TRX_IRQ_TX_END);
#else
#  error "Unknown IRQ bits"
#endif
    sei();
    LED_SET_VALUE(2);

    /* Step 3: Going to receive frames */
    rxcnt = 0;

    LED_SET_VALUE(0);
    while(1);
}

#if defined(TRX_IF_RFA1)
ISR(TRX24_RX_END_vect)
{
uint8_t *pfrm, tmp, flen;
uint16_t crc;

    LED_SET_VALUE(0);
    /* upload frame and check for CRC16 validity */
    pfrm = rxfrm;
    flen = trx_frame_read(pfrm, sizeof(rxfrm), NULL);
    tmp = flen;
    crc = 0;
    do
    {
        crc = _crc_ccitt_update(crc, *pfrm++);
    }
    while(tmp--);
    /* if crc is correct, update RX frame counter */
    if (crc == 0)
    {
        rxcnt ++;
        /* echo the frame if CRC is valid*/
        trx_reg_write(RG_TRX_STATE,CMD_FORCE_TRX_OFF);
        trx_reg_write(RG_TRX_STATE,CMD_PLL_ON);
        /*invert sequence number, just to show if it is from pinger */
        rxfrm[2] ^=0xff;
        DELAY_US(16); /* wait 1 symbol, XXX check this timing */
        TRX_SLPTR_HIGH();
        TRX_SLPTR_LOW();
        trx_frame_write(flen,rxfrm);
        state = STATE_TX;
    }

    /* display current frame count */
    LED_SET_VALUE(rxcnt);

}

ISR(TRX24_TX_END_vect)
{

    trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
    state = STATE_RX;
}
#else  /* !RFA1 */
ISR(TRX_IRQ_vect)
{
static volatile trx_regval_t irq_cause;
uint8_t *pfrm, tmp, flen;
uint16_t crc;

    irq_cause = trx_reg_read(RG_IRQ_STATUS);
    if (irq_cause & TRX_IRQ_TRX_END)
    {

        if (state == STATE_TX)
        {
            trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
            state = STATE_RX;
        }
        else
        {
            LED_SET_VALUE(0);
            /* upload frame and check for CRC16 validity */
            pfrm = rxfrm;
            flen = trx_frame_read(pfrm, sizeof(rxfrm), NULL);
            tmp = flen;
            crc = 0;
            do
            {
                crc = _crc_ccitt_update(crc, *pfrm++);
            }
            while(tmp--);
            /* if crc is correct, update RX frame counter */
            if (crc == 0)
            {
                rxcnt ++;
                /* echo the frame if CRC is valid*/
                trx_reg_write(RG_TRX_STATE,CMD_FORCE_TRX_OFF);
                trx_reg_write(RG_TRX_STATE,CMD_PLL_ON);
                /*invert sequence number, just to show if it is from pinger */
                rxfrm[2] ^=0xff;
                DELAY_US(16); /* wait 1 symbol, XXX check this timing */
                TRX_SLPTR_HIGH();
                TRX_SLPTR_LOW();
                trx_frame_write(flen,rxfrm);
                state = STATE_TX;
            }

            /* display current frame count */
            LED_SET_VALUE(rxcnt);

        }
    }
}
#endif  /* RFA1 */

/* EOF */


This documentation for µracoli was generated on Tue Apr 9 2013 by  doxygen 1.7.1