Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, STMicroelectronics. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above 00011 * copyright notice, this list of conditions and the following 00012 * disclaimer in the documentation and/or other materials provided 00013 * with the distribution. 00014 * 3. The name of the author may not be used to endorse or promote 00015 * products derived from this software without specific prior 00016 * written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00019 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00022 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00024 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * This file is part of the Contiki OS 00031 * 00032 * $Id: stm32w-radio.c,v 1.2 2010/10/27 14:05:23 salvopitru Exp $ 00033 */ 00034 /*---------------------------------------------------------------------------*/ 00035 /** 00036 * \file 00037 * Machine dependent STM32W radio code. 00038 * \author 00039 * Salvatore Pitrulli 00040 * Chi-Anh La la@imag.fr 00041 * Simon Duquennoy <simonduq@sics.se> 00042 */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 #include PLATFORM_HEADER 00046 #include "hal/error.h" 00047 #include "hal/hal.h" 00048 00049 #include "contiki.h" 00050 00051 #include "net/mac/frame802154.h" 00052 00053 #include "dev/stm32w-radio.h" 00054 #include "net/netstack.h" 00055 00056 #include "net/packetbuf.h" 00057 #include "net/rime/rimestats.h" 00058 #include "sys/rtimer.h" 00059 00060 #define DEBUG 0 00061 00062 #include "dev/leds.h" 00063 #define LED_ACTIVITY 0 00064 00065 #ifdef ST_CONF_RADIO_AUTOACK 00066 #define ST_RADIO_AUTOACK ST_CONF_RADIO_AUTOACK 00067 #else 00068 #define ST_RADIO_AUTOACK 0 00069 #endif /* ST_CONF_RADIO_AUTOACK */ 00070 00071 #if RDC_CONF_DEBUG_LED 00072 #define LED_RDC RDC_CONF_DEBUG_LED 00073 #define LED_ACTIVITY 1 00074 #else 00075 #define LED_RDC 0 00076 #endif 00077 00078 00079 #if DEBUG > 0 00080 #include <stdio.h> 00081 #define PRINTF(...) printf(__VA_ARGS__) 00082 #else 00083 #define PRINTF(...) do {} while (0) 00084 #endif 00085 00086 #if LED_ACTIVITY 00087 #define LED_TX_ON() leds_on(LEDS_GREEN) 00088 #define LED_TX_OFF() leds_off(LEDS_GREEN) 00089 #define LED_RX_ON() { \ 00090 if(LED_RDC == 0){ \ 00091 leds_on(LEDS_RED); \ 00092 } \ 00093 } 00094 #define LED_RX_OFF() { \ 00095 if(LED_RDC == 0){ \ 00096 leds_off(LEDS_RED); \ 00097 } \ 00098 } 00099 #define LED_RDC_ON() { \ 00100 if(LED_RDC == 1){ \ 00101 leds_on(LEDS_RED); \ 00102 } \ 00103 } 00104 #define LED_RDC_OFF() { \ 00105 if(LED_RDC == 1){ \ 00106 leds_off(LEDS_RED); \ 00107 } \ 00108 } 00109 #else 00110 #define LED_TX_ON() 00111 #define LED_TX_OFF() 00112 #define LED_RX_ON() 00113 #define LED_RX_OFF() 00114 #define LED_RDC_ON() 00115 #define LED_RDC_OFF() 00116 #endif 00117 00118 #if RDC_CONF_HARDWARE_CSMA 00119 #define MAC_RETRIES 0 00120 #endif 00121 00122 #ifndef MAC_RETRIES 00123 #define MAC_RETRIES 1 00124 #endif 00125 00126 #if MAC_RETRIES 00127 00128 int8_t mac_retries_left; 00129 00130 #define INIT_RETRY_CNT() (mac_retries_left = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS)) 00131 #define DEC_RETRY_CNT() (mac_retries_left--) 00132 #define RETRY_CNT_GTZ() (mac_retries_left > 0) 00133 00134 #else 00135 00136 #define INIT_RETRY_CNT() 00137 #define DEC_RETRY_CNT() 00138 #define RETRY_CNT_GTZ() 0 00139 00140 #endif 00141 00142 00143 /* If set to 1, a send() returns only after the packet has been transmitted. 00144 This is necessary if you use the x-mac module, for example. */ 00145 #ifndef RADIO_WAIT_FOR_PACKET_SENT 00146 #define RADIO_WAIT_FOR_PACKET_SENT 1 00147 #endif 00148 00149 #define TO_PREV_STATE() { \ 00150 if(onoroff == OFF){ \ 00151 ST_RadioSleep(); \ 00152 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); \ 00153 } \ 00154 } 00155 #if RDC_CONF_HARDWARE_CSMA 00156 #define ST_RADIO_CHECK_CCA FALSE 00157 #define ST_RADIO_CCA_ATTEMPT_MAX 0 00158 #define ST_BACKOFF_EXP_MIN 0 00159 #define ST_BACKOFF_EXP_MAX 0 00160 #else 00161 #define ST_RADIO_CHECK_CCA TRUE 00162 #define ST_RADIO_CCA_ATTEMPT_MAX 4 00163 #define ST_BACKOFF_EXP_MIN 2 00164 #define ST_BACKOFF_EXP_MAX 6 00165 #endif 00166 const RadioTransmitConfig radioTransmitConfig = { 00167 TRUE, // waitForAck; 00168 ST_RADIO_CHECK_CCA, // checkCca; // Set to FALSE with low-power MACs. 00169 ST_RADIO_CCA_ATTEMPT_MAX, // ccaAttemptMax; 00170 ST_BACKOFF_EXP_MIN, // backoffExponentMin; 00171 ST_BACKOFF_EXP_MAX, // backoffExponentMax; 00172 TRUE // appendCrc; 00173 }; 00174 00175 #define MAC_RETRIES 0 00176 00177 /* 00178 * The buffers which hold incoming data. 00179 */ 00180 #ifndef RADIO_RXBUFS 00181 #define RADIO_RXBUFS 1 00182 #endif 00183 00184 static uint8_t stm32w_rxbufs[RADIO_RXBUFS][STM32W_MAX_PACKET_LEN+1]; // +1 because of the first byte, which will contain the length of the packet. 00185 00186 #if RADIO_RXBUFS > 1 00187 static volatile int8_t first = -1, last=0; 00188 #else 00189 static const int8_t first=0, last=0; 00190 #endif 00191 00192 #if RADIO_RXBUFS > 1 00193 #define CLEAN_RXBUFS() do{first = -1; last = 0;}while(0) 00194 #define RXBUFS_EMPTY() (first == -1) 00195 00196 int RXBUFS_FULL(){ 00197 00198 int8_t first_tmp = first; 00199 return first_tmp == last; 00200 } 00201 00202 #else /* RADIO_RXBUFS > 1 */ 00203 #define CLEAN_RXBUFS() (stm32w_rxbufs[0][0] = 0) 00204 #define RXBUFS_EMPTY() (stm32w_rxbufs[0][0] == 0) 00205 #define RXBUFS_FULL() (stm32w_rxbufs[0][0] != 0) 00206 #endif /* RADIO_RXBUFS > 1 */ 00207 00208 static uint8_t __attribute__(( aligned(2) )) stm32w_txbuf[STM32W_MAX_PACKET_LEN+1]; 00209 00210 00211 #define CLEAN_TXBUF() (stm32w_txbuf[0] = 0) 00212 #define TXBUF_EMPTY() (stm32w_txbuf[0] == 0) 00213 00214 #define CHECKSUM_LEN 2 00215 00216 /* 00217 * The transceiver state. 00218 */ 00219 #define ON 0 00220 #define OFF 1 00221 00222 static volatile uint8_t onoroff = OFF; 00223 static uint8_t receiving_packet = 0; 00224 static s8 last_rssi; 00225 static volatile StStatus last_tx_status; 00226 00227 #define BUSYWAIT_UNTIL(cond, max_time) \ 00228 do { \ 00229 rtimer_clock_t t0; \ 00230 t0 = RTIMER_NOW(); \ 00231 while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \ 00232 } while(0) 00233 00234 static uint8_t locked; 00235 #define GET_LOCK() locked++ 00236 static void RELEASE_LOCK(void) { 00237 if(locked>0) 00238 locked--; 00239 } 00240 static volatile uint8_t is_transmit_ack; 00241 /*---------------------------------------------------------------------------*/ 00242 PROCESS(stm32w_radio_process, "STM32W radio driver"); 00243 /*---------------------------------------------------------------------------*/ 00244 00245 static int stm32w_radio_init(void); 00246 static int stm32w_radio_prepare(const void *payload, unsigned short payload_len); 00247 static int stm32w_radio_transmit(unsigned short payload_len); 00248 static int stm32w_radio_send(const void *data, unsigned short len); 00249 static int stm32w_radio_read(void *buf, unsigned short bufsize); 00250 static int stm32w_radio_channel_clear(void); 00251 static int stm32w_radio_receiving_packet(void); 00252 static int stm32w_radio_pending_packet(void); 00253 static int stm32w_radio_on(void); 00254 static int stm32w_radio_off(void); 00255 00256 static int add_to_rxbuf(uint8_t * src); 00257 static int read_from_rxbuf(void * dest, unsigned short len); 00258 00259 00260 const struct radio_driver stm32w_radio_driver = 00261 { 00262 stm32w_radio_init, 00263 stm32w_radio_prepare, 00264 stm32w_radio_transmit, 00265 stm32w_radio_send, 00266 stm32w_radio_read, 00267 stm32w_radio_channel_clear, 00268 stm32w_radio_receiving_packet, 00269 stm32w_radio_pending_packet, 00270 stm32w_radio_on, 00271 stm32w_radio_off, 00272 }; 00273 /*---------------------------------------------------------------------------*/ 00274 static int stm32w_radio_init(void) 00275 { 00276 // A channel needs also to be setted. 00277 ST_RadioSetChannel(RF_CHANNEL); 00278 00279 // Initialize radio (analog section, digital baseband and MAC). 00280 // Leave radio powered up in non-promiscuous rx mode. 00281 ST_RadioInit(ST_RADIO_POWER_MODE_OFF); 00282 00283 onoroff = OFF; 00284 ST_RadioSetPanId(IEEE802154_PANID); 00285 00286 CLEAN_RXBUFS(); 00287 CLEAN_TXBUF(); 00288 00289 #if ST_RADIO_AUTOACK && !(UIP_CONF_LL_802154 && RIMEADDR_CONF_SIZE==8) 00290 #error "Autoack and address filtering can only be used with EUI 64" 00291 #endif 00292 ST_RadioEnableAutoAck(ST_RADIO_AUTOACK); 00293 ST_RadioEnableAddressFiltering(ST_RADIO_AUTOACK); 00294 00295 locked = 0; 00296 process_start(&stm32w_radio_process, NULL); 00297 00298 return 0; 00299 } 00300 /*---------------------------------------------------------------------------*/ 00301 int stm32w_radio_set_channel(uint8_t channel) 00302 { 00303 if (ST_RadioSetChannel(channel) == ST_SUCCESS) 00304 return 0; 00305 else 00306 return 1; 00307 } 00308 /*---------------------------------------------------------------------------*/ 00309 static int wait_for_tx(void){ 00310 00311 struct timer t; 00312 00313 timer_set(&t, CLOCK_SECOND/10); 00314 while(!TXBUF_EMPTY()){ 00315 if(timer_expired(&t)){ 00316 PRINTF("stm32w: tx buffer full.\r\n"); 00317 return 1; 00318 } 00319 /* Put CPU in sleep mode. */ 00320 halSleepWithOptions(SLEEPMODE_IDLE,0); 00321 } 00322 return 0; 00323 } 00324 /*---------------------------------------------------------------------------*/ 00325 static int stm32w_radio_prepare(const void *payload, unsigned short payload_len) 00326 { 00327 if(payload_len > STM32W_MAX_PACKET_LEN){ 00328 PRINTF("stm32w: payload length=%d is too long.\r\n", payload_len); 00329 return RADIO_TX_ERR; 00330 } 00331 00332 #if !RADIO_WAIT_FOR_PACKET_SENT 00333 /* Check if the txbuf is empty. 00334 * Wait for a finite time. 00335 * This sould not occur if we wait for the end of transmission in stm32w_radio_transmit(). 00336 */ 00337 if(wait_for_tx()){ 00338 PRINTF("stm32w: tx buffer full.\r\n"); 00339 return RADIO_TX_ERR; 00340 } 00341 #endif /* RADIO_WAIT_FOR_PACKET_SENT */ 00342 00343 /* Copy to the txbuf. 00344 * The first byte must be the packet length. 00345 */ 00346 CLEAN_TXBUF(); 00347 memcpy(stm32w_txbuf + 1, payload, payload_len); 00348 00349 return RADIO_TX_OK; 00350 00351 } 00352 /*---------------------------------------------------------------------------*/ 00353 static int stm32w_radio_transmit(unsigned short payload_len) 00354 { 00355 stm32w_txbuf[0] = payload_len + CHECKSUM_LEN; 00356 00357 INIT_RETRY_CNT(); 00358 00359 if(onoroff == OFF){ 00360 PRINTF("stm32w: Radio is off, turning it on.\r\n"); 00361 ST_RadioWake(); 00362 ENERGEST_ON(ENERGEST_TYPE_LISTEN); 00363 } 00364 00365 #if RADIO_WAIT_FOR_PACKET_SENT 00366 GET_LOCK(); 00367 #endif /* RADIO_WAIT_FOR_PACKET_SENT */ 00368 last_tx_status = -1; 00369 LED_TX_ON(); 00370 if(ST_RadioTransmit(stm32w_txbuf)==ST_SUCCESS){ 00371 00372 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); 00373 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); 00374 00375 PRINTF("stm32w: sending %d bytes\r\n", payload_len); 00376 00377 #if DEBUG > 1 00378 for(uint8_t c=1; c <= stm32w_txbuf[0]-2; c++){ 00379 PRINTF("%x:",stm32w_txbuf[c]); 00380 } 00381 PRINTF("\r\n"); 00382 #endif 00383 00384 #if RADIO_WAIT_FOR_PACKET_SENT 00385 00386 if(wait_for_tx()){ 00387 PRINTF("stm32w: unknown tx error.\r\n"); 00388 TO_PREV_STATE(); 00389 LED_TX_OFF(); 00390 RELEASE_LOCK(); 00391 return RADIO_TX_ERR; 00392 } 00393 TO_PREV_STATE(); 00394 if(last_tx_status == ST_SUCCESS || last_tx_status == ST_PHY_ACK_RECEIVED || last_tx_status == ST_MAC_NO_ACK_RECEIVED){ 00395 RELEASE_LOCK(); 00396 if(last_tx_status == ST_PHY_ACK_RECEIVED){ 00397 return RADIO_TX_OK; /* ACK status */ 00398 } 00399 else if (last_tx_status == ST_MAC_NO_ACK_RECEIVED || last_tx_status == ST_SUCCESS){ 00400 return RADIO_TX_NOACK; 00401 } 00402 } 00403 LED_TX_OFF(); 00404 RELEASE_LOCK(); 00405 return RADIO_TX_ERR; 00406 00407 #else /* RADIO_WAIT_FOR_PACKET_SENT */ 00408 00409 TO_PREV_STATE(); 00410 LED_TX_OFF(); 00411 return RADIO_TX_OK; 00412 00413 #endif /* RADIO_WAIT_FOR_PACKET_SENT */ 00414 00415 } 00416 00417 #if RADIO_WAIT_FOR_PACKET_SENT 00418 RELEASE_LOCK(); 00419 #endif /* RADIO_WAIT_FOR_PACKET_SENT */ 00420 TO_PREV_STATE(); 00421 00422 PRINTF("stm32w: transmission never started.\r\n"); 00423 /* TODO: Do we have to retransmit? */ 00424 00425 CLEAN_TXBUF(); 00426 LED_TX_OFF(); 00427 return RADIO_TX_ERR; 00428 00429 } 00430 /*---------------------------------------------------------------------------*/ 00431 static int stm32w_radio_send(const void *payload, unsigned short payload_len) 00432 { 00433 if(stm32w_radio_prepare(payload, payload_len) == RADIO_TX_ERR) 00434 return RADIO_TX_ERR; 00435 00436 return stm32w_radio_transmit(payload_len); 00437 00438 } 00439 /*---------------------------------------------------------------------------*/ 00440 static int stm32w_radio_channel_clear(void) 00441 { 00442 return ST_RadioChannelIsClear(); 00443 } 00444 /*---------------------------------------------------------------------------*/ 00445 static int stm32w_radio_receiving_packet(void) 00446 { 00447 return receiving_packet; 00448 } 00449 /*---------------------------------------------------------------------------*/ 00450 static int stm32w_radio_pending_packet(void) 00451 { 00452 return !RXBUFS_EMPTY(); 00453 } 00454 /*---------------------------------------------------------------------------*/ 00455 static int stm32w_radio_off(void) 00456 { 00457 /* Any transmit or receive packets in progress are aborted. 00458 * Waiting for end of transmission or reception have to be done. 00459 */ 00460 if(locked) 00461 { 00462 PRINTF("stm32w: try to off while sending/receiving (lock=%u).\r\n", locked); 00463 return 0; 00464 } 00465 /* off only if there is no transmission or reception of packet. */ 00466 if(onoroff == ON && TXBUF_EMPTY() && !receiving_packet){ 00467 LED_RDC_OFF(); 00468 ST_RadioSleep(); 00469 onoroff = OFF; 00470 CLEAN_TXBUF(); 00471 CLEAN_RXBUFS(); 00472 00473 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); 00474 } 00475 00476 return 1; 00477 } 00478 /*---------------------------------------------------------------------------*/ 00479 static int stm32w_radio_on(void) 00480 { 00481 PRINTF("stm32w: turn radio on\n"); 00482 if(onoroff == OFF){ 00483 LED_RDC_ON(); 00484 ST_RadioWake(); 00485 onoroff = ON; 00486 00487 ENERGEST_ON(ENERGEST_TYPE_LISTEN); 00488 } 00489 00490 return 1; 00491 } 00492 /*---------------------------------------------------------------------------*/ 00493 int stm32w_radio_is_on(void) 00494 { 00495 return onoroff == ON; 00496 } 00497 /*---------------------------------------------------------------------------*/ 00498 00499 00500 void ST_RadioReceiveIsrCallback(u8 *packet, 00501 boolean ackFramePendingSet, 00502 u32 time, 00503 u16 errors, 00504 s8 rssi) 00505 { 00506 LED_RX_ON(); 00507 PRINTF("stm32w: incomming packet received\n"); 00508 receiving_packet = 0; 00509 /* Copy packet into the buffer. It is better to do this here. */ 00510 if(add_to_rxbuf(packet)){ 00511 process_poll(&stm32w_radio_process); 00512 last_rssi = rssi; 00513 } 00514 LED_RX_OFF(); 00515 GET_LOCK(); 00516 is_transmit_ack = 1; 00517 /* Wait for sending ACK */ 00518 BUSYWAIT_UNTIL(!is_transmit_ack, RTIMER_SECOND / 1500); 00519 RELEASE_LOCK(); 00520 00521 } 00522 00523 void ST_RadioTxAckIsrCallback (void) 00524 { 00525 /* This callback is for simplemac 1.1.0. 00526 Till now we block (RTIMER_SECOND / 1500) 00527 to prevent radio off during ACK transmission */ 00528 is_transmit_ack = 0; 00529 //RELEASE_LOCK(); 00530 } 00531 00532 00533 void ST_RadioTransmitCompleteIsrCallback(StStatus status, 00534 u32 txSyncTime, 00535 boolean framePending) 00536 { 00537 00538 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); 00539 ENERGEST_ON(ENERGEST_TYPE_LISTEN); 00540 LED_TX_OFF(); 00541 00542 last_tx_status = status; 00543 00544 if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED){ 00545 CLEAN_TXBUF(); 00546 } 00547 else { 00548 00549 if(RETRY_CNT_GTZ()){ 00550 // Retransmission 00551 LED_TX_ON(); 00552 if(ST_RadioTransmit(stm32w_txbuf)==ST_SUCCESS){ 00553 00554 ENERGEST_OFF(ENERGEST_TYPE_LISTEN); 00555 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); 00556 00557 PRINTF("stm32w: retransmission.\r\n"); 00558 00559 DEC_RETRY_CNT(); 00560 } 00561 else { 00562 CLEAN_TXBUF(); 00563 LED_TX_OFF(); 00564 PRINTF("stm32w: retransmission failed.\r\n"); 00565 } 00566 } 00567 else { 00568 CLEAN_TXBUF(); 00569 } 00570 } 00571 00572 /* Debug outputs. */ 00573 if(status == ST_SUCCESS || status == ST_PHY_ACK_RECEIVED){ 00574 PRINTF("stm32w: return status TX_END\r\n"); 00575 } 00576 else if (status == ST_MAC_NO_ACK_RECEIVED){ 00577 PRINTF("stm32w: return status TX_END_NOACK\r\n"); 00578 } 00579 else if (status == ST_PHY_TX_CCA_FAIL){ 00580 PRINTF("stm32w: return status TX_END_CCA_FAIL\r\n"); 00581 } 00582 else if(status == ST_PHY_TX_UNDERFLOW){ 00583 PRINTF("stm32w: return status TX_END_UNDERFLOW\r\n"); 00584 } 00585 else { 00586 PRINTF("stm32w: return status TX_END_INCOMPLETE\r\n"); 00587 } 00588 } 00589 00590 00591 boolean ST_RadioDataPendingShortIdIsrCallback(int16u shortId) { 00592 receiving_packet = 1; 00593 return FALSE; 00594 } 00595 00596 boolean ST_RadioDataPendingLongIdIsrCallback(int8u* longId) { 00597 receiving_packet = 1; 00598 return FALSE; 00599 } 00600 /*---------------------------------------------------------------------------*/ 00601 PROCESS_THREAD(stm32w_radio_process, ev, data) 00602 { 00603 int len; 00604 00605 PROCESS_BEGIN(); 00606 00607 PRINTF("stm32w_radio_process: started\r\n"); 00608 00609 while(1) { 00610 00611 PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); 00612 00613 PRINTF("stm32w_radio_process: calling receiver callback\r\n"); 00614 00615 #if DEBUG > 1 00616 for(uint8_t c=1; c <= RCVD_PACKET_LEN; c++){ 00617 PRINTF("%x",stm32w_rxbuf[c]); 00618 } 00619 PRINTF("\r\n"); 00620 #endif 00621 00622 packetbuf_clear(); 00623 len = stm32w_radio_read(packetbuf_dataptr(), PACKETBUF_SIZE); 00624 if(len > 0) { 00625 packetbuf_set_datalen(len); 00626 NETSTACK_RDC.input(); 00627 } 00628 if(!RXBUFS_EMPTY()){ 00629 // Some data packet still in rx buffer (this happens because process_poll doesn't queue requests), 00630 // so stm32w_radio_process need to be called again. 00631 process_poll(&stm32w_radio_process); 00632 } 00633 } 00634 00635 PROCESS_END(); 00636 } 00637 /*---------------------------------------------------------------------------*/ 00638 static int stm32w_radio_read(void *buf, unsigned short bufsize) 00639 { 00640 return read_from_rxbuf(buf,bufsize); 00641 } 00642 00643 /*---------------------------------------------------------------------------*/ 00644 void ST_RadioOverflowIsrCallback(void) 00645 { 00646 PRINTF("stm32w: radio overflow\r\n"); 00647 } 00648 /*---------------------------------------------------------------------------*/ 00649 void ST_RadioSfdSentIsrCallback(u32 sfdSentTime) 00650 { 00651 } 00652 /*---------------------------------------------------------------------------*/ 00653 void ST_RadioMacTimerCompareIsrCallback(void) 00654 { 00655 } 00656 /*---------------------------------------------------------------------------*/ 00657 static int add_to_rxbuf(uint8_t * src) 00658 { 00659 if(RXBUFS_FULL()){ 00660 return 0; 00661 } 00662 00663 memcpy(stm32w_rxbufs[last], src, src[0] + 1); 00664 #if RADIO_RXBUFS > 1 00665 last = (last + 1) % RADIO_RXBUFS; 00666 if(first == -1){ 00667 first = 0; 00668 } 00669 #endif 00670 00671 return 1; 00672 } 00673 /*---------------------------------------------------------------------------*/ 00674 static int read_from_rxbuf(void * dest, unsigned short len) 00675 { 00676 00677 if(RXBUFS_EMPTY()){ // Buffers are all empty 00678 return 0; 00679 } 00680 00681 if(stm32w_rxbufs[first][0] > len){ // Too large packet for dest. 00682 len = 0; 00683 } 00684 else { 00685 len = stm32w_rxbufs[first][0]; 00686 memcpy(dest,stm32w_rxbufs[first]+1,len); 00687 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi); 00688 } 00689 00690 #if RADIO_RXBUFS > 1 00691 ATOMIC( 00692 first = (first + 1) % RADIO_RXBUFS; 00693 int first_tmp = first; 00694 if(first_tmp == last){ 00695 CLEAN_RXBUFS(); 00696 } 00697 ) 00698 #else 00699 CLEAN_RXBUFS(); 00700 #endif 00701 00702 return len; 00703 } 00704 /*---------------------------------------------------------------------------*/ 00705 short last_packet_rssi(){ 00706 return last_rssi; 00707 } 00708