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.
NanostackRfPhyKw41z.cpp
00001 /* 00002 Copyright 2017, Igor Stepura <igor.stepura@gmail.com> 00003 00004 Inspired by mcr20a-rf-driver by Andrei Kovacs <Andrei.Kovacs@freescale.com> 00005 and NXP KW41Z 802.15.4 PHY implementation 00006 00007 Licensed under the Apache License, Version 2.0 (the "License"); 00008 you may not use this file except in compliance with the License. 00009 You may obtain a copy of the License at 00010 00011 http://www.apache.org/licenses/LICENSE-2.0 00012 00013 Unless required by applicable law or agreed to in writing, software 00014 distributed under the License is distributed on an "AS IS" BASIS, 00015 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 See the License for the specific language governing permissions and 00017 limitations under the License. 00018 */ 00019 00020 #include "NanostackRfPhyKw41z.h" 00021 #include "ns_types.h" 00022 #include "platform/arm_hal_interrupt.h" 00023 #include "nanostack/platform/arm_hal_phy.h" 00024 #include <string.h> 00025 #include "rtos.h" 00026 #include "fsl_xcvr.h " 00027 #include "PhyTypes.h " 00028 00029 /* PHY states */ 00030 typedef enum { 00031 gIdle_c, 00032 gRX_c, 00033 gTX_c, 00034 gCCA_c, 00035 gTR_c, 00036 gCCCA_c, 00037 }phySeqState_t; 00038 00039 typedef enum{ 00040 gPhyPwrRun_c, 00041 gPhyPwrDSM_c, 00042 }phyPwrMode_t; 00043 00044 /* PHY channel state */ 00045 enum { 00046 gChannelIdle_c, 00047 gChannelBusy_c 00048 }; 00049 00050 enum { 00051 gMacRole_DeviceOrCoord_c, 00052 gMacRole_PanCoord_c 00053 }; 00054 00055 /* Cca types */ 00056 enum { 00057 gCcaED_c, /* energy detect - CCA bit not active, not to be used for T and CCCA sequences */ 00058 gCcaCCA_MODE1_c, /* energy detect - CCA bit ACTIVE */ 00059 gCcaCCA_MODE2_c, /* 802.15.4 compliant signal detect - CCA bit ACTIVE */ 00060 gCcaCCA_MODE3_c, /* 802.15.4 compliant signal detect and energy detect - CCA bit ACTIVE */ 00061 gInvalidCcaType_c /* illegal type */ 00062 }; 00063 00064 static phyPwrMode_t mPhyPwrState = gPhyPwrRun_c; 00065 #ifndef MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS 00066 #define MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS {1, 2, 3, 4, 5, 6, 7, 8} 00067 #endif 00068 00069 #ifndef MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL 00070 #define MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL (12) 00071 #endif 00072 00073 static uint8_t MAC_address[8] = MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS; 00074 static NanostackRfPhyKw41z *rf = NULL; 00075 00076 #ifdef MBED_CONF_RTOS_PRESENT 00077 static Thread irq_thread(osPriorityRealtime, 1024); 00078 #endif 00079 00080 static phy_device_driver_s device_driver; 00081 static int8_t rf_radio_driver_id = -1; 00082 static uint8_t mac_tx_handle = 0; 00083 00084 static uint8_t rf_phy_channel = 0; 00085 static uint8_t need_ack = 0; 00086 00087 #define RF_BUFFER_SIZE 128 00088 /*RF receive buffer*/ 00089 static uint8_t rf_buffer[RF_BUFFER_SIZE]; 00090 00091 /* Channel configurations for 2.4 */ 00092 static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK}; 00093 00094 static const phy_device_channel_page_s phy_channel_pages[] = { 00095 { CHANNEL_PAGE_0, &phy_24ghz}, 00096 { CHANNEL_PAGE_0, NULL} 00097 }; 00098 /* Set the default power level to 0dBm */ 00099 #ifndef gPhyDefaultTxPowerLevel_d 00100 #define gPhyDefaultTxPowerLevel_d (22) 00101 #endif 00102 #define CORE_CLOCK_FREQ 47972352U 00103 #define gPhyMaxTxPowerLevel_d (32) 00104 00105 #define ZLL_IRQSTS_TMRMSK_MASK (ZLL_IRQSTS_TMR1MSK_MASK | \ 00106 ZLL_IRQSTS_TMR2MSK_MASK | \ 00107 ZLL_IRQSTS_TMR3MSK_MASK | \ 00108 ZLL_IRQSTS_TMR4MSK_MASK ) 00109 00110 uint8_t gPhyChannelTxPowerLimits[] = { gPhyMaxTxPowerLevel_d, /* 11 */ \ 00111 gPhyMaxTxPowerLevel_d, /* 12 */ \ 00112 gPhyMaxTxPowerLevel_d, /* 13 */ \ 00113 gPhyMaxTxPowerLevel_d, /* 14 */ \ 00114 gPhyMaxTxPowerLevel_d, /* 15 */ \ 00115 gPhyMaxTxPowerLevel_d, /* 16 */ \ 00116 gPhyMaxTxPowerLevel_d, /* 17 */ \ 00117 gPhyMaxTxPowerLevel_d, /* 18 */ \ 00118 gPhyMaxTxPowerLevel_d, /* 19 */ \ 00119 gPhyMaxTxPowerLevel_d, /* 20 */ \ 00120 gPhyMaxTxPowerLevel_d, /* 21 */ \ 00121 gPhyMaxTxPowerLevel_d, /* 22 */ \ 00122 gPhyMaxTxPowerLevel_d, /* 23 */ \ 00123 gPhyMaxTxPowerLevel_d, /* 24 */ \ 00124 gPhyMaxTxPowerLevel_d, /* 25 */ \ 00125 gPhyMaxTxPowerLevel_d }; /* 26 */ 00126 00127 00128 00129 MBED_UNUSED static void rf_init(void); 00130 MBED_UNUSED static int8_t rf_device_register(void); 00131 MBED_UNUSED static void rf_device_unregister(void); 00132 MBED_UNUSED static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel); 00133 MBED_UNUSED static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr); 00134 MBED_UNUSED static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr); 00135 MBED_UNUSED static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol ); 00136 MBED_UNUSED static void rf_abort(void); 00137 MBED_UNUSED static void rf_promiscuous(uint8_t mode); 00138 MBED_UNUSED static void rf_receive(void); 00139 MBED_UNUSED static void rf_mac64_read(uint8_t *address); 00140 MBED_UNUSED static void rf_set_power_state(phyPwrMode_t newState); 00141 MBED_UNUSED static void rf_handle_tx_end(uint8_t); 00142 static void rf_set_timeout(uint32_t timeout); 00143 static inline uint32_t rf_get_timestamp(void); 00144 static void rf_set_address(uint8_t *address); 00145 static uint8_t rf_detect_channel_energy(void); 00146 00147 static inline phySeqState_t rf_get_state(void) 00148 { 00149 return (phySeqState_t)(((ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) >> ZLL_PHY_CTRL_XCVSEQ_SHIFT)); 00150 } 00151 00152 00153 static void PHY_InterruptHandler(void); 00154 static void PHY_InterruptThread(void); 00155 static void handle_interrupt(uint32_t irqStatus); 00156 00157 static void rf_if_lock(void) 00158 { 00159 platform_enter_critical(); 00160 } 00161 00162 static void rf_if_unlock(void) 00163 { 00164 platform_exit_critical(); 00165 } 00166 00167 static void rf_set_power_level( uint8_t pwrStep) 00168 { 00169 /* Do not exceed the Tx power limit for the current channel */ 00170 if( pwrStep > gPhyChannelTxPowerLimits[ZLL->CHANNEL_NUM0 - 11] ) 00171 { 00172 pwrStep = gPhyChannelTxPowerLimits[ZLL->CHANNEL_NUM0 - 11]; 00173 } 00174 if( pwrStep > 2 ) 00175 { 00176 pwrStep = (pwrStep << 1) - 2; 00177 } 00178 00179 ZLL->PA_PWR = pwrStep; 00180 } 00181 00182 static uint8_t rf_get_power_level(void) 00183 { 00184 uint8_t pwrStep = (uint8_t)ZLL->PA_PWR; 00185 00186 if( pwrStep > 2 ) 00187 { 00188 pwrStep = (pwrStep + 2) >> 1; 00189 } 00190 00191 return pwrStep; 00192 } 00193 00194 #define gPhyIrqNo_d (Radio_1_IRQn) 00195 static void PHY_InstallIsr() 00196 { 00197 NVIC_SetVector(gPhyIrqNo_d, (uint32_t)&PHY_InterruptHandler); 00198 NVIC_ClearPendingIRQ(gPhyIrqNo_d); 00199 NVIC_EnableIRQ(gPhyIrqNo_d); 00200 } 00201 00202 static void rf_channel_set(uint8_t channel) 00203 { 00204 rf_phy_channel = channel; 00205 00206 ZLL->CHANNEL_NUM0 = channel; 00207 00208 if( rf_get_power_level() > gPhyChannelTxPowerLimits[channel - 11] ) 00209 { 00210 rf_set_power_level(gPhyChannelTxPowerLimits[channel - 11]); 00211 } 00212 } 00213 00214 static inline uint32_t rf_get_timestamp(void) 00215 { 00216 uint32_t retval = ZLL->EVENT_TMR >> ZLL_EVENT_TMR_EVENT_TMR_SHIFT; 00217 00218 return retval; 00219 } 00220 00221 static void rf_set_timeout(uint32_t timeout) 00222 { 00223 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK; 00224 ZLL->T3CMP = timeout & 0x00FFFFFF; 00225 00226 uint32_t sts = ZLL->IRQSTS & ZLL_IRQSTS_TMRMSK_MASK; 00227 sts &= ~(ZLL_IRQSTS_TMR3MSK_MASK); 00228 sts |= ZLL_IRQSTS_TMR3IRQ_MASK; 00229 ZLL->IRQSTS = sts; 00230 00231 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_TMR3CMP_EN_MASK; 00232 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_TC3TMOUT_MASK; 00233 } 00234 00235 static uint8_t rf_detect_channel_energy(void) 00236 { 00237 if (rf_get_state() !=gIdle_c) 00238 { 00239 return 0; 00240 } 00241 rf_set_power_state(gPhyPwrRun_c); 00242 00243 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_CCATYPE_MASK; 00244 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | 00245 ZLL_PHY_CTRL_RXMSK_MASK | 00246 ZLL_PHY_CTRL_TXMSK_MASK | 00247 ZLL_PHY_CTRL_SEQMSK_MASK; 00248 00249 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCATYPE(gCcaED_c); 00250 00251 ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); 00252 ZLL->PHY_CTRL |= gCCA_c; 00253 00254 /* Busy wait. No interrupt will be raised */ 00255 while (!(ZLL->IRQSTS & ZLL_IRQSTS_SEQIRQ_MASK)){} 00256 ZLL->IRQSTS = ZLL->IRQSTS; 00257 ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); 00258 00259 int8_t caa1_ed_fnl = (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_CCA1_ED_FNL_MASK) >> ZLL_LQI_AND_RSSI_CCA1_ED_FNL_SHIFT; 00260 00261 return 128 + caa1_ed_fnl; 00262 } 00263 00264 static void rf_init(void) 00265 { 00266 uint32_t phyReg; 00267 XCVR_Init( ZIGBEE_MODE, DR_500KBPS ); 00268 00269 XCVR_SetXtalTrim(0x30); 00270 00271 /* Enable 16 bit mode for TC2 - TC2 prime EN, disable all timers, 00272 enable AUTOACK, mask all interrupts */ 00273 ZLL->PHY_CTRL = (gCcaCCA_MODE1_c << ZLL_PHY_CTRL_CCATYPE_SHIFT) | 00274 ZLL_PHY_CTRL_TC2PRIME_EN_MASK | 00275 ZLL_PHY_CTRL_TSM_MSK_MASK | 00276 ZLL_PHY_CTRL_WAKE_MSK_MASK | 00277 ZLL_PHY_CTRL_CRC_MSK_MASK | 00278 ZLL_PHY_CTRL_PLL_UNLOCK_MSK_MASK | 00279 ZLL_PHY_CTRL_FILTERFAIL_MSK_MASK | 00280 ZLL_PHY_CTRL_RX_WMRK_MSK_MASK | 00281 ZLL_PHY_CTRL_CCAMSK_MASK | 00282 ZLL_PHY_CTRL_RXMSK_MASK | 00283 ZLL_PHY_CTRL_TXMSK_MASK | 00284 ZLL_PHY_CTRL_SEQMSK_MASK | 00285 ZLL_PHY_CTRL_AUTOACK_MASK | 00286 ZLL_PHY_CTRL_TRCV_MSK_MASK; 00287 00288 /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after init 00289 disable all timer interrupts */ 00290 ZLL->IRQSTS = ZLL->IRQSTS; 00291 00292 /* Enable Source Addresing Match module */ 00293 ZLL->SAM_CTRL |= ZLL_SAM_CTRL_SAP0_EN_MASK; 00294 00295 /* Clear HW indirect queue */ 00296 ZLL->SAM_TABLE |= ZLL_SAM_TABLE_INVALIDATE_ALL_MASK; 00297 00298 /* Frame Filtering 00299 FRM_VER[7:6] = b11. Accept FrameVersion 0 and 1 packets, reject all others */ 00300 ZLL->RX_FRAME_FILTER &= ~ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK; 00301 ZLL->RX_FRAME_FILTER = ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3) | 00302 ZLL_RX_FRAME_FILTER_CMD_FT_MASK | 00303 ZLL_RX_FRAME_FILTER_DATA_FT_MASK | 00304 ZLL_RX_FRAME_FILTER_BEACON_FT_MASK; 00305 00306 /* Set prescaller to obtain 1 symbol (16us) timebase */ 00307 ZLL->TMR_PRESCALE = 0x05; 00308 00309 /* Set CCA threshold to -75 dBm */ 00310 ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_CCA1_THRESH_MASK; 00311 ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_CCA1_THRESH(0xB5); 00312 00313 /* Set the default power level */ 00314 rf_set_power_level(gPhyDefaultTxPowerLevel_d); 00315 00316 /* Adjust ACK delay to fulfill the 802.15.4 turnaround requirements */ 00317 ZLL->ACKDELAY &= ~ZLL_ACKDELAY_ACKDELAY_MASK; 00318 ZLL->ACKDELAY |= ZLL_ACKDELAY_ACKDELAY(-8); 00319 00320 /* Adjust LQI compensation */ 00321 ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP_MASK; 00322 ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP(96); 00323 00324 /* Enable the RxWatermark IRQ and FilterFail IRQ */ 00325 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RX_WMRK_MSK_MASK; 00326 /* Set Rx watermark level */ 00327 ZLL->RX_WTR_MARK = 0; 00328 00329 rf_channel_set(MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL); 00330 00331 /* DSM settings */ 00332 phyReg = (RSIM->RF_OSC_CTRL & RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_MASK) >> 00333 RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_SHIFT; 00334 phyReg = (1024U << phyReg) / (CORE_CLOCK_FREQ / 32768) + 1; 00335 RSIM->DSM_OSC_OFFSET = phyReg; 00336 00337 /* Install PHY ISR */ 00338 PHY_InstallIsr(); 00339 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TRCV_MSK_MASK; 00340 00341 rf_receive(); 00342 } 00343 00344 static void rf_mac64_read(uint8_t *address) 00345 { 00346 uint64_t val = ZLL->MACLONGADDRS0_MSB; 00347 val <<= 32; 00348 val |= ZLL->MACLONGADDRS0_LSB; 00349 00350 *((uint64_t*)address) = val; 00351 } 00352 00353 static void rf_promiscuous(uint8_t state) 00354 { 00355 if( state ) 00356 { 00357 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_PROMISCUOUS_MASK; 00358 /* FRM_VER[11:8] = b1111. Any FrameVersion accepted */ 00359 ZLL->RX_FRAME_FILTER |= (ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | 00360 ZLL_RX_FRAME_FILTER_ACK_FT_MASK | 00361 ZLL_RX_FRAME_FILTER_NS_FT_MASK); 00362 } 00363 else 00364 { 00365 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_PROMISCUOUS_MASK; 00366 /* FRM_VER[11:8] = b0011. Accept FrameVersion 0 and 1 packets, reject all others */ 00367 /* Beacon, Data and MAC command frame types accepted */ 00368 ZLL->RX_FRAME_FILTER &= ~(ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | 00369 ZLL_RX_FRAME_FILTER_ACK_FT_MASK | 00370 ZLL_RX_FRAME_FILTER_NS_FT_MASK | 00371 ZLL_RX_FRAME_FILTER_ACTIVE_PROMISCUOUS_MASK); 00372 ZLL->RX_FRAME_FILTER |= ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3); 00373 } 00374 } 00375 00376 static void rf_receive(void) 00377 { 00378 uint32_t irqSts; 00379 /* RX can start only from Idle state */ 00380 if( rf_get_state() != gIdle_c ) 00381 { 00382 return; 00383 } 00384 rf_set_power_state(gPhyPwrRun_c); 00385 00386 irqSts = ZLL->IRQSTS; 00387 irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; 00388 ZLL->IRQSTS = irqSts; 00389 00390 ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); 00391 ZLL->PHY_CTRL |= gRX_c ; 00392 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; 00393 } 00394 00395 static int8_t rf_device_register(void) 00396 { 00397 00398 rf_init(); 00399 00400 /*Set pointer to MAC address*/ 00401 device_driver.PHY_MAC = MAC_address; 00402 device_driver.driver_description = (char*)"NXP_KWx"; 00403 00404 //Create setup Used Radio chips 00405 /*Type of RF PHY is SubGHz*/ 00406 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE; 00407 00408 device_driver.phy_channel_pages = phy_channel_pages; 00409 /*Maximum size of payload is 127*/ 00410 device_driver.phy_MTU = 127; 00411 /*No header in PHY*/ 00412 device_driver.phy_header_length = 0; 00413 /*No tail in PHY*/ 00414 device_driver.phy_tail_length = 0; 00415 /*Set address write function*/ 00416 device_driver.address_write = &rf_address_write; 00417 /*Set RF extension function*/ 00418 device_driver.extension = &rf_extension; 00419 /*Set RF state control function*/ 00420 device_driver.state_control = &rf_interface_state_control; 00421 /*Set transmit function*/ 00422 device_driver.tx = &rf_start_cca; 00423 /*Upper layer callbacks init to NULL*/ 00424 device_driver.phy_rx_cb = NULL; 00425 device_driver.phy_tx_done_cb = NULL; 00426 /*Virtual upper data callback init to NULL*/ 00427 device_driver.arm_net_virtual_rx_cb = NULL; 00428 device_driver.arm_net_virtual_tx_cb = NULL; 00429 00430 /*Register device driver*/ 00431 rf_radio_driver_id = arm_net_phy_register(&device_driver); 00432 00433 return rf_radio_driver_id; 00434 } 00435 00436 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol ) 00437 { 00438 if( rf_get_state() == gRX_c ) 00439 { 00440 uint8_t phyReg = (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK); 00441 /* Check for an Rx in progress. */ 00442 if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16)) 00443 { 00444 if (device_driver.phy_tx_done_cb) { 00445 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00446 } 00447 return -1; 00448 } 00449 rf_abort(); 00450 } 00451 uint8_t* pPB = (uint8_t*)ZLL->PKT_BUFFER_TX; 00452 pPB[0] = data_length + 2; /* including 2 bytes of FCS */ 00453 memcpy(&pPB[1], data_ptr, data_length); 00454 00455 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCABFRTX_MASK; 00456 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_CCATYPE_MASK; 00457 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCATYPE(gCcaCCA_MODE1_c); 00458 00459 ZLL->IRQSTS = ZLL->IRQSTS; 00460 00461 mac_tx_handle = tx_handle; 00462 need_ack = (*data_ptr & 0x20) == 0x20; 00463 00464 /* Set XCVR power state in run mode */ 00465 rf_set_power_state(gPhyPwrRun_c); 00466 00467 uint8_t xcvseq; 00468 if(need_ack) 00469 { 00470 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_RXACKRQD_MASK; 00471 xcvseq = gTR_c; 00472 } 00473 else 00474 { 00475 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RXACKRQD_MASK; 00476 xcvseq = gTX_c; 00477 00478 uint32_t timeout = rf_get_timestamp(); 00479 timeout += ((XCVR_TSM->END_OF_SEQ & XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_TX_WU_SHIFT) >> 4; 00480 timeout += 50; /* Maigic numbers are the best!! */ 00481 00482 rf_set_timeout(timeout); 00483 } 00484 ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); 00485 ZLL->PHY_CTRL |= xcvseq; 00486 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; 00487 00488 return 0; 00489 } 00490 00491 static void rf_set_short_adr(uint8_t * short_address) 00492 { 00493 uint16_t value = ((uint16_t)short_address[0] << 8) | (uint16_t)short_address[1]; 00494 ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACSHORTADDRS0_MASK; 00495 ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACSHORTADDRS0(value); 00496 } 00497 00498 static void rf_set_pan_id(uint8_t *pan_id) 00499 { 00500 uint16_t value = ((uint16_t)pan_id[0] << 8) | (uint16_t)pan_id[1]; 00501 ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACPANID0_MASK; 00502 ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACPANID0(value); 00503 } 00504 00505 #define TO_UINT32(ptr, num) do {\ 00506 num = (((uint32_t)(ptr)[0] << 24) |\ 00507 ((uint32_t)(ptr)[1] << 16) |\ 00508 ((uint32_t)(ptr)[2] << 8) |\ 00509 ((uint32_t)(ptr)[3])); \ 00510 }while(0) 00511 00512 static void rf_set_address(uint8_t *address) 00513 { 00514 uint32_t addrLo; 00515 uint32_t addrHi; 00516 00517 TO_UINT32(address, addrHi); 00518 TO_UINT32(address + 4, addrLo); 00519 00520 ZLL->MACLONGADDRS0_LSB = addrLo; 00521 ZLL->MACLONGADDRS0_MSB = addrHi; 00522 } 00523 00524 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00525 { 00526 int8_t ret_val = 0; 00527 switch (address_type) 00528 { 00529 /*Set 48-bit address*/ 00530 case PHY_MAC_48BIT: 00531 break; 00532 /*Set 64-bit address*/ 00533 case PHY_MAC_64BIT: 00534 rf_set_address(address_ptr); 00535 break; 00536 /*Set 16-bit address*/ 00537 case PHY_MAC_16BIT: 00538 rf_set_short_adr(address_ptr); 00539 break; 00540 /*Set PAN Id*/ 00541 case PHY_MAC_PANID: 00542 rf_set_pan_id(address_ptr); 00543 break; 00544 } 00545 return ret_val; 00546 } 00547 00548 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) 00549 { 00550 uint32_t type = (uint32_t)extension_type; 00551 switch (type) 00552 { 00553 /*Return frame pending status*/ 00554 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: 00555 *data_ptr = ((ZLL->IRQSTS & ZLL_IRQSTS_RX_FRM_PEND_MASK) >> ZLL_IRQSTS_RX_FRM_PEND_SHIFT); 00556 break; 00557 case PHY_EXTENSION_SET_CHANNEL: 00558 rf_channel_set(*data_ptr); 00559 break; 00560 case PHY_EXTENSION_READ_CHANNEL_ENERGY: 00561 *data_ptr = rf_detect_channel_energy(); 00562 break; 00563 } 00564 return 0; 00565 } 00566 00567 #define mPhyDSM_GuardTime_d (5) /* DSM_TIME ticks (32.768KHz) */ 00568 static uint32_t mPhyDSMDuration = 0xFFFFF0; 00569 static void rf_set_power_state(phyPwrMode_t newState) 00570 { 00571 if( newState == mPhyPwrState ) 00572 { 00573 return; 00574 } 00575 else 00576 { 00577 switch(newState) 00578 { 00579 case gPhyPwrRun_c: 00580 /* Set XCVR in run mode if not allready */ 00581 if(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK) 00582 { 00583 RSIM->ZIG_WAKE = (RSIM->DSM_TIMER + mPhyDSM_GuardTime_d); 00584 while(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK); 00585 } 00586 break; 00587 00588 case gPhyPwrDSM_c: 00589 /* Set XCVR in low power mode if not allready */ 00590 if(!(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK)) 00591 { 00592 uint32_t minTime = (RSIM->DSM_OSC_OFFSET > mPhyDSM_GuardTime_d) ? RSIM->DSM_OSC_OFFSET : mPhyDSM_GuardTime_d; 00593 00594 RSIM->ZIG_SLEEP = RSIM->DSM_TIMER + minTime; 00595 RSIM->ZIG_WAKE = RSIM->DSM_TIMER + mPhyDSMDuration; 00596 RSIM->DSM_CONTROL |= RSIM_DSM_CONTROL_ZIG_SYSCLK_REQUEST_EN_MASK | 00597 RSIM_DSM_CONTROL_DSM_TIMER_EN_MASK | 00598 RSIM_DSM_CONTROL_ZIG_SYSCLK_INTERRUPT_EN_MASK; 00599 } 00600 break; 00601 } 00602 00603 mPhyPwrState = newState; 00604 } 00605 } 00606 00607 static void rf_off(void) 00608 { 00609 rf_abort(); 00610 rf_set_power_state(gPhyPwrDSM_c); 00611 } 00612 00613 static void rf_shutdown(void) 00614 { 00615 rf_off(); 00616 } 00617 00618 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) 00619 { 00620 int8_t ret_val = 0; 00621 switch (new_state) 00622 { 00623 /*Reset PHY driver and set to idle*/ 00624 case PHY_INTERFACE_RESET: 00625 break; 00626 /*Disable PHY Interface driver*/ 00627 case PHY_INTERFACE_DOWN: 00628 rf_shutdown(); 00629 break; 00630 /*Enable PHY Interface driver*/ 00631 case PHY_INTERFACE_UP: 00632 rf_channel_set(rf_channel); 00633 rf_receive(); 00634 break; 00635 /*Enable wireless interface ED scan mode*/ 00636 case PHY_INTERFACE_RX_ENERGY_STATE: 00637 rf_abort(); 00638 rf_channel_set(rf_channel); 00639 break; 00640 case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */ 00641 rf_promiscuous(1); 00642 rf_channel_set(rf_channel); 00643 rf_receive(); 00644 break; 00645 } 00646 return ret_val; 00647 } 00648 00649 static void rf_device_unregister(void) 00650 { 00651 arm_net_phy_unregister(rf_radio_driver_id); 00652 } 00653 00654 static void rf_abort(void) 00655 { 00656 /* Mask SEQ interrupt */ 00657 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_SEQMSK_MASK; 00658 /* Disable timer trigger (for scheduled XCVSEQ) */ 00659 if( ZLL->PHY_CTRL & ZLL_PHY_CTRL_TMRTRIGEN_MASK ) 00660 { 00661 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMRTRIGEN_MASK; 00662 /* give the FSM enough time to start if it was triggered */ 00663 while( (XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) == 0) {} 00664 } 00665 00666 /* If XCVR is not idle, abort current SEQ */ 00667 if( ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK ) 00668 { 00669 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; 00670 /* wait for Sequence Idle (if not already) */ 00671 while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} 00672 } 00673 00674 /* Stop timers */ 00675 ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR2CMP_EN_MASK | 00676 ZLL_PHY_CTRL_TMR3CMP_EN_MASK | 00677 ZLL_PHY_CTRL_TC3TMOUT_MASK ); 00678 ZLL->IRQSTS &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); 00679 } 00680 00681 00682 static volatile uint32_t gIrqStatus = 0; 00683 static void PHY_InterruptHandler(void) 00684 { 00685 gIrqStatus = ZLL->IRQSTS; 00686 ZLL->IRQSTS = gIrqStatus; 00687 #ifdef MBED_CONF_RTOS_PRESENT 00688 irq_thread.signal_set(1); 00689 #else 00690 handle_interrupt(gIrqStatus); 00691 #endif 00692 00693 } 00694 00695 static void PHY_InterruptThread(void) 00696 { 00697 #ifdef MBED_CONF_RTOS_PRESENT 00698 for (;;) { 00699 osEvent event = irq_thread.signal_wait(0); 00700 if (event.status != osEventSignal) { 00701 continue; 00702 } 00703 handle_interrupt(gIrqStatus); 00704 00705 } 00706 #endif 00707 } 00708 00709 static inline void rf_clean_seq_isr(void) 00710 { 00711 uint32_t irqStatus; 00712 00713 /* Set the PHY sequencer back to IDLE */ 00714 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; 00715 /* Mask SEQ, RX, TX and CCA interrupts */ 00716 ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | 00717 ZLL_PHY_CTRL_RXMSK_MASK | 00718 ZLL_PHY_CTRL_TXMSK_MASK | 00719 ZLL_PHY_CTRL_SEQMSK_MASK; 00720 00721 while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} 00722 00723 irqStatus = ZLL->IRQSTS; 00724 irqStatus |= ZLL_IRQSTS_TMR3MSK_MASK; 00725 irqStatus &= ~( ZLL_IRQSTS_TMR1IRQ_MASK | 00726 ZLL_IRQSTS_TMR2IRQ_MASK | 00727 ZLL_IRQSTS_TMR3IRQ_MASK | 00728 ZLL_IRQSTS_TMR4IRQ_MASK ); 00729 ZLL->IRQSTS = irqStatus; 00730 } 00731 00732 static inline uint8_t rf_convert_lqi(uint8_t rssi) 00733 { 00734 if (rssi >= 220) 00735 { 00736 rssi = 255; 00737 } 00738 else 00739 { 00740 rssi = (51 * rssi) / 44; 00741 } 00742 00743 return rssi; 00744 } 00745 00746 static inline int8_t rf_lqi_to_rssi(uint8_t lqi) 00747 { 00748 /* As per NXP's PHY implemenation */ 00749 int32_t rssi = (36 * lqi - 9836) / 109; 00750 00751 return (int8_t)rssi; 00752 } 00753 00754 static void rf_handle_rx_end(void) 00755 { 00756 uint32_t irqSts; 00757 00758 /* disable TMR3 compare */ 00759 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK; 00760 /* disable autosequence stop by TC3 match */ 00761 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TC3TMOUT_MASK; 00762 /* mask TMR3 interrupt (do not change other IRQ status) */ 00763 irqSts = ZLL->IRQSTS & ZLL_IRQSTS_TMR3MSK_MASK; 00764 irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; 00765 /* aknowledge TMR3 IRQ */ 00766 irqSts |= ZLL_IRQSTS_TMR3IRQ_MASK; 00767 ZLL->IRQSTS = irqSts; 00768 00769 uint8_t phyRssi = (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_LQI_VALUE_MASK) >> ZLL_LQI_AND_RSSI_LQI_VALUE_SHIFT; 00770 uint8_t lqi = rf_convert_lqi(phyRssi); 00771 int8_t rssi = rf_lqi_to_rssi(lqi); 00772 00773 uint8_t psduLength = (ZLL->IRQSTS & ZLL_IRQSTS_RX_FRAME_LENGTH_MASK) >> ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT; /* Including FCS (2 bytes) */ 00774 uint8_t len = psduLength - 2; 00775 00776 rf_receive(); 00777 if (psduLength > 0 ) 00778 { 00779 for (uint8_t i = 0; i < len; i++) 00780 { 00781 rf_buffer[i] = ((uint8_t*)ZLL->PKT_BUFFER_RX)[i]; 00782 } 00783 00784 if (device_driver.phy_rx_cb) { 00785 device_driver.phy_rx_cb(rf_buffer, len, lqi, rssi, rf_radio_driver_id); 00786 } 00787 } 00788 00789 } 00790 00791 static void handle_interrupt(uint32_t irqStatus) 00792 { 00793 /* RSIM Wake-up IRQ */ 00794 if(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_SYSCLK_REQ_INT_MASK) 00795 { 00796 RSIM->DSM_CONTROL = RSIM->DSM_CONTROL; 00797 return; 00798 } 00799 00800 /* Read current XCVRSEQ and interrup status */ 00801 uint32_t xcvseqCopy = ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK; 00802 00803 /* WAKE IRQ */ 00804 if( irqStatus & ZLL_IRQSTS_WAKE_IRQ_MASK ) 00805 { 00806 uint32_t timeAdjust = RSIM->ZIG_WAKE; 00807 /* Adjust the 802.15.4 EVENT_TMR */ 00808 timeAdjust = (timeAdjust - RSIM->ZIG_SLEEP)/32768U * 1000000U; /* [us] */ 00809 ZLL->EVENT_TMR = (timeAdjust << 4) | ZLL_EVENT_TMR_EVENT_TMR_ADD_MASK; 00810 } 00811 00812 if( (!(ZLL->PHY_CTRL & ZLL_PHY_CTRL_SEQMSK_MASK)) && (irqStatus & ZLL_IRQSTS_SEQIRQ_MASK) ) 00813 { 00814 if( irqStatus & ZLL_IRQSTS_PLL_UNLOCK_IRQ_MASK ) 00815 { 00816 rf_clean_seq_isr(); 00817 } 00818 /* TMR3 timeout, the autosequence has been aborted due to TMR3 timeout */ 00819 else if( (irqStatus & ZLL_IRQSTS_TMR3IRQ_MASK) && 00820 (!(irqStatus & ZLL_IRQSTS_RXIRQ_MASK)) && 00821 (gTX_c != xcvseqCopy) ) 00822 { 00823 ZLL->IRQSTS = irqStatus | ZLL_IRQSTS_TMR3MSK_MASK; 00824 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK; 00825 00826 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_FAIL, 1, 1); 00827 } 00828 else 00829 { 00830 rf_clean_seq_isr(); 00831 switch(xcvseqCopy) 00832 { 00833 case gTX_c: 00834 if( (ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && (irqStatus & ZLL_IRQSTS_CCA_MASK ) ) 00835 { 00836 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00837 } 00838 else 00839 { 00840 ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; 00841 ZLL->PHY_CTRL |= (ZLL_PHY_CTRL_CCAMSK_MASK | 00842 ZLL_PHY_CTRL_RXMSK_MASK | 00843 ZLL_PHY_CTRL_TXMSK_MASK | 00844 ZLL_PHY_CTRL_SEQMSK_MASK); 00845 while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} 00846 rf_handle_tx_end(0); 00847 } 00848 break; 00849 00850 case gTR_c: 00851 if( (ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && (irqStatus & ZLL_IRQSTS_CCA_MASK ) ) 00852 { 00853 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00854 } 00855 else 00856 { 00857 rf_handle_tx_end((irqStatus & ZLL_IRQSTS_RX_FRM_PEND_MASK) > 0); 00858 00859 } 00860 break; 00861 00862 case gRX_c: 00863 rf_handle_rx_end(); 00864 break; 00865 default: 00866 break; 00867 } 00868 } 00869 } 00870 } 00871 00872 static void rf_handle_tx_end(uint8_t rx_frame_pending) 00873 { 00874 rf_receive(); 00875 00876 if (!device_driver.phy_tx_done_cb) { 00877 return; 00878 } 00879 if( need_ack ) 00880 { 00881 if( rx_frame_pending ) 00882 { 00883 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1); 00884 } 00885 else 00886 { 00887 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1); 00888 } 00889 } 00890 else 00891 { 00892 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00893 } 00894 00895 00896 } 00897 00898 NanostackRfPhyKw41z::NanostackRfPhyKw41z() 00899 { 00900 } 00901 00902 NanostackRfPhyKw41z::~NanostackRfPhyKw41z() 00903 { 00904 } 00905 00906 int8_t NanostackRfPhyKw41z::rf_register() 00907 { 00908 00909 rf_if_lock(); 00910 00911 if (rf != NULL) { 00912 rf_if_unlock(); 00913 error("Multiple registrations of NanostackRfPhyKw41z not supported"); 00914 return -1; 00915 } 00916 00917 #ifdef MBED_CONF_RTOS_PRESENT 00918 irq_thread.start(mbed::callback(PHY_InterruptThread)); 00919 #endif 00920 00921 int8_t radio_id = rf_device_register(); 00922 if (radio_id < 0) { 00923 rf = NULL; 00924 } 00925 00926 rf_if_unlock(); 00927 return radio_id; 00928 } 00929 00930 void NanostackRfPhyKw41z::rf_unregister() 00931 { 00932 rf_if_lock(); 00933 00934 if (rf != this) { 00935 rf_if_unlock(); 00936 return; 00937 } 00938 00939 rf_device_unregister(); 00940 rf = NULL; 00941 rf_if_unlock(); 00942 } 00943 00944 00945 void NanostackRfPhyKw41z::set_mac_address(uint8_t* mac) 00946 { 00947 rf_if_lock(); 00948 00949 if (NULL != rf) { 00950 error("NanostackRfPhyKw41z cannot change mac address when running"); 00951 rf_if_unlock(); 00952 return; 00953 } 00954 memcpy((void*)MAC_address, (void*)mac, sizeof(MAC_address)); 00955 00956 rf_if_unlock(); 00957 } 00958 00959 void NanostackRfPhyKw41z::get_mac_address(uint8_t *mac) 00960 { 00961 rf_if_lock(); 00962 00963 memcpy((void*)mac, (void*)MAC_address, sizeof(MAC_address)); 00964 00965 rf_if_unlock(); 00966 } 00967
Generated on Wed Jul 13 2022 07:46:57 by
1.7.2