Contiki 2.6

stm32w-radio.c

Go to the documentation of this file.
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