Version of easy-connect with the u-blox cellular platforms C027 and C030 added.
Embed:
(wiki syntax)
Show/hide line numbers
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 1.7.2