44 #include "sys/clock.h"
54 #define CHECKSUM_LEN 2
56 #if CC2530_RF_CONF_LEDS
57 #define CC2530_RF_LEDS CC2530_RF_CONF_LEDS
59 #define CC2530_RF_LEDS 0
64 #define RF_RX_LED_ON() leds_on(LEDS_RED);
65 #define RF_RX_LED_OFF() leds_off(LEDS_RED);
66 #define RF_TX_LED_ON() leds_on(LEDS_GREEN);
67 #define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
69 #define RF_RX_LED_ON()
70 #define RF_RX_LED_OFF()
71 #define RF_TX_LED_ON()
72 #define RF_TX_LED_OFF()
78 #define PUTSTRING(...) putstring(__VA_ARGS__)
79 #define PUTHEX(...) puthex(__VA_ARGS__)
81 #define PUTSTRING(...)
86 #define RX_ACTIVE 0x80
91 #define CRC_BIT_MASK 0x80
92 #define LQI_BIT_MASK 0x7F
94 #define RSSI_OFFSET 73
97 #define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
100 #if CC2530_RF_CONF_HEXDUMP
102 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 };
105 #ifdef CC2530_RF_CONF_AUTOACK
106 #define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK
108 #define CC2530_RF_AUTOACK 1
111 static uint8_t CC_AT_DATA rf_flags;
114 static int off(
void);
115 static int channel_clear(
void);
118 cc2530_rf_channel_set(uint8_t channel)
120 PUTSTRING(
"RF: Set Chan\n");
122 if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) {
128 FREQCTRL = (CC2530_RF_CHANNEL_MIN
129 + (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING);
132 return (int8_t) channel;
136 cc2530_rf_power_set(uint8_t new_power)
138 PUTSTRING(
"RF: Set Power\n");
147 cc2530_rf_set_addr(uint16_t pan)
151 for(i = (LINKADDR_SIZE - 1); i >= 0; --i) {
156 PAN_ID0 = pan & 0xFF;
168 PUTSTRING(
"RF: Init\n");
170 if(rf_flags & RF_ON) {
174 #if CC2530_RF_LOW_POWER_RX
183 CCACTRL0 = CC2530_RF_CCA_THRES;
196 FRMCTRL0 = FRMCTRL0_AUTOCRC;
197 #if CC2530_RF_AUTOACK
198 FRMCTRL0 |= FRMCTRL0_AUTOACK;
205 FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN;
207 cc2530_rf_power_set(CC2530_RF_TX_POWER);
208 cc2530_rf_channel_set(CC2530_RF_CHANNEL);
219 prepare(
const void *payload,
unsigned short payload_len)
223 PUTSTRING(
"RF: Prepare 0x");
224 PUTHEX(payload_len + CHECKSUM_LEN);
225 PUTSTRING(
" bytes\n");
231 while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE);
233 if((rf_flags & RX_ACTIVE) == 0) {
237 CC2530_CSP_ISFLUSHTX();
239 PUTSTRING(
"RF: data = ");
241 RFD = payload_len + CHECKSUM_LEN;
242 for(i = 0; i < payload_len; i++) {
243 RFD = ((
unsigned char *)(payload))[i];
244 PUTHEX(((
unsigned char *)(payload))[i]);
256 transmit(
unsigned short transmit_len)
259 int ret = RADIO_TX_ERR;
263 if(!(rf_flags & RX_ACTIVE)) {
267 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + ONOFF_TIME));
270 if(channel_clear() == CC2530_RF_CCA_BUSY) {
271 RIMESTATS_ADD(contentiondrop);
272 return RADIO_TX_COLLISION;
279 if(FSMSTAT1 & FSMSTAT1_SFD) {
280 RIMESTATS_ADD(contentiondrop);
281 return RADIO_TX_COLLISION;
286 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
287 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
292 while(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE) && (counter++ < 3)) {
296 if(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE)) {
297 PUTSTRING(
"RF: TX never active.\n");
298 CC2530_CSP_ISFLUSHTX();
302 while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE);
305 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
306 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
308 if(rf_flags & WAS_OFF) {
321 send(
void *payload,
unsigned short payload_len)
323 prepare(payload, payload_len);
324 return transmit(payload_len);
328 read(
void *buf,
unsigned short bufsize)
335 PUTSTRING(
"RF: Read\n");
341 if(len > CC2530_RF_MAX_PACKET_LEN) {
343 PUTSTRING(
"RF: bad sync\n");
345 RIMESTATS_ADD(badsynch);
346 CC2530_CSP_ISFLUSHRX();
350 if(len <= CC2530_RF_MIN_PACKET_LEN) {
351 PUTSTRING(
"RF: too short\n");
353 RIMESTATS_ADD(tooshort);
354 CC2530_CSP_ISFLUSHRX();
358 if(len - CHECKSUM_LEN > bufsize) {
359 PUTSTRING(
"RF: too long\n");
361 RIMESTATS_ADD(toolong);
362 CC2530_CSP_ISFLUSHRX();
366 #if CC2530_RF_CONF_HEXDUMP
368 io_arch_writeb(magic[0]);
369 io_arch_writeb(magic[1]);
370 io_arch_writeb(magic[2]);
371 io_arch_writeb(magic[3]);
377 PUTSTRING(
"RF: read (0x");
379 PUTSTRING(
" bytes) = ");
381 for(i = 0; i < len; ++i) {
382 ((
unsigned char *)(buf))[i] = RFD;
383 #if CC2530_RF_CONF_HEXDUMP
384 io_arch_writeb(((
unsigned char *)(buf))[i]);
386 PUTHEX(((
unsigned char *)(buf))[i]);
391 rssi = ((int8_t) RFD) - RSSI_OFFSET;
394 #if CC2530_RF_CONF_HEXDUMP
395 io_arch_writeb(rssi);
396 io_arch_writeb(crc_corr);
401 if(crc_corr & CRC_BIT_MASK) {
402 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
403 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
406 RIMESTATS_ADD(badcrc);
407 CC2530_CSP_ISFLUSHRX();
413 if((FSMSTAT1 & (FSMSTAT1_FIFO | FSMSTAT1_FIFOP)) == FSMSTAT1_FIFOP) {
422 CC2530_CSP_ISFLUSHRX();
434 if(FSMSTAT1 & FSMSTAT1_CCA) {
435 return CC2530_RF_CCA_CLEAR;
437 return CC2530_RF_CCA_BUSY;
441 receiving_packet(
void)
443 PUTSTRING(
"RF: Receiving\n");
451 return (FSMSTAT1 & (FSMSTAT1_TX_ACTIVE | FSMSTAT1_SFD) == FSMSTAT1_SFD);
457 return (FSMSTAT1 & FSMSTAT1_FIFOP);
463 if(!(rf_flags & RX_ACTIVE)) {
464 CC2530_CSP_ISFLUSHRX();
467 rf_flags |= RX_ACTIVE;
470 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
477 CC2530_CSP_ISRFOFF();
478 CC2530_CSP_ISFLUSHRX();
480 rf_flags &= ~RX_ACTIVE;
482 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);