Added support for the WNC M14A2A Cellular LTE Data Module.
Dependencies: WNC14A2AInterface
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 19:09:04 by 1.7.2