47 #include PLATFORM_HEADER
48 #include "hal/error.h"
65 #define LED_ACTIVITY 0
67 #ifdef ST_CONF_RADIO_AUTOACK
68 #define ST_RADIO_AUTOACK ST_CONF_RADIO_AUTOACK
70 #define ST_RADIO_AUTOACK 0
73 #if RDC_CONF_DEBUG_LED
74 #define LED_RDC RDC_CONF_DEBUG_LED
75 #define LED_ACTIVITY 1
82 #define PRINTF(...) printf(__VA_ARGS__)
84 #define PRINTF(...) do {} while (0)
88 #define LED_TX_ON() leds_on(LEDS_GREEN)
89 #define LED_TX_OFF() leds_off(LEDS_GREEN)
90 #define LED_RX_ON() do { \
95 #define LED_RX_OFF() do { \
100 #define LED_RDC_ON() do { \
105 #define LED_RDC_OFF() do { \
107 leds_off(LEDS_RED); \
116 #define LED_RDC_OFF()
119 #if RDC_CONF_HARDWARE_CSMA
120 #define MAC_RETRIES 0
124 #define MAC_RETRIES 1
128 int8_t mac_retries_left;
129 #define INIT_RETRY_CNT() (mac_retries_left = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS))
130 #define DEC_RETRY_CNT() (mac_retries_left--)
131 #define RETRY_CNT_GTZ() (mac_retries_left > 0)
133 #define INIT_RETRY_CNT()
134 #define DEC_RETRY_CNT()
135 #define RETRY_CNT_GTZ() 0
141 #ifndef RADIO_WAIT_FOR_PACKET_SENT
142 #define RADIO_WAIT_FOR_PACKET_SENT 1
145 #define TO_PREV_STATE() do { \
146 if(onoroff == OFF){ \
148 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); \
151 #if RDC_CONF_HARDWARE_CSMA
152 #define ST_RADIO_CHECK_CCA FALSE
153 #define ST_RADIO_CCA_ATTEMPT_MAX 0
154 #define ST_BACKOFF_EXP_MIN 0
155 #define ST_BACKOFF_EXP_MAX 0
157 #define ST_RADIO_CHECK_CCA TRUE
158 #define ST_RADIO_CCA_ATTEMPT_MAX 4
159 #define ST_BACKOFF_EXP_MIN 2
160 #define ST_BACKOFF_EXP_MAX 6
163 const RadioTransmitConfig radioTransmitConfig = {
166 ST_RADIO_CCA_ATTEMPT_MAX,
172 #define MAC_RETRIES 0
178 #define RADIO_RXBUFS 1
182 static uint8_t stm32w_rxbufs[RADIO_RXBUFS][STM32W_MAX_PACKET_LEN + 1];
185 static volatile int8_t first = -1, last = 0;
187 static const int8_t first = 0, last = 0;
191 #define CLEAN_RXBUFS() do{first = -1; last = 0;}while(0)
192 #define RXBUFS_EMPTY() (first == -1)
196 int8_t first_tmp = first;
197 return first_tmp == last;
200 #define CLEAN_RXBUFS() (stm32w_rxbufs[0][0] = 0)
201 #define RXBUFS_EMPTY() (stm32w_rxbufs[0][0] == 0)
202 #define RXBUFS_FULL() (stm32w_rxbufs[0][0] != 0)
206 __attribute__ ((aligned(2))) stm32w_txbuf[STM32W_MAX_PACKET_LEN + 1];
209 #define CLEAN_TXBUF() (stm32w_txbuf[0] = 0)
210 #define TXBUF_EMPTY() (stm32w_txbuf[0] == 0)
211 #define CHECKSUM_LEN 2
219 #define BUSYWAIT_UNTIL(cond, max_time) \
223 while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
226 #define GET_LOCK() locked++
228 static volatile uint8_t onoroff = OFF;
229 static uint8_t receiving_packet = 0;
230 static int8_t last_rssi;
231 static volatile StStatus last_tx_status;
232 static uint8_t locked;
233 static volatile uint8_t is_transmit_ack;
242 PROCESS(stm32w_radio_process,
"STM32W radio driver");
244 static int stm32w_radio_init(
void);
246 static int stm32w_radio_prepare(
const void *payload,
247 unsigned short payload_len);
248 static int stm32w_radio_transmit(
unsigned short payload_len);
250 static int stm32w_radio_send(
const void *data,
unsigned short len);
252 static int stm32w_radio_read(
void *buf,
unsigned short bufsize);
254 static int stm32w_radio_channel_clear(
void);
256 static int stm32w_radio_receiving_packet(
void);
258 static int stm32w_radio_pending_packet(
void);
260 static int stm32w_radio_on(
void);
262 static int stm32w_radio_off(
void);
264 static int add_to_rxbuf(uint8_t * src);
266 static int read_from_rxbuf(
void *dest,
unsigned short len);
270 stm32w_radio_prepare,
271 stm32w_radio_transmit,
274 stm32w_radio_channel_clear,
275 stm32w_radio_receiving_packet,
276 stm32w_radio_pending_packet,
282 stm32w_radio_init(
void)
285 ST_RadioSetChannel(RF_CHANNEL);
289 ST_RadioInit(ST_RADIO_POWER_MODE_OFF);
292 ST_RadioSetPanId(IEEE802154_PANID);
297 #if ST_RADIO_AUTOACK && !(UIP_CONF_LL_802154 && LINKADDR_CONF_SIZE==8)
298 #error "Autoack and address filtering can only be used with EUI 64"
300 ST_RadioEnableAutoAck(ST_RADIO_AUTOACK);
301 ST_RadioEnableAddressFiltering(ST_RADIO_AUTOACK);
310 stm32w_radio_set_promiscous(uint8_t
on)
313 ST_RadioEnableAddressFiltering(0);
315 ST_RadioEnableAddressFiltering(ST_RADIO_AUTOACK);
320 stm32w_radio_set_channel(uint8_t channel)
322 if (ST_RadioSetChannel(channel) == ST_SUCCESS) {
334 while(!TXBUF_EMPTY()) {
336 PRINTF(
"stm32w: tx buffer full.\r\n");
346 stm32w_radio_prepare(
const void *payload,
unsigned short payload_len)
348 if(payload_len > STM32W_MAX_PACKET_LEN) {
349 PRINTF(
"stm32w: payload length=%d is too long.\r\n", payload_len);
352 #if !RADIO_WAIT_FOR_PACKET_SENT
359 PRINTF(
"stm32w: tx buffer full.\r\n");
369 memcpy(stm32w_txbuf + 1, payload, payload_len);
375 stm32w_radio_transmit(
unsigned short payload_len)
377 stm32w_txbuf[0] = payload_len + CHECKSUM_LEN;
381 PRINTF(
"stm32w: Radio is off, turning it on.\r\n");
383 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
385 #if RADIO_WAIT_FOR_PACKET_SENT
390 if(ST_RadioTransmit(stm32w_txbuf) == ST_SUCCESS) {
391 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
392 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
393 PRINTF(
"stm32w: sending %d bytes\r\n", payload_len);
396 for(uint8_t c = 1; c <= stm32w_txbuf[0] - 2; c++) {
397 PRINTF(
"%x:", stm32w_txbuf[c]);
402 #if RADIO_WAIT_FOR_PACKET_SENT
405 PRINTF(
"stm32w: unknown tx error.\r\n");
413 if(last_tx_status == ST_SUCCESS || last_tx_status == ST_PHY_ACK_RECEIVED ||
414 last_tx_status == ST_MAC_NO_ACK_RECEIVED) {
416 if(last_tx_status == ST_PHY_ACK_RECEIVED) {
418 }
else if(last_tx_status == ST_MAC_NO_ACK_RECEIVED ||
419 last_tx_status == ST_SUCCESS) {
420 return RADIO_TX_NOACK;
435 #if RADIO_WAIT_FOR_PACKET_SENT
440 PRINTF(
"stm32w: transmission never started.\r\n");
449 stm32w_radio_send(
const void *payload,
unsigned short payload_len)
451 if (stm32w_radio_prepare(payload, payload_len) == RADIO_TX_ERR) {
454 return stm32w_radio_transmit(payload_len);
458 stm32w_radio_channel_clear(
void)
460 return ST_RadioChannelIsClear();
464 stm32w_radio_receiving_packet(
void)
466 return receiving_packet;
470 stm32w_radio_pending_packet(
void)
472 return !RXBUFS_EMPTY();
476 stm32w_radio_off(
void)
482 PRINTF(
"stm32w: try to off while sending/receiving (lock=%u).\r\n",
487 if(onoroff == ON && TXBUF_EMPTY() && !receiving_packet) {
494 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
501 stm32w_radio_on(
void)
503 PRINTF(
"stm32w: turn radio on\n");
509 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
516 stm32w_radio_is_on(
void)
518 return onoroff == ON;
522 ST_RadioReceiveIsrCallback(uint8_t *packet,
523 boolean ackFramePendingSet,
524 uint32_t time, uint16_t errors, int8_t rssi)
527 PRINTF(
"stm32w: incomming packet received\n");
528 receiving_packet = 0;
531 if(add_to_rxbuf(packet)) {
539 BUSYWAIT_UNTIL(!is_transmit_ack, RTIMER_SECOND / 1500);
544 ST_RadioTxAckIsrCallback(
void)
556 ST_RadioTransmitCompleteIsrCallback(StStatus status,
557 uint32_t txSyncTime,
boolean framePending)
559 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
560 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
563 last_tx_status = status;
565 if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED) {
568 if(RETRY_CNT_GTZ()) {
572 if(ST_RadioTransmit(stm32w_txbuf) == ST_SUCCESS) {
573 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
574 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
575 PRINTF(
"stm32w: retransmission.\r\n");
580 PRINTF(
"stm32w: retransmission failed.\r\n");
588 if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED) {
589 PRINTF(
"stm32w: return status TX_END\r\n");
590 }
else if(status == ST_MAC_NO_ACK_RECEIVED) {
591 PRINTF(
"stm32w: return status TX_END_NOACK\r\n");
592 }
else if(status == ST_PHY_TX_CCA_FAIL) {
593 PRINTF(
"stm32w: return status TX_END_CCA_FAIL\r\n");
594 }
else if(status == ST_PHY_TX_UNDERFLOW) {
595 PRINTF(
"stm32w: return status TX_END_UNDERFLOW\r\n");
597 PRINTF(
"stm32w: return status TX_END_INCOMPLETE\r\n");
604 receiving_packet = 1;
611 receiving_packet = 1;
619 PRINTF(
"stm32w_radio_process: started\r\n");
623 PRINTF(
"stm32w_radio_process: calling receiver callback\r\n");
626 for(uint8_t c = 1; c <= RCVD_PACKET_LEN; c++) {
627 PRINTF(
"%x", stm32w_rxbuf[c]);
636 NETSTACK_RDC.input();
638 if(!RXBUFS_EMPTY()) {
651 stm32w_radio_read(
void *buf,
unsigned short bufsize)
653 return read_from_rxbuf(buf, bufsize);
659 PRINTF(
"stm32w: radio overflow\r\n");
663 ST_RadioSfdSentIsrCallback(uint32_t sfdSentTime)
673 add_to_rxbuf(uint8_t *src)
679 memcpy(stm32w_rxbufs[last], src, src[0] + 1);
681 last = (last + 1) % RADIO_RXBUFS;
691 read_from_rxbuf(
void *dest,
unsigned short len)
697 if(stm32w_rxbufs[first][0] > len) {
700 len = stm32w_rxbufs[first][0];
701 memcpy(dest, stm32w_rxbufs[first] + 1, len);
702 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
706 ATOMIC(first = (first + 1) % RADIO_RXBUFS;
707 int first_tmp = first;
if(first_tmp == last) {