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