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.
NanostackRfPhyMcr20a.cpp
00001 /* 00002 * Copyright (c) 2014-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "NanostackRfPhyMcr20a.h" 00017 #include "ns_types.h" 00018 #include "platform/arm_hal_interrupt.h" 00019 #include "nanostack/platform/arm_hal_phy.h" 00020 #include <string.h> 00021 #include "rtos.h" 00022 00023 /* Freescale headers which are for C files */ 00024 extern "C" { 00025 #include "MCR20Drv.h " 00026 #include "MCR20Reg.h" 00027 #include "MCR20Overwrites.h " 00028 } 00029 00030 00031 #define RF_BUFFER_SIZE 128 00032 00033 /*Radio RX and TX state definitions*/ 00034 #define RFF_ON 0x01 00035 #define RFF_RX 0x02 00036 #define RFF_TX 0x04 00037 #define RFF_CCA 0x08 00038 00039 #define RF_MODE_NORMAL 0 00040 #define RF_MODE_SNIFFER 1 00041 00042 #define RF_CCA_THRESHOLD 75 /* -75 dBm */ 00043 00044 #define RF_TX_POWER_MAX 0 00045 00046 /* PHY constants in symbols */ 00047 #define gPhyWarmUpTime_c 9 00048 #define gPhySHRDuration_c 10 00049 #define gPhySymbolsPerOctet_c 2 00050 #define gPhyAckWaitDuration_c 54 00051 00052 #define gCcaED_c 0 00053 #define gCcaCCA_MODE1_c 1 00054 00055 #define gXcvrRunState_d gXcvrPwrAutodoze_c 00056 #if !defined(TARGET_KW24D) 00057 #define gXcvrLowPowerState_d gXcvrPwrHibernate_c 00058 #else 00059 #define gXcvrLowPowerState_d gXcvrPwrAutodoze_c 00060 #endif 00061 00062 /* MCR20A XCVR states */ 00063 typedef enum xcvrState_tag{ 00064 gIdle_c, 00065 gRX_c, 00066 gTX_c, 00067 gCCA_c, 00068 gTR_c, 00069 gCCCA_c, 00070 }xcvrState_t; 00071 00072 /* MCR20A XCVR low power states */ 00073 typedef enum xcvrPwrMode_tag{ 00074 gXcvrPwrIdle_c, 00075 gXcvrPwrAutodoze_c, 00076 gXcvrPwrDoze_c, 00077 gXcvrPwrHibernate_c 00078 }xcvrPwrMode_t; 00079 00080 00081 /*RF Part Type*/ 00082 typedef enum 00083 { 00084 FREESCALE_UNKNOW_DEV = 0, 00085 FREESCALE_MCR20A 00086 }rf_trx_part_e; 00087 00088 /*Atmel RF states*/ 00089 typedef enum 00090 { 00091 NOP = 0x00, 00092 BUSY_RX = 0x01, 00093 RF_TX_START = 0x02, 00094 FORCE_TRX_OFF = 0x03, 00095 FORCE_PLL_ON = 0x04, 00096 RX_ON = 0x06, 00097 TRX_OFF = 0x08, 00098 PLL_ON = 0x09, 00099 BUSY_RX_AACK = 0x11, 00100 SLEEP = 0x0F, 00101 RX_AACK_ON = 0x16, 00102 TX_ARET_ON = 0x19 00103 }rf_trx_states_t; 00104 00105 /*RF receive buffer*/ 00106 static uint8_t rf_buffer[RF_BUFFER_SIZE]; 00107 00108 /* TX info */ 00109 static uint8_t radio_tx_power = 0x17; /* 0 dBm */ 00110 static uint8_t mac_tx_handle = 0; 00111 static uint8_t need_ack = 0; 00112 static uint16_t tx_len = 0; 00113 00114 /* RF driver data */ 00115 static xcvrState_t mPhySeqState; 00116 static xcvrPwrMode_t mPwrState; 00117 static phy_device_driver_s device_driver; 00118 static uint8_t mStatusAndControlRegs[8]; 00119 static uint8_t rf_rnd = 0; 00120 static int8_t rf_radio_driver_id = -1; 00121 static uint8_t MAC_address[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 00122 00123 /* Driver instance handle and hardware */ 00124 static NanostackRfPhyMcr20a *rf = NULL; 00125 static SPI *spi = NULL; 00126 static DigitalOut *cs = NULL; 00127 static DigitalOut *rst = NULL; 00128 static InterruptIn *irq = NULL; 00129 static DigitalIn *irq_pin = NULL; 00130 static Thread irq_thread(osPriorityRealtime, 1024); 00131 00132 /* Channel info */ /* 2405 2410 2415 2420 2425 2430 2435 2440 2445 2450 2455 2460 2465 2470 2475 2480 */ 00133 static const uint8_t pll_int[16] = {0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D}; 00134 static const uint16_t pll_frac[16] = {0x2800, 0x5000, 0x7800, 0xA000, 0xC800, 0xF000, 0x1800, 0x4000, 0x6800, 0x9000, 0xB800, 0xE000, 0x0800, 0x3000, 0x5800, 0x8000}; 00135 static uint8_t rf_phy_channel = 0; 00136 00137 /* Channel configurations for 2.4 */ 00138 static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK}; 00139 00140 static const phy_device_channel_page_s phy_channel_pages[] = { 00141 { CHANNEL_PAGE_0, &phy_24ghz}, 00142 { CHANNEL_PAGE_0, NULL} 00143 }; 00144 00145 00146 static rf_trx_part_e rf_radio_type_read(void); 00147 00148 MBED_UNUSED static void rf_ack_wait_timer_start(uint16_t slots); 00149 MBED_UNUSED static void rf_ack_wait_timer_stop(void); 00150 MBED_UNUSED static void rf_handle_cca_ed_done(void); 00151 MBED_UNUSED static void rf_handle_tx_end(void); 00152 MBED_UNUSED static void rf_handle_rx_end(void); 00153 MBED_UNUSED static void rf_on(void); 00154 MBED_UNUSED static void rf_receive(void); 00155 MBED_UNUSED static void rf_poll_trx_state_change(rf_trx_states_t trx_state); 00156 MBED_UNUSED static void rf_init(void); 00157 MBED_UNUSED static void rf_set_mac_address(const uint8_t *ptr); 00158 MBED_UNUSED static int8_t rf_device_register(void); 00159 MBED_UNUSED static void rf_device_unregister(void); 00160 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 ); 00161 MBED_UNUSED static void rf_cca_abort(void); 00162 MBED_UNUSED static void rf_read_mac_address(uint8_t *ptr); 00163 MBED_UNUSED static int8_t rf_read_random(void); 00164 MBED_UNUSED static void rf_calibration_cb(void); 00165 MBED_UNUSED static void rf_init_phy_mode(void); 00166 MBED_UNUSED static void rf_ack_wait_timer_interrupt(void); 00167 MBED_UNUSED static void rf_calibration_timer_interrupt(void); 00168 MBED_UNUSED static void rf_calibration_timer_start(uint32_t slots); 00169 MBED_UNUSED static void rf_cca_timer_interrupt(void); 00170 MBED_UNUSED static void rf_cca_timer_start(uint32_t slots); 00171 MBED_UNUSED static uint16_t rf_get_phy_mtu_size(void); 00172 MBED_UNUSED static uint8_t rf_scale_lqi(int8_t rssi); 00173 00174 /** 00175 * RF output power write 00176 * 00177 * \brief TX power has to be set before network start. 00178 * 00179 * \param power 00180 * See datasheet for TX power settings 00181 * 00182 * \return 0, Supported Value 00183 * \return -1, Not Supported Value 00184 */ 00185 MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power); 00186 MBED_UNUSED static uint8_t rf_tx_power_get(void); 00187 MBED_UNUSED static int8_t rf_enable_antenna_diversity(void); 00188 00189 /* Private functions */ 00190 MBED_UNUSED static void rf_abort(void); 00191 MBED_UNUSED static void rf_promiscuous(uint8_t mode); 00192 MBED_UNUSED static void rf_get_timestamp(uint32_t *pRetClk); 00193 MBED_UNUSED static void rf_set_timeout(uint32_t *pEndTime); 00194 MBED_UNUSED static void rf_set_power_state(xcvrPwrMode_t newState); 00195 MBED_UNUSED static uint8_t rf_if_read_rnd(void); 00196 MBED_UNUSED static uint8_t rf_convert_LQI(uint8_t hwLqi); 00197 MBED_UNUSED static uint8_t rf_get_channel_energy(void); 00198 MBED_UNUSED static uint8_t rf_convert_energy_level(uint8_t energyLevel); 00199 MBED_UNUSED static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi); 00200 MBED_UNUSED static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel); 00201 MBED_UNUSED static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr); 00202 MBED_UNUSED static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr); 00203 MBED_UNUSED static void rf_mac64_read(uint8_t *address); 00204 static void PHY_InterruptThread(void); 00205 static void handle_interrupt(void); 00206 00207 00208 /* 00209 * \brief Read connected radio part. 00210 * 00211 * This function only return valid information when rf_init() is called 00212 * 00213 * \return 00214 */ 00215 static rf_trx_part_e rf_radio_type_read(void) 00216 { 00217 return FREESCALE_MCR20A; 00218 } 00219 00220 /* 00221 * \brief Function initialises and registers the RF driver. 00222 * 00223 * \param none 00224 * 00225 * \return rf_radio_driver_id Driver ID given by NET library 00226 */ 00227 static int8_t rf_device_register(void) 00228 { 00229 rf_trx_part_e radio_type; 00230 00231 rf_init(); 00232 00233 00234 00235 radio_type = rf_radio_type_read(); 00236 if(radio_type == FREESCALE_MCR20A) 00237 { 00238 /*Set pointer to MAC address*/ 00239 device_driver.PHY_MAC = MAC_address; 00240 device_driver.driver_description = (char*)"FREESCALE_MAC"; 00241 00242 //Create setup Used Radio chips 00243 /*Type of RF PHY is SubGHz*/ 00244 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE; 00245 00246 device_driver.phy_channel_pages = phy_channel_pages; 00247 /*Maximum size of payload is 127*/ 00248 device_driver.phy_MTU = 127; 00249 /*No header in PHY*/ 00250 device_driver.phy_header_length = 0; 00251 /*No tail in PHY*/ 00252 device_driver.phy_tail_length = 0; 00253 /*Set address write function*/ 00254 device_driver.address_write = &rf_address_write; 00255 /*Set RF extension function*/ 00256 device_driver.extension = &rf_extension; 00257 /*Set RF state control function*/ 00258 device_driver.state_control = &rf_interface_state_control; 00259 /*Set transmit function*/ 00260 device_driver.tx = &rf_start_cca; 00261 /*Upper layer callbacks init to NULL*/ 00262 device_driver.phy_rx_cb = NULL; 00263 device_driver.phy_tx_done_cb = NULL; 00264 /*Virtual upper data callback init to NULL*/ 00265 device_driver.arm_net_virtual_rx_cb = NULL; 00266 device_driver.arm_net_virtual_tx_cb = NULL; 00267 00268 /*Register device driver*/ 00269 rf_radio_driver_id = arm_net_phy_register(&device_driver); 00270 } 00271 00272 return rf_radio_driver_id; 00273 } 00274 00275 /* 00276 * \brief Function unregisters the RF driver. 00277 * 00278 * \param none 00279 * 00280 * \return none 00281 */ 00282 static void rf_device_unregister(void) 00283 { 00284 arm_net_phy_unregister(rf_radio_driver_id); 00285 } 00286 00287 /* 00288 * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator. 00289 * 00290 * \param none 00291 * 00292 * \return random value 00293 */ 00294 static int8_t rf_read_random(void) 00295 { 00296 return rf_rnd; 00297 } 00298 00299 /* 00300 * \brief Function is a call back for ACK wait timeout. 00301 * 00302 * \param none 00303 * 00304 * \return none 00305 */ 00306 static void rf_ack_wait_timer_interrupt(void) 00307 { 00308 /* The packet was transmitted successfully, but no ACK was received */ 00309 if (device_driver.phy_tx_done_cb) { 00310 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00311 } 00312 rf_receive(); 00313 } 00314 00315 /* 00316 * \brief Function is a call back for calibration interval timer. 00317 * 00318 * \param none 00319 * 00320 * \return none 00321 */ 00322 static void rf_calibration_timer_interrupt(void) 00323 { 00324 } 00325 00326 /* 00327 * \brief Function is a call back for cca interval timer. 00328 * 00329 * \param none 00330 * 00331 * \return none 00332 */ 00333 static void rf_cca_timer_interrupt(void) 00334 { 00335 /* CCA time-out handled by Hardware */ 00336 } 00337 00338 00339 /* 00340 * \brief Function starts the ACK wait time-out. 00341 * 00342 * \param slots The ACK wait time-out in [symbols] 00343 * 00344 * \return none 00345 */ 00346 static void rf_ack_wait_timer_start(uint16_t time) 00347 { 00348 uint32_t timeout; 00349 00350 rf_get_timestamp(&timeout); 00351 timeout += time; 00352 rf_set_timeout(&timeout); 00353 } 00354 00355 /* 00356 * \brief Function starts the calibration interval. 00357 * 00358 * \param slots Given slots, resolution 50us 00359 * 00360 * \return none 00361 */ 00362 static void rf_calibration_timer_start(uint32_t slots) 00363 { 00364 (void)slots; 00365 } 00366 00367 /* 00368 * \brief Function starts the CCA timout. 00369 * 00370 * \param slots Given slots, resolution 50us 00371 * 00372 * \return none 00373 */ 00374 static void rf_cca_timer_start(uint32_t slots) 00375 { 00376 (void)slots; 00377 } 00378 00379 /* 00380 * \brief Function stops the ACK wait timeout. 00381 * 00382 * \param none 00383 * 00384 * \return none 00385 */ 00386 static void rf_ack_wait_timer_stop(void) 00387 { 00388 } 00389 00390 /* 00391 * \brief Function reads the MAC address array. 00392 * 00393 * \param ptr Pointer to read array 00394 * 00395 * \return none 00396 */ 00397 static void rf_read_mac_address(uint8_t *ptr) 00398 { 00399 memcpy(ptr, MAC_address, 8); 00400 } 00401 00402 /* 00403 * \brief Function sets the MAC address array. 00404 * 00405 * \param ptr Pointer to given MAC address array 00406 * 00407 * \return none 00408 */ 00409 static void rf_set_mac_address(const uint8_t *ptr) 00410 { 00411 memcpy(MAC_address, ptr, 8); 00412 } 00413 00414 static uint16_t rf_get_phy_mtu_size(void) 00415 { 00416 return device_driver.phy_MTU; 00417 } 00418 00419 /* 00420 * \brief Function writes 16-bit address in RF address filter. 00421 * 00422 * \param short_address Given short address 00423 * 00424 * \return none 00425 */ 00426 static void rf_set_short_adr(uint8_t * short_address) 00427 { 00428 /* Write one register at a time to be accessible from hibernate mode */ 00429 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_MSB, short_address[0]); 00430 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_LSB, short_address[1]); 00431 } 00432 00433 /* 00434 * \brief Function writes PAN Id in RF PAN Id filter. 00435 * 00436 * \param pan_id Given PAN Id 00437 * 00438 * \return none 00439 */ 00440 static void rf_set_pan_id(uint8_t *pan_id) 00441 { 00442 /* Write one register at a time to be accessible from hibernate mode */ 00443 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_MSB, pan_id[0]); 00444 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_LSB, pan_id[1]); 00445 } 00446 00447 /* 00448 * \brief Function writes 64-bit address in RF address filter. 00449 * 00450 * \param address Given 64-bit address 00451 * 00452 * \return none 00453 */ 00454 static void rf_set_address(uint8_t *address) 00455 { 00456 /* Write one register at a time to be accessible from hibernate mode */ 00457 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_0, address[7]); 00458 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_8, address[6]); 00459 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_16, address[5]); 00460 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_24, address[4]); 00461 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_32, address[3]); 00462 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_40, address[2]); 00463 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_48, address[1]); 00464 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_56, address[0]); 00465 } 00466 00467 /* 00468 * \brief Function sets the RF channel. 00469 * 00470 * \param ch New channel 00471 * 00472 * \return none 00473 */ 00474 static void rf_channel_set(uint8_t channel) 00475 { 00476 rf_phy_channel = channel; 00477 MCR20Drv_DirectAccessSPIWrite(PLL_INT0, pll_int[channel - 11]); 00478 MCR20Drv_DirectAccessSPIMultiByteWrite(PLL_FRAC0_LSB, (uint8_t *) &pll_frac[channel - 11], 2); 00479 } 00480 00481 00482 /* 00483 * \brief Function initialises the radio driver and resets the radio. 00484 * 00485 * \param none 00486 * 00487 * \return none 00488 */ 00489 static void rf_init(void) 00490 { 00491 uint32_t index; 00492 mPhySeqState = gIdle_c; 00493 mPwrState = gXcvrPwrIdle_c; 00494 /*Reset RF module*/ 00495 MCR20Drv_RESET(); 00496 /* Initialize the transceiver SPI driver */ 00497 MCR20Drv_Init(); 00498 /* Disable Tristate on MISO for SPI reads */ 00499 MCR20Drv_IndirectAccessSPIWrite(MISC_PAD_CTRL, 0x02); 00500 /* Set XCVR clock output settings */ 00501 #if !defined(TARGET_KW24D) 00502 MCR20Drv_Set_CLK_OUT_Freq(gMCR20_ClkOutFreq_d); 00503 #endif 00504 /* Set default XCVR power state */ 00505 rf_set_power_state(gXcvrRunState_d); 00506 00507 /* PHY_CTRL1 default HW settings + AUTOACK enabled */ 00508 mStatusAndControlRegs[PHY_CTRL1] = cPHY_CTRL1_AUTOACK; 00509 /* PHY_CTRL2 : mask all PP interrupts */ 00510 mStatusAndControlRegs[PHY_CTRL2] = cPHY_CTRL2_CRC_MSK | \ 00511 cPHY_CTRL2_PLL_UNLOCK_MSK | \ 00512 /*cPHY_CTRL2_FILTERFAIL_MSK | */ \ 00513 cPHY_CTRL2_RX_WMRK_MSK | \ 00514 cPHY_CTRL2_CCAMSK | \ 00515 cPHY_CTRL2_RXMSK | \ 00516 cPHY_CTRL2_TXMSK | \ 00517 cPHY_CTRL2_SEQMSK; 00518 /* PHY_CTRL3 : enable timer 3 and disable remaining interrupts */ 00519 mStatusAndControlRegs[PHY_CTRL3] = cPHY_CTRL3_ASM_MSK | \ 00520 cPHY_CTRL3_PB_ERR_MSK | \ 00521 cPHY_CTRL3_WAKE_MSK | \ 00522 cPHY_CTRL3_TMR3CMP_EN; 00523 /* PHY_CTRL4 unmask global TRX interrupts, enable 16 bit mode for TC2 - TC2 prime EN */ 00524 mStatusAndControlRegs[PHY_CTRL4] = cPHY_CTRL4_TC2PRIME_EN | (gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c); 00525 /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after initialization */ 00526 mStatusAndControlRegs[IRQSTS1] = cIRQSTS1_PLL_UNLOCK_IRQ | \ 00527 cIRQSTS1_FILTERFAIL_IRQ | \ 00528 cIRQSTS1_RXWTRMRKIRQ | \ 00529 cIRQSTS1_CCAIRQ | \ 00530 cIRQSTS1_RXIRQ | \ 00531 cIRQSTS1_TXIRQ | \ 00532 cIRQSTS1_SEQIRQ; 00533 00534 mStatusAndControlRegs[IRQSTS2] = cIRQSTS2_ASM_IRQ | cIRQSTS2_PB_ERR_IRQ | cIRQSTS2_WAKE_IRQ; 00535 /* Mask and clear all TMR IRQs */ 00536 mStatusAndControlRegs[IRQSTS3] = cIRQSTS3_TMR4MSK | cIRQSTS3_TMR3MSK | cIRQSTS3_TMR2MSK | cIRQSTS3_TMR1MSK | \ 00537 cIRQSTS3_TMR4IRQ | cIRQSTS3_TMR3IRQ | cIRQSTS3_TMR2IRQ | cIRQSTS3_TMR1IRQ; 00538 /* Write settings to XCVR */ 00539 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 5); 00540 /* Clear all interrupts */ 00541 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, &mStatusAndControlRegs[IRQSTS1], 3); 00542 00543 /* RX_FRAME_FILTER. Accept FrameVersion 0 and 1 packets, reject all others */ 00544 MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, (cRX_FRAME_FLT_FRM_VER | \ 00545 cRX_FRAME_FLT_BEACON_FT | \ 00546 cRX_FRAME_FLT_DATA_FT | \ 00547 cRX_FRAME_FLT_CMD_FT )); 00548 /* Direct register overwrites */ 00549 for (index = 0; index < sizeof(overwrites_direct)/sizeof(overwrites_t); index++) 00550 MCR20Drv_DirectAccessSPIWrite(overwrites_direct[index].address, overwrites_direct[index].data); 00551 /* Indirect register overwrites */ 00552 for (index = 0; index < sizeof(overwrites_indirect)/sizeof(overwrites_t); index++) 00553 MCR20Drv_IndirectAccessSPIWrite(overwrites_indirect[index].address, overwrites_indirect[index].data); 00554 00555 /* Set the CCA energy threshold value */ 00556 MCR20Drv_IndirectAccessSPIWrite(CCA1_THRESH, RF_CCA_THRESHOLD); 00557 /* Set prescaller to obtain 1 symbol (16us) timebase */ 00558 MCR20Drv_IndirectAccessSPIWrite(TMR_PRESCALE, 0x05); 00559 00560 MCR20Drv_IRQ_Enable(); 00561 00562 /*Read random variable. This will be used when seeding pseudo-random generator*/ 00563 rf_rnd = rf_if_read_rnd(); 00564 /*Read eui64*/ 00565 rf_mac64_read(MAC_address); 00566 /*set default channel to 11*/ 00567 rf_channel_set(11); 00568 /*Start receiver*/ 00569 rf_receive(); 00570 } 00571 00572 /** 00573 * \brief Function gets called when MAC is setting radio off. 00574 * 00575 * \param none 00576 * 00577 * \return none 00578 */ 00579 static void rf_off(void) 00580 { 00581 /* Abort any ongoing sequences */ 00582 rf_abort(); 00583 /* Set XCVR in a low power state */ 00584 rf_set_power_state(gXcvrLowPowerState_d); 00585 } 00586 00587 /* 00588 * \brief Function polls the RF state until it has changed to desired state. 00589 * 00590 * \param trx_state RF state 00591 * 00592 * \return none 00593 */ 00594 static void rf_poll_trx_state_change(rf_trx_states_t trx_state) 00595 { 00596 (void)trx_state; 00597 } 00598 00599 /* 00600 * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO. 00601 * 00602 * \param data_ptr Pointer to TX data 00603 * \param data_length Length of the TX data 00604 * \param tx_handle Handle to transmission 00605 * \return 0 Success 00606 * \return -1 Busy 00607 */ 00608 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol ) 00609 { 00610 uint8_t ccaMode; 00611 00612 /* Parameter validation */ 00613 if( !data_ptr || (data_length > 125) || (PHY_LAYER_PAYLOAD != data_protocol) ) 00614 { 00615 return -1; 00616 } 00617 00618 if( mPhySeqState == gRX_c ) 00619 { 00620 uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F; 00621 /* Check for an Rx in progress. */ 00622 if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16)) 00623 { 00624 if (device_driver.phy_tx_done_cb) { 00625 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00626 } 00627 return -1; 00628 } 00629 rf_abort(); 00630 } 00631 00632 /*Check if transmitter is busy*/ 00633 if( mPhySeqState != gIdle_c ) 00634 { 00635 /*Return busy*/ 00636 return -1; 00637 } 00638 00639 /*Store TX handle*/ 00640 mac_tx_handle = tx_handle; 00641 /*Check if transmitted data needs to be acked*/ 00642 need_ack = (*data_ptr & 0x20) == 0x20; 00643 00644 /* Set XCVR power state in run mode */ 00645 rf_set_power_state(gXcvrRunState_d); 00646 /* Load data into XCVR */ 00647 tx_len = data_length + 2; 00648 MCR20Drv_PB_SPIBurstWrite(data_ptr - 1, data_length + 1); 00649 MCR20Drv_PB_SPIByteWrite(0,tx_len); 00650 00651 /* Set CCA mode 1 */ 00652 ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE; 00653 if( ccaMode != gCcaCCA_MODE1_c ) 00654 { 00655 mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c); 00656 mStatusAndControlRegs[PHY_CTRL4] |= gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c; 00657 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]); 00658 } 00659 00660 /* Read XCVR registers */ 00661 mStatusAndControlRegs[0] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[1], 4); 00662 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00663 mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c; 00664 mPhySeqState = gCCA_c; 00665 00666 /* Ensure that no spurious interrupts are raised */ 00667 mStatusAndControlRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */ 00668 mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ); 00669 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3); 00670 00671 /* Write XCVR settings */ 00672 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 00673 00674 /* Unmask SEQ interrupt */ 00675 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00676 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]); 00677 00678 /*Return success*/ 00679 return 0; 00680 } 00681 00682 /* 00683 * \brief Function aborts CCA process. 00684 * 00685 * \param none 00686 * 00687 * \return none 00688 */ 00689 static void rf_cca_abort(void) 00690 { 00691 rf_abort(); 00692 } 00693 00694 /* 00695 * \brief Function starts the transmission of the frame. Called from ISR context! 00696 * 00697 * \param none 00698 * 00699 * \return none 00700 */ 00701 static void rf_start_tx(void) 00702 { 00703 /* Perform TxRxAck sequence if required by phyTxMode */ 00704 if( need_ack ) 00705 { 00706 mStatusAndControlRegs[PHY_CTRL1] |= cPHY_CTRL1_RXACKRQD; 00707 mPhySeqState = gTR_c; 00708 } 00709 else 00710 { 00711 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_RXACKRQD); 00712 mPhySeqState = gTX_c; 00713 } 00714 00715 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00716 mStatusAndControlRegs[PHY_CTRL1] |= mPhySeqState; 00717 00718 /* Unmask SEQ interrupt */ 00719 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00720 00721 /* Start the sequence immediately */ 00722 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 2); 00723 00724 if( need_ack ) 00725 { 00726 rf_ack_wait_timer_start(gPhyWarmUpTime_c + gPhySHRDuration_c + tx_len * gPhySymbolsPerOctet_c + gPhyAckWaitDuration_c); 00727 } 00728 } 00729 00730 /* 00731 * \brief Function sets the RF in RX state. Called from ISR context! 00732 * 00733 * \param none 00734 * 00735 * \return none 00736 */ 00737 static void rf_receive(void) 00738 { 00739 uint8_t phyRegs[5]; 00740 00741 /* RX can start only from Idle state */ 00742 if( mPhySeqState != gIdle_c ) 00743 { 00744 return; 00745 } 00746 00747 /* Set XCVR power state in run mode */ 00748 rf_set_power_state(gXcvrRunState_d); 00749 /* read XVCR settings */ 00750 phyRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &phyRegs[IRQSTS2], 4); 00751 /* unmask SEQ interrupt */ 00752 phyRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00753 /* set XcvrSeq to RX */ 00754 phyRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00755 phyRegs[PHY_CTRL1] |= gRX_c; 00756 mPhySeqState = gRX_c; 00757 /* Ensure that no spurious interrupts are raised */ 00758 phyRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */ 00759 phyRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ; 00760 /* sync settings with XCVR */ 00761 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, phyRegs, 5); 00762 } 00763 00764 /* 00765 * \brief Function calibrates the radio. 00766 * 00767 * \param none 00768 * 00769 * \return none 00770 */ 00771 static void rf_calibration_cb(void) 00772 { 00773 } 00774 00775 /* 00776 * \brief Function sets RF_ON flag when radio is powered. 00777 * 00778 * \param none 00779 * 00780 * \return none 00781 */ 00782 static void rf_on(void) 00783 { 00784 } 00785 00786 /* 00787 * \brief Function is a call back for RX end interrupt. 00788 * 00789 * \param none 00790 * 00791 * \return none 00792 */ 00793 static void rf_handle_rx_end(void) 00794 { 00795 uint8_t rf_lqi = MCR20Drv_DirectAccessSPIRead(LQI_VALUE); 00796 int8_t rf_rssi = 0; 00797 uint8_t len = mStatusAndControlRegs[RX_FRM_LEN] - 2; 00798 00799 00800 /*Start receiver*/ 00801 rf_receive(); 00802 00803 /*Check the length is valid*/ 00804 if(len > 1 && len < RF_BUFFER_SIZE) 00805 { 00806 rf_lqi = rf_convert_LQI(rf_lqi); 00807 rf_rssi = rf_convert_LQI_to_RSSI(rf_lqi); 00808 /*gcararu: Scale LQI using received RSSI, to match the LQI reported by the ATMEL radio */ 00809 rf_lqi = rf_scale_lqi(rf_rssi); 00810 00811 /*Read received packet*/ 00812 MCR20Drv_PB_SPIBurstRead(rf_buffer, len); 00813 if (device_driver.phy_rx_cb) { 00814 device_driver.phy_rx_cb(rf_buffer, len, rf_lqi, rf_rssi, rf_radio_driver_id); 00815 } 00816 } 00817 } 00818 00819 /* 00820 * \brief Function is called when MAC is shutting down the radio. 00821 * 00822 * \param none 00823 * 00824 * \return none 00825 */ 00826 static void rf_shutdown(void) 00827 { 00828 /*Call RF OFF*/ 00829 rf_off(); 00830 } 00831 00832 /* 00833 * \brief Function is a call back for TX end interrupt. 00834 * 00835 * \param none 00836 * 00837 * \return none 00838 */ 00839 static void rf_handle_tx_end(void) 00840 { 00841 uint8_t rx_frame_pending = mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_RX_FRM_PEND; 00842 00843 /*Start receiver*/ 00844 rf_receive(); 00845 00846 if (!device_driver.phy_tx_done_cb) { 00847 return; 00848 } 00849 00850 /*Call PHY TX Done API*/ 00851 if( need_ack ) 00852 { 00853 if( rx_frame_pending ) 00854 { 00855 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1); 00856 } 00857 else 00858 { 00859 // arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00860 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1); 00861 } 00862 } 00863 else 00864 { 00865 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00866 } 00867 } 00868 00869 /* 00870 * \brief Function is a call back for CCA ED done interrupt. 00871 * 00872 * \param none 00873 * 00874 * \return none 00875 */ 00876 static void rf_handle_cca_ed_done(void) 00877 { 00878 /*Check the result of CCA process*/ 00879 if( !(mStatusAndControlRegs[IRQSTS2] & cIRQSTS2_CCA) ) 00880 { 00881 rf_start_tx(); 00882 } 00883 else if (device_driver.phy_tx_done_cb) 00884 { 00885 /*Send CCA fail notification*/ 00886 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00887 } 00888 } 00889 00890 /* 00891 * \brief Function sets the TX power variable. 00892 * 00893 * \param power TX power setting 00894 * 00895 * \return 0 Success 00896 * \return -1 Fail 00897 */ 00898 static int8_t rf_tx_power_set(uint8_t power) 00899 { 00900 /* gcapraru: Map MCR20A Tx power levels over ATMEL values */ 00901 static uint8_t pwrLevelMapping[16] = {25,25,25,24,24,24,23,23,22,22,21,20,19,18,17,14}; 00902 00903 if( power > 15 ) 00904 { 00905 return -1; 00906 } 00907 00908 radio_tx_power = power; 00909 MCR20Drv_DirectAccessSPIWrite(PA_PWR, pwrLevelMapping[power]); 00910 return 0; 00911 } 00912 00913 /* 00914 * \brief Function returns the TX power variable. 00915 * 00916 * \param none 00917 * 00918 * \return radio_tx_power TX power variable 00919 */ 00920 static uint8_t rf_tx_power_get(void) 00921 { 00922 return radio_tx_power; 00923 } 00924 00925 /* 00926 * \brief Function enables the usage of Antenna diversity. 00927 * 00928 * \param none 00929 * 00930 * \return 0 Success 00931 */ 00932 static int8_t rf_enable_antenna_diversity(void) 00933 { 00934 uint8_t phyReg; 00935 00936 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_AGC_CTRL); 00937 phyReg |= cANT_AGC_CTRL_FAD_EN_Mask_c; 00938 MCR20Drv_IndirectAccessSPIWrite(ANT_AGC_CTRL, phyReg); 00939 00940 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_PAD_CTRL); 00941 phyReg |= 0x02; 00942 MCR20Drv_IndirectAccessSPIWrite(ANT_PAD_CTRL, phyReg); 00943 00944 return 0; 00945 } 00946 00947 /* 00948 * \brief Function gives the control of RF states to MAC. 00949 * 00950 * \param new_state RF state 00951 * \param rf_channel RF channel 00952 * 00953 * \return 0 Success 00954 */ 00955 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) 00956 { 00957 int8_t ret_val = 0; 00958 switch (new_state) 00959 { 00960 /*Reset PHY driver and set to idle*/ 00961 case PHY_INTERFACE_RESET: 00962 break; 00963 /*Disable PHY Interface driver*/ 00964 case PHY_INTERFACE_DOWN: 00965 rf_shutdown(); 00966 break; 00967 /*Enable PHY Interface driver*/ 00968 case PHY_INTERFACE_UP: 00969 rf_channel_set(rf_channel); 00970 rf_receive(); 00971 break; 00972 /*Enable wireless interface ED scan mode*/ 00973 case PHY_INTERFACE_RX_ENERGY_STATE: 00974 rf_abort(); 00975 rf_channel_set(rf_channel); 00976 break; 00977 case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */ 00978 rf_promiscuous(1); 00979 rf_channel_set(rf_channel); 00980 rf_receive(); 00981 break; 00982 } 00983 return ret_val; 00984 } 00985 00986 /* 00987 * \brief Function controls the ACK pending, channel setting and energy detection. 00988 * 00989 * \param extension_type Type of control 00990 * \param data_ptr Data from NET library 00991 * 00992 * \return 0 Success 00993 */ 00994 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) 00995 { 00996 switch (extension_type) 00997 { 00998 /*Control MAC pending bit for Indirect data transmission*/ 00999 case PHY_EXTENSION_CTRL_PENDING_BIT: 01000 { 01001 uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL); 01002 01003 if(*data_ptr) 01004 { 01005 reg |= cSRC_CTRL_ACK_FRM_PND; 01006 } 01007 else 01008 { 01009 reg &= ~cSRC_CTRL_ACK_FRM_PND; 01010 } 01011 01012 MCR20Drv_DirectAccessSPIWrite(SRC_CTRL, reg); 01013 break; 01014 01015 } 01016 /*Return frame Auto Ack frame pending status*/ 01017 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: { 01018 uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL); 01019 if (reg & cSRC_CTRL_ACK_FRM_PND) { 01020 *data_ptr = 1; 01021 } else { 01022 *data_ptr = 0; 01023 } 01024 break; 01025 } 01026 /*Set channel*/ 01027 case PHY_EXTENSION_SET_CHANNEL: 01028 break; 01029 /*Read energy on the channel*/ 01030 case PHY_EXTENSION_READ_CHANNEL_ENERGY: 01031 *data_ptr = rf_get_channel_energy(); 01032 break; 01033 /*Read status of the link*/ 01034 case PHY_EXTENSION_READ_LINK_STATUS: 01035 break; 01036 case PHY_EXTENSION_CONVERT_SIGNAL_INFO: 01037 break; 01038 } 01039 return 0; 01040 } 01041 01042 /* 01043 * \brief Function sets the addresses to RF address filters. 01044 * 01045 * \param address_type Type of address 01046 * \param address_ptr Pointer to given address 01047 * 01048 * \return 0 Success 01049 */ 01050 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) 01051 { 01052 int8_t ret_val = 0; 01053 switch (address_type) 01054 { 01055 /*Set 48-bit address*/ 01056 case PHY_MAC_48BIT: 01057 break; 01058 /*Set 64-bit address*/ 01059 case PHY_MAC_64BIT: 01060 rf_set_address(address_ptr); 01061 break; 01062 /*Set 16-bit address*/ 01063 case PHY_MAC_16BIT: 01064 rf_set_short_adr(address_ptr); 01065 break; 01066 /*Set PAN Id*/ 01067 case PHY_MAC_PANID: 01068 rf_set_pan_id(address_ptr); 01069 break; 01070 } 01071 return ret_val; 01072 } 01073 01074 static void rf_mac64_read(uint8_t *address) 01075 { 01076 /* Write one register at a time to be accessible from hibernate mode */ 01077 address[7] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_0); 01078 address[6] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_8); 01079 address[5] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_16); 01080 address[4] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_24); 01081 address[3] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_32); 01082 address[2] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_40); 01083 address[1] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_48); 01084 address[0] = MCR20Drv_DirectAccessSPIRead(MACLONGADDRS0_56); 01085 01086 } 01087 01088 /* 01089 * \brief Function initialises the ACK wait time and returns the used PHY mode. 01090 * 01091 * \param none 01092 * 01093 * \return tmp Used PHY mode 01094 */ 01095 static void rf_init_phy_mode(void) 01096 { 01097 } 01098 01099 /* 01100 * \brief Function is a RF interrupt vector. End of frame in RX and TX are handled here as well as CCA process interrupt. 01101 * 01102 * \param none 01103 * 01104 * \return none 01105 */ 01106 static void PHY_InterruptHandler(void) 01107 { 01108 /* Disable and clear transceiver(IRQ_B) interrupt */ 01109 MCR20Drv_IRQ_Disable(); 01110 irq_thread.signal_set(1); 01111 } 01112 01113 static void PHY_InterruptThread(void) 01114 { 01115 for (;;) { 01116 osEvent event = irq_thread.signal_wait(0); 01117 if (event.status != osEventSignal) { 01118 continue; 01119 } 01120 handle_interrupt(); 01121 } 01122 } 01123 01124 static void handle_interrupt(void) 01125 { 01126 uint8_t xcvseqCopy; 01127 01128 //MCR20Drv_IRQ_Clear(); 01129 01130 /* Read transceiver interrupt status and control registers */ 01131 mStatusAndControlRegs[IRQSTS1] = 01132 MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 7); 01133 01134 xcvseqCopy = mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ; 01135 01136 /* Flter Fail IRQ */ 01137 if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_FILTERFAIL_IRQ) && 01138 !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_FILTERFAIL_MSK) ) 01139 { 01140 if( xcvseqCopy == gRX_c ) 01141 { 01142 /* Abort current SEQ */ 01143 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 01144 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 01145 /* Wait for Sequence Idle */ 01146 while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0); 01147 /* Clear IRQ flags: */ 01148 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ); 01149 /* Restart Rx asap */ 01150 mStatusAndControlRegs[PHY_CTRL1] |= gRX_c; 01151 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 01152 } 01153 } 01154 01155 /* TMR3 IRQ: ACK wait time-out */ 01156 if( (mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3IRQ) && 01157 !(mStatusAndControlRegs[IRQSTS3] & cIRQSTS3_TMR3MSK) ) 01158 { 01159 /* Disable TMR3 IRQ */ 01160 mStatusAndControlRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK; 01161 01162 if( xcvseqCopy == gTR_c ) 01163 { 01164 /* Set XCVR to Idle */ 01165 mPhySeqState = gIdle_c; 01166 mStatusAndControlRegs[PHY_CTRL1] &= ~( cPHY_CTRL1_XCVSEQ ); 01167 /* Mask interrupts */ 01168 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK; 01169 /* Sync settings with XCVR */ 01170 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5); 01171 01172 rf_ack_wait_timer_interrupt(); 01173 MCR20Drv_IRQ_Enable(); 01174 return; 01175 } 01176 } 01177 01178 /* Sequencer interrupt, the autosequence has completed */ 01179 if( (mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_SEQIRQ) && 01180 !(mStatusAndControlRegs[PHY_CTRL2] & cPHY_CTRL2_SEQMSK) ) 01181 { 01182 /* Set XCVR to Idle */ 01183 mPhySeqState = gIdle_c; 01184 mStatusAndControlRegs[PHY_CTRL1] &= ~( cPHY_CTRL1_XCVSEQ ); 01185 /* Mask interrupts */ 01186 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_CCAMSK | cPHY_CTRL2_RXMSK | cPHY_CTRL2_TXMSK | cPHY_CTRL2_SEQMSK; 01187 /* Sync settings with XCVR */ 01188 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 5); 01189 01190 /* PLL unlock, the autosequence has been aborted due to PLL unlock */ 01191 if( mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_PLL_UNLOCK_IRQ ) 01192 { 01193 if(xcvseqCopy == gRX_c) 01194 { 01195 rf_receive(); 01196 } 01197 MCR20Drv_IRQ_Enable(); 01198 return; 01199 } 01200 01201 switch(xcvseqCopy) 01202 { 01203 case gTX_c: 01204 case gTR_c: 01205 rf_handle_tx_end(); 01206 break; 01207 01208 case gRX_c: 01209 rf_handle_rx_end(); 01210 break; 01211 01212 case gCCA_c: 01213 rf_handle_cca_ed_done(); 01214 break; 01215 01216 default: 01217 break; 01218 } 01219 01220 MCR20Drv_IRQ_Enable(); 01221 return; 01222 } 01223 /* Other IRQ. Clear XCVR interrupt flags */ 01224 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3); 01225 MCR20Drv_IRQ_Enable(); 01226 } 01227 01228 /* 01229 * \brief Function forces the XCVR to Idle state. 01230 * 01231 * \param none 01232 * 01233 * \return none 01234 */ 01235 static void rf_abort(void) 01236 { 01237 /* Mask XCVR irq */ 01238 MCR20Drv_IRQ_Disable(); 01239 01240 mPhySeqState = gIdle_c; 01241 01242 mStatusAndControlRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[IRQSTS2], 5); 01243 01244 /* Mask SEQ interrupt */ 01245 mStatusAndControlRegs[PHY_CTRL2] |= cPHY_CTRL2_SEQMSK; 01246 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]); 01247 01248 if( (mStatusAndControlRegs[PHY_CTRL1] & cPHY_CTRL1_XCVSEQ) != gIdle_c ) 01249 { 01250 /* Abort current SEQ */ 01251 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 01252 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 01253 01254 /* Wait for Sequence Idle (if not already) */ 01255 while ((MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F) != 0); 01256 //while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ)); 01257 mStatusAndControlRegs[IRQSTS1] |= cIRQSTS1_SEQIRQ; 01258 } 01259 01260 /* Clear all PP IRQ bits to avoid unexpected interrupts and mask TMR3 interrupt. 01261 Do not change TMR IRQ status. */ 01262 mStatusAndControlRegs[IRQSTS3] &= 0xF0; 01263 mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ); 01264 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3); 01265 01266 /* Unmask XCVR irq */ 01267 MCR20Drv_IRQ_Enable(); 01268 } 01269 01270 /* 01271 * \brief Function reads a time-stamp value from XCVR [symbols] 01272 * 01273 * \param pEndTime pointer to location where time-stamp will be stored 01274 * 01275 * \return none 01276 */ 01277 static void rf_get_timestamp(uint32_t *pRetClk) 01278 { 01279 if(NULL == pRetClk) 01280 { 01281 return; 01282 } 01283 01284 platform_enter_critical(); 01285 01286 *pRetClk = 0; 01287 MCR20Drv_DirectAccessSPIMultiByteRead(EVENT_TMR_LSB, (uint8_t *) pRetClk, 3); 01288 01289 platform_exit_critical(); 01290 } 01291 01292 /* 01293 * \brief Function set a time-out to an XCVR sequence. 01294 * 01295 * \param pEndTime pointer to the sequence time-out value [symbols] 01296 * 01297 * \return none 01298 */ 01299 static void rf_set_timeout(uint32_t *pEndTime) 01300 { 01301 uint8_t phyReg; 01302 01303 if(NULL == pEndTime) 01304 { 01305 return; 01306 } 01307 01308 platform_enter_critical(); 01309 01310 phyReg = MCR20Drv_DirectAccessSPIRead(IRQSTS3); 01311 phyReg &= 0xF0; /* do not change IRQ status */ 01312 phyReg |= (cIRQSTS3_TMR3MSK); /* mask TMR3 interrupt */ 01313 MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg); 01314 01315 MCR20Drv_DirectAccessSPIMultiByteWrite(T3CMP_LSB, (uint8_t *) pEndTime, 3); 01316 01317 phyReg &= ~(cIRQSTS3_TMR3MSK); /* unmask TMR3 interrupt */ 01318 phyReg |= (cIRQSTS3_TMR3IRQ); /* aknowledge TMR3 IRQ */ 01319 MCR20Drv_DirectAccessSPIWrite(IRQSTS3, phyReg); 01320 01321 platform_exit_critical(); 01322 } 01323 01324 /* 01325 * \brief Function reads a random number from RF. 01326 * 01327 * \param none 01328 * 01329 * \return 8-bit random number 01330 */ 01331 static uint8_t rf_if_read_rnd(void) 01332 { 01333 uint8_t phyReg; 01334 01335 MCR20Drv_IRQ_Disable(); 01336 /* Check if XCVR is idle */ 01337 phyReg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL1); 01338 01339 if( (phyReg & cPHY_CTRL1_XCVSEQ) == gIdle_c ) 01340 { 01341 /* Program a new sequence */ 01342 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, phyReg | gCCA_c); 01343 /* Wait for sequence to finish */ 01344 while( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ) ); 01345 /* Clear interrupt flag */ 01346 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_SEQIRQ); 01347 } 01348 01349 MCR20Drv_IRQ_Enable(); 01350 01351 return MCR20Drv_IndirectAccessSPIRead(_RNG); 01352 } 01353 01354 /* 01355 * \brief Function converts LQI into RSSI. 01356 * 01357 * \param LQI 01358 * 01359 * \return RSSI 01360 */ 01361 static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi) 01362 { 01363 int32_t rssi = (50*lqi - 16820) / 163; 01364 return (int8_t)rssi; 01365 } 01366 01367 /* 01368 * \brief Function scale the LQI value reported by RF into a 0-255 value. 01369 * 01370 * \param hwLqi - the LQI value reported by RF 01371 * 01372 * \return scaled LQI 01373 */ 01374 static uint8_t rf_convert_LQI(uint8_t hwLqi) 01375 { 01376 uint32_t tmpLQI; 01377 01378 /* LQI Saturation Level */ 01379 if (hwLqi >= 230) 01380 { 01381 return 0xFF; 01382 } 01383 else if (hwLqi <= 9) 01384 { 01385 return 0; 01386 } 01387 else 01388 { 01389 /* Rescale the LQI values from min to saturation to the 0x00 - 0xFF range */ 01390 /* The LQI value mst be multiplied by ~1.1087 */ 01391 /* tmpLQI = hwLqi * 7123 ~= hwLqi * 65536 * 0.1087 = hwLqi * 2^16 * 0.1087*/ 01392 tmpLQI = ((uint32_t)hwLqi * (uint32_t)7123 ); 01393 /* tmpLQI = (tmpLQI / 2^16) + hwLqi */ 01394 tmpLQI = (uint32_t)(tmpLQI >> 16) + (uint32_t)hwLqi; 01395 01396 return (uint8_t)tmpLQI; 01397 } 01398 } 01399 01400 /* 01401 * \brief Function enables/disables Rx promiscuous mode. 01402 * 01403 * \param state of XCVR promiscuous mode 01404 * 01405 * \return none 01406 */ 01407 static void rf_promiscuous(uint8_t state) 01408 { 01409 uint8_t rxFrameFltReg, phyCtrl4Reg; 01410 01411 rxFrameFltReg = MCR20Drv_IndirectAccessSPIRead(RX_FRAME_FILTER); 01412 phyCtrl4Reg = MCR20Drv_DirectAccessSPIRead(PHY_CTRL4); 01413 01414 if( state ) 01415 { 01416 /* FRM_VER[1:0] = b00. 00: Any FrameVersion accepted (0,1,2 & 3) */ 01417 /* All frame types accepted*/ 01418 phyCtrl4Reg |= cPHY_CTRL4_PROMISCUOUS; 01419 rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER); 01420 rxFrameFltReg |= (cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT); 01421 } 01422 else 01423 { 01424 phyCtrl4Reg &= ~cPHY_CTRL4_PROMISCUOUS; 01425 /* FRM_VER[1:0] = b11. Accept FrameVersion 0 and 1 packets, reject all others */ 01426 /* Beacon, Data and MAC command frame types accepted */ 01427 rxFrameFltReg &= ~(cRX_FRAME_FLT_FRM_VER); 01428 rxFrameFltReg |= (0x03 << cRX_FRAME_FLT_FRM_VER_Shift_c); 01429 rxFrameFltReg &= ~(cRX_FRAME_FLT_ACK_FT | cRX_FRAME_FLT_NS_FT); 01430 } 01431 01432 MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, rxFrameFltReg); 01433 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, phyCtrl4Reg); 01434 } 01435 01436 /* 01437 * \brief Function used to switch XCVR power state. 01438 * 01439 * \param state The XCVR power mode 01440 * 01441 * \return none 01442 */ 01443 static void rf_set_power_state(xcvrPwrMode_t newState) 01444 { 01445 uint8_t pwrMode; 01446 uint8_t xtalState; 01447 01448 if( mPwrState == newState ) 01449 { 01450 return; 01451 } 01452 01453 /* Read power settings from RF */ 01454 pwrMode = MCR20Drv_DirectAccessSPIRead(PWR_MODES); 01455 xtalState = pwrMode & cPWR_MODES_XTALEN; 01456 01457 switch( newState ) 01458 { 01459 case gXcvrPwrIdle_c: 01460 pwrMode &= ~(cPWR_MODES_AUTODOZE); 01461 pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_PMC_MODE); 01462 break; 01463 case gXcvrPwrAutodoze_c: 01464 pwrMode |= (cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE); 01465 break; 01466 case gXcvrPwrDoze_c: 01467 pwrMode &= ~(cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE); 01468 pwrMode |= cPWR_MODES_XTALEN; 01469 break; 01470 case gXcvrPwrHibernate_c: 01471 pwrMode &= ~(cPWR_MODES_XTALEN | cPWR_MODES_AUTODOZE | cPWR_MODES_PMC_MODE); 01472 break; 01473 default: 01474 return; 01475 } 01476 01477 mPwrState = newState; 01478 MCR20Drv_DirectAccessSPIWrite(PWR_MODES, pwrMode); 01479 01480 if( !xtalState && (pwrMode & cPWR_MODES_XTALEN)) 01481 { 01482 /* wait for crystal oscillator to complet its warmup */ 01483 while( ( MCR20Drv_DirectAccessSPIRead(PWR_MODES) & cPWR_MODES_XTAL_READY ) != cPWR_MODES_XTAL_READY); 01484 /* wait for radio wakeup from hibernate interrupt */ 01485 while( ( MCR20Drv_DirectAccessSPIRead(IRQSTS2) & (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) ) != (cIRQSTS2_WAKE_IRQ | cIRQSTS2_TMRSTATUS) ); 01486 01487 MCR20Drv_DirectAccessSPIWrite(IRQSTS2, cIRQSTS2_WAKE_IRQ); 01488 } 01489 } 01490 01491 /* 01492 * \brief Function reads the energy level on the preselected channel. 01493 * 01494 * \return energy level 01495 */ 01496 static uint8_t rf_get_channel_energy(void) 01497 { 01498 uint8_t ccaMode; 01499 01500 MCR20Drv_IRQ_Disable(); 01501 /* RX can start only from Idle state */ 01502 if( mPhySeqState != gIdle_c ) 01503 { 01504 MCR20Drv_IRQ_Enable(); 01505 return 0; 01506 } 01507 01508 /* Set XCVR power state in run mode */ 01509 rf_set_power_state(gXcvrRunState_d); 01510 01511 /* Switch to ED mode */ 01512 ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE; 01513 if( ccaMode != gCcaED_c ) 01514 { 01515 mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c); 01516 mStatusAndControlRegs[PHY_CTRL4] |= gCcaED_c << cPHY_CTRL4_CCATYPE_Shift_c; 01517 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]); 01518 } 01519 01520 /* Start ED sequence */ 01521 mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c; 01522 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ); 01523 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 01524 /* Wait for sequence to finish */ 01525 while ( !(MCR20Drv_DirectAccessSPIRead(IRQSTS1) & cIRQSTS1_SEQIRQ)); 01526 /* Set XCVR to Idle */ 01527 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 01528 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 01529 MCR20Drv_DirectAccessSPIWrite(IRQSTS1, cIRQSTS1_CCAIRQ | cIRQSTS1_SEQIRQ); 01530 01531 MCR20Drv_IRQ_Enable(); 01532 01533 return rf_convert_energy_level(MCR20Drv_DirectAccessSPIRead(CCA1_ED_FNL)); 01534 } 01535 01536 /* 01537 * \brief Function converts the energy level from dBm to a 0-255 value. 01538 * 01539 * \param energyLevel in dBm 01540 * 01541 * \return energy level (0-255) 01542 */ 01543 static uint8_t rf_convert_energy_level(uint8_t energyLevel) 01544 { 01545 if(energyLevel >= 90) 01546 { 01547 /* ED value is below minimum. Return 0x00. */ 01548 energyLevel = 0x00; 01549 } 01550 else if(energyLevel <= 26) 01551 { 01552 /* ED value is above maximum. Return 0xFF. */ 01553 energyLevel = 0xFF; 01554 } 01555 else 01556 { 01557 /* Energy level (-90 dBm to -26 dBm ) --> varies form 0 to 64 */ 01558 energyLevel = (90 - energyLevel); 01559 /* Rescale the energy level values to the 0x00-0xff range (0 to 64 translates in 0 to 255) */ 01560 /* energyLevel * 3.9844 ~= 4 */ 01561 /* Multiply with 4=2^2 by shifting left. 01562 The multiplication will not overflow beacause energyLevel has values between 0 and 63 */ 01563 energyLevel <<= 2; 01564 } 01565 01566 return energyLevel; 01567 } 01568 01569 static uint8_t rf_scale_lqi(int8_t rssi) 01570 { 01571 uint8_t scaled_lqi; 01572 /*Worst case sensitivity*/ 01573 const int8_t rf_sensitivity = -98; 01574 01575 /*rssi < RF sensitivity*/ 01576 if(rssi < rf_sensitivity) 01577 scaled_lqi=0; 01578 /*-91 dBm < rssi < -81 dBm (AT86RF233 XPro)*/ 01579 /*-90 dBm < rssi < -80 dBm (AT86RF212B XPro)*/ 01580 else if(rssi < (rf_sensitivity + 10)) 01581 scaled_lqi=31; 01582 /*-81 dBm < rssi < -71 dBm (AT86RF233 XPro)*/ 01583 /*-80 dBm < rssi < -70 dBm (AT86RF212B XPro)*/ 01584 else if(rssi < (rf_sensitivity + 20)) 01585 scaled_lqi=207; 01586 /*-71 dBm < rssi < -61 dBm (AT86RF233 XPro)*/ 01587 /*-70 dBm < rssi < -60 dBm (AT86RF212B XPro)*/ 01588 else if(rssi < (rf_sensitivity + 30)) 01589 scaled_lqi=255; 01590 /*-61 dBm < rssi < -51 dBm (AT86RF233 XPro)*/ 01591 /*-60 dBm < rssi < -50 dBm (AT86RF212B XPro)*/ 01592 else if(rssi < (rf_sensitivity + 40)) 01593 scaled_lqi=255; 01594 /*-51 dBm < rssi < -41 dBm (AT86RF233 XPro)*/ 01595 /*-50 dBm < rssi < -40 dBm (AT86RF212B XPro)*/ 01596 else if(rssi < (rf_sensitivity + 50)) 01597 scaled_lqi=255; 01598 /*-41 dBm < rssi < -31 dBm (AT86RF233 XPro)*/ 01599 /*-40 dBm < rssi < -30 dBm (AT86RF212B XPro)*/ 01600 else if(rssi < (rf_sensitivity + 60)) 01601 scaled_lqi=255; 01602 /*-31 dBm < rssi < -21 dBm (AT86RF233 XPro)*/ 01603 /*-30 dBm < rssi < -20 dBm (AT86RF212B XPro)*/ 01604 else if(rssi < (rf_sensitivity + 70)) 01605 scaled_lqi=255; 01606 /*rssi > RF saturation*/ 01607 else if(rssi > (rf_sensitivity + 80)) 01608 scaled_lqi=111; 01609 /*-21 dBm < rssi < -11 dBm (AT86RF233 XPro)*/ 01610 /*-20 dBm < rssi < -10 dBm (AT86RF212B XPro)*/ 01611 else 01612 scaled_lqi=255; 01613 01614 return scaled_lqi; 01615 } 01616 01617 01618 /*****************************************************************************/ 01619 /* Layer porting to the Freescale driver */ 01620 /*****************************************************************************/ 01621 extern "C" void xcvr_spi_init(uint32_t instance) 01622 { 01623 (void)instance; 01624 } 01625 01626 extern "C" void RF_IRQ_Init(void) { 01627 MBED_ASSERT(irq != NULL); 01628 irq->mode(PullUp); 01629 irq->fall(&PHY_InterruptHandler); 01630 } 01631 01632 extern "C" void RF_IRQ_Enable(void) { 01633 MBED_ASSERT(irq != NULL); 01634 irq->enable_irq(); 01635 } 01636 01637 extern "C" void RF_IRQ_Disable(void) { 01638 MBED_ASSERT(irq != NULL); 01639 irq->disable_irq(); 01640 } 01641 01642 extern "C" uint8_t RF_isIRQ_Pending(void) { 01643 MBED_ASSERT(rf != NULL); 01644 return !irq_pin->read(); 01645 } 01646 01647 extern "C" void RF_RST_Set(int state) { 01648 MBED_ASSERT(rst != NULL); 01649 *rst = state; 01650 } 01651 01652 extern "C" void gXcvrAssertCS_d(void) 01653 { 01654 MBED_ASSERT(cs != NULL); 01655 *cs = 0; 01656 } 01657 01658 extern "C" void gXcvrDeassertCS_d(void) 01659 { 01660 MBED_ASSERT(cs != NULL); 01661 *cs = 1; 01662 } 01663 01664 extern "C" void xcvr_spi_configure_speed(uint32_t instance, uint32_t freq) 01665 { 01666 MBED_ASSERT(spi != NULL); 01667 (void)instance; 01668 spi->frequency(freq); 01669 } 01670 01671 extern "C" void xcvr_spi_transfer(uint32_t instance, 01672 uint8_t * sendBuffer, 01673 uint8_t * receiveBuffer, 01674 size_t transferByteCount) 01675 { 01676 MBED_ASSERT(spi != NULL); 01677 (void)instance; 01678 volatile uint8_t dummy; 01679 01680 if( !transferByteCount ) 01681 return; 01682 01683 if( !sendBuffer && !receiveBuffer ) 01684 return; 01685 01686 while( transferByteCount-- ) 01687 { 01688 if( sendBuffer ) 01689 { 01690 dummy = *sendBuffer; 01691 sendBuffer++; 01692 } 01693 else 01694 { 01695 dummy = 0xFF; 01696 } 01697 01698 dummy = spi->write(dummy); 01699 01700 if( receiveBuffer ) 01701 { 01702 *receiveBuffer = dummy; 01703 receiveBuffer++; 01704 } 01705 } 01706 } 01707 01708 /*****************************************************************************/ 01709 /*****************************************************************************/ 01710 01711 static void rf_if_lock(void) 01712 { 01713 platform_enter_critical(); 01714 } 01715 01716 static void rf_if_unlock(void) 01717 { 01718 platform_exit_critical(); 01719 } 01720 01721 NanostackRfPhyMcr20a::NanostackRfPhyMcr20a(PinName spi_mosi, PinName spi_miso, 01722 PinName spi_sclk, PinName spi_cs, PinName spi_rst, PinName spi_irq) 01723 : _spi(spi_mosi, spi_miso, spi_sclk), _rf_cs(spi_cs), _rf_rst(spi_rst, 1), 01724 _rf_irq(spi_irq), _rf_irq_pin(spi_irq) 01725 { 01726 // Do nothing 01727 } 01728 01729 NanostackRfPhyMcr20a::~NanostackRfPhyMcr20a() 01730 { 01731 // Do nothing 01732 } 01733 01734 int8_t NanostackRfPhyMcr20a::rf_register() 01735 { 01736 01737 rf_if_lock(); 01738 01739 if (rf != NULL) { 01740 rf_if_unlock(); 01741 error("Multiple registrations of NanostackRfPhyMcr20a not supported"); 01742 return -1; 01743 } 01744 01745 irq_thread.start(mbed::callback(PHY_InterruptThread)); 01746 01747 _pins_set(); 01748 int8_t radio_id = rf_device_register(); 01749 if (radio_id < 0) { 01750 _pins_clear(); 01751 rf = NULL; 01752 } 01753 01754 rf_if_unlock(); 01755 return radio_id; 01756 } 01757 01758 void NanostackRfPhyMcr20a::rf_unregister() 01759 { 01760 rf_if_lock(); 01761 01762 if (rf != this) { 01763 rf_if_unlock(); 01764 return; 01765 } 01766 01767 rf_device_unregister(); 01768 rf = NULL; 01769 _pins_clear(); 01770 01771 rf_if_unlock(); 01772 } 01773 01774 void NanostackRfPhyMcr20a::get_mac_address(uint8_t *mac) 01775 { 01776 rf_if_lock(); 01777 01778 memcpy((void*)mac, (void*)MAC_address, sizeof(MAC_address)); 01779 01780 rf_if_unlock(); 01781 } 01782 01783 void NanostackRfPhyMcr20a::set_mac_address(uint8_t *mac) 01784 { 01785 rf_if_lock(); 01786 01787 if (NULL != rf) { 01788 error("NanostackRfPhyAtmel cannot change mac address when running"); 01789 rf_if_unlock(); 01790 return; 01791 } 01792 memcpy((void*)MAC_address, (void*)mac, sizeof(MAC_address)); 01793 01794 rf_if_unlock(); 01795 } 01796 01797 void NanostackRfPhyMcr20a::_pins_set() 01798 { 01799 spi = &_spi; 01800 cs = &_rf_cs; 01801 rst = &_rf_rst; 01802 irq = &_rf_irq; 01803 irq_pin = &_rf_irq_pin; 01804 } 01805 01806 void NanostackRfPhyMcr20a::_pins_clear() 01807 { 01808 spi = NULL; 01809 cs = NULL; 01810 rst = NULL; 01811 irq = NULL; 01812 irq_pin = NULL; 01813 }
Generated on Wed Jul 13 2022 01:16:06 by
1.7.2