http
Embed:
(wiki syntax)
Show/hide line numbers
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