Added support for WNC M14A2A Cellular LTE Data Module.

Dependencies:   WNC14A2AInterface

Dependents:   http-example-wnc http-example-wnc-modified

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NanostackRfPhySpirit1.cpp Source File

NanostackRfPhySpirit1.cpp

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