Reem M / Mbed OS http-server-example1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NanostackRfPhySpirit1.cpp Source File

NanostackRfPhySpirit1.cpp

00001 #if MBED_CONF_RTOS_PRESENT
00002 
00003 #include "NanostackRfPhySpirit1.h"
00004 #include "SimpleSpirit1.h"
00005 #include "nanostack/platform/arm_hal_phy.h"
00006 #include "platform/arm_hal_interrupt.h"
00007 
00008 #include "mbed_trace.h"
00009 #define TRACE_GROUP  "SPIRIT"
00010 
00011 /* Define beyond macro if you want to perform heavy debug tracing (includes tracing in IRQ context) */
00012 // #define HEAVY_TRACING
00013 
00014 static phy_device_driver_s device_driver;
00015 static int8_t rf_radio_driver_id = -1;
00016 
00017 const phy_rf_channel_configuration_s phy_subghz = {868000000, 1000000, 250000, 11, M_GFSK};
00018 
00019 static phy_device_channel_page_s phy_channel_pages[] = {
00020     {CHANNEL_PAGE_2, &phy_subghz},
00021     {CHANNEL_PAGE_0, NULL}
00022 };
00023 
00024 static uint8_t tx_sequence = 0xff;
00025 static uint8_t mac_tx_handle = 0;
00026 
00027 static SimpleSpirit1 *rf_device = NULL;
00028 static uint8_t rf_rx_buf[MAX_PACKET_LEN];
00029 
00030 static uint16_t stored_short_adr;
00031 static uint16_t stored_pan_id;
00032 static uint8_t stored_mac_address[8] = MBED_CONF_SPIRIT1_MAC_ADDRESS;
00033 
00034 #define RF_SIG_ACK_NEEDED (1<<0)
00035 #define RF_SIG_CB_TX_DONE (1<<1)
00036 #define RF_SIG_CB_RX_RCVD (1<<2)
00037 static Thread rf_ack_sender(osPriorityRealtime);
00038 static volatile uint8_t rf_rx_sequence;
00039 static volatile bool rf_ack_sent = false;
00040 
00041 /* MAC frame helper macros */
00042 #define MAC_FCF_FRAME_TYPE_MASK         0x0007
00043 #define MAC_FCF_FRAME_TYPE_SHIFT        0
00044 #define MAC_FCF_SECURITY_BIT_MASK       0x0008
00045 #define MAC_FCF_SECURITY_BIT_SHIFT      3
00046 #define MAC_FCF_PENDING_BIT_MASK        0x0010
00047 #define MAC_FCF_PENDING_BIT_SHIFT       4
00048 #define MAC_FCF_ACK_REQ_BIT_MASK        0x0020
00049 #define MAC_FCF_ACK_REQ_BIT_SHIFT       5
00050 #define MAC_FCF_INTRA_PANID_MASK        0x0040
00051 #define MAC_FCF_INTRA_PANID_SHIFT       6
00052 #define MAC_FCF_DST_ADDR_MASK           0x0c00
00053 #define MAC_FCF_DST_ADDR_SHIFT          10
00054 #define MAC_FCF_VERSION_MASK            0x3000
00055 #define MAC_FCF_VERSION_SHIFT           12
00056 #define MAC_FCF_SRC_ADDR_MASK           0xc000
00057 #define MAC_FCF_SRC_ADDR_SHIFT          14
00058 
00059 /* MAC supported frame types */
00060 #define FC_BEACON_FRAME         0x00
00061 #define FC_DATA_FRAME           0x01
00062 #define FC_ACK_FRAME            0x02
00063 #define FC_CMD_FRAME            0x03
00064 
00065 static void rf_if_lock(void)
00066 {
00067     platform_enter_critical();
00068 }
00069 
00070 static void rf_if_unlock(void)
00071 {
00072     platform_exit_critical();
00073 }
00074 
00075 static inline uint16_t rf_read_16_bit(uint8_t *data_ptr) { // little-endian
00076     uint16_t ret;
00077 
00078     ret = ((uint16_t)data_ptr[0]) + (((uint16_t)data_ptr[1]) << 8);
00079     return ret;
00080 }
00081 
00082 static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
00083 {
00084 #ifndef NDEBUG
00085     debug_if(!(data_length >= 3), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
00086 #endif
00087 
00088     /* Give 'rf_ack_sender' a better chance to run */
00089     Thread::yield();
00090 
00091     /* Get Lock */
00092     rf_if_lock();
00093 
00094     /*Check if transmitter is busy*/
00095     if(rf_device->is_receiving()) { /* betzw - WAS: (rf_device->channel_clear() != 0)), do NOT use this but rather study and enable automatic CCA */
00096 #ifdef HEAVY_TRACING
00097     tr_debug("%s (%d)", __func__, __LINE__);
00098 #endif
00099     
00100     /* Release Lock */
00101     rf_if_unlock();
00102 
00103     /*Return busy*/
00104     return -1;
00105     } else {
00106 #ifdef HEAVY_TRACING
00107     uint16_t fcf = rf_read_16_bit(data_ptr);
00108     uint16_t need_ack;
00109 
00110     /*Check if transmitted data needs to be acked*/
00111     if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
00112         need_ack = 1;
00113     else
00114         need_ack = 0;
00115 #endif
00116 
00117     /*Store the sequence number for ACK handling*/
00118     tx_sequence = *(data_ptr + 2);
00119 
00120     /*Store TX handle*/
00121     mac_tx_handle = tx_handle;
00122 
00123 #ifdef HEAVY_TRACING
00124     tr_info("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, need_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
00125         data_length, tx_handle, tx_sequence, need_ack,
00126         data_ptr[3], data_ptr[4], data_ptr[5], data_ptr[6],
00127         data_ptr[7], data_ptr[8], data_ptr[9], data_ptr[10]);
00128 #endif
00129 
00130     /*Send the packet*/
00131     rf_device->send(data_ptr, data_length);
00132 
00133     /* Release Lock */
00134     rf_if_unlock();
00135     }
00136 
00137     /*Return success*/
00138     return 0;
00139 }
00140 
00141 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
00142 {
00143     int8_t ret_val = 0;
00144     switch (new_state)
00145     {
00146     /*Reset PHY driver and set to idle*/
00147     case PHY_INTERFACE_RESET:
00148     tr_debug("%s (%d)", __func__, __LINE__);
00149     rf_device->reset_board();
00150     break;
00151     /*Disable PHY Interface driver*/
00152     case PHY_INTERFACE_DOWN:
00153     tr_debug("%s (%d)", __func__, __LINE__);
00154     ret_val = rf_device->off();
00155     if(ret_val != 0) ret_val = -1;
00156     break;
00157     /*Enable PHY Interface driver*/
00158     case PHY_INTERFACE_UP:
00159     ret_val = rf_device->on();
00160     if(ret_val != 0) {
00161         tr_debug("%s (%d)", __func__, __LINE__);
00162         ret_val = -1;
00163         break;
00164     }
00165     tr_debug("%s (%d) - channel: %d", __func__, __LINE__, (int)rf_channel);
00166     rf_device->set_channel(rf_channel);
00167     break;
00168     /*Enable wireless interface ED scan mode*/
00169     case PHY_INTERFACE_RX_ENERGY_STATE:
00170     tr_debug("%s (%d)", __func__, __LINE__);
00171     break;
00172     /*Enable Sniffer state*/
00173     case PHY_INTERFACE_SNIFFER_STATE:
00174     // TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel);
00175     tr_debug("%s (%d)", __func__, __LINE__);
00176     ret_val = -1;
00177     break;
00178     default:
00179     tr_debug("%s (%d)", __func__, __LINE__);
00180     break;
00181     }
00182     return ret_val;
00183 }
00184 
00185 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
00186 {
00187     switch (extension_type)
00188     {
00189     /*Control MAC pending bit for Indirect data transmission*/
00190     case PHY_EXTENSION_CTRL_PENDING_BIT:
00191     tr_debug("%s (%d)", __func__, __LINE__);
00192     break;
00193 
00194     /*Return frame pending status*/
00195     case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
00196     tr_debug("%s (%d)", __func__, __LINE__);
00197     *data_ptr = 0;
00198     break;
00199 
00200     /*Set channel, used for setting channel for energy scan*/
00201     case PHY_EXTENSION_SET_CHANNEL:
00202     tr_debug("%s (%d)", __func__, __LINE__);
00203     break;
00204 
00205     /*Read energy on the channel*/
00206     case PHY_EXTENSION_READ_CHANNEL_ENERGY:
00207     // TODO: *data_ptr = rf_get_channel_energy();
00208     tr_debug("%s (%d)", __func__, __LINE__);
00209     *data_ptr = (int8_t)rf_device->get_last_rssi_dbm();
00210     break;
00211 
00212     /*Read status of the link*/
00213     case PHY_EXTENSION_READ_LINK_STATUS:
00214     // TODO: *data_ptr = rf_get_link_status();
00215     tr_debug("%s (%d)", __func__, __LINE__);
00216     *data_ptr = rf_device->get_last_sqi(); // use SQI as link quality
00217     break;
00218 
00219     default:
00220     tr_debug("%s (%d)", __func__, __LINE__);
00221     break;
00222     }
00223     return 0;
00224 }
00225 
00226 static inline void rf_set_mac_address(uint8_t *ptr) {
00227     tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
00228          __func__, __LINE__,
00229          ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
00230     for(int i = 0; i < 8; i++) {
00231     stored_mac_address[i] = ptr[i];
00232     }
00233 }
00234 
00235 static inline void rf_get_mac_address(uint8_t *ptr) {
00236     for(int i = 0; i < 8; i++) {
00237     ptr[i] = stored_mac_address[i];
00238     }
00239     tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
00240          __func__, __LINE__,
00241          ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
00242 }
00243 
00244 static inline void rf_set_short_adr(uint8_t *ptr) {
00245     stored_short_adr = (ptr[0] << 8) + ptr[1]; // big-endian
00246     tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
00247          __func__, __LINE__,
00248          ptr[0], ptr[1], stored_short_adr);
00249 }
00250 
00251 static inline void rf_set_pan_id(uint8_t *ptr) {
00252     stored_pan_id = (ptr[0] << 8) + ptr[1]; // big-endian
00253     tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
00254          __func__, __LINE__,
00255          ptr[0], ptr[1], stored_pan_id);
00256 }
00257 
00258 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
00259 {
00260     switch (address_type)
00261     {
00262     /*Set 48-bit address*/
00263     case PHY_MAC_48BIT:
00264     /* Not used in this example */
00265     // betzw - WAS: rf_set_mac_48bit(address_ptr);
00266     break;
00267     /*Set 64-bit address*/
00268     case PHY_MAC_64BIT:
00269     rf_set_mac_address(address_ptr);
00270     break;
00271     /*Set 16-bit address*/
00272     case PHY_MAC_16BIT:
00273     rf_set_short_adr(address_ptr);
00274     break;
00275     /*Set PAN Id*/
00276     case PHY_MAC_PANID:
00277     rf_set_pan_id(address_ptr);
00278     break;
00279     }
00280 
00281     return 0;
00282 }
00283 
00284 /* Note: we are in IRQ context */
00285 static inline void rf_send_signal(int32_t signal) {
00286 #ifdef HEAVY_TRACING
00287     tr_info("%s (%d): %d", __func__, __LINE__, signal);
00288 #endif
00289     rf_ack_sender.signal_set(signal);
00290 }
00291 
00292 static phy_link_tx_status_e phy_status;
00293 /* Note: we are in IRQ context */
00294 static void rf_handle_ack(uint8_t seq_number)
00295 {
00296     /*Received ACK sequence must be equal with transmitted packet sequence*/
00297     if(tx_sequence == seq_number)
00298     {
00299 #ifdef HEAVY_TRACING
00300     tr_info("%s (%d)", __func__, __LINE__);
00301 #endif
00302 
00303     /*Call PHY TX Done API*/
00304     if(device_driver.phy_tx_done_cb){
00305         phy_status = PHY_LINK_TX_DONE;
00306         rf_send_signal(RF_SIG_CB_TX_DONE);
00307     }
00308     } else {
00309 #ifdef HEAVY_TRACING
00310     tr_info("%s (%d)", __func__, __LINE__);
00311 #endif
00312     }
00313 }
00314 
00315 /* Note: we are in IRQ context */
00316 static inline bool rf_check_mac_address(uint8_t *dest) {
00317     for(int i = 0; i < 8; i++) {
00318     if(dest[i] != stored_mac_address[7-i]) return false;
00319     }
00320     return true;
00321 }
00322 
00323 /* Note: we are in IRQ context */
00324 /* Returns true if packet should be accepted */
00325 static bool rf_check_destination(int len, uint8_t *ack_requested) {
00326     uint8_t frame_type;
00327     uint16_t dst_pan_id;
00328     uint16_t dst_short_adr;
00329     uint8_t dst_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
00330     uint8_t src_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
00331     uint8_t min_size = 3; // FCF & SeqNr
00332     bool ret = false;
00333 #if defined(HEAVY_TRACING)
00334     bool panid_compr = false;
00335 #endif
00336 
00337     if(len < 3) {
00338     tr_debug("%s (%d)", __func__, __LINE__);
00339     return false;
00340     }
00341 
00342     uint16_t fcf = rf_read_16_bit(rf_rx_buf);
00343     frame_type = ((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT);
00344     (*ack_requested) = ((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT);
00345     dst_addr_mode = ((fcf & MAC_FCF_DST_ADDR_MASK) >> MAC_FCF_DST_ADDR_SHIFT);
00346     src_addr_mode = ((fcf & MAC_FCF_SRC_ADDR_MASK) >> MAC_FCF_SRC_ADDR_SHIFT);
00347 #if defined(HEAVY_TRACING)
00348     panid_compr = ((fcf & MAC_FCF_INTRA_PANID_MASK) >> MAC_FCF_INTRA_PANID_SHIFT);
00349 #endif
00350 
00351 #ifdef HEAVY_TRACING
00352     tr_info("%s (%d): len=%d, ftype=%x, snr=%x, ack=%d, dst=%x, src=%x, intra=%d", __func__, __LINE__, len, frame_type,
00353         rf_rx_buf[2], (*ack_requested), dst_addr_mode, src_addr_mode, panid_compr);
00354 #endif
00355 
00356     if(frame_type == FC_ACK_FRAME) { // betzw: we support up to two different forms of ACK frames!
00357     if((len == 3) && (dst_addr_mode == 0x0) && (src_addr_mode == 0x0)) {
00358         ret = true;
00359     }
00360 
00361 #ifdef HEAVY_TRACING
00362     tr_info("%s (%d): ret=%d", __func__, __LINE__, ret);
00363 #endif
00364     (*ack_requested) = 0;  // Never acknowledge ACK frames
00365     return ret;
00366     }
00367 
00368     switch(dst_addr_mode) {
00369     case 0x00:
00370     ret = true; // no check possible;
00371     break;
00372     case 0x02:
00373     min_size += 4; // pan id + short dest adr
00374 
00375     if(len < 5) {
00376 #ifdef HEAVY_TRACING
00377         tr_debug("%s (%d)", __func__, __LINE__);
00378 #endif
00379         return false;
00380     }
00381 
00382     dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
00383     if(dst_pan_id == 0xFFFF) {
00384 #ifdef HEAVY_TRACING
00385         tr_debug("%s (%d)", __func__, __LINE__);
00386 #endif
00387         ret = true;
00388         break;
00389     }
00390 
00391     if(dst_pan_id == stored_pan_id) {
00392 #ifdef HEAVY_TRACING
00393         tr_debug("%s (%d)", __func__, __LINE__);
00394 #endif
00395         ret = true;
00396         break;
00397     } else {
00398 #ifdef HEAVY_TRACING
00399         tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_pan_id, stored_pan_id);
00400 #endif
00401     }
00402 
00403     if(len < 7) {
00404 #ifdef HEAVY_TRACING
00405         tr_debug("%s (%d)", __func__, __LINE__);
00406 #endif
00407         return false;
00408     }
00409 
00410     dst_short_adr = rf_read_16_bit(&rf_rx_buf[5]);
00411     if(dst_short_adr == stored_short_adr) {
00412 #ifdef HEAVY_TRACING
00413         tr_debug("%s (%d)", __func__, __LINE__);
00414 #endif
00415         ret = true;
00416         break;
00417     } else {
00418 #ifdef HEAVY_TRACING
00419         tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_short_adr, stored_short_adr);
00420 #endif
00421     }
00422     break;
00423     case 0x03:
00424     min_size += 10; // pan id + dest mac addr
00425 
00426     if(len < 5) {
00427 #ifdef HEAVY_TRACING
00428         tr_debug("%s (%d)", __func__, __LINE__);
00429 #endif
00430         return false;
00431     }
00432 
00433     dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
00434     if(dst_pan_id == 0xFFFF) {
00435 #ifdef HEAVY_TRACING
00436         tr_debug("%s (%d)", __func__, __LINE__);
00437 #endif
00438         ret = true;
00439         break;
00440     }
00441 
00442     if(dst_pan_id == stored_pan_id) {
00443 #ifdef HEAVY_TRACING
00444         tr_debug("%s (%d)", __func__, __LINE__);
00445 #endif
00446         ret = true;
00447         break;
00448     }
00449 
00450     if(len < 13) {
00451 #ifdef HEAVY_TRACING
00452         tr_debug("%s (%d)", __func__, __LINE__);
00453 #endif
00454         return false;
00455     }
00456 
00457     ret = rf_check_mac_address(&rf_rx_buf[5]);
00458     break;
00459     default:
00460     /* not supported */
00461 #ifdef HEAVY_TRACING
00462     tr_debug("%s (%d)", __func__, __LINE__);
00463 #endif
00464     return false;
00465     }
00466 
00467     if(ret && (*ack_requested)) {
00468     rf_rx_sequence = rf_rx_buf[2];
00469     }
00470 
00471 #ifdef HEAVY_TRACING
00472     tr_info("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
00473 #endif
00474     return ret;
00475 }
00476 
00477 static uint16_t rf_buffer_len = 0;
00478 static uint8_t rf_sqi;
00479 static int8_t rf_rssi;
00480 /* Note: we are in IRQ context */
00481 static inline void rf_handle_rx_end(void)
00482 {
00483     uint8_t ack_requested = 0;
00484 
00485     /* Get received data */
00486     rf_buffer_len = rf_device->read(rf_rx_buf, MAX_PACKET_LEN);
00487     if(!rf_buffer_len)
00488     return;
00489 
00490 #ifdef HEAVY_TRACING
00491     tr_debug("%s (%d)", __func__, __LINE__);
00492 #endif
00493 
00494     /* Check if packet should be accepted */
00495     if(!rf_check_destination(rf_buffer_len, &ack_requested)) {
00496 #ifdef HEAVY_TRACING
00497     tr_debug("%s (%d)", __func__, __LINE__);
00498 #endif
00499     return;
00500     }
00501 
00502     /* If waiting for ACK, check here if the packet is an ACK to a message previously sent */
00503     uint16_t fcf = rf_read_16_bit(rf_rx_buf);
00504     if(((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT) == FC_ACK_FRAME) {
00505     /*Send sequence number in ACK handler*/
00506 #ifdef HEAVY_TRACING
00507     tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
00508 #endif
00509     rf_handle_ack(rf_rx_buf[2]);
00510     return;
00511     }
00512 
00513     /* Kick off ACK sending */
00514     if(ack_requested) {
00515 #ifdef HEAVY_TRACING
00516     tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
00517 #endif
00518     rf_send_signal(RF_SIG_ACK_NEEDED);
00519     }
00520 
00521     /* Get link information */
00522     rf_rssi = (int8_t)rf_device->get_last_rssi_dbm();
00523     rf_sqi = (uint8_t)rf_device->get_last_sqi(); // use SQI as link quality
00524 
00525     /* Note: Checksum of the packet must be checked and removed before entering here */
00526     /* TODO - betzw: what to do? */
00527 
00528 #ifdef HEAVY_TRACING
00529     tr_debug("%s (%d)", __func__, __LINE__);
00530 #endif
00531 
00532     /* Send received data and link information to the network stack */
00533     if( device_driver.phy_rx_cb ){
00534     rf_send_signal(RF_SIG_CB_RX_RCVD);
00535     }
00536 }
00537 
00538 /* Note: we are in IRQ context */
00539 static inline void rf_handle_tx_end(void)
00540 {
00541     /* Check if this is an ACK sending which is still pending */
00542     if(rf_ack_sent) {
00543     rf_ack_sent = false;
00544 #ifdef HEAVY_TRACING
00545     tr_debug("%s (%d)", __func__, __LINE__);
00546 #endif
00547     return; // no need to inform stack
00548     }
00549 
00550     /*Call PHY TX Done API*/
00551     if(device_driver.phy_tx_done_cb){
00552     phy_status = PHY_LINK_TX_SUCCESS;
00553     rf_send_signal(RF_SIG_CB_TX_DONE);
00554     }
00555 }
00556 
00557 /* Note: we are in IRQ context */
00558 static inline void rf_handle_tx_err(void) {
00559     /*Call PHY TX Done API*/
00560     if(device_driver.phy_tx_done_cb){
00561     phy_status = PHY_LINK_TX_FAIL;
00562     rf_send_signal(RF_SIG_CB_TX_DONE);
00563     }
00564 }
00565 
00566 /* Note: we are in IRQ context */
00567 static void rf_callback_func(int event) {
00568     switch(event) {
00569     case SimpleSpirit1::RX_DONE:
00570     rf_handle_rx_end();
00571     break;
00572     case SimpleSpirit1::TX_DONE:
00573     rf_handle_tx_end();
00574     break;
00575     case SimpleSpirit1::TX_ERR:
00576 #ifdef HEAVY_TRACING
00577     tr_debug("%s (%d): TX_ERR!!!", __func__, __LINE__);
00578 #endif
00579     rf_handle_tx_err();
00580     break;
00581     }
00582 }
00583 
00584 static void rf_ack_loop(void) {
00585     static uint16_t buffer[2] = {
00586     (FC_ACK_FRAME << MAC_FCF_FRAME_TYPE_SHIFT),
00587     0x0
00588     };
00589 
00590     tr_debug("%s (%d)", __func__, __LINE__);
00591 
00592     do {
00593     /* Wait for signal */
00594     osEvent event = rf_ack_sender.signal_wait(0);
00595 
00596     if(event.status != osEventSignal) {
00597 #ifdef HEAVY_TRACING
00598         tr_debug("%s (%d)", __func__, __LINE__);
00599 #endif
00600         continue;
00601     }
00602 
00603     int32_t signals = event.value.signals;
00604 
00605 #ifdef HEAVY_TRACING
00606         tr_debug("%s (%d)", __func__, __LINE__);
00607 #endif
00608 
00609         /* Get Lock */
00610     rf_if_lock();
00611 
00612     if(signals & RF_SIG_ACK_NEEDED) {
00613 #ifdef HEAVY_TRACING
00614         tr_debug("%s (%d)", __func__, __LINE__);
00615 #endif
00616 
00617         /* Prepare payload */
00618         uint8_t *ptr = (uint8_t*)&buffer[1];
00619         ptr[0] = rf_rx_sequence;   // Sequence number
00620 
00621         /* Wait for device not receiving */
00622         while(rf_device->is_receiving()) {
00623 #ifdef HEAVY_TRACING
00624         tr_info("%s (%d)", __func__, __LINE__);
00625 #endif
00626         wait_us(10);
00627         }
00628 
00629 #ifdef HEAVY_TRACING
00630         tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
00631 #endif
00632 
00633         /* Set information that we have sent an ACK */
00634         rf_ack_sent = true;
00635 
00636         /*Send the packet*/
00637         rf_device->send((uint8_t*)buffer, 3);
00638 
00639 #ifdef HEAVY_TRACING
00640         tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
00641 #endif
00642     }
00643 
00644     if(signals & RF_SIG_CB_TX_DONE) {
00645         device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 0, 0);
00646 #ifdef HEAVY_TRACING
00647         tr_debug("%s (%d)", __func__, __LINE__);
00648 #endif
00649     }
00650 
00651     if(signals & RF_SIG_CB_RX_RCVD) {
00652         device_driver.phy_rx_cb(rf_rx_buf, rf_buffer_len, rf_sqi, rf_rssi, rf_radio_driver_id);
00653 #ifdef HEAVY_TRACING
00654         tr_debug("%s (%d)", __func__, __LINE__);
00655 #endif
00656     }
00657 
00658     /* Release Lock */
00659     rf_if_unlock();
00660 
00661 #ifdef HEAVY_TRACING
00662     tr_debug("%s (%d)", __func__, __LINE__);
00663 #endif
00664     } while(true);
00665 }
00666 
00667 void NanostackRfPhySpirit1::rf_init(void) {
00668 #ifndef NDEBUG
00669     osStatus ret;
00670 #endif
00671 
00672     if(rf_device == NULL) {
00673     rf_device = &SimpleSpirit1::CreateInstance(_spi_mosi, _spi_miso, _spi_sclk, _dev_irq, _dev_cs, _dev_sdn, _brd_led);
00674     rf_device->attach_irq_callback(rf_callback_func);
00675 
00676 #ifndef NDEBUG
00677     ret =
00678 #endif
00679         rf_ack_sender.start(rf_ack_loop);
00680 
00681 #ifndef NDEBUG
00682     debug_if(!(ret == osOK), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
00683 #endif
00684     }
00685 }
00686 
00687 NanostackRfPhySpirit1::NanostackRfPhySpirit1(PinName spi_mosi, PinName spi_miso, PinName spi_sclk,
00688                          PinName dev_irq,  PinName dev_cs, PinName dev_sdn, PinName brd_led) :
00689     _spi_mosi(spi_mosi),
00690     _spi_miso(spi_miso),
00691     _spi_sclk(spi_sclk),
00692     _dev_irq(dev_irq),
00693     _dev_cs(dev_cs),
00694     _dev_sdn(dev_sdn),
00695     _brd_led(brd_led)
00696 {
00697     /* Nothing to do */
00698     tr_debug("%s (%d)", __func__, __LINE__);
00699 }
00700 
00701 NanostackRfPhySpirit1::~NanostackRfPhySpirit1()
00702 {
00703     /* Nothing to do */
00704     tr_debug("%s (%d)", __func__, __LINE__);
00705 }
00706 
00707 int8_t NanostackRfPhySpirit1::rf_register()
00708 {
00709     tr_debug("%s (%d)", __func__, __LINE__);
00710 
00711     /* Get Lock */
00712     rf_if_lock();
00713 
00714     /* Do some initialization */
00715     rf_init();
00716 
00717     /* Set pointer to MAC address */
00718     device_driver.PHY_MAC = stored_mac_address;
00719 
00720     /* Set driver Name */
00721     device_driver.driver_description = (char*)"Spirit1 Sub-GHz RF";
00722 
00723     /*Type of RF PHY is SubGHz*/
00724     device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
00725 
00726     /*Maximum size of payload*/
00727     device_driver.phy_MTU = MAX_PACKET_LEN;
00728 
00729     /*No header in PHY*/
00730     device_driver.phy_header_length = 0;
00731 
00732     /*No tail in PHY*/
00733     device_driver.phy_tail_length = 0;
00734 
00735     /*Set up driver functions*/
00736     device_driver.address_write = &rf_address_write;
00737     device_driver.extension = &rf_extension;
00738     device_driver.state_control = &rf_interface_state_control;
00739     device_driver.tx = &rf_trigger_send;
00740 
00741     /*Set supported channel pages*/
00742     device_driver.phy_channel_pages = phy_channel_pages;
00743 
00744     //Nullify rx/tx callbacks
00745     device_driver.phy_rx_cb = NULL;
00746     device_driver.phy_tx_done_cb = NULL;
00747     device_driver.arm_net_virtual_rx_cb = NULL;
00748     device_driver.arm_net_virtual_tx_cb = NULL;
00749 
00750     /*Register device driver*/
00751     rf_radio_driver_id = arm_net_phy_register(&device_driver);
00752 
00753     /* Release Lock */
00754     rf_if_unlock();
00755 
00756     tr_debug("%s (%d)", __func__, __LINE__);
00757     return rf_radio_driver_id;
00758 }
00759 
00760 void NanostackRfPhySpirit1::rf_unregister()
00761 {
00762     tr_debug("%s (%d)", __func__, __LINE__);
00763 
00764     /* Get Lock */
00765     rf_if_lock();
00766 
00767     if (rf_radio_driver_id >= 0) {
00768         arm_net_phy_unregister(rf_radio_driver_id);
00769         rf_radio_driver_id = -1;
00770     }
00771 
00772     /* Release Lock */
00773     rf_if_unlock();
00774 }
00775 
00776 void NanostackRfPhySpirit1::get_mac_address(uint8_t *mac)
00777 {
00778     tr_debug("%s (%d)", __func__, __LINE__);
00779 
00780     /* Get Lock */
00781     rf_if_lock();
00782 
00783     if(rf_radio_driver_id >= 0) {
00784     rf_get_mac_address(mac);
00785     } else {
00786         error("NanostackRfPhySpirit1 must be registered to read mac address");
00787     }
00788 
00789     /* Release Lock */
00790     rf_if_unlock();
00791 }
00792 
00793 void NanostackRfPhySpirit1::set_mac_address(uint8_t *mac)
00794 {
00795     tr_debug("%s (%d)", __func__, __LINE__);
00796 
00797     /* Get Lock */
00798     rf_if_lock();
00799 
00800     if(rf_radio_driver_id < 0) {
00801     rf_set_mac_address(mac);
00802     } else {
00803         error("NanostackRfPhySpirit1 cannot change mac address when running");
00804     }
00805 
00806     /* Release Lock */
00807     rf_if_unlock();
00808 }
00809 
00810 #endif /* MBED_CONF_RTOS_PRESENT */