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 #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 }
Generated on Tue Jul 12 2022 18:06:46 by
 1.7.2
 1.7.2