Version of easy-connect with the u-blox cellular platforms C027 and C030 added.
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 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