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
#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;
#define STATE_RX (0)
#define STATE_TX (1)
int main(void)
{
trx_regval_t rval;
trap_if_key_pressed();
LED_INIT();
trx_io_init(SPI_RATE_1_2);
LED_SET_VALUE(LED_MAX_VALUE);
LED_SET_VALUE(0);
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);
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);
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);
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 == 0)
{
rxcnt ++;
trx_reg_write(RG_TRX_STATE,CMD_FORCE_TRX_OFF);
trx_reg_write(RG_TRX_STATE,CMD_PLL_ON);
rxfrm[2] ^=0xff;
DELAY_US(16);
TRX_SLPTR_HIGH();
TRX_SLPTR_LOW();
trx_frame_write(flen,rxfrm);
state = STATE_TX;
}
LED_SET_VALUE(rxcnt);
}
ISR(TRX24_TX_END_vect)
{
trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
state = STATE_RX;
}
#else
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);
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 == 0)
{
rxcnt ++;
trx_reg_write(RG_TRX_STATE,CMD_FORCE_TRX_OFF);
trx_reg_write(RG_TRX_STATE,CMD_PLL_ON);
rxfrm[2] ^=0xff;
DELAY_US(16);
TRX_SLPTR_HIGH();
TRX_SLPTR_LOW();
trx_frame_write(flen,rxfrm);
state = STATE_TX;
}
LED_SET_VALUE(rxcnt);
}
}
}
#endif