Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 */
Generated on Wed Jul 13 2022 01:16:06 by
1.7.2