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