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.
ARM mbed Nanostack RF driver for NXP KW41Z 802.15.4 wireless MCU
This driver is used with 6LoWPAN stack.
Code far from being stable yet, but basic functionality seems to be working. Two FRDM-KW41Z boards running code build from mbed-os-example-mesh-minimal and nanostack-border-router are able to build mesh.
Main repository is at https://github.com/istepura/kw41z-rf-driver
source/NanostackRfPhyKw41z.cpp@2:8b42f07a0f12, 2017-07-22 (annotated)
- Committer:
- Igor Stepura
- Date:
- Sat Jul 22 13:22:46 2017 -0400
- Revision:
- 2:8b42f07a0f12
- Parent:
- 1:4e0ed8184753
- Child:
- 3:9f6427e86978
Code cleanup
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| igor Stepura |
1:4e0ed8184753 | 1 | /* |
| igor Stepura |
1:4e0ed8184753 | 2 | Copyright 2017, Igor Stepura <igor.stepura@gmail.com> |
| igor Stepura |
1:4e0ed8184753 | 3 | |
| Igor Stepura |
2:8b42f07a0f12 | 4 | Inspired by mcr20a-rf-driver by Andrei Kovacs <Andrei.Kovacs@freescale.com> |
| Igor Stepura |
2:8b42f07a0f12 | 5 | and NXP KW41Z 802.15.4 PHY implementation |
| Igor Stepura |
2:8b42f07a0f12 | 6 | |
| igor Stepura |
1:4e0ed8184753 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); |
| igor Stepura |
1:4e0ed8184753 | 8 | you may not use this file except in compliance with the License. |
| igor Stepura |
1:4e0ed8184753 | 9 | You may obtain a copy of the License at |
| igor Stepura |
1:4e0ed8184753 | 10 | |
| igor Stepura |
1:4e0ed8184753 | 11 | http://www.apache.org/licenses/LICENSE-2.0 |
| igor Stepura |
1:4e0ed8184753 | 12 | |
| igor Stepura |
1:4e0ed8184753 | 13 | Unless required by applicable law or agreed to in writing, software |
| igor Stepura |
1:4e0ed8184753 | 14 | distributed under the License is distributed on an "AS IS" BASIS, |
| igor Stepura |
1:4e0ed8184753 | 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| igor Stepura |
1:4e0ed8184753 | 16 | See the License for the specific language governing permissions and |
| igor Stepura |
1:4e0ed8184753 | 17 | limitations under the License. |
| igor Stepura |
1:4e0ed8184753 | 18 | */ |
| igor Stepura |
1:4e0ed8184753 | 19 | |
| igor Stepura |
0:bb6687c3a462 | 20 | #include "NanostackRfPhyKw41z.h" |
| igor Stepura |
0:bb6687c3a462 | 21 | #include "ns_types.h" |
| igor Stepura |
0:bb6687c3a462 | 22 | #include "platform/arm_hal_interrupt.h" |
| igor Stepura |
0:bb6687c3a462 | 23 | #include "nanostack/platform/arm_hal_phy.h" |
| igor Stepura |
0:bb6687c3a462 | 24 | #include <string.h> |
| igor Stepura |
0:bb6687c3a462 | 25 | #include "rtos.h" |
| igor Stepura |
0:bb6687c3a462 | 26 | #include "fsl_xcvr.h" |
| igor Stepura |
0:bb6687c3a462 | 27 | #include "PhyTypes.h" |
| igor Stepura |
0:bb6687c3a462 | 28 | |
| igor Stepura |
0:bb6687c3a462 | 29 | /* PHY states */ |
| igor Stepura |
0:bb6687c3a462 | 30 | typedef enum { |
| igor Stepura |
0:bb6687c3a462 | 31 | gIdle_c, |
| igor Stepura |
0:bb6687c3a462 | 32 | gRX_c, |
| igor Stepura |
0:bb6687c3a462 | 33 | gTX_c, |
| igor Stepura |
0:bb6687c3a462 | 34 | gCCA_c, |
| igor Stepura |
0:bb6687c3a462 | 35 | gTR_c, |
| igor Stepura |
0:bb6687c3a462 | 36 | gCCCA_c, |
| igor Stepura |
0:bb6687c3a462 | 37 | }phySeqState_t; |
| igor Stepura |
0:bb6687c3a462 | 38 | |
| igor Stepura |
0:bb6687c3a462 | 39 | typedef enum{ |
| Igor Stepura |
2:8b42f07a0f12 | 40 | gPhyPwrRun_c, |
| igor Stepura |
0:bb6687c3a462 | 41 | gPhyPwrDSM_c, |
| igor Stepura |
0:bb6687c3a462 | 42 | }phyPwrMode_t; |
| igor Stepura |
0:bb6687c3a462 | 43 | |
| igor Stepura |
0:bb6687c3a462 | 44 | /* PHY channel state */ |
| igor Stepura |
0:bb6687c3a462 | 45 | enum { |
| igor Stepura |
0:bb6687c3a462 | 46 | gChannelIdle_c, |
| igor Stepura |
0:bb6687c3a462 | 47 | gChannelBusy_c |
| igor Stepura |
0:bb6687c3a462 | 48 | }; |
| igor Stepura |
0:bb6687c3a462 | 49 | |
| igor Stepura |
0:bb6687c3a462 | 50 | enum { |
| igor Stepura |
0:bb6687c3a462 | 51 | gMacRole_DeviceOrCoord_c, |
| igor Stepura |
0:bb6687c3a462 | 52 | gMacRole_PanCoord_c |
| igor Stepura |
0:bb6687c3a462 | 53 | }; |
| igor Stepura |
0:bb6687c3a462 | 54 | |
| igor Stepura |
0:bb6687c3a462 | 55 | /* Cca types */ |
| igor Stepura |
0:bb6687c3a462 | 56 | enum { |
| igor Stepura |
0:bb6687c3a462 | 57 | gCcaED_c, /* energy detect - CCA bit not active, not to be used for T and CCCA sequences */ |
| igor Stepura |
0:bb6687c3a462 | 58 | gCcaCCA_MODE1_c, /* energy detect - CCA bit ACTIVE */ |
| igor Stepura |
0:bb6687c3a462 | 59 | gCcaCCA_MODE2_c, /* 802.15.4 compliant signal detect - CCA bit ACTIVE */ |
| igor Stepura |
0:bb6687c3a462 | 60 | gCcaCCA_MODE3_c, /* 802.15.4 compliant signal detect and energy detect - CCA bit ACTIVE */ |
| igor Stepura |
0:bb6687c3a462 | 61 | gInvalidCcaType_c /* illegal type */ |
| igor Stepura |
0:bb6687c3a462 | 62 | }; |
| igor Stepura |
0:bb6687c3a462 | 63 | |
| Igor Stepura |
2:8b42f07a0f12 | 64 | static phyPwrMode_t mPhyPwrState = gPhyPwrRun_c; |
| igor Stepura |
1:4e0ed8184753 | 65 | #ifndef MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS |
| igor Stepura |
1:4e0ed8184753 | 66 | #define MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS {1, 2, 3, 4, 5, 6, 7, 8} |
| igor Stepura |
1:4e0ed8184753 | 67 | #endif |
| igor Stepura |
1:4e0ed8184753 | 68 | |
| igor Stepura |
1:4e0ed8184753 | 69 | #ifndef MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL |
| igor Stepura |
1:4e0ed8184753 | 70 | #define MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL (12) |
| igor Stepura |
1:4e0ed8184753 | 71 | #endif |
| igor Stepura |
1:4e0ed8184753 | 72 | |
| igor Stepura |
1:4e0ed8184753 | 73 | static uint8_t MAC_address[8] = MBED_CONF_KW41Z_RF_LONG_MAC_ADDRESS; |
| igor Stepura |
0:bb6687c3a462 | 74 | static NanostackRfPhyKw41z *rf = NULL; |
| Igor Stepura |
2:8b42f07a0f12 | 75 | |
| Igor Stepura |
2:8b42f07a0f12 | 76 | #ifdef MBED_CONF_RTOS_PRESENT |
| igor Stepura |
0:bb6687c3a462 | 77 | static Thread irq_thread(osPriorityRealtime, 1024); |
| Igor Stepura |
2:8b42f07a0f12 | 78 | #endif |
| Igor Stepura |
2:8b42f07a0f12 | 79 | |
| igor Stepura |
0:bb6687c3a462 | 80 | static phy_device_driver_s device_driver; |
| igor Stepura |
0:bb6687c3a462 | 81 | static int8_t rf_radio_driver_id = -1; |
| igor Stepura |
0:bb6687c3a462 | 82 | static uint8_t mac_tx_handle = 0; |
| igor Stepura |
0:bb6687c3a462 | 83 | |
| igor Stepura |
0:bb6687c3a462 | 84 | static uint8_t rf_phy_channel = 0; |
| igor Stepura |
0:bb6687c3a462 | 85 | static uint8_t need_ack = 0; |
| igor Stepura |
0:bb6687c3a462 | 86 | |
| igor Stepura |
0:bb6687c3a462 | 87 | #define RF_BUFFER_SIZE 128 |
| igor Stepura |
0:bb6687c3a462 | 88 | /*RF receive buffer*/ |
| igor Stepura |
0:bb6687c3a462 | 89 | static uint8_t rf_buffer[RF_BUFFER_SIZE]; |
| igor Stepura |
0:bb6687c3a462 | 90 | |
| igor Stepura |
0:bb6687c3a462 | 91 | /* Channel configurations for 2.4 */ |
| igor Stepura |
0:bb6687c3a462 | 92 | static const phy_rf_channel_configuration_s phy_24ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK}; |
| igor Stepura |
0:bb6687c3a462 | 93 | |
| igor Stepura |
0:bb6687c3a462 | 94 | static const phy_device_channel_page_s phy_channel_pages[] = { |
| igor Stepura |
0:bb6687c3a462 | 95 | { CHANNEL_PAGE_0, &phy_24ghz}, |
| igor Stepura |
0:bb6687c3a462 | 96 | { CHANNEL_PAGE_0, NULL} |
| igor Stepura |
0:bb6687c3a462 | 97 | }; |
| igor Stepura |
0:bb6687c3a462 | 98 | /* Set the default power level to 0dBm */ |
| igor Stepura |
0:bb6687c3a462 | 99 | #ifndef gPhyDefaultTxPowerLevel_d |
| igor Stepura |
0:bb6687c3a462 | 100 | #define gPhyDefaultTxPowerLevel_d (22) |
| igor Stepura |
0:bb6687c3a462 | 101 | #endif |
| igor Stepura |
0:bb6687c3a462 | 102 | #define CORE_CLOCK_FREQ 47972352U |
| igor Stepura |
0:bb6687c3a462 | 103 | #define gPhyMaxTxPowerLevel_d (32) |
| igor Stepura |
0:bb6687c3a462 | 104 | uint8_t gPhyChannelTxPowerLimits[] = { gPhyMaxTxPowerLevel_d, /* 11 */ \ |
| igor Stepura |
0:bb6687c3a462 | 105 | gPhyMaxTxPowerLevel_d, /* 12 */ \ |
| igor Stepura |
0:bb6687c3a462 | 106 | gPhyMaxTxPowerLevel_d, /* 13 */ \ |
| igor Stepura |
0:bb6687c3a462 | 107 | gPhyMaxTxPowerLevel_d, /* 14 */ \ |
| igor Stepura |
0:bb6687c3a462 | 108 | gPhyMaxTxPowerLevel_d, /* 15 */ \ |
| igor Stepura |
0:bb6687c3a462 | 109 | gPhyMaxTxPowerLevel_d, /* 16 */ \ |
| igor Stepura |
0:bb6687c3a462 | 110 | gPhyMaxTxPowerLevel_d, /* 17 */ \ |
| igor Stepura |
0:bb6687c3a462 | 111 | gPhyMaxTxPowerLevel_d, /* 18 */ \ |
| igor Stepura |
0:bb6687c3a462 | 112 | gPhyMaxTxPowerLevel_d, /* 19 */ \ |
| igor Stepura |
0:bb6687c3a462 | 113 | gPhyMaxTxPowerLevel_d, /* 20 */ \ |
| igor Stepura |
0:bb6687c3a462 | 114 | gPhyMaxTxPowerLevel_d, /* 21 */ \ |
| igor Stepura |
0:bb6687c3a462 | 115 | gPhyMaxTxPowerLevel_d, /* 22 */ \ |
| igor Stepura |
0:bb6687c3a462 | 116 | gPhyMaxTxPowerLevel_d, /* 23 */ \ |
| igor Stepura |
0:bb6687c3a462 | 117 | gPhyMaxTxPowerLevel_d, /* 24 */ \ |
| igor Stepura |
0:bb6687c3a462 | 118 | gPhyMaxTxPowerLevel_d, /* 25 */ \ |
| igor Stepura |
0:bb6687c3a462 | 119 | gPhyMaxTxPowerLevel_d }; /* 26 */ |
| igor Stepura |
0:bb6687c3a462 | 120 | |
| igor Stepura |
0:bb6687c3a462 | 121 | |
| igor Stepura |
0:bb6687c3a462 | 122 | |
| igor Stepura |
0:bb6687c3a462 | 123 | MBED_UNUSED static void rf_init(void); |
| igor Stepura |
0:bb6687c3a462 | 124 | MBED_UNUSED static int8_t rf_device_register(void); |
| igor Stepura |
0:bb6687c3a462 | 125 | MBED_UNUSED static void rf_device_unregister(void); |
| igor Stepura |
0:bb6687c3a462 | 126 | MBED_UNUSED static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel); |
| igor Stepura |
0:bb6687c3a462 | 127 | MBED_UNUSED static int8_t rf_extension(phy_extension_type_e extension_type,uint8_t *data_ptr); |
| igor Stepura |
0:bb6687c3a462 | 128 | MBED_UNUSED static int8_t rf_address_write(phy_address_type_e address_type,uint8_t *address_ptr); |
| igor Stepura |
0:bb6687c3a462 | 129 | 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 ); |
| igor Stepura |
0:bb6687c3a462 | 130 | MBED_UNUSED static void rf_abort(void); |
| igor Stepura |
0:bb6687c3a462 | 131 | MBED_UNUSED static void rf_promiscuous(uint8_t mode); |
| igor Stepura |
0:bb6687c3a462 | 132 | MBED_UNUSED static void rf_receive(void); |
| igor Stepura |
0:bb6687c3a462 | 133 | MBED_UNUSED static void rf_mac64_read(uint8_t *address); |
| igor Stepura |
0:bb6687c3a462 | 134 | MBED_UNUSED static void rf_set_power_state(phyPwrMode_t newState); |
| igor Stepura |
0:bb6687c3a462 | 135 | MBED_UNUSED static void rf_handle_tx_end(uint8_t); |
| igor Stepura |
0:bb6687c3a462 | 136 | static void rf_set_address(uint8_t *address); |
| igor Stepura |
1:4e0ed8184753 | 137 | |
| igor Stepura |
0:bb6687c3a462 | 138 | static inline phySeqState_t rf_get_state(void) |
| igor Stepura |
0:bb6687c3a462 | 139 | { |
| igor Stepura |
0:bb6687c3a462 | 140 | return (phySeqState_t)(((ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK) >> ZLL_PHY_CTRL_XCVSEQ_SHIFT)); |
| igor Stepura |
0:bb6687c3a462 | 141 | } |
| igor Stepura |
0:bb6687c3a462 | 142 | |
| igor Stepura |
0:bb6687c3a462 | 143 | |
| igor Stepura |
0:bb6687c3a462 | 144 | static void PHY_InterruptHandler(void); |
| igor Stepura |
0:bb6687c3a462 | 145 | static void PHY_InterruptThread(void); |
| igor Stepura |
0:bb6687c3a462 | 146 | static void handle_interrupt(uint32_t irqStatus); |
| igor Stepura |
0:bb6687c3a462 | 147 | |
| igor Stepura |
0:bb6687c3a462 | 148 | static void rf_if_lock(void) |
| igor Stepura |
0:bb6687c3a462 | 149 | { |
| igor Stepura |
0:bb6687c3a462 | 150 | platform_enter_critical(); |
| igor Stepura |
0:bb6687c3a462 | 151 | } |
| igor Stepura |
0:bb6687c3a462 | 152 | |
| igor Stepura |
0:bb6687c3a462 | 153 | static void rf_if_unlock(void) |
| igor Stepura |
0:bb6687c3a462 | 154 | { |
| igor Stepura |
0:bb6687c3a462 | 155 | platform_exit_critical(); |
| igor Stepura |
0:bb6687c3a462 | 156 | } |
| igor Stepura |
0:bb6687c3a462 | 157 | |
| igor Stepura |
1:4e0ed8184753 | 158 | static void rf_set_power_level( uint8_t pwrStep) |
| igor Stepura |
0:bb6687c3a462 | 159 | { |
| igor Stepura |
1:4e0ed8184753 | 160 | /* Do not exceed the Tx power limit for the current channel */ |
| igor Stepura |
1:4e0ed8184753 | 161 | if( pwrStep > gPhyChannelTxPowerLimits[ZLL->CHANNEL_NUM0 - 11] ) |
| igor Stepura |
0:bb6687c3a462 | 162 | { |
| igor Stepura |
1:4e0ed8184753 | 163 | pwrStep = gPhyChannelTxPowerLimits[ZLL->CHANNEL_NUM0 - 11]; |
| igor Stepura |
0:bb6687c3a462 | 164 | } |
| igor Stepura |
1:4e0ed8184753 | 165 | if( pwrStep > 2 ) |
| igor Stepura |
1:4e0ed8184753 | 166 | { |
| igor Stepura |
1:4e0ed8184753 | 167 | pwrStep = (pwrStep << 1) - 2; |
| igor Stepura |
1:4e0ed8184753 | 168 | } |
| igor Stepura |
1:4e0ed8184753 | 169 | |
| igor Stepura |
1:4e0ed8184753 | 170 | ZLL->PA_PWR = pwrStep; |
| igor Stepura |
0:bb6687c3a462 | 171 | } |
| igor Stepura |
0:bb6687c3a462 | 172 | |
| igor Stepura |
1:4e0ed8184753 | 173 | static uint8_t rf_get_power_level(void) |
| igor Stepura |
0:bb6687c3a462 | 174 | { |
| igor Stepura |
0:bb6687c3a462 | 175 | uint8_t pwrStep = (uint8_t)ZLL->PA_PWR; |
| igor Stepura |
0:bb6687c3a462 | 176 | |
| igor Stepura |
0:bb6687c3a462 | 177 | if( pwrStep > 2 ) |
| igor Stepura |
0:bb6687c3a462 | 178 | { |
| igor Stepura |
0:bb6687c3a462 | 179 | pwrStep = (pwrStep + 2) >> 1; |
| igor Stepura |
0:bb6687c3a462 | 180 | } |
| igor Stepura |
0:bb6687c3a462 | 181 | |
| igor Stepura |
0:bb6687c3a462 | 182 | return pwrStep; |
| igor Stepura |
0:bb6687c3a462 | 183 | } |
| igor Stepura |
0:bb6687c3a462 | 184 | |
| igor Stepura |
0:bb6687c3a462 | 185 | #define gPhyIrqNo_d (Radio_1_IRQn) |
| igor Stepura |
0:bb6687c3a462 | 186 | static void PHY_InstallIsr() |
| igor Stepura |
0:bb6687c3a462 | 187 | { |
| igor Stepura |
0:bb6687c3a462 | 188 | NVIC_SetVector(gPhyIrqNo_d, (uint32_t)&PHY_InterruptHandler); |
| igor Stepura |
0:bb6687c3a462 | 189 | NVIC_ClearPendingIRQ(gPhyIrqNo_d); |
| igor Stepura |
0:bb6687c3a462 | 190 | NVIC_EnableIRQ(gPhyIrqNo_d); |
| igor Stepura |
0:bb6687c3a462 | 191 | } |
| igor Stepura |
0:bb6687c3a462 | 192 | |
| igor Stepura |
0:bb6687c3a462 | 193 | static void rf_channel_set(uint8_t channel) |
| igor Stepura |
0:bb6687c3a462 | 194 | { |
| igor Stepura |
0:bb6687c3a462 | 195 | rf_phy_channel = channel; |
| igor Stepura |
1:4e0ed8184753 | 196 | |
| igor Stepura |
1:4e0ed8184753 | 197 | ZLL->CHANNEL_NUM0 = channel; |
| igor Stepura |
1:4e0ed8184753 | 198 | |
| igor Stepura |
1:4e0ed8184753 | 199 | if( rf_get_power_level() > gPhyChannelTxPowerLimits[channel - 11] ) |
| igor Stepura |
1:4e0ed8184753 | 200 | { |
| igor Stepura |
1:4e0ed8184753 | 201 | rf_set_power_level(gPhyChannelTxPowerLimits[channel - 11]); |
| igor Stepura |
1:4e0ed8184753 | 202 | } |
| igor Stepura |
0:bb6687c3a462 | 203 | } |
| igor Stepura |
0:bb6687c3a462 | 204 | |
| igor Stepura |
0:bb6687c3a462 | 205 | static void rf_init(void) |
| igor Stepura |
0:bb6687c3a462 | 206 | { |
| igor Stepura |
0:bb6687c3a462 | 207 | uint32_t phyReg; |
| igor Stepura |
0:bb6687c3a462 | 208 | XCVR_Init( ZIGBEE_MODE, DR_500KBPS ); |
| igor Stepura |
0:bb6687c3a462 | 209 | |
| igor Stepura |
0:bb6687c3a462 | 210 | XCVR_SetXtalTrim(0x30); |
| igor Stepura |
0:bb6687c3a462 | 211 | |
| igor Stepura |
0:bb6687c3a462 | 212 | /* Enable 16 bit mode for TC2 - TC2 prime EN, disable all timers, |
| igor Stepura |
0:bb6687c3a462 | 213 | enable AUTOACK, mask all interrupts */ |
| igor Stepura |
0:bb6687c3a462 | 214 | ZLL->PHY_CTRL = (gCcaCCA_MODE1_c << ZLL_PHY_CTRL_CCATYPE_SHIFT) | |
| igor Stepura |
0:bb6687c3a462 | 215 | ZLL_PHY_CTRL_TC2PRIME_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 216 | ZLL_PHY_CTRL_TSM_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 217 | ZLL_PHY_CTRL_WAKE_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 218 | ZLL_PHY_CTRL_CRC_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 219 | ZLL_PHY_CTRL_PLL_UNLOCK_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 220 | ZLL_PHY_CTRL_FILTERFAIL_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 221 | ZLL_PHY_CTRL_RX_WMRK_MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 222 | ZLL_PHY_CTRL_CCAMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 223 | ZLL_PHY_CTRL_RXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 224 | ZLL_PHY_CTRL_TXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 225 | ZLL_PHY_CTRL_SEQMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 226 | ZLL_PHY_CTRL_AUTOACK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 227 | ZLL_PHY_CTRL_TRCV_MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 228 | |
| igor Stepura |
0:bb6687c3a462 | 229 | /* Clear all PP IRQ bits to avoid unexpected interrupts immediately after init |
| igor Stepura |
0:bb6687c3a462 | 230 | disable all timer interrupts */ |
| igor Stepura |
0:bb6687c3a462 | 231 | ZLL->IRQSTS = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 232 | |
| igor Stepura |
0:bb6687c3a462 | 233 | /* Enable Source Addresing Match module */ |
| igor Stepura |
0:bb6687c3a462 | 234 | ZLL->SAM_CTRL |= ZLL_SAM_CTRL_SAP0_EN_MASK; |
| igor Stepura |
0:bb6687c3a462 | 235 | |
| igor Stepura |
0:bb6687c3a462 | 236 | /* Clear HW indirect queue */ |
| igor Stepura |
0:bb6687c3a462 | 237 | ZLL->SAM_TABLE |= ZLL_SAM_TABLE_INVALIDATE_ALL_MASK; |
| igor Stepura |
0:bb6687c3a462 | 238 | |
| igor Stepura |
0:bb6687c3a462 | 239 | /* Frame Filtering |
| igor Stepura |
0:bb6687c3a462 | 240 | FRM_VER[7:6] = b11. Accept FrameVersion 0 and 1 packets, reject all others */ |
| igor Stepura |
0:bb6687c3a462 | 241 | ZLL->RX_FRAME_FILTER &= ~ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK; |
| igor Stepura |
0:bb6687c3a462 | 242 | ZLL->RX_FRAME_FILTER = ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3) | |
| igor Stepura |
0:bb6687c3a462 | 243 | ZLL_RX_FRAME_FILTER_CMD_FT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 244 | ZLL_RX_FRAME_FILTER_DATA_FT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 245 | ZLL_RX_FRAME_FILTER_BEACON_FT_MASK; |
| igor Stepura |
0:bb6687c3a462 | 246 | |
| igor Stepura |
0:bb6687c3a462 | 247 | /* Set prescaller to obtain 1 symbol (16us) timebase */ |
| igor Stepura |
0:bb6687c3a462 | 248 | ZLL->TMR_PRESCALE = 0x05; |
| igor Stepura |
0:bb6687c3a462 | 249 | |
| igor Stepura |
0:bb6687c3a462 | 250 | /* Set CCA threshold to -75 dBm */ |
| igor Stepura |
0:bb6687c3a462 | 251 | ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_CCA1_THRESH_MASK; |
| igor Stepura |
0:bb6687c3a462 | 252 | ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_CCA1_THRESH(0xB5); |
| igor Stepura |
0:bb6687c3a462 | 253 | |
| igor Stepura |
0:bb6687c3a462 | 254 | /* Set the default power level */ |
| igor Stepura |
1:4e0ed8184753 | 255 | rf_set_power_level(gPhyDefaultTxPowerLevel_d); |
| igor Stepura |
0:bb6687c3a462 | 256 | |
| igor Stepura |
0:bb6687c3a462 | 257 | /* Adjust ACK delay to fulfill the 802.15.4 turnaround requirements */ |
| igor Stepura |
0:bb6687c3a462 | 258 | ZLL->ACKDELAY &= ~ZLL_ACKDELAY_ACKDELAY_MASK; |
| igor Stepura |
0:bb6687c3a462 | 259 | ZLL->ACKDELAY |= ZLL_ACKDELAY_ACKDELAY(-8); |
| igor Stepura |
0:bb6687c3a462 | 260 | |
| igor Stepura |
0:bb6687c3a462 | 261 | /* Adjust LQI compensation */ |
| igor Stepura |
0:bb6687c3a462 | 262 | ZLL->CCA_LQI_CTRL &= ~ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP_MASK; |
| igor Stepura |
0:bb6687c3a462 | 263 | ZLL->CCA_LQI_CTRL |= ZLL_CCA_LQI_CTRL_LQI_OFFSET_COMP(96); |
| igor Stepura |
0:bb6687c3a462 | 264 | |
| igor Stepura |
0:bb6687c3a462 | 265 | /* Enable the RxWatermark IRQ and FilterFail IRQ */ |
| igor Stepura |
0:bb6687c3a462 | 266 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RX_WMRK_MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 267 | /* Set Rx watermark level */ |
| igor Stepura |
0:bb6687c3a462 | 268 | ZLL->RX_WTR_MARK = 0; |
| igor Stepura |
0:bb6687c3a462 | 269 | |
| igor Stepura |
1:4e0ed8184753 | 270 | rf_channel_set(MBED_CONF_MBED_MESH_API_6LOWPAN_ND_CHANNEL); |
| igor Stepura |
0:bb6687c3a462 | 271 | |
| igor Stepura |
0:bb6687c3a462 | 272 | /* DSM settings */ |
| igor Stepura |
0:bb6687c3a462 | 273 | phyReg = (RSIM->RF_OSC_CTRL & RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_MASK) >> |
| igor Stepura |
0:bb6687c3a462 | 274 | RSIM_RF_OSC_CTRL_BB_XTAL_READY_COUNT_SEL_SHIFT; |
| igor Stepura |
0:bb6687c3a462 | 275 | phyReg = (1024U << phyReg) / (CORE_CLOCK_FREQ / 32768) + 1; |
| igor Stepura |
0:bb6687c3a462 | 276 | RSIM->DSM_OSC_OFFSET = phyReg; |
| igor Stepura |
0:bb6687c3a462 | 277 | |
| igor Stepura |
0:bb6687c3a462 | 278 | /* Install PHY ISR */ |
| igor Stepura |
0:bb6687c3a462 | 279 | PHY_InstallIsr(); |
| igor Stepura |
1:4e0ed8184753 | 280 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TRCV_MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 281 | rf_receive(); |
| igor Stepura |
0:bb6687c3a462 | 282 | } |
| igor Stepura |
0:bb6687c3a462 | 283 | |
| igor Stepura |
0:bb6687c3a462 | 284 | static void rf_mac64_read(uint8_t *address) |
| igor Stepura |
0:bb6687c3a462 | 285 | { |
| igor Stepura |
0:bb6687c3a462 | 286 | uint64_t val = ZLL->MACLONGADDRS0_MSB; |
| igor Stepura |
0:bb6687c3a462 | 287 | val <<= 32; |
| igor Stepura |
0:bb6687c3a462 | 288 | val |= ZLL->MACLONGADDRS0_LSB; |
| igor Stepura |
0:bb6687c3a462 | 289 | |
| igor Stepura |
0:bb6687c3a462 | 290 | *((uint64_t*)address) = val; |
| igor Stepura |
0:bb6687c3a462 | 291 | } |
| igor Stepura |
0:bb6687c3a462 | 292 | |
| igor Stepura |
0:bb6687c3a462 | 293 | static void rf_promiscuous(uint8_t state) |
| igor Stepura |
0:bb6687c3a462 | 294 | { |
| igor Stepura |
0:bb6687c3a462 | 295 | if( state ) |
| igor Stepura |
0:bb6687c3a462 | 296 | { |
| igor Stepura |
0:bb6687c3a462 | 297 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_PROMISCUOUS_MASK; |
| igor Stepura |
0:bb6687c3a462 | 298 | /* FRM_VER[11:8] = b1111. Any FrameVersion accepted */ |
| igor Stepura |
0:bb6687c3a462 | 299 | ZLL->RX_FRAME_FILTER |= (ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | |
| igor Stepura |
0:bb6687c3a462 | 300 | ZLL_RX_FRAME_FILTER_ACK_FT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 301 | ZLL_RX_FRAME_FILTER_NS_FT_MASK); |
| igor Stepura |
0:bb6687c3a462 | 302 | } |
| igor Stepura |
0:bb6687c3a462 | 303 | else |
| igor Stepura |
0:bb6687c3a462 | 304 | { |
| igor Stepura |
0:bb6687c3a462 | 305 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_PROMISCUOUS_MASK; |
| igor Stepura |
0:bb6687c3a462 | 306 | /* FRM_VER[11:8] = b0011. Accept FrameVersion 0 and 1 packets, reject all others */ |
| igor Stepura |
0:bb6687c3a462 | 307 | /* Beacon, Data and MAC command frame types accepted */ |
| igor Stepura |
0:bb6687c3a462 | 308 | ZLL->RX_FRAME_FILTER &= ~(ZLL_RX_FRAME_FILTER_FRM_VER_FILTER_MASK | |
| igor Stepura |
0:bb6687c3a462 | 309 | ZLL_RX_FRAME_FILTER_ACK_FT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 310 | ZLL_RX_FRAME_FILTER_NS_FT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 311 | ZLL_RX_FRAME_FILTER_ACTIVE_PROMISCUOUS_MASK); |
| igor Stepura |
0:bb6687c3a462 | 312 | ZLL->RX_FRAME_FILTER |= ZLL_RX_FRAME_FILTER_FRM_VER_FILTER(3); |
| igor Stepura |
0:bb6687c3a462 | 313 | } |
| igor Stepura |
0:bb6687c3a462 | 314 | } |
| igor Stepura |
0:bb6687c3a462 | 315 | |
| igor Stepura |
0:bb6687c3a462 | 316 | static void rf_receive(void) |
| igor Stepura |
0:bb6687c3a462 | 317 | { |
| igor Stepura |
0:bb6687c3a462 | 318 | uint32_t irqSts; |
| igor Stepura |
0:bb6687c3a462 | 319 | /* RX can start only from Idle state */ |
| igor Stepura |
0:bb6687c3a462 | 320 | if( rf_get_state() != gIdle_c ) |
| igor Stepura |
0:bb6687c3a462 | 321 | { |
| igor Stepura |
0:bb6687c3a462 | 322 | return; |
| igor Stepura |
0:bb6687c3a462 | 323 | } |
| Igor Stepura |
2:8b42f07a0f12 | 324 | rf_set_power_state(gPhyPwrRun_c); |
| igor Stepura |
0:bb6687c3a462 | 325 | |
| igor Stepura |
0:bb6687c3a462 | 326 | /* Ensure that no spurious interrupts are raised, but do not change TMR1 and TMR4 IRQ status */ |
| igor Stepura |
0:bb6687c3a462 | 327 | irqSts = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 328 | irqSts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 329 | irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 330 | ZLL->IRQSTS = irqSts; |
| igor Stepura |
0:bb6687c3a462 | 331 | |
| igor Stepura |
0:bb6687c3a462 | 332 | ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 333 | ZLL->PHY_CTRL |= gRX_c ; |
| igor Stepura |
0:bb6687c3a462 | 334 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 335 | } |
| igor Stepura |
0:bb6687c3a462 | 336 | |
| igor Stepura |
0:bb6687c3a462 | 337 | static int8_t rf_device_register(void) |
| igor Stepura |
0:bb6687c3a462 | 338 | { |
| igor Stepura |
0:bb6687c3a462 | 339 | |
| igor Stepura |
0:bb6687c3a462 | 340 | rf_init(); |
| igor Stepura |
0:bb6687c3a462 | 341 | |
| igor Stepura |
0:bb6687c3a462 | 342 | /*Set pointer to MAC address*/ |
| igor Stepura |
0:bb6687c3a462 | 343 | device_driver.PHY_MAC = MAC_address; |
| igor Stepura |
0:bb6687c3a462 | 344 | device_driver.driver_description = (char*)"NXP_KWx"; |
| igor Stepura |
0:bb6687c3a462 | 345 | |
| igor Stepura |
0:bb6687c3a462 | 346 | //Create setup Used Radio chips |
| igor Stepura |
0:bb6687c3a462 | 347 | /*Type of RF PHY is SubGHz*/ |
| igor Stepura |
0:bb6687c3a462 | 348 | device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE; |
| igor Stepura |
0:bb6687c3a462 | 349 | |
| igor Stepura |
0:bb6687c3a462 | 350 | device_driver.phy_channel_pages = phy_channel_pages; |
| igor Stepura |
0:bb6687c3a462 | 351 | /*Maximum size of payload is 127*/ |
| igor Stepura |
0:bb6687c3a462 | 352 | device_driver.phy_MTU = 127; |
| igor Stepura |
0:bb6687c3a462 | 353 | /*No header in PHY*/ |
| igor Stepura |
0:bb6687c3a462 | 354 | device_driver.phy_header_length = 0; |
| igor Stepura |
0:bb6687c3a462 | 355 | /*No tail in PHY*/ |
| igor Stepura |
0:bb6687c3a462 | 356 | device_driver.phy_tail_length = 0; |
| igor Stepura |
0:bb6687c3a462 | 357 | /*Set address write function*/ |
| igor Stepura |
0:bb6687c3a462 | 358 | device_driver.address_write = &rf_address_write; |
| igor Stepura |
0:bb6687c3a462 | 359 | /*Set RF extension function*/ |
| igor Stepura |
0:bb6687c3a462 | 360 | device_driver.extension = &rf_extension; |
| igor Stepura |
0:bb6687c3a462 | 361 | /*Set RF state control function*/ |
| igor Stepura |
0:bb6687c3a462 | 362 | device_driver.state_control = &rf_interface_state_control; |
| igor Stepura |
0:bb6687c3a462 | 363 | /*Set transmit function*/ |
| igor Stepura |
0:bb6687c3a462 | 364 | device_driver.tx = &rf_start_cca; |
| igor Stepura |
0:bb6687c3a462 | 365 | /*Upper layer callbacks init to NULL*/ |
| igor Stepura |
0:bb6687c3a462 | 366 | device_driver.phy_rx_cb = NULL; |
| igor Stepura |
0:bb6687c3a462 | 367 | device_driver.phy_tx_done_cb = NULL; |
| igor Stepura |
0:bb6687c3a462 | 368 | /*Virtual upper data callback init to NULL*/ |
| igor Stepura |
0:bb6687c3a462 | 369 | device_driver.arm_net_virtual_rx_cb = NULL; |
| igor Stepura |
0:bb6687c3a462 | 370 | device_driver.arm_net_virtual_tx_cb = NULL; |
| igor Stepura |
0:bb6687c3a462 | 371 | |
| igor Stepura |
0:bb6687c3a462 | 372 | /*Register device driver*/ |
| igor Stepura |
0:bb6687c3a462 | 373 | rf_radio_driver_id = arm_net_phy_register(&device_driver); |
| igor Stepura |
0:bb6687c3a462 | 374 | |
| igor Stepura |
0:bb6687c3a462 | 375 | return rf_radio_driver_id; |
| igor Stepura |
0:bb6687c3a462 | 376 | } |
| igor Stepura |
0:bb6687c3a462 | 377 | |
| igor Stepura |
0:bb6687c3a462 | 378 | static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol ) |
| igor Stepura |
0:bb6687c3a462 | 379 | { |
| igor Stepura |
0:bb6687c3a462 | 380 | if( rf_get_state() == gRX_c ) |
| igor Stepura |
0:bb6687c3a462 | 381 | { |
| igor Stepura |
0:bb6687c3a462 | 382 | uint8_t phyReg = (ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK); |
| igor Stepura |
0:bb6687c3a462 | 383 | /* Check for an Rx in progress. */ |
| igor Stepura |
0:bb6687c3a462 | 384 | if((phyReg <= 0x06) || (phyReg == 0x15) || (phyReg == 0x16)) |
| igor Stepura |
0:bb6687c3a462 | 385 | { |
| igor Stepura |
0:bb6687c3a462 | 386 | if (device_driver.phy_tx_done_cb) { |
| igor Stepura |
0:bb6687c3a462 | 387 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 388 | } |
| igor Stepura |
0:bb6687c3a462 | 389 | return -1; |
| igor Stepura |
0:bb6687c3a462 | 390 | } |
| igor Stepura |
0:bb6687c3a462 | 391 | rf_abort(); |
| igor Stepura |
0:bb6687c3a462 | 392 | } |
| igor Stepura |
0:bb6687c3a462 | 393 | uint8_t* pPB = (uint8_t*)ZLL->PKT_BUFFER_TX; |
| igor Stepura |
0:bb6687c3a462 | 394 | pPB[0] = data_length + 2; /* including 2 bytes of FCS */ |
| igor Stepura |
0:bb6687c3a462 | 395 | memcpy(&pPB[1], data_ptr, data_length); |
| igor Stepura |
0:bb6687c3a462 | 396 | |
| igor Stepura |
0:bb6687c3a462 | 397 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCABFRTX_MASK; |
| igor Stepura |
0:bb6687c3a462 | 398 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_CCATYPE_MASK; |
| igor Stepura |
0:bb6687c3a462 | 399 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCATYPE(gCcaCCA_MODE1_c); |
| igor Stepura |
0:bb6687c3a462 | 400 | |
| igor Stepura |
0:bb6687c3a462 | 401 | mac_tx_handle = tx_handle; |
| igor Stepura |
0:bb6687c3a462 | 402 | need_ack = (*data_ptr & 0x20) == 0x20; |
| igor Stepura |
0:bb6687c3a462 | 403 | |
| igor Stepura |
0:bb6687c3a462 | 404 | /* Set XCVR power state in run mode */ |
| Igor Stepura |
2:8b42f07a0f12 | 405 | rf_set_power_state(gPhyPwrRun_c); |
| igor Stepura |
0:bb6687c3a462 | 406 | |
| igor Stepura |
0:bb6687c3a462 | 407 | uint8_t xcvseq; |
| igor Stepura |
0:bb6687c3a462 | 408 | if(need_ack) |
| igor Stepura |
0:bb6687c3a462 | 409 | { |
| igor Stepura |
0:bb6687c3a462 | 410 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_RXACKRQD_MASK; |
| igor Stepura |
0:bb6687c3a462 | 411 | xcvseq = gTR_c; |
| igor Stepura |
0:bb6687c3a462 | 412 | |
| igor Stepura |
0:bb6687c3a462 | 413 | } |
| igor Stepura |
0:bb6687c3a462 | 414 | else |
| igor Stepura |
0:bb6687c3a462 | 415 | { |
| igor Stepura |
0:bb6687c3a462 | 416 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RXACKRQD_MASK; |
| igor Stepura |
0:bb6687c3a462 | 417 | xcvseq = gTX_c; |
| igor Stepura |
0:bb6687c3a462 | 418 | } |
| igor Stepura |
0:bb6687c3a462 | 419 | uint32_t irqSts; |
| igor Stepura |
0:bb6687c3a462 | 420 | /* Ensure that no spurious interrupts are raised(do not change TMR1 and TMR4 IRQ status) */ |
| igor Stepura |
0:bb6687c3a462 | 421 | irqSts = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 422 | irqSts &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 423 | irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 424 | ZLL->IRQSTS = irqSts; |
| igor Stepura |
0:bb6687c3a462 | 425 | |
| igor Stepura |
0:bb6687c3a462 | 426 | ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_XCVSEQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 427 | /* Start the TX / TRX / CCA sequence */ |
| igor Stepura |
0:bb6687c3a462 | 428 | ZLL->PHY_CTRL |= xcvseq; |
| igor Stepura |
0:bb6687c3a462 | 429 | /* Unmask SEQ interrupt */ |
| igor Stepura |
0:bb6687c3a462 | 430 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_SEQMSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 431 | |
| igor Stepura |
0:bb6687c3a462 | 432 | return 0; |
| igor Stepura |
0:bb6687c3a462 | 433 | } |
| igor Stepura |
0:bb6687c3a462 | 434 | |
| igor Stepura |
0:bb6687c3a462 | 435 | static void rf_set_short_adr(uint8_t * short_address) |
| igor Stepura |
0:bb6687c3a462 | 436 | { |
| igor Stepura |
0:bb6687c3a462 | 437 | uint16_t value = ((uint16_t)short_address[0] << 8) | (uint16_t)short_address[1]; |
| igor Stepura |
0:bb6687c3a462 | 438 | //memcpy(&value, short_address, sizeof(value)); |
| igor Stepura |
0:bb6687c3a462 | 439 | ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACSHORTADDRS0_MASK; |
| igor Stepura |
0:bb6687c3a462 | 440 | ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACSHORTADDRS0(value); |
| igor Stepura |
0:bb6687c3a462 | 441 | } |
| igor Stepura |
0:bb6687c3a462 | 442 | |
| igor Stepura |
0:bb6687c3a462 | 443 | static void rf_set_pan_id(uint8_t *pan_id) |
| igor Stepura |
0:bb6687c3a462 | 444 | { |
| igor Stepura |
0:bb6687c3a462 | 445 | uint16_t value = ((uint16_t)pan_id[0] << 8) | (uint16_t)pan_id[1]; |
| igor Stepura |
0:bb6687c3a462 | 446 | ZLL->MACSHORTADDRS0 &= ~ZLL_MACSHORTADDRS0_MACPANID0_MASK; |
| igor Stepura |
0:bb6687c3a462 | 447 | ZLL->MACSHORTADDRS0 |= ZLL_MACSHORTADDRS0_MACPANID0(value); |
| igor Stepura |
0:bb6687c3a462 | 448 | } |
| igor Stepura |
0:bb6687c3a462 | 449 | |
| igor Stepura |
0:bb6687c3a462 | 450 | #define TO_UINT32(ptr, num) do {\ |
| igor Stepura |
0:bb6687c3a462 | 451 | num = (((uint32_t)(ptr)[0] << 24) |\ |
| igor Stepura |
0:bb6687c3a462 | 452 | ((uint32_t)(ptr)[1] << 16) |\ |
| igor Stepura |
0:bb6687c3a462 | 453 | ((uint32_t)(ptr)[2] << 8) |\ |
| igor Stepura |
0:bb6687c3a462 | 454 | ((uint32_t)(ptr)[3])); \ |
| igor Stepura |
0:bb6687c3a462 | 455 | }while(0) |
| igor Stepura |
0:bb6687c3a462 | 456 | |
| igor Stepura |
0:bb6687c3a462 | 457 | static void rf_set_address(uint8_t *address) |
| igor Stepura |
0:bb6687c3a462 | 458 | { |
| igor Stepura |
0:bb6687c3a462 | 459 | uint32_t addrLo; |
| igor Stepura |
0:bb6687c3a462 | 460 | uint32_t addrHi; |
| igor Stepura |
0:bb6687c3a462 | 461 | |
| igor Stepura |
0:bb6687c3a462 | 462 | TO_UINT32(address, addrHi); |
| igor Stepura |
0:bb6687c3a462 | 463 | TO_UINT32(address + 4, addrLo); |
| igor Stepura |
0:bb6687c3a462 | 464 | |
| igor Stepura |
0:bb6687c3a462 | 465 | ZLL->MACLONGADDRS0_LSB = addrLo; |
| igor Stepura |
0:bb6687c3a462 | 466 | ZLL->MACLONGADDRS0_MSB = addrHi; |
| igor Stepura |
0:bb6687c3a462 | 467 | } |
| igor Stepura |
0:bb6687c3a462 | 468 | |
| igor Stepura |
0:bb6687c3a462 | 469 | static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) |
| igor Stepura |
0:bb6687c3a462 | 470 | { |
| igor Stepura |
0:bb6687c3a462 | 471 | int8_t ret_val = 0; |
| igor Stepura |
0:bb6687c3a462 | 472 | switch (address_type) |
| igor Stepura |
0:bb6687c3a462 | 473 | { |
| igor Stepura |
0:bb6687c3a462 | 474 | /*Set 48-bit address*/ |
| igor Stepura |
0:bb6687c3a462 | 475 | case PHY_MAC_48BIT: |
| igor Stepura |
0:bb6687c3a462 | 476 | break; |
| igor Stepura |
0:bb6687c3a462 | 477 | /*Set 64-bit address*/ |
| igor Stepura |
0:bb6687c3a462 | 478 | case PHY_MAC_64BIT: |
| igor Stepura |
0:bb6687c3a462 | 479 | rf_set_address(address_ptr); |
| igor Stepura |
0:bb6687c3a462 | 480 | break; |
| igor Stepura |
0:bb6687c3a462 | 481 | /*Set 16-bit address*/ |
| igor Stepura |
0:bb6687c3a462 | 482 | case PHY_MAC_16BIT: |
| igor Stepura |
0:bb6687c3a462 | 483 | rf_set_short_adr(address_ptr); |
| igor Stepura |
0:bb6687c3a462 | 484 | break; |
| igor Stepura |
0:bb6687c3a462 | 485 | /*Set PAN Id*/ |
| igor Stepura |
0:bb6687c3a462 | 486 | case PHY_MAC_PANID: |
| igor Stepura |
0:bb6687c3a462 | 487 | rf_set_pan_id(address_ptr); |
| igor Stepura |
0:bb6687c3a462 | 488 | break; |
| igor Stepura |
0:bb6687c3a462 | 489 | } |
| igor Stepura |
0:bb6687c3a462 | 490 | return ret_val; |
| igor Stepura |
0:bb6687c3a462 | 491 | } |
| igor Stepura |
0:bb6687c3a462 | 492 | |
| igor Stepura |
0:bb6687c3a462 | 493 | static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) |
| igor Stepura |
0:bb6687c3a462 | 494 | { |
| igor Stepura |
0:bb6687c3a462 | 495 | uint32_t type = (uint32_t)extension_type; |
| igor Stepura |
0:bb6687c3a462 | 496 | switch (type) |
| igor Stepura |
0:bb6687c3a462 | 497 | { |
| igor Stepura |
0:bb6687c3a462 | 498 | /*Return frame pending status*/ |
| igor Stepura |
0:bb6687c3a462 | 499 | case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: |
| igor Stepura |
0:bb6687c3a462 | 500 | *data_ptr = ((ZLL->IRQSTS & ZLL_IRQSTS_RX_FRM_PEND_MASK) >> ZLL_IRQSTS_RX_FRM_PEND_SHIFT); |
| igor Stepura |
0:bb6687c3a462 | 501 | break; |
| igor Stepura |
0:bb6687c3a462 | 502 | /*Read energy on the channel*/ |
| igor Stepura |
0:bb6687c3a462 | 503 | case PHY_EXTENSION_READ_CHANNEL_ENERGY: |
| igor Stepura |
0:bb6687c3a462 | 504 | *data_ptr = 100; |
| igor Stepura |
0:bb6687c3a462 | 505 | break; |
| igor Stepura |
0:bb6687c3a462 | 506 | } |
| igor Stepura |
0:bb6687c3a462 | 507 | return 0; |
| igor Stepura |
0:bb6687c3a462 | 508 | } |
| igor Stepura |
0:bb6687c3a462 | 509 | |
| igor Stepura |
0:bb6687c3a462 | 510 | #define mPhyDSM_GuardTime_d (5) /* DSM_TIME ticks (32.768KHz) */ |
| igor Stepura |
0:bb6687c3a462 | 511 | static uint32_t mPhyDSMDuration = 0xFFFFF0; |
| igor Stepura |
0:bb6687c3a462 | 512 | static void rf_set_power_state(phyPwrMode_t newState) |
| igor Stepura |
0:bb6687c3a462 | 513 | { |
| Igor Stepura |
2:8b42f07a0f12 | 514 | if( newState == mPhyPwrState ) |
| igor Stepura |
0:bb6687c3a462 | 515 | { |
| igor Stepura |
0:bb6687c3a462 | 516 | return; |
| igor Stepura |
0:bb6687c3a462 | 517 | } |
| igor Stepura |
0:bb6687c3a462 | 518 | else |
| igor Stepura |
0:bb6687c3a462 | 519 | { |
| igor Stepura |
0:bb6687c3a462 | 520 | switch(newState) |
| igor Stepura |
0:bb6687c3a462 | 521 | { |
| Igor Stepura |
2:8b42f07a0f12 | 522 | case gPhyPwrRun_c: |
| igor Stepura |
0:bb6687c3a462 | 523 | /* Set XCVR in run mode if not allready */ |
| igor Stepura |
0:bb6687c3a462 | 524 | if(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK) |
| igor Stepura |
0:bb6687c3a462 | 525 | { |
| igor Stepura |
0:bb6687c3a462 | 526 | RSIM->ZIG_WAKE = (RSIM->DSM_TIMER + mPhyDSM_GuardTime_d); |
| igor Stepura |
0:bb6687c3a462 | 527 | while(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK); |
| igor Stepura |
0:bb6687c3a462 | 528 | } |
| igor Stepura |
0:bb6687c3a462 | 529 | break; |
| igor Stepura |
0:bb6687c3a462 | 530 | |
| igor Stepura |
0:bb6687c3a462 | 531 | case gPhyPwrDSM_c: |
| igor Stepura |
0:bb6687c3a462 | 532 | /* Set XCVR in low power mode if not allready */ |
| igor Stepura |
0:bb6687c3a462 | 533 | if(!(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_DEEP_SLEEP_STATUS_MASK)) |
| igor Stepura |
0:bb6687c3a462 | 534 | { |
| igor Stepura |
0:bb6687c3a462 | 535 | uint32_t minTime = (RSIM->DSM_OSC_OFFSET > mPhyDSM_GuardTime_d) ? RSIM->DSM_OSC_OFFSET : mPhyDSM_GuardTime_d; |
| igor Stepura |
0:bb6687c3a462 | 536 | |
| igor Stepura |
0:bb6687c3a462 | 537 | RSIM->ZIG_SLEEP = RSIM->DSM_TIMER + minTime; |
| igor Stepura |
0:bb6687c3a462 | 538 | RSIM->ZIG_WAKE = RSIM->DSM_TIMER + mPhyDSMDuration; |
| igor Stepura |
0:bb6687c3a462 | 539 | RSIM->DSM_CONTROL |= RSIM_DSM_CONTROL_ZIG_SYSCLK_REQUEST_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 540 | RSIM_DSM_CONTROL_DSM_TIMER_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 541 | RSIM_DSM_CONTROL_ZIG_SYSCLK_INTERRUPT_EN_MASK; |
| igor Stepura |
0:bb6687c3a462 | 542 | } |
| igor Stepura |
0:bb6687c3a462 | 543 | break; |
| igor Stepura |
0:bb6687c3a462 | 544 | } |
| igor Stepura |
0:bb6687c3a462 | 545 | |
| igor Stepura |
0:bb6687c3a462 | 546 | mPhyPwrState = newState; |
| igor Stepura |
0:bb6687c3a462 | 547 | } |
| igor Stepura |
0:bb6687c3a462 | 548 | } |
| igor Stepura |
0:bb6687c3a462 | 549 | |
| igor Stepura |
0:bb6687c3a462 | 550 | static void rf_off(void) |
| igor Stepura |
0:bb6687c3a462 | 551 | { |
| igor Stepura |
0:bb6687c3a462 | 552 | rf_abort(); |
| Igor Stepura |
2:8b42f07a0f12 | 553 | rf_set_power_state(gPhyPwrDSM_c); |
| igor Stepura |
0:bb6687c3a462 | 554 | } |
| igor Stepura |
0:bb6687c3a462 | 555 | |
| igor Stepura |
0:bb6687c3a462 | 556 | static void rf_shutdown(void) |
| igor Stepura |
0:bb6687c3a462 | 557 | { |
| igor Stepura |
0:bb6687c3a462 | 558 | rf_off(); |
| igor Stepura |
0:bb6687c3a462 | 559 | } |
| igor Stepura |
0:bb6687c3a462 | 560 | |
| igor Stepura |
0:bb6687c3a462 | 561 | static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) |
| igor Stepura |
0:bb6687c3a462 | 562 | { |
| igor Stepura |
0:bb6687c3a462 | 563 | int8_t ret_val = 0; |
| igor Stepura |
0:bb6687c3a462 | 564 | switch (new_state) |
| igor Stepura |
0:bb6687c3a462 | 565 | { |
| igor Stepura |
0:bb6687c3a462 | 566 | /*Reset PHY driver and set to idle*/ |
| igor Stepura |
0:bb6687c3a462 | 567 | case PHY_INTERFACE_RESET: |
| igor Stepura |
0:bb6687c3a462 | 568 | break; |
| igor Stepura |
0:bb6687c3a462 | 569 | /*Disable PHY Interface driver*/ |
| igor Stepura |
0:bb6687c3a462 | 570 | case PHY_INTERFACE_DOWN: |
| igor Stepura |
0:bb6687c3a462 | 571 | rf_shutdown(); |
| igor Stepura |
0:bb6687c3a462 | 572 | break; |
| igor Stepura |
0:bb6687c3a462 | 573 | /*Enable PHY Interface driver*/ |
| igor Stepura |
0:bb6687c3a462 | 574 | case PHY_INTERFACE_UP: |
| igor Stepura |
0:bb6687c3a462 | 575 | rf_channel_set(rf_channel); |
| igor Stepura |
0:bb6687c3a462 | 576 | rf_receive(); |
| igor Stepura |
0:bb6687c3a462 | 577 | break; |
| igor Stepura |
0:bb6687c3a462 | 578 | /*Enable wireless interface ED scan mode*/ |
| igor Stepura |
0:bb6687c3a462 | 579 | case PHY_INTERFACE_RX_ENERGY_STATE: |
| igor Stepura |
0:bb6687c3a462 | 580 | rf_abort(); |
| igor Stepura |
0:bb6687c3a462 | 581 | rf_channel_set(rf_channel); |
| igor Stepura |
0:bb6687c3a462 | 582 | break; |
| igor Stepura |
0:bb6687c3a462 | 583 | case PHY_INTERFACE_SNIFFER_STATE: /**< Enable Sniffer state */ |
| igor Stepura |
0:bb6687c3a462 | 584 | rf_promiscuous(1); |
| igor Stepura |
0:bb6687c3a462 | 585 | rf_channel_set(rf_channel); |
| igor Stepura |
0:bb6687c3a462 | 586 | rf_receive(); |
| igor Stepura |
0:bb6687c3a462 | 587 | break; |
| igor Stepura |
0:bb6687c3a462 | 588 | } |
| igor Stepura |
0:bb6687c3a462 | 589 | return ret_val; |
| igor Stepura |
0:bb6687c3a462 | 590 | } |
| igor Stepura |
0:bb6687c3a462 | 591 | |
| igor Stepura |
0:bb6687c3a462 | 592 | static void rf_device_unregister(void) |
| igor Stepura |
0:bb6687c3a462 | 593 | { |
| igor Stepura |
0:bb6687c3a462 | 594 | arm_net_phy_unregister(rf_radio_driver_id); |
| igor Stepura |
0:bb6687c3a462 | 595 | } |
| igor Stepura |
0:bb6687c3a462 | 596 | |
| igor Stepura |
0:bb6687c3a462 | 597 | static void rf_abort(void) |
| igor Stepura |
0:bb6687c3a462 | 598 | { |
| igor Stepura |
0:bb6687c3a462 | 599 | /* Mask SEQ interrupt */ |
| igor Stepura |
0:bb6687c3a462 | 600 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_SEQMSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 601 | /* Disable timer trigger (for scheduled XCVSEQ) */ |
| igor Stepura |
0:bb6687c3a462 | 602 | if( ZLL->PHY_CTRL & ZLL_PHY_CTRL_TMRTRIGEN_MASK ) |
| igor Stepura |
0:bb6687c3a462 | 603 | { |
| igor Stepura |
0:bb6687c3a462 | 604 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMRTRIGEN_MASK; |
| igor Stepura |
0:bb6687c3a462 | 605 | /* give the FSM enough time to start if it was triggered */ |
| igor Stepura |
0:bb6687c3a462 | 606 | while( (XCVR_MISC->XCVR_CTRL & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) == 0) {} |
| igor Stepura |
0:bb6687c3a462 | 607 | } |
| igor Stepura |
0:bb6687c3a462 | 608 | |
| igor Stepura |
0:bb6687c3a462 | 609 | /* If XCVR is not idle, abort current SEQ */ |
| igor Stepura |
0:bb6687c3a462 | 610 | if( ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK ) |
| igor Stepura |
0:bb6687c3a462 | 611 | { |
| igor Stepura |
0:bb6687c3a462 | 612 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; |
| igor Stepura |
0:bb6687c3a462 | 613 | /* wait for Sequence Idle (if not already) */ |
| igor Stepura |
0:bb6687c3a462 | 614 | while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} |
| igor Stepura |
0:bb6687c3a462 | 615 | } |
| igor Stepura |
0:bb6687c3a462 | 616 | |
| igor Stepura |
0:bb6687c3a462 | 617 | /* Stop timers */ |
| igor Stepura |
0:bb6687c3a462 | 618 | ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR2CMP_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 619 | ZLL_PHY_CTRL_TMR3CMP_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 620 | ZLL_PHY_CTRL_TC3TMOUT_MASK ); |
| igor Stepura |
0:bb6687c3a462 | 621 | /* clear all PP IRQ bits to avoid unexpected interrupts( do not change TMR1 and TMR4 IRQ status ) */ |
| igor Stepura |
0:bb6687c3a462 | 622 | ZLL->IRQSTS &= ~(ZLL_IRQSTS_TMR1IRQ_MASK | ZLL_IRQSTS_TMR4IRQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 623 | } |
| igor Stepura |
0:bb6687c3a462 | 624 | |
| igor Stepura |
0:bb6687c3a462 | 625 | |
| igor Stepura |
0:bb6687c3a462 | 626 | |
| igor Stepura |
0:bb6687c3a462 | 627 | /* |
| igor Stepura |
0:bb6687c3a462 | 628 | * \brief Function is a RF interrupt vector. End of frame in RX and TX are handled here as well as CCA process interrupt. |
| igor Stepura |
0:bb6687c3a462 | 629 | * |
| igor Stepura |
0:bb6687c3a462 | 630 | * \param none |
| igor Stepura |
0:bb6687c3a462 | 631 | * |
| igor Stepura |
0:bb6687c3a462 | 632 | * \return none |
| igor Stepura |
0:bb6687c3a462 | 633 | */ |
| Igor Stepura |
2:8b42f07a0f12 | 634 | static volatile uint32_t gIrqStatus = 0; |
| igor Stepura |
0:bb6687c3a462 | 635 | static void PHY_InterruptHandler(void) |
| igor Stepura |
0:bb6687c3a462 | 636 | { |
| igor Stepura |
0:bb6687c3a462 | 637 | gIrqStatus = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 638 | ZLL->IRQSTS = gIrqStatus; |
| Igor Stepura |
2:8b42f07a0f12 | 639 | #ifdef MBED_CONF_RTOS_PRESENT |
| igor Stepura |
0:bb6687c3a462 | 640 | irq_thread.signal_set(1); |
| Igor Stepura |
2:8b42f07a0f12 | 641 | #else |
| Igor Stepura |
2:8b42f07a0f12 | 642 | handle_interrupt(gIrqStatus); |
| Igor Stepura |
2:8b42f07a0f12 | 643 | #endif |
| Igor Stepura |
2:8b42f07a0f12 | 644 | |
| igor Stepura |
0:bb6687c3a462 | 645 | } |
| igor Stepura |
0:bb6687c3a462 | 646 | |
| igor Stepura |
0:bb6687c3a462 | 647 | static void PHY_InterruptThread(void) |
| igor Stepura |
0:bb6687c3a462 | 648 | { |
| Igor Stepura |
2:8b42f07a0f12 | 649 | #ifdef MBED_CONF_RTOS_PRESENT |
| igor Stepura |
0:bb6687c3a462 | 650 | for (;;) { |
| igor Stepura |
0:bb6687c3a462 | 651 | osEvent event = irq_thread.signal_wait(0); |
| igor Stepura |
0:bb6687c3a462 | 652 | if (event.status != osEventSignal) { |
| igor Stepura |
0:bb6687c3a462 | 653 | continue; |
| igor Stepura |
0:bb6687c3a462 | 654 | } |
| igor Stepura |
0:bb6687c3a462 | 655 | handle_interrupt(gIrqStatus); |
| igor Stepura |
0:bb6687c3a462 | 656 | |
| igor Stepura |
0:bb6687c3a462 | 657 | } |
| Igor Stepura |
2:8b42f07a0f12 | 658 | #endif |
| igor Stepura |
0:bb6687c3a462 | 659 | } |
| igor Stepura |
0:bb6687c3a462 | 660 | |
| Igor Stepura |
2:8b42f07a0f12 | 661 | static inline void rf_clean_seq_isr(void) |
| igor Stepura |
0:bb6687c3a462 | 662 | { |
| igor Stepura |
0:bb6687c3a462 | 663 | uint32_t irqStatus; |
| igor Stepura |
0:bb6687c3a462 | 664 | |
| igor Stepura |
0:bb6687c3a462 | 665 | /* Set the PHY sequencer back to IDLE */ |
| igor Stepura |
0:bb6687c3a462 | 666 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; |
| igor Stepura |
0:bb6687c3a462 | 667 | /* Mask SEQ, RX, TX and CCA interrupts */ |
| igor Stepura |
0:bb6687c3a462 | 668 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 669 | ZLL_PHY_CTRL_RXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 670 | ZLL_PHY_CTRL_TXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 671 | ZLL_PHY_CTRL_SEQMSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 672 | |
| igor Stepura |
0:bb6687c3a462 | 673 | while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} |
| igor Stepura |
0:bb6687c3a462 | 674 | |
| igor Stepura |
0:bb6687c3a462 | 675 | irqStatus = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 676 | /* Mask TMR3 interrupt */ |
| igor Stepura |
0:bb6687c3a462 | 677 | irqStatus |= ZLL_IRQSTS_TMR3MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 678 | /* Clear transceiver interrupts except TMRxIRQ */ |
| igor Stepura |
0:bb6687c3a462 | 679 | irqStatus &= ~( ZLL_IRQSTS_TMR1IRQ_MASK | |
| igor Stepura |
0:bb6687c3a462 | 680 | ZLL_IRQSTS_TMR2IRQ_MASK | |
| igor Stepura |
0:bb6687c3a462 | 681 | ZLL_IRQSTS_TMR3IRQ_MASK | |
| igor Stepura |
0:bb6687c3a462 | 682 | ZLL_IRQSTS_TMR4IRQ_MASK ); |
| igor Stepura |
0:bb6687c3a462 | 683 | ZLL->IRQSTS = irqStatus; |
| igor Stepura |
0:bb6687c3a462 | 684 | } |
| igor Stepura |
0:bb6687c3a462 | 685 | |
| Igor Stepura |
2:8b42f07a0f12 | 686 | static inline void rf_clean_timeout_isr(void) |
| igor Stepura |
0:bb6687c3a462 | 687 | { |
| igor Stepura |
0:bb6687c3a462 | 688 | uint32_t irqStatus; |
| igor Stepura |
0:bb6687c3a462 | 689 | |
| igor Stepura |
0:bb6687c3a462 | 690 | /* Set the PHY sequencer back to IDLE and disable TMR3 comparator and timeout */ |
| igor Stepura |
0:bb6687c3a462 | 691 | ZLL->PHY_CTRL &= ~(ZLL_PHY_CTRL_TMR3CMP_EN_MASK | |
| igor Stepura |
0:bb6687c3a462 | 692 | ZLL_PHY_CTRL_TC3TMOUT_MASK | |
| igor Stepura |
0:bb6687c3a462 | 693 | ZLL_PHY_CTRL_XCVSEQ_MASK); |
| igor Stepura |
0:bb6687c3a462 | 694 | /* Mask SEQ, RX, TX and CCA interrupts */ |
| igor Stepura |
0:bb6687c3a462 | 695 | ZLL->PHY_CTRL |= ZLL_PHY_CTRL_CCAMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 696 | ZLL_PHY_CTRL_RXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 697 | ZLL_PHY_CTRL_TXMSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 698 | ZLL_PHY_CTRL_SEQMSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 699 | |
| igor Stepura |
0:bb6687c3a462 | 700 | while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} |
| igor Stepura |
0:bb6687c3a462 | 701 | |
| igor Stepura |
0:bb6687c3a462 | 702 | irqStatus = ZLL->IRQSTS; |
| igor Stepura |
0:bb6687c3a462 | 703 | /* Mask TMR3 interrupt */ |
| igor Stepura |
0:bb6687c3a462 | 704 | irqStatus |= ZLL_IRQSTS_TMR3MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 705 | /* Clear transceiver interrupts except TMR1IRQ and TMR4IRQ. */ |
| igor Stepura |
0:bb6687c3a462 | 706 | irqStatus &= ~( ZLL_IRQSTS_TMR1IRQ_MASK | |
| igor Stepura |
0:bb6687c3a462 | 707 | ZLL_IRQSTS_TMR4IRQ_MASK ); |
| igor Stepura |
0:bb6687c3a462 | 708 | ZLL->IRQSTS = irqStatus; |
| igor Stepura |
0:bb6687c3a462 | 709 | } |
| igor Stepura |
0:bb6687c3a462 | 710 | |
| igor Stepura |
0:bb6687c3a462 | 711 | static inline uint8_t rf_convert_lqi(uint8_t rssi) |
| igor Stepura |
0:bb6687c3a462 | 712 | { |
| igor Stepura |
0:bb6687c3a462 | 713 | if (rssi >= 220) |
| igor Stepura |
0:bb6687c3a462 | 714 | { |
| igor Stepura |
0:bb6687c3a462 | 715 | rssi = 255; |
| igor Stepura |
0:bb6687c3a462 | 716 | } |
| igor Stepura |
0:bb6687c3a462 | 717 | else |
| igor Stepura |
0:bb6687c3a462 | 718 | { |
| igor Stepura |
0:bb6687c3a462 | 719 | rssi = (51 * rssi) / 44; |
| igor Stepura |
0:bb6687c3a462 | 720 | } |
| igor Stepura |
0:bb6687c3a462 | 721 | |
| igor Stepura |
0:bb6687c3a462 | 722 | return rssi; |
| igor Stepura |
0:bb6687c3a462 | 723 | } |
| igor Stepura |
0:bb6687c3a462 | 724 | |
| igor Stepura |
0:bb6687c3a462 | 725 | static void rf_handle_rx_end(void) |
| igor Stepura |
0:bb6687c3a462 | 726 | { |
| igor Stepura |
0:bb6687c3a462 | 727 | uint32_t irqSts; |
| igor Stepura |
0:bb6687c3a462 | 728 | |
| igor Stepura |
0:bb6687c3a462 | 729 | /* disable TMR3 compare */ |
| igor Stepura |
0:bb6687c3a462 | 730 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR3CMP_EN_MASK; |
| igor Stepura |
0:bb6687c3a462 | 731 | /* disable autosequence stop by TC3 match */ |
| igor Stepura |
0:bb6687c3a462 | 732 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TC3TMOUT_MASK; |
| igor Stepura |
0:bb6687c3a462 | 733 | /* mask TMR3 interrupt (do not change other IRQ status) */ |
| igor Stepura |
0:bb6687c3a462 | 734 | irqSts = ZLL->IRQSTS & (ZLL_IRQSTS_TMR1MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 735 | ZLL_IRQSTS_TMR2MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 736 | ZLL_IRQSTS_TMR3MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 737 | ZLL_IRQSTS_TMR4MSK_MASK ); |
| igor Stepura |
0:bb6687c3a462 | 738 | irqSts |= ZLL_IRQSTS_TMR3MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 739 | /* aknowledge TMR3 IRQ */ |
| igor Stepura |
0:bb6687c3a462 | 740 | irqSts |= ZLL_IRQSTS_TMR3IRQ_MASK; |
| igor Stepura |
0:bb6687c3a462 | 741 | ZLL->IRQSTS = irqSts; |
| igor Stepura |
0:bb6687c3a462 | 742 | |
| igor Stepura |
0:bb6687c3a462 | 743 | uint8_t rssi = (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_LQI_VALUE_MASK) >> ZLL_LQI_AND_RSSI_LQI_VALUE_SHIFT; |
| igor Stepura |
0:bb6687c3a462 | 744 | uint8_t lqi = rf_convert_lqi(rssi); |
| igor Stepura |
0:bb6687c3a462 | 745 | uint8_t psduLength = (ZLL->IRQSTS & ZLL_IRQSTS_RX_FRAME_LENGTH_MASK) >> ZLL_IRQSTS_RX_FRAME_LENGTH_SHIFT; /* Including FCS (2 bytes) */ |
| igor Stepura |
0:bb6687c3a462 | 746 | uint8_t len = psduLength - 2; |
| igor Stepura |
0:bb6687c3a462 | 747 | |
| igor Stepura |
0:bb6687c3a462 | 748 | rf_receive(); |
| igor Stepura |
0:bb6687c3a462 | 749 | if (psduLength > 0 ) |
| igor Stepura |
0:bb6687c3a462 | 750 | { |
| igor Stepura |
0:bb6687c3a462 | 751 | for (uint8_t i = 0; i < len; i++) |
| igor Stepura |
0:bb6687c3a462 | 752 | { |
| igor Stepura |
0:bb6687c3a462 | 753 | rf_buffer[i] = ((uint8_t*)ZLL->PKT_BUFFER_RX)[i]; |
| igor Stepura |
0:bb6687c3a462 | 754 | } |
| igor Stepura |
0:bb6687c3a462 | 755 | |
| igor Stepura |
0:bb6687c3a462 | 756 | if (device_driver.phy_rx_cb) { |
| igor Stepura |
0:bb6687c3a462 | 757 | device_driver.phy_rx_cb(rf_buffer, len, lqi, rssi, rf_radio_driver_id); |
| igor Stepura |
0:bb6687c3a462 | 758 | } |
| igor Stepura |
0:bb6687c3a462 | 759 | } |
| igor Stepura |
0:bb6687c3a462 | 760 | |
| igor Stepura |
0:bb6687c3a462 | 761 | } |
| igor Stepura |
0:bb6687c3a462 | 762 | |
| igor Stepura |
0:bb6687c3a462 | 763 | static void handle_interrupt(uint32_t irqStatus) |
| igor Stepura |
0:bb6687c3a462 | 764 | { |
| Igor Stepura |
2:8b42f07a0f12 | 765 | /* RSIM Wake-up IRQ */ |
| igor Stepura |
0:bb6687c3a462 | 766 | if(RSIM->DSM_CONTROL & RSIM_DSM_CONTROL_ZIG_SYSCLK_REQ_INT_MASK) |
| igor Stepura |
0:bb6687c3a462 | 767 | { |
| igor Stepura |
0:bb6687c3a462 | 768 | RSIM->DSM_CONTROL = RSIM->DSM_CONTROL; |
| igor Stepura |
0:bb6687c3a462 | 769 | return; |
| igor Stepura |
0:bb6687c3a462 | 770 | } |
| igor Stepura |
0:bb6687c3a462 | 771 | |
| igor Stepura |
0:bb6687c3a462 | 772 | /* Read current XCVRSEQ and interrup status */ |
| igor Stepura |
0:bb6687c3a462 | 773 | uint32_t xcvseqCopy = ZLL->PHY_CTRL & ZLL_PHY_CTRL_XCVSEQ_MASK; |
| igor Stepura |
0:bb6687c3a462 | 774 | |
| igor Stepura |
0:bb6687c3a462 | 775 | /* WAKE IRQ */ |
| igor Stepura |
0:bb6687c3a462 | 776 | if( irqStatus & ZLL_IRQSTS_WAKE_IRQ_MASK ) |
| igor Stepura |
0:bb6687c3a462 | 777 | { |
| igor Stepura |
0:bb6687c3a462 | 778 | uint32_t timeAdjust = RSIM->ZIG_WAKE; |
| igor Stepura |
0:bb6687c3a462 | 779 | /* Adjust the 802.15.4 EVENT_TMR */ |
| igor Stepura |
0:bb6687c3a462 | 780 | timeAdjust = (timeAdjust - RSIM->ZIG_SLEEP)/32768U * 1000000U; /* [us] */ |
| igor Stepura |
0:bb6687c3a462 | 781 | ZLL->EVENT_TMR = (timeAdjust << 4) | ZLL_EVENT_TMR_EVENT_TMR_ADD_MASK; |
| igor Stepura |
0:bb6687c3a462 | 782 | } |
| igor Stepura |
0:bb6687c3a462 | 783 | |
| igor Stepura |
0:bb6687c3a462 | 784 | if( (!(ZLL->PHY_CTRL & ZLL_PHY_CTRL_SEQMSK_MASK)) && (irqStatus & ZLL_IRQSTS_SEQIRQ_MASK) ) |
| igor Stepura |
0:bb6687c3a462 | 785 | { |
| igor Stepura |
0:bb6687c3a462 | 786 | if( irqStatus & ZLL_IRQSTS_PLL_UNLOCK_IRQ_MASK ) |
| igor Stepura |
0:bb6687c3a462 | 787 | { |
| Igor Stepura |
2:8b42f07a0f12 | 788 | rf_clean_seq_isr(); |
| igor Stepura |
0:bb6687c3a462 | 789 | } |
| igor Stepura |
0:bb6687c3a462 | 790 | /* TMR3 timeout, the autosequence has been aborted due to TMR3 timeout */ |
| igor Stepura |
0:bb6687c3a462 | 791 | else if( (irqStatus & ZLL_IRQSTS_TMR3IRQ_MASK) && |
| igor Stepura |
0:bb6687c3a462 | 792 | (!(irqStatus & ZLL_IRQSTS_RXIRQ_MASK)) && |
| igor Stepura |
0:bb6687c3a462 | 793 | (gTX_c != xcvseqCopy) ) |
| igor Stepura |
0:bb6687c3a462 | 794 | { |
| Igor Stepura |
2:8b42f07a0f12 | 795 | rf_clean_timeout_isr(); |
| igor Stepura |
0:bb6687c3a462 | 796 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_FAIL, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 797 | } |
| igor Stepura |
0:bb6687c3a462 | 798 | else |
| igor Stepura |
0:bb6687c3a462 | 799 | { |
| Igor Stepura |
2:8b42f07a0f12 | 800 | rf_clean_seq_isr(); |
| igor Stepura |
0:bb6687c3a462 | 801 | switch(xcvseqCopy) |
| igor Stepura |
0:bb6687c3a462 | 802 | { |
| igor Stepura |
1:4e0ed8184753 | 803 | case gTX_c: |
| igor Stepura |
1:4e0ed8184753 | 804 | if( (ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && (irqStatus & ZLL_IRQSTS_CCA_MASK ) ) |
| igor Stepura |
1:4e0ed8184753 | 805 | { |
| igor Stepura |
1:4e0ed8184753 | 806 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); |
| igor Stepura |
1:4e0ed8184753 | 807 | } |
| igor Stepura |
1:4e0ed8184753 | 808 | else |
| igor Stepura |
1:4e0ed8184753 | 809 | { |
| igor Stepura |
1:4e0ed8184753 | 810 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_XCVSEQ_MASK; |
| igor Stepura |
1:4e0ed8184753 | 811 | /* wait for Sequence Idle (if not already) */ |
| igor Stepura |
1:4e0ed8184753 | 812 | ZLL->PHY_CTRL |= (ZLL_PHY_CTRL_CCAMSK_MASK | |
| igor Stepura |
1:4e0ed8184753 | 813 | ZLL_PHY_CTRL_RXMSK_MASK | |
| igor Stepura |
1:4e0ed8184753 | 814 | ZLL_PHY_CTRL_TXMSK_MASK | |
| igor Stepura |
1:4e0ed8184753 | 815 | ZLL_PHY_CTRL_SEQMSK_MASK); |
| igor Stepura |
1:4e0ed8184753 | 816 | while( ZLL->SEQ_STATE & ZLL_SEQ_STATE_SEQ_STATE_MASK ) {} |
| igor Stepura |
1:4e0ed8184753 | 817 | rf_handle_tx_end(0); |
| igor Stepura |
1:4e0ed8184753 | 818 | } |
| igor Stepura |
1:4e0ed8184753 | 819 | break; |
| igor Stepura |
0:bb6687c3a462 | 820 | |
| igor Stepura |
1:4e0ed8184753 | 821 | case gTR_c: |
| igor Stepura |
1:4e0ed8184753 | 822 | if( (ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCABFRTX_MASK) && (irqStatus & ZLL_IRQSTS_CCA_MASK ) ) |
| igor Stepura |
0:bb6687c3a462 | 823 | { |
| igor Stepura |
0:bb6687c3a462 | 824 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 825 | } |
| igor Stepura |
0:bb6687c3a462 | 826 | else |
| igor Stepura |
0:bb6687c3a462 | 827 | { |
| igor Stepura |
1:4e0ed8184753 | 828 | rf_handle_tx_end((irqStatus & ZLL_IRQSTS_RX_FRM_PEND_MASK) > 0); |
| igor Stepura |
1:4e0ed8184753 | 829 | |
| igor Stepura |
0:bb6687c3a462 | 830 | } |
| igor Stepura |
1:4e0ed8184753 | 831 | break; |
| igor Stepura |
1:4e0ed8184753 | 832 | |
| igor Stepura |
1:4e0ed8184753 | 833 | case gRX_c: |
| igor Stepura |
1:4e0ed8184753 | 834 | rf_handle_rx_end(); |
| igor Stepura |
1:4e0ed8184753 | 835 | break; |
| igor Stepura |
1:4e0ed8184753 | 836 | |
| igor Stepura |
1:4e0ed8184753 | 837 | case gCCA_c: |
| igor Stepura |
1:4e0ed8184753 | 838 | if( gCcaED_c == ((ZLL->PHY_CTRL & ZLL_PHY_CTRL_CCATYPE_MASK) >> ZLL_PHY_CTRL_CCATYPE_SHIFT) ) |
| igor Stepura |
1:4e0ed8184753 | 839 | { |
| igor Stepura |
1:4e0ed8184753 | 840 | //Radio_Phy_PlmeEdConfirm( (ZLL->LQI_AND_RSSI & ZLL_LQI_AND_RSSI_CCA1_ED_FNL_MASK) >> ZLL_LQI_AND_RSSI_CCA1_ED_FNL_SHIFT, mPhyInstance ); |
| igor Stepura |
1:4e0ed8184753 | 841 | } |
| igor Stepura |
1:4e0ed8184753 | 842 | else /* CCA */ |
| igor Stepura |
1:4e0ed8184753 | 843 | { |
| igor Stepura |
1:4e0ed8184753 | 844 | if( irqStatus & ZLL_IRQSTS_CCA_MASK ) |
| igor Stepura |
1:4e0ed8184753 | 845 | { |
| igor Stepura |
1:4e0ed8184753 | 846 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); |
| igor Stepura |
1:4e0ed8184753 | 847 | } |
| igor Stepura |
1:4e0ed8184753 | 848 | else |
| igor Stepura |
1:4e0ed8184753 | 849 | { |
| igor Stepura |
1:4e0ed8184753 | 850 | } |
| igor Stepura |
1:4e0ed8184753 | 851 | } |
| igor Stepura |
1:4e0ed8184753 | 852 | break; |
| igor Stepura |
1:4e0ed8184753 | 853 | default: |
| igor Stepura |
1:4e0ed8184753 | 854 | break; |
| igor Stepura |
0:bb6687c3a462 | 855 | } |
| igor Stepura |
0:bb6687c3a462 | 856 | } |
| igor Stepura |
0:bb6687c3a462 | 857 | } |
| igor Stepura |
0:bb6687c3a462 | 858 | /* Timers interrupt */ |
| igor Stepura |
0:bb6687c3a462 | 859 | else |
| igor Stepura |
0:bb6687c3a462 | 860 | { |
| igor Stepura |
0:bb6687c3a462 | 861 | /* Timer 3 Compare Match */ |
| igor Stepura |
0:bb6687c3a462 | 862 | if( (irqStatus & ZLL_IRQSTS_TMR3IRQ_MASK) && (!(irqStatus & ZLL_IRQSTS_TMR3MSK_MASK)) ) |
| igor Stepura |
0:bb6687c3a462 | 863 | { |
| igor Stepura |
0:bb6687c3a462 | 864 | |
| igor Stepura |
0:bb6687c3a462 | 865 | if( gIdle_c == xcvseqCopy ) |
| igor Stepura |
0:bb6687c3a462 | 866 | { |
| Igor Stepura |
2:8b42f07a0f12 | 867 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_FAIL, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 868 | } |
| igor Stepura |
0:bb6687c3a462 | 869 | } |
| igor Stepura |
0:bb6687c3a462 | 870 | |
| igor Stepura |
0:bb6687c3a462 | 871 | /* Timer 4 Compare Match */ |
| igor Stepura |
0:bb6687c3a462 | 872 | if( (irqStatus & ZLL_IRQSTS_TMR4IRQ_MASK) && (!(irqStatus & ZLL_IRQSTS_TMR4MSK_MASK)) ) |
| igor Stepura |
0:bb6687c3a462 | 873 | { |
| igor Stepura |
0:bb6687c3a462 | 874 | /* Disable TMR4 comparator */ |
| igor Stepura |
0:bb6687c3a462 | 875 | ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_TMR4CMP_EN_MASK; |
| igor Stepura |
0:bb6687c3a462 | 876 | /* Mask and clear TMR4 interrupt (do not change other IRQ status) */ |
| igor Stepura |
0:bb6687c3a462 | 877 | irqStatus &= ~( ZLL_IRQSTS_TMR1MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 878 | ZLL_IRQSTS_TMR2MSK_MASK | |
| igor Stepura |
0:bb6687c3a462 | 879 | ZLL_IRQSTS_TMR3MSK_MASK ); |
| igor Stepura |
0:bb6687c3a462 | 880 | irqStatus |= ZLL_IRQSTS_TMR4IRQ_MASK | ZLL_IRQSTS_TMR4MSK_MASK; |
| igor Stepura |
0:bb6687c3a462 | 881 | ZLL->IRQSTS = irqStatus; |
| igor Stepura |
0:bb6687c3a462 | 882 | } |
| igor Stepura |
0:bb6687c3a462 | 883 | } |
| igor Stepura |
0:bb6687c3a462 | 884 | } |
| igor Stepura |
0:bb6687c3a462 | 885 | |
| igor Stepura |
0:bb6687c3a462 | 886 | static void rf_handle_tx_end(uint8_t rx_frame_pending) |
| igor Stepura |
0:bb6687c3a462 | 887 | { |
| igor Stepura |
0:bb6687c3a462 | 888 | rf_receive(); |
| igor Stepura |
0:bb6687c3a462 | 889 | |
| igor Stepura |
0:bb6687c3a462 | 890 | if (!device_driver.phy_tx_done_cb) { |
| igor Stepura |
0:bb6687c3a462 | 891 | return; |
| igor Stepura |
0:bb6687c3a462 | 892 | } |
| igor Stepura |
0:bb6687c3a462 | 893 | if( need_ack ) |
| igor Stepura |
0:bb6687c3a462 | 894 | { |
| igor Stepura |
0:bb6687c3a462 | 895 | if( rx_frame_pending ) |
| igor Stepura |
0:bb6687c3a462 | 896 | { |
| igor Stepura |
0:bb6687c3a462 | 897 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE_PENDING, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 898 | } |
| igor Stepura |
0:bb6687c3a462 | 899 | else |
| igor Stepura |
0:bb6687c3a462 | 900 | { |
| igor Stepura |
0:bb6687c3a462 | 901 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_DONE, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 902 | } |
| igor Stepura |
0:bb6687c3a462 | 903 | } |
| igor Stepura |
0:bb6687c3a462 | 904 | else |
| igor Stepura |
0:bb6687c3a462 | 905 | { |
| igor Stepura |
0:bb6687c3a462 | 906 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); |
| igor Stepura |
0:bb6687c3a462 | 907 | } |
| igor Stepura |
0:bb6687c3a462 | 908 | |
| igor Stepura |
0:bb6687c3a462 | 909 | |
| igor Stepura |
0:bb6687c3a462 | 910 | } |
| igor Stepura |
0:bb6687c3a462 | 911 | |
| igor Stepura |
0:bb6687c3a462 | 912 | NanostackRfPhyKw41z::NanostackRfPhyKw41z() |
| igor Stepura |
0:bb6687c3a462 | 913 | { |
| igor Stepura |
0:bb6687c3a462 | 914 | } |
| igor Stepura |
0:bb6687c3a462 | 915 | |
| igor Stepura |
0:bb6687c3a462 | 916 | NanostackRfPhyKw41z::~NanostackRfPhyKw41z() |
| igor Stepura |
0:bb6687c3a462 | 917 | { |
| igor Stepura |
0:bb6687c3a462 | 918 | } |
| igor Stepura |
0:bb6687c3a462 | 919 | |
| igor Stepura |
0:bb6687c3a462 | 920 | int8_t NanostackRfPhyKw41z::rf_register() |
| igor Stepura |
0:bb6687c3a462 | 921 | { |
| igor Stepura |
0:bb6687c3a462 | 922 | |
| igor Stepura |
0:bb6687c3a462 | 923 | rf_if_lock(); |
| igor Stepura |
0:bb6687c3a462 | 924 | |
| igor Stepura |
0:bb6687c3a462 | 925 | if (rf != NULL) { |
| igor Stepura |
0:bb6687c3a462 | 926 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 927 | error("Multiple registrations of NanostackRfPhyKw41z not supported"); |
| igor Stepura |
0:bb6687c3a462 | 928 | return -1; |
| igor Stepura |
0:bb6687c3a462 | 929 | } |
| igor Stepura |
0:bb6687c3a462 | 930 | |
| Igor Stepura |
2:8b42f07a0f12 | 931 | #ifdef MBED_CONF_RTOS_PRESENT |
| igor Stepura |
0:bb6687c3a462 | 932 | irq_thread.start(mbed::callback(PHY_InterruptThread)); |
| Igor Stepura |
2:8b42f07a0f12 | 933 | #endif |
| igor Stepura |
0:bb6687c3a462 | 934 | |
| igor Stepura |
0:bb6687c3a462 | 935 | int8_t radio_id = rf_device_register(); |
| igor Stepura |
0:bb6687c3a462 | 936 | if (radio_id < 0) { |
| igor Stepura |
0:bb6687c3a462 | 937 | rf = NULL; |
| igor Stepura |
0:bb6687c3a462 | 938 | } |
| igor Stepura |
0:bb6687c3a462 | 939 | |
| igor Stepura |
0:bb6687c3a462 | 940 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 941 | return radio_id; |
| igor Stepura |
0:bb6687c3a462 | 942 | } |
| igor Stepura |
0:bb6687c3a462 | 943 | |
| igor Stepura |
0:bb6687c3a462 | 944 | void NanostackRfPhyKw41z::rf_unregister() |
| igor Stepura |
0:bb6687c3a462 | 945 | { |
| igor Stepura |
0:bb6687c3a462 | 946 | rf_if_lock(); |
| igor Stepura |
0:bb6687c3a462 | 947 | |
| igor Stepura |
0:bb6687c3a462 | 948 | if (rf != this) { |
| igor Stepura |
0:bb6687c3a462 | 949 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 950 | return; |
| igor Stepura |
0:bb6687c3a462 | 951 | } |
| igor Stepura |
0:bb6687c3a462 | 952 | |
| igor Stepura |
0:bb6687c3a462 | 953 | rf_device_unregister(); |
| igor Stepura |
0:bb6687c3a462 | 954 | rf = NULL; |
| igor Stepura |
0:bb6687c3a462 | 955 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 956 | } |
| igor Stepura |
0:bb6687c3a462 | 957 | |
| igor Stepura |
0:bb6687c3a462 | 958 | |
| igor Stepura |
0:bb6687c3a462 | 959 | void NanostackRfPhyKw41z::set_mac_address(uint8_t* mac) |
| igor Stepura |
0:bb6687c3a462 | 960 | { |
| igor Stepura |
0:bb6687c3a462 | 961 | rf_if_lock(); |
| igor Stepura |
0:bb6687c3a462 | 962 | |
| igor Stepura |
0:bb6687c3a462 | 963 | if (NULL != rf) { |
| igor Stepura |
0:bb6687c3a462 | 964 | error("NanostackRfPhyKw41z cannot change mac address when running"); |
| igor Stepura |
0:bb6687c3a462 | 965 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 966 | return; |
| igor Stepura |
0:bb6687c3a462 | 967 | } |
| igor Stepura |
0:bb6687c3a462 | 968 | memcpy((void*)MAC_address, (void*)mac, sizeof(MAC_address)); |
| igor Stepura |
0:bb6687c3a462 | 969 | |
| igor Stepura |
0:bb6687c3a462 | 970 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 971 | } |
| igor Stepura |
0:bb6687c3a462 | 972 | |
| igor Stepura |
0:bb6687c3a462 | 973 | void NanostackRfPhyKw41z::get_mac_address(uint8_t *mac) |
| igor Stepura |
0:bb6687c3a462 | 974 | { |
| igor Stepura |
0:bb6687c3a462 | 975 | rf_if_lock(); |
| igor Stepura |
0:bb6687c3a462 | 976 | |
| igor Stepura |
0:bb6687c3a462 | 977 | memcpy((void*)mac, (void*)MAC_address, sizeof(MAC_address)); |
| igor Stepura |
0:bb6687c3a462 | 978 | |
| igor Stepura |
0:bb6687c3a462 | 979 | rf_if_unlock(); |
| igor Stepura |
0:bb6687c3a462 | 980 | } |
| igor Stepura |
0:bb6687c3a462 | 981 |