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