Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
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 Tue Jul 12 2022 16:22:08 by 1.7.2