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 00136 /* Channel configurations for 2.4 */ 00137 static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK}; 00138 00139 static const phy_device_channel_page_s phy_channel_pages[] = { 00140 { CHANNEL_PAGE_0, &phy_24ghz}, 00141 { CHANNEL_PAGE_0, NULL} 00142 }; 00143 00144 00145 static rf_trx_part_e rf_radio_type_read(void); 00146 00147 MBED_UNUSED static void rf_ack_wait_timer_start(uint16_t slots); 00148 MBED_UNUSED static void rf_ack_wait_timer_stop(void); 00149 MBED_UNUSED static void rf_handle_cca_ed_done(void); 00150 MBED_UNUSED static void rf_handle_tx_end(void); 00151 MBED_UNUSED static void rf_handle_rx_end(void); 00152 MBED_UNUSED static void rf_on(void); 00153 MBED_UNUSED static void rf_receive(void); 00154 MBED_UNUSED static void rf_poll_trx_state_change(rf_trx_states_t trx_state); 00155 MBED_UNUSED static void rf_init(void); 00156 MBED_UNUSED static void rf_set_mac_address(const uint8_t *ptr); 00157 MBED_UNUSED static int8_t rf_device_register(void); 00158 MBED_UNUSED static void rf_device_unregister(void); 00159 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 ); 00160 MBED_UNUSED static void rf_cca_abort(void); 00161 MBED_UNUSED static void rf_read_mac_address(uint8_t *ptr); 00162 MBED_UNUSED static int8_t rf_read_random(void); 00163 MBED_UNUSED static void rf_calibration_cb(void); 00164 MBED_UNUSED static void rf_init_phy_mode(void); 00165 MBED_UNUSED static void rf_ack_wait_timer_interrupt(void); 00166 MBED_UNUSED static void rf_calibration_timer_interrupt(void); 00167 MBED_UNUSED static void rf_calibration_timer_start(uint32_t slots); 00168 MBED_UNUSED static void rf_cca_timer_interrupt(void); 00169 MBED_UNUSED static void rf_cca_timer_start(uint32_t slots); 00170 MBED_UNUSED static uint16_t rf_get_phy_mtu_size(void); 00171 MBED_UNUSED static uint8_t rf_scale_lqi(int8_t rssi); 00172 00173 /** 00174 * RF output power write 00175 * 00176 * \brief TX power has to be set before network start. 00177 * 00178 * \param power 00179 * See datasheet for TX power settings 00180 * 00181 * \return 0, Supported Value 00182 * \return -1, Not Supported Value 00183 */ 00184 MBED_UNUSED static int8_t rf_tx_power_set(uint8_t power); 00185 MBED_UNUSED static uint8_t rf_tx_power_get(void); 00186 MBED_UNUSED static int8_t rf_enable_antenna_diversity(void); 00187 00188 /* Private functions */ 00189 MBED_UNUSED static void rf_abort(void); 00190 MBED_UNUSED static void rf_promiscuous(uint8_t mode); 00191 MBED_UNUSED static void rf_get_timestamp(uint32_t *pRetClk); 00192 MBED_UNUSED static void rf_set_timeout(uint32_t *pEndTime); 00193 MBED_UNUSED static void rf_set_power_state(xcvrPwrMode_t newState); 00194 MBED_UNUSED static uint8_t rf_if_read_rnd(void); 00195 MBED_UNUSED static uint8_t rf_convert_LQI(uint8_t hwLqi); 00196 MBED_UNUSED static uint8_t rf_get_channel_energy(void); 00197 MBED_UNUSED static uint8_t rf_convert_energy_level(uint8_t energyLevel); 00198 MBED_UNUSED static int8_t rf_convert_LQI_to_RSSI(uint8_t lqi); 00199 MBED_UNUSED static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel); 00200 MBED_UNUSED static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr); 00201 MBED_UNUSED static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr); 00202 MBED_UNUSED static void rf_mac64_read(uint8_t *address); 00203 static void PHY_InterruptThread(void); 00204 static void handle_interrupt(void); 00205 00206 00207 /* 00208 * \brief Read connected radio part. 00209 * 00210 * This function only return valid information when rf_init() is called 00211 * 00212 * \return 00213 */ 00214 static rf_trx_part_e rf_radio_type_read(void) 00215 { 00216 return FREESCALE_MCR20A; 00217 } 00218 00219 /* 00220 * \brief Function initialises and registers the RF driver. 00221 * 00222 * \param none 00223 * 00224 * \return rf_radio_driver_id Driver ID given by NET library 00225 */ 00226 static int8_t rf_device_register(void) 00227 { 00228 rf_trx_part_e radio_type; 00229 00230 rf_init(); 00231 00232 00233 00234 radio_type = rf_radio_type_read(); 00235 if(radio_type == FREESCALE_MCR20A) 00236 { 00237 /*Set pointer to MAC address*/ 00238 device_driver.PHY_MAC = MAC_address; 00239 device_driver.driver_description = (char*)"FREESCALE_MAC"; 00240 00241 //Create setup Used Radio chips 00242 /*Type of RF PHY is SubGHz*/ 00243 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE; 00244 00245 device_driver.phy_channel_pages = phy_channel_pages; 00246 /*Maximum size of payload is 127*/ 00247 device_driver.phy_MTU = 127; 00248 /*No header in PHY*/ 00249 device_driver.phy_header_length = 0; 00250 /*No tail in PHY*/ 00251 device_driver.phy_tail_length = 0; 00252 /*Set address write function*/ 00253 device_driver.address_write = &rf_address_write; 00254 /*Set RF extension function*/ 00255 device_driver.extension = &rf_extension; 00256 /*Set RF state control function*/ 00257 device_driver.state_control = &rf_interface_state_control; 00258 /*Set transmit function*/ 00259 device_driver.tx = &rf_start_cca; 00260 /*Upper layer callbacks init to NULL*/ 00261 device_driver.phy_rx_cb = NULL; 00262 device_driver.phy_tx_done_cb = NULL; 00263 /*Virtual upper data callback init to NULL*/ 00264 device_driver.arm_net_virtual_rx_cb = NULL; 00265 device_driver.arm_net_virtual_tx_cb = NULL; 00266 00267 /*Register device driver*/ 00268 rf_radio_driver_id = arm_net_phy_register(&device_driver); 00269 } 00270 00271 return rf_radio_driver_id; 00272 } 00273 00274 /* 00275 * \brief Function unregisters the RF driver. 00276 * 00277 * \param none 00278 * 00279 * \return none 00280 */ 00281 static void rf_device_unregister(void) 00282 { 00283 arm_net_phy_unregister(rf_radio_driver_id); 00284 } 00285 00286 /* 00287 * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator. 00288 * 00289 * \param none 00290 * 00291 * \return random value 00292 */ 00293 static int8_t rf_read_random(void) 00294 { 00295 return rf_rnd; 00296 } 00297 00298 /* 00299 * \brief Function is a call back for ACK wait timeout. 00300 * 00301 * \param none 00302 * 00303 * \return none 00304 */ 00305 static void rf_ack_wait_timer_interrupt(void) 00306 { 00307 /* The packet was transmitted successfully, but no ACK was received */ 00308 if (device_driver.phy_tx_done_cb) { 00309 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00310 } 00311 rf_receive(); 00312 } 00313 00314 /* 00315 * \brief Function is a call back for calibration interval timer. 00316 * 00317 * \param none 00318 * 00319 * \return none 00320 */ 00321 static void rf_calibration_timer_interrupt(void) 00322 { 00323 } 00324 00325 /* 00326 * \brief Function is a call back for cca interval timer. 00327 * 00328 * \param none 00329 * 00330 * \return none 00331 */ 00332 static void rf_cca_timer_interrupt(void) 00333 { 00334 /* CCA time-out handled by Hardware */ 00335 } 00336 00337 00338 /* 00339 * \brief Function starts the ACK wait time-out. 00340 * 00341 * \param slots The ACK wait time-out in [symbols] 00342 * 00343 * \return none 00344 */ 00345 static void rf_ack_wait_timer_start(uint16_t time) 00346 { 00347 uint32_t timeout; 00348 00349 rf_get_timestamp(&timeout); 00350 timeout += time; 00351 rf_set_timeout(&timeout); 00352 } 00353 00354 /* 00355 * \brief Function starts the calibration interval. 00356 * 00357 * \param slots Given slots, resolution 50us 00358 * 00359 * \return none 00360 */ 00361 static void rf_calibration_timer_start(uint32_t slots) 00362 { 00363 (void)slots; 00364 } 00365 00366 /* 00367 * \brief Function starts the CCA timout. 00368 * 00369 * \param slots Given slots, resolution 50us 00370 * 00371 * \return none 00372 */ 00373 static void rf_cca_timer_start(uint32_t slots) 00374 { 00375 (void)slots; 00376 } 00377 00378 /* 00379 * \brief Function stops the ACK wait timeout. 00380 * 00381 * \param none 00382 * 00383 * \return none 00384 */ 00385 static void rf_ack_wait_timer_stop(void) 00386 { 00387 } 00388 00389 /* 00390 * \brief Function reads the MAC address array. 00391 * 00392 * \param ptr Pointer to read array 00393 * 00394 * \return none 00395 */ 00396 static void rf_read_mac_address(uint8_t *ptr) 00397 { 00398 memcpy(ptr, MAC_address, 8); 00399 } 00400 00401 /* 00402 * \brief Function sets the MAC address array. 00403 * 00404 * \param ptr Pointer to given MAC address array 00405 * 00406 * \return none 00407 */ 00408 static void rf_set_mac_address(const uint8_t *ptr) 00409 { 00410 memcpy(MAC_address, ptr, 8); 00411 } 00412 00413 static uint16_t rf_get_phy_mtu_size(void) 00414 { 00415 return device_driver.phy_MTU; 00416 } 00417 00418 /* 00419 * \brief Function writes 16-bit address in RF address filter. 00420 * 00421 * \param short_address Given short address 00422 * 00423 * \return none 00424 */ 00425 static void rf_set_short_adr(uint8_t * short_address) 00426 { 00427 /* Write one register at a time to be accessible from hibernate mode */ 00428 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_MSB, short_address[0]); 00429 MCR20Drv_IndirectAccessSPIWrite(MACSHORTADDRS0_LSB, short_address[1]); 00430 } 00431 00432 /* 00433 * \brief Function writes PAN Id in RF PAN Id filter. 00434 * 00435 * \param pan_id Given PAN Id 00436 * 00437 * \return none 00438 */ 00439 static void rf_set_pan_id(uint8_t *pan_id) 00440 { 00441 /* Write one register at a time to be accessible from hibernate mode */ 00442 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_MSB, pan_id[0]); 00443 MCR20Drv_IndirectAccessSPIWrite(MACPANID0_LSB, pan_id[1]); 00444 } 00445 00446 /* 00447 * \brief Function writes 64-bit address in RF address filter. 00448 * 00449 * \param address Given 64-bit address 00450 * 00451 * \return none 00452 */ 00453 static void rf_set_address(uint8_t *address) 00454 { 00455 /* Write one register at a time to be accessible from hibernate mode */ 00456 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_0, address[7]); 00457 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_8, address[6]); 00458 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_16, address[5]); 00459 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_24, address[4]); 00460 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_32, address[3]); 00461 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_40, address[2]); 00462 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_48, address[1]); 00463 MCR20Drv_IndirectAccessSPIWrite(MACLONGADDRS0_56, address[0]); 00464 } 00465 00466 /* 00467 * \brief Function sets the RF channel. 00468 * 00469 * \param ch New channel 00470 * 00471 * \return none 00472 */ 00473 static void rf_channel_set(uint8_t channel) 00474 { 00475 MCR20Drv_DirectAccessSPIWrite(PLL_INT0, pll_int[channel - 11]); 00476 MCR20Drv_DirectAccessSPIMultiByteWrite(PLL_FRAC0_LSB, (uint8_t *) &pll_frac[channel - 11], 2); 00477 } 00478 00479 00480 /* 00481 * \brief Function initialises the radio driver and resets the radio. 00482 * 00483 * \param none 00484 * 00485 * \return none 00486 */ 00487 static void rf_init(void) 00488 { 00489 uint32_t index; 00490 mPhySeqState = gIdle_c; 00491 mPwrState = gXcvrPwrIdle_c; 00492 /*Reset RF module*/ 00493 MCR20Drv_RESET(); 00494 /* Initialize the transceiver SPI driver */ 00495 MCR20Drv_Init(); 00496 /* Disable Tristate on MISO for SPI reads */ 00497 MCR20Drv_IndirectAccessSPIWrite(MISC_PAD_CTRL, 0x02); 00498 /* Set XCVR clock output settings */ 00499 #if !defined(TARGET_KW24D) 00500 MCR20Drv_Set_CLK_OUT_Freq(gMCR20_ClkOutFreq_d); 00501 #endif 00502 /* Set default XCVR power state */ 00503 rf_set_power_state(gXcvrRunState_d); 00504 00505 /* PHY_CTRL1 default HW settings + AUTOACK enabled */ 00506 mStatusAndControlRegs[PHY_CTRL1] = cPHY_CTRL1_AUTOACK; 00507 /* PHY_CTRL2 : mask all PP interrupts */ 00508 mStatusAndControlRegs[PHY_CTRL2] = cPHY_CTRL2_CRC_MSK | \ 00509 cPHY_CTRL2_PLL_UNLOCK_MSK | \ 00510 /*cPHY_CTRL2_FILTERFAIL_MSK | */ \ 00511 cPHY_CTRL2_RX_WMRK_MSK | \ 00512 cPHY_CTRL2_CCAMSK | \ 00513 cPHY_CTRL2_RXMSK | \ 00514 cPHY_CTRL2_TXMSK | \ 00515 cPHY_CTRL2_SEQMSK; 00516 /* PHY_CTRL3 : enable timer 3 and disable remaining interrupts */ 00517 mStatusAndControlRegs[PHY_CTRL3] = cPHY_CTRL3_ASM_MSK | \ 00518 cPHY_CTRL3_PB_ERR_MSK | \ 00519 cPHY_CTRL3_WAKE_MSK | \ 00520 cPHY_CTRL3_TMR3CMP_EN; 00521 /* PHY_CTRL4 unmask global TRX interrupts, enable 16 bit mode for TC2 - TC2 prime EN */ 00522 mStatusAndControlRegs[PHY_CTRL4] = cPHY_CTRL4_TC2PRIME_EN | (gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c); 00523 /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after initialization */ 00524 mStatusAndControlRegs[IRQSTS1] = cIRQSTS1_PLL_UNLOCK_IRQ | \ 00525 cIRQSTS1_FILTERFAIL_IRQ | \ 00526 cIRQSTS1_RXWTRMRKIRQ | \ 00527 cIRQSTS1_CCAIRQ | \ 00528 cIRQSTS1_RXIRQ | \ 00529 cIRQSTS1_TXIRQ | \ 00530 cIRQSTS1_SEQIRQ; 00531 00532 mStatusAndControlRegs[IRQSTS2] = cIRQSTS2_ASM_IRQ | cIRQSTS2_PB_ERR_IRQ | cIRQSTS2_WAKE_IRQ; 00533 /* Mask and clear all TMR IRQs */ 00534 mStatusAndControlRegs[IRQSTS3] = cIRQSTS3_TMR4MSK | cIRQSTS3_TMR3MSK | cIRQSTS3_TMR2MSK | cIRQSTS3_TMR1MSK | \ 00535 cIRQSTS3_TMR4IRQ | cIRQSTS3_TMR3IRQ | cIRQSTS3_TMR2IRQ | cIRQSTS3_TMR1IRQ; 00536 /* Write settings to XCVR */ 00537 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 5); 00538 /* Clear all interrupts */ 00539 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, &mStatusAndControlRegs[IRQSTS1], 3); 00540 00541 /* RX_FRAME_FILTER. Accept FrameVersion 0 and 1 packets, reject all others */ 00542 MCR20Drv_IndirectAccessSPIWrite(RX_FRAME_FILTER, (cRX_FRAME_FLT_FRM_VER | \ 00543 cRX_FRAME_FLT_BEACON_FT | \ 00544 cRX_FRAME_FLT_DATA_FT | \ 00545 cRX_FRAME_FLT_CMD_FT )); 00546 /* Direct register overwrites */ 00547 for (index = 0; index < sizeof(overwrites_direct)/sizeof(overwrites_t); index++) 00548 MCR20Drv_DirectAccessSPIWrite(overwrites_direct[index].address, overwrites_direct[index].data); 00549 /* Indirect register overwrites */ 00550 for (index = 0; index < sizeof(overwrites_indirect)/sizeof(overwrites_t); index++) 00551 MCR20Drv_IndirectAccessSPIWrite(overwrites_indirect[index].address, overwrites_indirect[index].data); 00552 00553 /* Set the CCA energy threshold value */ 00554 MCR20Drv_IndirectAccessSPIWrite(CCA1_THRESH, RF_CCA_THRESHOLD); 00555 /* Set prescaller to obtain 1 symbol (16us) timebase */ 00556 MCR20Drv_IndirectAccessSPIWrite(TMR_PRESCALE, 0x05); 00557 00558 MCR20Drv_IRQ_Enable(); 00559 00560 /*Read random variable. This will be used when seeding pseudo-random generator*/ 00561 rf_rnd = rf_if_read_rnd(); 00562 /*Read eui64*/ 00563 rf_mac64_read(MAC_address); 00564 /*set default channel to 11*/ 00565 rf_channel_set(11); 00566 /*Start receiver*/ 00567 rf_receive(); 00568 } 00569 00570 /** 00571 * \brief Function gets called when MAC is setting radio off. 00572 * 00573 * \param none 00574 * 00575 * \return none 00576 */ 00577 static void rf_off(void) 00578 { 00579 /* Abort any ongoing sequences */ 00580 rf_abort(); 00581 /* Set XCVR in a low power state */ 00582 rf_set_power_state(gXcvrLowPowerState_d); 00583 } 00584 00585 /* 00586 * \brief Function polls the RF state until it has changed to desired state. 00587 * 00588 * \param trx_state RF state 00589 * 00590 * \return none 00591 */ 00592 static void rf_poll_trx_state_change(rf_trx_states_t trx_state) 00593 { 00594 (void)trx_state; 00595 } 00596 00597 /* 00598 * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO. 00599 * 00600 * \param data_ptr Pointer to TX data 00601 * \param data_length Length of the TX data 00602 * \param tx_handle Handle to transmission 00603 * \return 0 Success 00604 * \return -1 Busy 00605 */ 00606 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol ) 00607 { 00608 uint8_t ccaMode; 00609 00610 /* Parameter validation */ 00611 if( !data_ptr || (data_length > 125) || (PHY_LAYER_PAYLOAD != data_protocol) ) 00612 { 00613 return -1; 00614 } 00615 00616 if( mPhySeqState == gRX_c ) 00617 { 00618 uint8_t phyReg = MCR20Drv_DirectAccessSPIRead(SEQ_STATE) & 0x1F; 00619 /* Check for an Rx in progress. */ 00620 if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16)) 00621 { 00622 if (device_driver.phy_tx_done_cb) { 00623 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00624 } 00625 return -1; 00626 } 00627 rf_abort(); 00628 } 00629 00630 /*Check if transmitter is busy*/ 00631 if( mPhySeqState != gIdle_c ) 00632 { 00633 /*Return busy*/ 00634 return -1; 00635 } 00636 00637 /*Store TX handle*/ 00638 mac_tx_handle = tx_handle; 00639 /*Check if transmitted data needs to be acked*/ 00640 need_ack = (*data_ptr & 0x20) == 0x20; 00641 00642 /* Set XCVR power state in run mode */ 00643 rf_set_power_state(gXcvrRunState_d); 00644 /* Load data into XCVR */ 00645 tx_len = data_length + 2; 00646 MCR20Drv_PB_SPIBurstWrite(data_ptr - 1, data_length + 1); 00647 MCR20Drv_PB_SPIByteWrite(0,tx_len); 00648 00649 /* Set CCA mode 1 */ 00650 ccaMode = (mStatusAndControlRegs[PHY_CTRL4] >> cPHY_CTRL4_CCATYPE_Shift_c) & cPHY_CTRL4_CCATYPE; 00651 if( ccaMode != gCcaCCA_MODE1_c ) 00652 { 00653 mStatusAndControlRegs[PHY_CTRL4] &= ~(cPHY_CTRL4_CCATYPE << cPHY_CTRL4_CCATYPE_Shift_c); 00654 mStatusAndControlRegs[PHY_CTRL4] |= gCcaCCA_MODE1_c << cPHY_CTRL4_CCATYPE_Shift_c; 00655 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL4, mStatusAndControlRegs[PHY_CTRL4]); 00656 } 00657 00658 /* Read XCVR registers */ 00659 mStatusAndControlRegs[0] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &mStatusAndControlRegs[1], 4); 00660 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00661 mStatusAndControlRegs[PHY_CTRL1] |= gCCA_c; 00662 mPhySeqState = gCCA_c; 00663 00664 /* Ensure that no spurious interrupts are raised */ 00665 mStatusAndControlRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */ 00666 mStatusAndControlRegs[IRQSTS3] |= (cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ); 00667 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, mStatusAndControlRegs, 3); 00668 00669 /* Write XCVR settings */ 00670 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL1, mStatusAndControlRegs[PHY_CTRL1]); 00671 00672 /* Unmask SEQ interrupt */ 00673 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00674 MCR20Drv_DirectAccessSPIWrite(PHY_CTRL2, mStatusAndControlRegs[PHY_CTRL2]); 00675 00676 /*Return success*/ 00677 return 0; 00678 } 00679 00680 /* 00681 * \brief Function aborts CCA process. 00682 * 00683 * \param none 00684 * 00685 * \return none 00686 */ 00687 static void rf_cca_abort(void) 00688 { 00689 rf_abort(); 00690 } 00691 00692 /* 00693 * \brief Function starts the transmission of the frame. Called from ISR context! 00694 * 00695 * \param none 00696 * 00697 * \return none 00698 */ 00699 static void rf_start_tx(void) 00700 { 00701 /* Perform TxRxAck sequence if required by phyTxMode */ 00702 if( need_ack ) 00703 { 00704 mStatusAndControlRegs[PHY_CTRL1] |= cPHY_CTRL1_RXACKRQD; 00705 mPhySeqState = gTR_c; 00706 } 00707 else 00708 { 00709 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_RXACKRQD); 00710 mPhySeqState = gTX_c; 00711 } 00712 00713 mStatusAndControlRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00714 mStatusAndControlRegs[PHY_CTRL1] |= mPhySeqState; 00715 00716 /* Unmask SEQ interrupt */ 00717 mStatusAndControlRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00718 00719 /* Start the sequence immediately */ 00720 MCR20Drv_DirectAccessSPIMultiByteWrite(PHY_CTRL1, &mStatusAndControlRegs[PHY_CTRL1], 2); 00721 00722 if( need_ack ) 00723 { 00724 rf_ack_wait_timer_start(gPhyWarmUpTime_c + gPhySHRDuration_c + tx_len * gPhySymbolsPerOctet_c + gPhyAckWaitDuration_c); 00725 } 00726 } 00727 00728 /* 00729 * \brief Function sets the RF in RX state. Called from ISR context! 00730 * 00731 * \param none 00732 * 00733 * \return none 00734 */ 00735 static void rf_receive(void) 00736 { 00737 uint8_t phyRegs[5]; 00738 00739 /* RX can start only from Idle state */ 00740 if( mPhySeqState != gIdle_c ) 00741 { 00742 return; 00743 } 00744 00745 /* Set XCVR power state in run mode */ 00746 rf_set_power_state(gXcvrRunState_d); 00747 /* read XVCR settings */ 00748 phyRegs[IRQSTS1] = MCR20Drv_DirectAccessSPIMultiByteRead(IRQSTS2, &phyRegs[IRQSTS2], 4); 00749 /* unmask SEQ interrupt */ 00750 phyRegs[PHY_CTRL2] &= ~(cPHY_CTRL2_SEQMSK); 00751 /* set XcvrSeq to RX */ 00752 phyRegs[PHY_CTRL1] &= ~(cPHY_CTRL1_XCVSEQ); 00753 phyRegs[PHY_CTRL1] |= gRX_c; 00754 mPhySeqState = gRX_c; 00755 /* Ensure that no spurious interrupts are raised */ 00756 phyRegs[IRQSTS3] &= 0xF0; /* do not change other IRQ status */ 00757 phyRegs[IRQSTS3] |= cIRQSTS3_TMR3MSK | cIRQSTS3_TMR3IRQ; 00758 /* sync settings with XCVR */ 00759 MCR20Drv_DirectAccessSPIMultiByteWrite(IRQSTS1, phyRegs, 5); 00760 } 00761 00762 /* 00763 * \brief Function calibrates the radio. 00764 * 00765 * \param none 00766 * 00767 * \return none 00768 */ 00769 static void rf_calibration_cb(void) 00770 { 00771 } 00772 00773 /* 00774 * \brief Function sets RF_ON flag when radio is powered. 00775 * 00776 * \param none 00777 * 00778 * \return none 00779 */ 00780 static void rf_on(void) 00781 { 00782 } 00783 00784 /* 00785 * \brief Function is a call back for RX end interrupt. 00786 * 00787 * \param none 00788 * 00789 * \return none 00790 */ 00791 static void rf_handle_rx_end(void) 00792 { 00793 uint8_t rf_lqi = MCR20Drv_DirectAccessSPIRead(LQI_VALUE); 00794 int8_t rf_rssi = 0; 00795 uint8_t len = mStatusAndControlRegs[RX_FRM_LEN] - 2; 00796 00797 00798 /*Start receiver*/ 00799 rf_receive(); 00800 00801 /*Check the length is valid*/ 00802 if(len > 1 && len < RF_BUFFER_SIZE) 00803 { 00804 rf_lqi = rf_convert_LQI(rf_lqi); 00805 rf_rssi = rf_convert_LQI_to_RSSI(rf_lqi); 00806 /*gcararu: Scale LQI using received RSSI, to match the LQI reported by the ATMEL radio */ 00807 rf_lqi = rf_scale_lqi(rf_rssi); 00808 00809 /*Read received packet*/ 00810 MCR20Drv_PB_SPIBurstRead(rf_buffer, len); 00811 if (device_driver.phy_rx_cb) { 00812 device_driver.phy_rx_cb(rf_buffer, len, rf_lqi, rf_rssi, rf_radio_driver_id); 00813 } 00814 } 00815 } 00816 00817 /* 00818 * \brief Function is called when MAC is shutting down the radio. 00819 * 00820 * \param none 00821 * 00822 * \return none 00823 */ 00824 static void rf_shutdown(void) 00825 { 00826 /*Call RF OFF*/ 00827 rf_off(); 00828 } 00829 00830 /* 00831 * \brief Function is a call back for TX end interrupt. 00832 * 00833 * \param none 00834 * 00835 * \return none 00836 */ 00837 static void rf_handle_tx_end(void) 00838 { 00839 uint8_t rx_frame_pending = mStatusAndControlRegs[IRQSTS1] & cIRQSTS1_RX_FRM_PEND; 00840 00841 /*Start receiver*/ 00842 rf_receive(); 00843 00844 if (!device_driver.phy_tx_done_cb) { 00845 return; 00846 } 00847 00848 /*Call PHY TX Done API*/ 00849 if( need_ack ) 00850 { 00851 if( rx_frame_pending ) 00852 { 00853 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1); 00854 } 00855 else 00856 { 00857 // arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00858 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1); 00859 } 00860 } 00861 else 00862 { 00863 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); 00864 } 00865 } 00866 00867 /* 00868 * \brief Function is a call back for CCA ED done interrupt. 00869 * 00870 * \param none 00871 * 00872 * \return none 00873 */ 00874 static void rf_handle_cca_ed_done(void) 00875 { 00876 /*Check the result of CCA process*/ 00877 if( !(mStatusAndControlRegs[IRQSTS2] & cIRQSTS2_CCA) ) 00878 { 00879 rf_start_tx(); 00880 } 00881 else if (device_driver.phy_tx_done_cb) 00882 { 00883 /*Send CCA fail notification*/ 00884 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); 00885 } 00886 } 00887 00888 /* 00889 * \brief Function sets the TX power variable. 00890 * 00891 * \param power TX power setting 00892 * 00893 * \return 0 Success 00894 * \return -1 Fail 00895 */ 00896 static int8_t rf_tx_power_set(uint8_t power) 00897 { 00898 /* gcapraru: Map MCR20A Tx power levels over ATMEL values */ 00899 static uint8_t pwrLevelMapping[16] = {25,25,25,24,24,24,23,23,22,22,21,20,19,18,17,14}; 00900 00901 if( power > 15 ) 00902 { 00903 return -1; 00904 } 00905 00906 radio_tx_power = power; 00907 MCR20Drv_DirectAccessSPIWrite(PA_PWR, pwrLevelMapping[power]); 00908 return 0; 00909 } 00910 00911 /* 00912 * \brief Function returns the TX power variable. 00913 * 00914 * \param none 00915 * 00916 * \return radio_tx_power TX power variable 00917 */ 00918 static uint8_t rf_tx_power_get(void) 00919 { 00920 return radio_tx_power; 00921 } 00922 00923 /* 00924 * \brief Function enables the usage of Antenna diversity. 00925 * 00926 * \param none 00927 * 00928 * \return 0 Success 00929 */ 00930 static int8_t rf_enable_antenna_diversity(void) 00931 { 00932 uint8_t phyReg; 00933 00934 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_AGC_CTRL); 00935 phyReg |= cANT_AGC_CTRL_FAD_EN_Mask_c; 00936 MCR20Drv_IndirectAccessSPIWrite(ANT_AGC_CTRL, phyReg); 00937 00938 phyReg = MCR20Drv_IndirectAccessSPIRead(ANT_PAD_CTRL); 00939 phyReg |= 0x02; 00940 MCR20Drv_IndirectAccessSPIWrite(ANT_PAD_CTRL, phyReg); 00941 00942 return 0; 00943 } 00944 00945 /* 00946 * \brief Function gives the control of RF states to MAC. 00947 * 00948 * \param new_state RF state 00949 * \param rf_channel RF channel 00950 * 00951 * \return 0 Success 00952 */ 00953 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) 00954 { 00955 int8_t ret_val = 0; 00956 switch (new_state) 00957 { 00958 /*Reset PHY driver and set to idle*/ 00959 case PHY_INTERFACE_RESET: 00960 break; 00961 /*Disable PHY Interface driver*/ 00962 case PHY_INTERFACE_DOWN: 00963 rf_shutdown(); 00964 break; 00965 /*Enable PHY Interface driver*/ 00966 case PHY_INTERFACE_UP: 00967 rf_channel_set(rf_channel); 00968 rf_receive(); 00969 break; 00970 /*Enable wireless interface ED scan mode*/ 00971 case PHY_INTERFACE_RX_ENERGY_STATE: 00972 rf_abort(); 00973 rf_channel_set(rf_channel); 00974 break; 00975 case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */ 00976 rf_promiscuous(1); 00977 rf_channel_set(rf_channel); 00978 rf_receive(); 00979 break; 00980 } 00981 return ret_val; 00982 } 00983 00984 /* 00985 * \brief Function controls the ACK pending, channel setting and energy detection. 00986 * 00987 * \param extension_type Type of control 00988 * \param data_ptr Data from NET library 00989 * 00990 * \return 0 Success 00991 */ 00992 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) 00993 { 00994 switch (extension_type) 00995 { 00996 /*Control MAC pending bit for Indirect data transmission*/ 00997 case PHY_EXTENSION_CTRL_PENDING_BIT: 00998 { 00999 uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL); 01000 01001 if(*data_ptr) 01002 { 01003 reg |= cSRC_CTRL_ACK_FRM_PND; 01004 } 01005 else 01006 { 01007 reg &= ~cSRC_CTRL_ACK_FRM_PND; 01008 } 01009 01010 MCR20Drv_DirectAccessSPIWrite(SRC_CTRL, reg); 01011 break; 01012 01013 } 01014 /*Return frame Auto Ack frame pending status*/ 01015 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: { 01016 uint8_t reg = MCR20Drv_DirectAccessSPIRead(SRC_CTRL); 01017 if (reg & cSRC_CTRL_ACK_FRM_PND) { 01018 *data_ptr = 1; 01019 } else { 01020 *data_ptr = 0; 01021 } 01022 break; 01023 } 01024 /*Set channel*/ 01025 case PHY_EXTENSION_SET_CHANNEL: 01026 break; 01027 /*Read energy on the channel*/ 01028 case PHY_EXTENSION_READ_CHANNEL_ENERGY: 01029 *data_ptr = rf_get_channel_energy(); 01030 break; 01031 /*Read status of the link*/ 01032 case PHY_EXTENSION_READ_LINK_STATUS: 01033 break; 01034 case PHY_EXTENSION_CONVERT_SIGNAL_INFO: 01035 break; 01036 case PHY_EXTENSION_ACCEPT_ANY_BEACON: 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 Tue Jul 12 2022 15:14:29 by
