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