takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2016-2016 ARM Limited. All rights reserved.
kadonotakashi 0:8fdf9a60065b 3 * SPDX-License-Identifier: Apache-2.0
kadonotakashi 0:8fdf9a60065b 4 * Licensed under the Apache License, Version 2.0 (the License); you may
kadonotakashi 0:8fdf9a60065b 5 * not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 6 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 9 *
kadonotakashi 0:8fdf9a60065b 10 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
kadonotakashi 0:8fdf9a60065b 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 13 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 14 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 15 */
kadonotakashi 0:8fdf9a60065b 16 #include "mbed.h"
kadonotakashi 0:8fdf9a60065b 17 #include "ns_types.h"
kadonotakashi 0:8fdf9a60065b 18 #include <string.h>
kadonotakashi 0:8fdf9a60065b 19 #include "common_functions.h"
kadonotakashi 0:8fdf9a60065b 20 #include "randLIB.h"
kadonotakashi 0:8fdf9a60065b 21 #include "platform/arm_hal_interrupt.h"
kadonotakashi 0:8fdf9a60065b 22 #include "platform/arm_hal_phy.h"
kadonotakashi 0:8fdf9a60065b 23 #include "NanostackRfPhyNcs36510.h"
kadonotakashi 0:8fdf9a60065b 24
kadonotakashi 0:8fdf9a60065b 25 extern "C" {
kadonotakashi 0:8fdf9a60065b 26 #include "TARGET_NCS36510/memory_map.h"
kadonotakashi 0:8fdf9a60065b 27 #include "TARGET_NCS36510/clock.h"
kadonotakashi 0:8fdf9a60065b 28 #include "TARGET_NCS36510/ticker.h"
kadonotakashi 0:8fdf9a60065b 29 #include "TARGET_NCS36510/rfAna.h"
kadonotakashi 0:8fdf9a60065b 30 }
kadonotakashi 0:8fdf9a60065b 31
kadonotakashi 0:8fdf9a60065b 32 #define RF_THREAD_STACK_SIZE 1024
kadonotakashi 0:8fdf9a60065b 33
kadonotakashi 0:8fdf9a60065b 34 #define SIGNAL_COUNT_RADIO 1
kadonotakashi 0:8fdf9a60065b 35
kadonotakashi 0:8fdf9a60065b 36 static void rf_thread_loop();
kadonotakashi 0:8fdf9a60065b 37 Thread rf_thread(osPriorityRealtime, RF_THREAD_STACK_SIZE);
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 #define PHY_MTU_SIZE 127
kadonotakashi 0:8fdf9a60065b 40 #define CRC_LENGTH 0
kadonotakashi 0:8fdf9a60065b 41 #define PHY_HEADER_LENGTH 0
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 /**
kadonotakashi 0:8fdf9a60065b 44 * MAC status code bit definition
kadonotakashi 0:8fdf9a60065b 45 */
kadonotakashi 0:8fdf9a60065b 46 #define MAC_STATUS_SUCCESS (0x0) /**< Success */
kadonotakashi 0:8fdf9a60065b 47 #define MAC_STATUS_TIMEOUT (0x1) /**< Time out */
kadonotakashi 0:8fdf9a60065b 48 #define MAC_STATUS_BUSY (0x2) /**< Channel Busy */
kadonotakashi 0:8fdf9a60065b 49 #define MAC_STATUS_CRCFAIL (0x3) /**< CRC Failed */
kadonotakashi 0:8fdf9a60065b 50 #define MAC_STATUS_NOACK (0x5) /**< No ACK */
kadonotakashi 0:8fdf9a60065b 51 #define MAC_STATUS_UNLOCK (0x6) /**< PLL unlocked */
kadonotakashi 0:8fdf9a60065b 52 #define MAC_STATUS_BADSTART (0x7) /**< Bad Start */
kadonotakashi 0:8fdf9a60065b 53 #define MAC_STATUS_RXACK_PENDING (0x8) /**< ACK frame was received with the Pending bit set */
kadonotakashi 0:8fdf9a60065b 54 #define MAC_STATUS_TXACK_PENDING (0x9) /**< ACK frame was transmitted with the Pending bit set */
kadonotakashi 0:8fdf9a60065b 55 #define MAC_STATUS_FAIL_FILTER (0xA) /**< One or more frame filtering tests has failed */
kadonotakashi 0:8fdf9a60065b 56 #define MAC_STATUS_PANID_CONFLICT (0xB) /**< A PANID conflict has been detected */
kadonotakashi 0:8fdf9a60065b 57 #define MAC_STATUS_NOTCOMPLETE (0xF) /**< Not complete */
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 /**
kadonotakashi 0:8fdf9a60065b 60 * MAC sequence modes
kadonotakashi 0:8fdf9a60065b 61 */
kadonotakashi 0:8fdf9a60065b 62 #define MAC_SEQUENCE_NOP (0x0) /**< NOP */
kadonotakashi 0:8fdf9a60065b 63 #define MAC_SEQUENCE_RX (0x3) /**< RX */
kadonotakashi 0:8fdf9a60065b 64 #define MAC_SEQUENCE_TX (0x4) /**< TX */
kadonotakashi 0:8fdf9a60065b 65 #define MAC_SEQUENCE_ED (0x5) /**< ED */
kadonotakashi 0:8fdf9a60065b 66 #define MAC_SEQUENCE_CCA (0x6) /**< CCA */
kadonotakashi 0:8fdf9a60065b 67
kadonotakashi 0:8fdf9a60065b 68 /**
kadonotakashi 0:8fdf9a60065b 69 * MAC Interrupt enable / disable
kadonotakashi 0:8fdf9a60065b 70 */
kadonotakashi 0:8fdf9a60065b 71 #define MAC_IRQ_NONE (0x0) /**< No IRQ */
kadonotakashi 0:8fdf9a60065b 72 #define MAC_IRQ_COMPLETE (0x1) /**< Event-complete IRQ */
kadonotakashi 0:8fdf9a60065b 73 #define MAC_IRQ_EVENT_STARTED (0x2) /**< Event-started IRQ */
kadonotakashi 0:8fdf9a60065b 74 #define MAC_IRQ_DATA (0x4) /**< Data-arrived IRQ */
kadonotakashi 0:8fdf9a60065b 75 #define MAC_IRQ_FRAME_STARTED (0x8) /**< Frame-started IRQ */
kadonotakashi 0:8fdf9a60065b 76 #define MAC_IRQ_PACKET_FAIL (0x10) /**< Failed-packet IRQ */
kadonotakashi 0:8fdf9a60065b 77 #define MAC_IRQ_FRAME_MATCH (0x20) /**< Frame-match IRQ (indicating matching process is done) */
kadonotakashi 0:8fdf9a60065b 78 #define MAC_IRQ_ALL (0x3F) /**< All IRQs */
kadonotakashi 0:8fdf9a60065b 79
kadonotakashi 0:8fdf9a60065b 80 #define MAC_RSSI_TO_ED 0
kadonotakashi 0:8fdf9a60065b 81 #define MAC_RSSI_TO_LQI 1
kadonotakashi 0:8fdf9a60065b 82
kadonotakashi 0:8fdf9a60065b 83 #define MAC_RF_TRX_OFF 0
kadonotakashi 0:8fdf9a60065b 84 #define MAC_RF_RX_ON 1
kadonotakashi 0:8fdf9a60065b 85 #define MAC_RF_TX_ON 2
kadonotakashi 0:8fdf9a60065b 86 #define MAC_RF_ED_SCAN 3
kadonotakashi 0:8fdf9a60065b 87
kadonotakashi 0:8fdf9a60065b 88 static int8_t rf_radio_driver_id = -1;
kadonotakashi 0:8fdf9a60065b 89
kadonotakashi 0:8fdf9a60065b 90 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel);
kadonotakashi 0:8fdf9a60065b 91 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol);
kadonotakashi 0:8fdf9a60065b 92 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr);
kadonotakashi 0:8fdf9a60065b 93 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr);
kadonotakashi 0:8fdf9a60065b 94
kadonotakashi 0:8fdf9a60065b 95 static void rf_mac_hw_init(void);
kadonotakashi 0:8fdf9a60065b 96 static void rf_mac_timers_disable_trig_event(void);
kadonotakashi 0:8fdf9a60065b 97 static void rf_mac_reset(void);
kadonotakashi 0:8fdf9a60065b 98 static void rf_mac_rx_enable(void);
kadonotakashi 0:8fdf9a60065b 99 static void rf_mac_ed_state_enable(void);
kadonotakashi 0:8fdf9a60065b 100 static uint8_t rf_mac_convert_rssi(uint8_t scale);
kadonotakashi 0:8fdf9a60065b 101 static int8_t rf_mac_get_rssi(void);
kadonotakashi 0:8fdf9a60065b 102 static void rf_mac_set_rx_on_state(bool enable);
kadonotakashi 0:8fdf9a60065b 103 static void rf_mac_write(uint8_t *data_ptr, uint8_t length);
kadonotakashi 0:8fdf9a60065b 104
kadonotakashi 0:8fdf9a60065b 105 static void rf_mac_set_pending(uint8_t status);
kadonotakashi 0:8fdf9a60065b 106
kadonotakashi 0:8fdf9a60065b 107 static void rf_mac_set_shortAddress(uint8_t* valueAddress);
kadonotakashi 0:8fdf9a60065b 108 static void rf_mac_set_panId(uint8_t* valueAddress);
kadonotakashi 0:8fdf9a60065b 109 static void rf_mac_set_mac64(const uint8_t* valueAddress);
kadonotakashi 0:8fdf9a60065b 110
kadonotakashi 0:8fdf9a60065b 111 static void rf_mac_get_mac64(uint8_t* valueAddress);
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 static int8_t set_channel(uint8_t channel);
kadonotakashi 0:8fdf9a60065b 114 static void handle_IRQ_events(void);
kadonotakashi 0:8fdf9a60065b 115
kadonotakashi 0:8fdf9a60065b 116 static uint8_t MAC64_addr_default[8] = {1, 2, 3, 4, 5, 6, 7, 8};
kadonotakashi 0:8fdf9a60065b 117 static uint8_t MAC64_addr[8];
kadonotakashi 0:8fdf9a60065b 118
kadonotakashi 0:8fdf9a60065b 119 static uint8_t rf_mac_state = MAC_RF_TRX_OFF;
kadonotakashi 0:8fdf9a60065b 120 static bool rf_ack_pending_state = false;
kadonotakashi 0:8fdf9a60065b 121 static bool rf_mac_ack_requsted = false;
kadonotakashi 0:8fdf9a60065b 122 static uint8_t rf_mac_handle;
kadonotakashi 0:8fdf9a60065b 123 volatile uint8_t rf_ed_value = 0;
kadonotakashi 0:8fdf9a60065b 124
kadonotakashi 0:8fdf9a60065b 125 static NanostackRfPhyNcs36510 *rf = NULL;
kadonotakashi 0:8fdf9a60065b 126
kadonotakashi 0:8fdf9a60065b 127 #define MAC_PACKET_SIZE 127 //MAX MAC payload is 127 bytes
kadonotakashi 0:8fdf9a60065b 128 static uint8_t PHYPAYLOAD[MAC_PACKET_SIZE];
kadonotakashi 0:8fdf9a60065b 129
kadonotakashi 0:8fdf9a60065b 130 //TODO: verify these values
kadonotakashi 0:8fdf9a60065b 131 const phy_rf_channel_configuration_s phy_2_4ghz = {2405000000U, 5000000U, 250000U, 16U, M_OQPSK};
kadonotakashi 0:8fdf9a60065b 132
kadonotakashi 0:8fdf9a60065b 133 const phy_device_channel_page_s phy_channel_pages[] = {
kadonotakashi 0:8fdf9a60065b 134 {CHANNEL_PAGE_0, &phy_2_4ghz},
kadonotakashi 0:8fdf9a60065b 135 {CHANNEL_PAGE_0, NULL}
kadonotakashi 0:8fdf9a60065b 136 };
kadonotakashi 0:8fdf9a60065b 137
kadonotakashi 0:8fdf9a60065b 138 static phy_device_driver_s device_driver = {
kadonotakashi 0:8fdf9a60065b 139 PHY_LINK_15_4_2_4GHZ_TYPE,
kadonotakashi 0:8fdf9a60065b 140 PHY_LAYER_PAYLOAD_DATA_FLOW,
kadonotakashi 0:8fdf9a60065b 141 MAC64_addr,
kadonotakashi 0:8fdf9a60065b 142 PHY_MTU_SIZE,
kadonotakashi 0:8fdf9a60065b 143 (char*)"ON Semi ncs36510",
kadonotakashi 0:8fdf9a60065b 144 CRC_LENGTH,
kadonotakashi 0:8fdf9a60065b 145 PHY_HEADER_LENGTH,
kadonotakashi 0:8fdf9a60065b 146 &rf_interface_state_control,
kadonotakashi 0:8fdf9a60065b 147 &rf_start_cca,
kadonotakashi 0:8fdf9a60065b 148 &rf_address_write,
kadonotakashi 0:8fdf9a60065b 149 &rf_extension,
kadonotakashi 0:8fdf9a60065b 150 phy_channel_pages,
kadonotakashi 0:8fdf9a60065b 151 NULL,
kadonotakashi 0:8fdf9a60065b 152 NULL,
kadonotakashi 0:8fdf9a60065b 153 NULL,
kadonotakashi 0:8fdf9a60065b 154 NULL
kadonotakashi 0:8fdf9a60065b 155 };
kadonotakashi 0:8fdf9a60065b 156
kadonotakashi 0:8fdf9a60065b 157 static void rf_thread_loop()
kadonotakashi 0:8fdf9a60065b 158 {
kadonotakashi 0:8fdf9a60065b 159 for (;;) {
kadonotakashi 0:8fdf9a60065b 160 osEvent event = rf_thread.signal_wait(0);
kadonotakashi 0:8fdf9a60065b 161 if (event.status != osEventSignal) {
kadonotakashi 0:8fdf9a60065b 162 continue;
kadonotakashi 0:8fdf9a60065b 163 }
kadonotakashi 0:8fdf9a60065b 164
kadonotakashi 0:8fdf9a60065b 165 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 166 if (event.value.signals & SIGNAL_COUNT_RADIO) {
kadonotakashi 0:8fdf9a60065b 167 handle_IRQ_events();
kadonotakashi 0:8fdf9a60065b 168 }
kadonotakashi 0:8fdf9a60065b 169 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 170 NVIC_ClearPendingIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 171 NVIC_EnableIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 172 }
kadonotakashi 0:8fdf9a60065b 173 }
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175 static int8_t rf_device_register(void)
kadonotakashi 0:8fdf9a60065b 176 {
kadonotakashi 0:8fdf9a60065b 177 if( rf_radio_driver_id < 0 ) {
kadonotakashi 0:8fdf9a60065b 178
kadonotakashi 0:8fdf9a60065b 179 rf_mac_hw_init();
kadonotakashi 0:8fdf9a60065b 180 /**
kadonotakashi 0:8fdf9a60065b 181 * Read factory stored Mac address to RAM
kadonotakashi 0:8fdf9a60065b 182 */
kadonotakashi 0:8fdf9a60065b 183 common_write_32_bit(MACHWREG->LONG_ADDRESS_HIGH, MAC64_addr);
kadonotakashi 0:8fdf9a60065b 184 common_write_32_bit(MACHWREG->LONG_ADDRESS_LOW, MAC64_addr + 4);
kadonotakashi 0:8fdf9a60065b 185 rf_radio_driver_id = arm_net_phy_register(&device_driver);
kadonotakashi 0:8fdf9a60065b 186 }
kadonotakashi 0:8fdf9a60065b 187
kadonotakashi 0:8fdf9a60065b 188 return rf_radio_driver_id;
kadonotakashi 0:8fdf9a60065b 189 }
kadonotakashi 0:8fdf9a60065b 190
kadonotakashi 0:8fdf9a60065b 191 static void rf_device_unregister(void)
kadonotakashi 0:8fdf9a60065b 192 {
kadonotakashi 0:8fdf9a60065b 193 arm_net_phy_unregister(rf_radio_driver_id);
kadonotakashi 0:8fdf9a60065b 194 }
kadonotakashi 0:8fdf9a60065b 195
kadonotakashi 0:8fdf9a60065b 196 void rf_read_mac_address(uint8_t *address_ptr)
kadonotakashi 0:8fdf9a60065b 197 {
kadonotakashi 0:8fdf9a60065b 198 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 199 rf_mac_get_mac64(address_ptr);
kadonotakashi 0:8fdf9a60065b 200 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 201 }
kadonotakashi 0:8fdf9a60065b 202
kadonotakashi 0:8fdf9a60065b 203 int8_t rf_read_random(void)
kadonotakashi 0:8fdf9a60065b 204 {
kadonotakashi 0:8fdf9a60065b 205 //TODO: Read random from randomizer
kadonotakashi 0:8fdf9a60065b 206 return 1;
kadonotakashi 0:8fdf9a60065b 207 }
kadonotakashi 0:8fdf9a60065b 208
kadonotakashi 0:8fdf9a60065b 209 void rf_set_mac_address(const uint8_t *ptr)
kadonotakashi 0:8fdf9a60065b 210 {
kadonotakashi 0:8fdf9a60065b 211 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 212 rf_mac_set_mac64(ptr);
kadonotakashi 0:8fdf9a60065b 213 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 214 }
kadonotakashi 0:8fdf9a60065b 215
kadonotakashi 0:8fdf9a60065b 216 static void rf_mac_set_pending(uint8_t status) {
kadonotakashi 0:8fdf9a60065b 217
kadonotakashi 0:8fdf9a60065b 218 if (status) {
kadonotakashi 0:8fdf9a60065b 219 MACHWREG->OPTIONS.BITS.TFPO = 0;
kadonotakashi 0:8fdf9a60065b 220 MACHWREG->OPTIONS.BITS.TFP = 1;
kadonotakashi 0:8fdf9a60065b 221 rf_ack_pending_state = true;
kadonotakashi 0:8fdf9a60065b 222 } else {
kadonotakashi 0:8fdf9a60065b 223 rf_ack_pending_state = false;
kadonotakashi 0:8fdf9a60065b 224 MACHWREG->OPTIONS.BITS.TFPO = 0;
kadonotakashi 0:8fdf9a60065b 225 MACHWREG->OPTIONS.BITS.TFP = 0;
kadonotakashi 0:8fdf9a60065b 226 }
kadonotakashi 0:8fdf9a60065b 227 }
kadonotakashi 0:8fdf9a60065b 228
kadonotakashi 0:8fdf9a60065b 229 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
kadonotakashi 0:8fdf9a60065b 230 {
kadonotakashi 0:8fdf9a60065b 231 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 232 switch(new_state){
kadonotakashi 0:8fdf9a60065b 233 case PHY_INTERFACE_RESET: { /**< Reset PHY driver and set to idle. */
kadonotakashi 0:8fdf9a60065b 234 rf_mac_set_rx_on_state(false);
kadonotakashi 0:8fdf9a60065b 235 break;
kadonotakashi 0:8fdf9a60065b 236 }
kadonotakashi 0:8fdf9a60065b 237 case PHY_INTERFACE_DOWN: { /**< Disable PHY interface driver (RF radio disable). */
kadonotakashi 0:8fdf9a60065b 238 rf_mac_set_rx_on_state(false);
kadonotakashi 0:8fdf9a60065b 239 break;
kadonotakashi 0:8fdf9a60065b 240 }
kadonotakashi 0:8fdf9a60065b 241 case PHY_INTERFACE_UP: { /**< Enable PHY interface driver (RF radio receiver ON). */
kadonotakashi 0:8fdf9a60065b 242 set_channel(rf_channel);
kadonotakashi 0:8fdf9a60065b 243 rf_mac_set_rx_on_state(true);
kadonotakashi 0:8fdf9a60065b 244
kadonotakashi 0:8fdf9a60065b 245 break;
kadonotakashi 0:8fdf9a60065b 246 }
kadonotakashi 0:8fdf9a60065b 247 case PHY_INTERFACE_RX_ENERGY_STATE: { /**< Enable wirless interface ED scan mode. */
kadonotakashi 0:8fdf9a60065b 248 rf_ed_value = 0;
kadonotakashi 0:8fdf9a60065b 249 set_channel(rf_channel);
kadonotakashi 0:8fdf9a60065b 250 rf_mac_set_rx_on_state(false);
kadonotakashi 0:8fdf9a60065b 251 rf_mac_ed_state_enable();
kadonotakashi 0:8fdf9a60065b 252 break;
kadonotakashi 0:8fdf9a60065b 253 }
kadonotakashi 0:8fdf9a60065b 254 case PHY_INTERFACE_SNIFFER_STATE: {
kadonotakashi 0:8fdf9a60065b 255 set_channel(rf_channel);
kadonotakashi 0:8fdf9a60065b 256 rf_mac_set_rx_on_state(true);
kadonotakashi 0:8fdf9a60065b 257 break;
kadonotakashi 0:8fdf9a60065b 258 }
kadonotakashi 0:8fdf9a60065b 259 }
kadonotakashi 0:8fdf9a60065b 260 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 261 return 0;
kadonotakashi 0:8fdf9a60065b 262 }
kadonotakashi 0:8fdf9a60065b 263
kadonotakashi 0:8fdf9a60065b 264 static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
kadonotakashi 0:8fdf9a60065b 265 {
kadonotakashi 0:8fdf9a60065b 266 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 267 (void)data_protocol;
kadonotakashi 0:8fdf9a60065b 268 rf_mac_handle = tx_handle;
kadonotakashi 0:8fdf9a60065b 269 rf_mac_write(data_ptr, data_length);
kadonotakashi 0:8fdf9a60065b 270 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 271 return 0;
kadonotakashi 0:8fdf9a60065b 272 }
kadonotakashi 0:8fdf9a60065b 273
kadonotakashi 0:8fdf9a60065b 274 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
kadonotakashi 0:8fdf9a60065b 275 {
kadonotakashi 0:8fdf9a60065b 276 int ret_value = 0;
kadonotakashi 0:8fdf9a60065b 277 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 278 switch (address_type) {
kadonotakashi 0:8fdf9a60065b 279 case PHY_MAC_64BIT: /**< RF/PLC link layer address. */
kadonotakashi 0:8fdf9a60065b 280 rf_mac_set_mac64(address_ptr);
kadonotakashi 0:8fdf9a60065b 281 break;
kadonotakashi 0:8fdf9a60065b 282 case PHY_MAC_16BIT: /**< RF interface short address. */
kadonotakashi 0:8fdf9a60065b 283 rf_mac_set_shortAddress(address_ptr);
kadonotakashi 0:8fdf9a60065b 284 break;
kadonotakashi 0:8fdf9a60065b 285 case PHY_MAC_PANID: /**< RF interface 16-Bit PAN-ID. */
kadonotakashi 0:8fdf9a60065b 286 rf_mac_set_panId(address_ptr);
kadonotakashi 0:8fdf9a60065b 287 break;
kadonotakashi 0:8fdf9a60065b 288 default:
kadonotakashi 0:8fdf9a60065b 289 ret_value = -1;
kadonotakashi 0:8fdf9a60065b 290 }
kadonotakashi 0:8fdf9a60065b 291 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 292
kadonotakashi 0:8fdf9a60065b 293 return ret_value;
kadonotakashi 0:8fdf9a60065b 294 }
kadonotakashi 0:8fdf9a60065b 295
kadonotakashi 0:8fdf9a60065b 296 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
kadonotakashi 0:8fdf9a60065b 297 {
kadonotakashi 0:8fdf9a60065b 298 int ret_value = 0;
kadonotakashi 0:8fdf9a60065b 299 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 300 switch (extension_type) {
kadonotakashi 0:8fdf9a60065b 301 case PHY_EXTENSION_CTRL_PENDING_BIT: /**< Control MAC pending bit for indirect data. */
kadonotakashi 0:8fdf9a60065b 302 rf_mac_set_pending(*data_ptr);
kadonotakashi 0:8fdf9a60065b 303 break;
kadonotakashi 0:8fdf9a60065b 304 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: /**< Read status if the last ACK is still pending. */
kadonotakashi 0:8fdf9a60065b 305 *data_ptr = rf_ack_pending_state;
kadonotakashi 0:8fdf9a60065b 306 break;
kadonotakashi 0:8fdf9a60065b 307 case PHY_EXTENSION_SET_CHANNEL: /**< Net library channel set. */
kadonotakashi 0:8fdf9a60065b 308 return set_channel(*data_ptr);
kadonotakashi 0:8fdf9a60065b 309
kadonotakashi 0:8fdf9a60065b 310 case PHY_EXTENSION_READ_CHANNEL_ENERGY: /**< RF interface ED scan energy read. */
kadonotakashi 0:8fdf9a60065b 311 *data_ptr = rf_ed_value;
kadonotakashi 0:8fdf9a60065b 312 break;
kadonotakashi 0:8fdf9a60065b 313
kadonotakashi 0:8fdf9a60065b 314 case PHY_EXTENSION_READ_LINK_STATUS: /**< Net library could read link status. */
kadonotakashi 0:8fdf9a60065b 315 case PHY_EXTENSION_CONVERT_SIGNAL_INFO: /**< Convert signal info. */
kadonotakashi 0:8fdf9a60065b 316 default:
kadonotakashi 0:8fdf9a60065b 317 ret_value = -1;
kadonotakashi 0:8fdf9a60065b 318 }
kadonotakashi 0:8fdf9a60065b 319 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 320
kadonotakashi 0:8fdf9a60065b 321 return ret_value;
kadonotakashi 0:8fdf9a60065b 322 }
kadonotakashi 0:8fdf9a60065b 323
kadonotakashi 0:8fdf9a60065b 324 static int8_t set_channel(uint8_t channel)
kadonotakashi 0:8fdf9a60065b 325 {
kadonotakashi 0:8fdf9a60065b 326 if( channel > 10 && channel < 27 ){
kadonotakashi 0:8fdf9a60065b 327 fRfAnaIoctl(SET_RF_CHANNEL, &channel);
kadonotakashi 0:8fdf9a60065b 328 return 0;
kadonotakashi 0:8fdf9a60065b 329 }
kadonotakashi 0:8fdf9a60065b 330 return -1;
kadonotakashi 0:8fdf9a60065b 331 }
kadonotakashi 0:8fdf9a60065b 332
kadonotakashi 0:8fdf9a60065b 333
kadonotakashi 0:8fdf9a60065b 334 /**
kadonotakashi 0:8fdf9a60065b 335 * SET MAC 16 address to Register
kadonotakashi 0:8fdf9a60065b 336 */
kadonotakashi 0:8fdf9a60065b 337 static void rf_mac_set_shortAddress(uint8_t* valueAddress) {
kadonotakashi 0:8fdf9a60065b 338 MACHWREG->SHORT_ADDRESS = common_read_16_bit(valueAddress);
kadonotakashi 0:8fdf9a60065b 339 }
kadonotakashi 0:8fdf9a60065b 340
kadonotakashi 0:8fdf9a60065b 341 /**
kadonotakashi 0:8fdf9a60065b 342 * SET PAN-ID to Register
kadonotakashi 0:8fdf9a60065b 343 */
kadonotakashi 0:8fdf9a60065b 344 static void rf_mac_set_panId(uint8_t* valueAddress) {
kadonotakashi 0:8fdf9a60065b 345 MACHWREG->PANID = common_read_16_bit(valueAddress);
kadonotakashi 0:8fdf9a60065b 346 }
kadonotakashi 0:8fdf9a60065b 347
kadonotakashi 0:8fdf9a60065b 348 /**
kadonotakashi 0:8fdf9a60065b 349 * SET MAC64 address to register
kadonotakashi 0:8fdf9a60065b 350 */
kadonotakashi 0:8fdf9a60065b 351 static void rf_mac_set_mac64(const uint8_t* valueAddress) {
kadonotakashi 0:8fdf9a60065b 352 MACHWREG->LONG_ADDRESS_HIGH = common_read_32_bit(valueAddress);
kadonotakashi 0:8fdf9a60065b 353 valueAddress += 4;
kadonotakashi 0:8fdf9a60065b 354 MACHWREG->LONG_ADDRESS_LOW = common_read_32_bit(valueAddress);
kadonotakashi 0:8fdf9a60065b 355 }
kadonotakashi 0:8fdf9a60065b 356
kadonotakashi 0:8fdf9a60065b 357 static void rf_mac_get_mac64(uint8_t* valueAddress) {
kadonotakashi 0:8fdf9a60065b 358 valueAddress = common_write_32_bit(MACHWREG->LONG_ADDRESS_HIGH, valueAddress);
kadonotakashi 0:8fdf9a60065b 359 common_write_32_bit(MACHWREG->LONG_ADDRESS_LOW, valueAddress);
kadonotakashi 0:8fdf9a60065b 360 }
kadonotakashi 0:8fdf9a60065b 361
kadonotakashi 0:8fdf9a60065b 362 static void rf_mac_timers_disable_trig_event(void) {
kadonotakashi 0:8fdf9a60065b 363 MACHWREG->TIMER_DISABLE.BITS.START = true;
kadonotakashi 0:8fdf9a60065b 364 MACHWREG->TIMER_DISABLE.BITS.STOP = true;
kadonotakashi 0:8fdf9a60065b 365 MACHWREG->SEQ_OPTIONS.BITS.NOW = true;
kadonotakashi 0:8fdf9a60065b 366 }
kadonotakashi 0:8fdf9a60065b 367
kadonotakashi 0:8fdf9a60065b 368 /**
kadonotakashi 0:8fdf9a60065b 369 * Call this only One time
kadonotakashi 0:8fdf9a60065b 370 */
kadonotakashi 0:8fdf9a60065b 371 static void rf_mac_hw_init(void) {
kadonotakashi 0:8fdf9a60065b 372 uint32_t periphClockfrequency;
kadonotakashi 0:8fdf9a60065b 373 uint8_t lutIndex;
kadonotakashi 0:8fdf9a60065b 374 volatile uint8_t *pMatchReg = MACMATCHREG;
kadonotakashi 0:8fdf9a60065b 375
kadonotakashi 0:8fdf9a60065b 376 /** Initialize rf peripheral */
kadonotakashi 0:8fdf9a60065b 377 fRfAnaInit();
kadonotakashi 0:8fdf9a60065b 378
kadonotakashi 0:8fdf9a60065b 379 /** Enable mac clock */
kadonotakashi 0:8fdf9a60065b 380 CLOCK_ENABLE(CLOCK_MACHW);
kadonotakashi 0:8fdf9a60065b 381
kadonotakashi 0:8fdf9a60065b 382 /** Disable and clear IRQs */
kadonotakashi 0:8fdf9a60065b 383 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_NONE;
kadonotakashi 0:8fdf9a60065b 384 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_ALL;
kadonotakashi 0:8fdf9a60065b 385 NVIC_ClearPendingIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 386
kadonotakashi 0:8fdf9a60065b 387 /** Set sequence options */
kadonotakashi 0:8fdf9a60065b 388 MACHWREG->SEQ_OPTIONS.BITS.MODE = 0x1;
kadonotakashi 0:8fdf9a60065b 389 MACHWREG->SEQ_OPTIONS.BITS.NOACK = false;
kadonotakashi 0:8fdf9a60065b 390 MACHWREG->SEQ_OPTIONS.BITS.NOW = true;
kadonotakashi 0:8fdf9a60065b 391 MACHWREG->SEQ_OPTIONS.BITS.PRM = false;
kadonotakashi 0:8fdf9a60065b 392
kadonotakashi 0:8fdf9a60065b 393 MACHWREG->SEQ_OPTIONS.BITS.ACK_ENABLE = false;
kadonotakashi 0:8fdf9a60065b 394 MACHWREG->SEQ_OPTIONS.BITS.RES_ENABLE = false;
kadonotakashi 0:8fdf9a60065b 395
kadonotakashi 0:8fdf9a60065b 396 /** Set clocks */
kadonotakashi 0:8fdf9a60065b 397 periphClockfrequency = fClockGetPeriphClockfrequency();
kadonotakashi 0:8fdf9a60065b 398 MACHWREG->DIVIDER.BITS.BIT_CLOCK_DIVIDER = (periphClockfrequency / 250000) - 1;
kadonotakashi 0:8fdf9a60065b 399 MACHWREG->DIVIDER.BITS.SYSTEM_CLOCK_DIVIDER = (periphClockfrequency / 1000000) - 1;
kadonotakashi 0:8fdf9a60065b 400 MACHWREG->DIVIDER.BITS.CHIP_CLOCK_DIVIDER = (periphClockfrequency / 2000000) - 1;
kadonotakashi 0:8fdf9a60065b 401
kadonotakashi 0:8fdf9a60065b 402 /** Set miscellaneous */
kadonotakashi 0:8fdf9a60065b 403
kadonotakashi 0:8fdf9a60065b 404 /** This value should be tuned tuned to hit tx sw ack window (192us-204us) */
kadonotakashi 0:8fdf9a60065b 405 MACHWREG->RX_TX_WARMPUPS.BITS.TRANSMIT_WARMPUP = 0x16;
kadonotakashi 0:8fdf9a60065b 406
kadonotakashi 0:8fdf9a60065b 407 /** This value is selected to allocate 1 bit margin between tr sw ack and tx sw ack */
kadonotakashi 0:8fdf9a60065b 408 MACHWREG->RX_TX_WARMPUPS.BITS.RECEIVE_WARMPUP = 0x15;
kadonotakashi 0:8fdf9a60065b 409
kadonotakashi 0:8fdf9a60065b 410 MACHWREG->TXCCA = 0x30;
kadonotakashi 0:8fdf9a60065b 411 MACHWREG->CCA.BITS.CCA_LENGTH = 0x43;
kadonotakashi 0:8fdf9a60065b 412 MACHWREG->CCA.BITS.CCA_DELAY = 0x26;
kadonotakashi 0:8fdf9a60065b 413 MACHWREG->TX_ACK_DELAY = 0x21;
kadonotakashi 0:8fdf9a60065b 414 MACHWREG->ACK_STOP.BITS.RXACK_END = 0xA8;
kadonotakashi 0:8fdf9a60065b 415 MACHWREG->SLOT_OFFSET.WORD = 0x00070007;
kadonotakashi 0:8fdf9a60065b 416 MACHWREG->TX_LENGTH.BITS.TX_PRE_CHIPS = 0x6;
kadonotakashi 0:8fdf9a60065b 417 MACHWREG->TX_FLUSH = 0x00000008; /** Transmit flush duration (8 x 4us = 32 us) */
kadonotakashi 0:8fdf9a60065b 418
kadonotakashi 0:8fdf9a60065b 419 /** Set AGC */
kadonotakashi 0:8fdf9a60065b 420 MACHWREG->AGC_CONTROL.WORD = 0x00000007; // AGC enabled / AGC freeze enabled / Preamble detection mode
kadonotakashi 0:8fdf9a60065b 421
kadonotakashi 0:8fdf9a60065b 422 /** It is unclear from design specification if a 16MHz is mandatory for AGC operations or only to build
kadonotakashi 0:8fdf9a60065b 423 * settle and measurements delays */
kadonotakashi 0:8fdf9a60065b 424 if (periphClockfrequency == CPU_CLOCK_ROOT_HZ) {
kadonotakashi 0:8fdf9a60065b 425 /** AGC time unit = T(PCLK) x 2 = 16MHz period */
kadonotakashi 0:8fdf9a60065b 426 MACHWREG->AGC_SETTINGS.BITS.DIVIDER = 1;
kadonotakashi 0:8fdf9a60065b 427 /** settle delay = (value + 1) * AGC time unit = 500ns targeted */
kadonotakashi 0:8fdf9a60065b 428 MACHWREG->AGC_SETTINGS.BITS.SETTLE_DELAY = 7;
kadonotakashi 0:8fdf9a60065b 429 /** measurement delay = (value + 1) * AGC time unit = 1500ns targeted */
kadonotakashi 0:8fdf9a60065b 430 MACHWREG->AGC_SETTINGS.BITS.MEASURE_DELAY = 0x17;
kadonotakashi 0:8fdf9a60065b 431 } else {
kadonotakashi 0:8fdf9a60065b 432 /** AGC time unit is T(PCLK) */
kadonotakashi 0:8fdf9a60065b 433 MACHWREG->AGC_SETTINGS.BITS.DIVIDER = 0;
kadonotakashi 0:8fdf9a60065b 434 /** settle delay = (value + 1) * AGC time unit = 500ns targeted */
kadonotakashi 0:8fdf9a60065b 435 MACHWREG->AGC_SETTINGS.BITS.SETTLE_DELAY = (16 / CPU_CLOCK_DIV) - 1;
kadonotakashi 0:8fdf9a60065b 436 /** measurement delay = (value + 1) * AGC time unit = 1500ns targeted */
kadonotakashi 0:8fdf9a60065b 437 MACHWREG->AGC_SETTINGS.BITS.MEASURE_DELAY = (48 / CPU_CLOCK_DIV) - 1;
kadonotakashi 0:8fdf9a60065b 438 }
kadonotakashi 0:8fdf9a60065b 439
kadonotakashi 0:8fdf9a60065b 440 /** AGC high threshold: 3dB below the clipping level */
kadonotakashi 0:8fdf9a60065b 441 MACHWREG->AGC_SETTINGS.BITS.HIGH_THRESHOLD = 1;
kadonotakashi 0:8fdf9a60065b 442 /** AGC low threshold: 9dB below the high threshold */
kadonotakashi 0:8fdf9a60065b 443 MACHWREG->AGC_SETTINGS.BITS.LOW_THRESHOLD = 0;
kadonotakashi 0:8fdf9a60065b 444
kadonotakashi 0:8fdf9a60065b 445 /** Set Demodulator */
kadonotakashi 0:8fdf9a60065b 446 DMDREG->DMD_CONTROL0.WORD = 0x7FFF0004;
kadonotakashi 0:8fdf9a60065b 447 MACHWREG->SHORT_ADDRESS = 0x0000ffff;
kadonotakashi 0:8fdf9a60065b 448 MACHWREG->PANID = 0x0000ffff;
kadonotakashi 0:8fdf9a60065b 449
kadonotakashi 0:8fdf9a60065b 450 /** Reset macHw peripheral */
kadonotakashi 0:8fdf9a60065b 451 rf_mac_reset();
kadonotakashi 0:8fdf9a60065b 452
kadonotakashi 0:8fdf9a60065b 453 /** Initialise LUT RAM */
kadonotakashi 0:8fdf9a60065b 454 for (lutIndex=0;lutIndex<96;lutIndex++) {
kadonotakashi 0:8fdf9a60065b 455 *(pMatchReg + lutIndex) = 0xFF;
kadonotakashi 0:8fdf9a60065b 456 }
kadonotakashi 0:8fdf9a60065b 457 osStatus status = rf_thread.start(mbed::callback(rf_thread_loop));
kadonotakashi 0:8fdf9a60065b 458 MBED_ASSERT(status == osOK);
kadonotakashi 0:8fdf9a60065b 459
kadonotakashi 0:8fdf9a60065b 460 /** Clear and enable MAC IRQ at task level, when scheduler is on. */
kadonotakashi 0:8fdf9a60065b 461 NVIC_ClearPendingIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 462 NVIC_EnableIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 463 }
kadonotakashi 0:8fdf9a60065b 464
kadonotakashi 0:8fdf9a60065b 465 static void rf_mac_set_rx_on_state(bool enable) {
kadonotakashi 0:8fdf9a60065b 466 /** Abort ongoing sequence */
kadonotakashi 0:8fdf9a60065b 467 rf_mac_reset();
kadonotakashi 0:8fdf9a60065b 468 /** Start rx if requested */
kadonotakashi 0:8fdf9a60065b 469 if (enable) {
kadonotakashi 0:8fdf9a60065b 470 /** Set requested filtering */
kadonotakashi 0:8fdf9a60065b 471 MACHWREG->SEQ_OPTIONS.BITS.BEA_ENABLE = true;
kadonotakashi 0:8fdf9a60065b 472 MACHWREG->SEQ_OPTIONS.BITS.DATA_ENABLE = true;
kadonotakashi 0:8fdf9a60065b 473 MACHWREG->SEQ_OPTIONS.BITS.CMD_ENABLE = true;
kadonotakashi 0:8fdf9a60065b 474 /** Start receiver */
kadonotakashi 0:8fdf9a60065b 475 rf_mac_rx_enable();
kadonotakashi 0:8fdf9a60065b 476 }
kadonotakashi 0:8fdf9a60065b 477 }
kadonotakashi 0:8fdf9a60065b 478
kadonotakashi 0:8fdf9a60065b 479 static void rf_mac_write(uint8_t *data_ptr, uint8_t length) {
kadonotakashi 0:8fdf9a60065b 480 uint8_t i;
kadonotakashi 0:8fdf9a60065b 481 volatile uint8_t *txRam = MACTXREG;
kadonotakashi 0:8fdf9a60065b 482
kadonotakashi 0:8fdf9a60065b 483 /* This is not make sense but... */
kadonotakashi 0:8fdf9a60065b 484 rf_mac_reset();
kadonotakashi 0:8fdf9a60065b 485
kadonotakashi 0:8fdf9a60065b 486 /* Set tx state */
kadonotakashi 0:8fdf9a60065b 487 rf_mac_state = MAC_RF_TX_ON;
kadonotakashi 0:8fdf9a60065b 488
kadonotakashi 0:8fdf9a60065b 489 if (*data_ptr & 0x20) {
kadonotakashi 0:8fdf9a60065b 490 MACHWREG->SEQ_OPTIONS.BITS.ACK_ENABLE = true;
kadonotakashi 0:8fdf9a60065b 491 } else {
kadonotakashi 0:8fdf9a60065b 492 MACHWREG->SEQ_OPTIONS.BITS.ACK_ENABLE = false;
kadonotakashi 0:8fdf9a60065b 493 }
kadonotakashi 0:8fdf9a60065b 494 rf_mac_ack_requsted = MACHWREG->SEQ_OPTIONS.BITS.ACK_ENABLE;
kadonotakashi 0:8fdf9a60065b 495
kadonotakashi 0:8fdf9a60065b 496 /* Set data length */
kadonotakashi 0:8fdf9a60065b 497 MACHWREG->TX_LENGTH.BITS.TXLENGTH = length + 2;
kadonotakashi 0:8fdf9a60065b 498
kadonotakashi 0:8fdf9a60065b 499 *txRam++ = *data_ptr++;
kadonotakashi 0:8fdf9a60065b 500 *txRam++ = *data_ptr++;
kadonotakashi 0:8fdf9a60065b 501 *txRam++ = *data_ptr;
kadonotakashi 0:8fdf9a60065b 502 //RR: Retransmission for Data request should have same DSN
kadonotakashi 0:8fdf9a60065b 503 MACHWREG->TX_SEQ_NUMBER = *data_ptr++;
kadonotakashi 0:8fdf9a60065b 504 for (i = 3; i < length; i++) {
kadonotakashi 0:8fdf9a60065b 505 *txRam++ = *data_ptr++;
kadonotakashi 0:8fdf9a60065b 506 }
kadonotakashi 0:8fdf9a60065b 507
kadonotakashi 0:8fdf9a60065b 508 MACHWREG->SEQ_OPTIONS.BITS.PRM = 0;
kadonotakashi 0:8fdf9a60065b 509
kadonotakashi 0:8fdf9a60065b 510 MACHWREG->SEQ_OPTIONS.BITS.NOACK = false;
kadonotakashi 0:8fdf9a60065b 511
kadonotakashi 0:8fdf9a60065b 512 rf_mac_state = MAC_RF_TX_ON;
kadonotakashi 0:8fdf9a60065b 513
kadonotakashi 0:8fdf9a60065b 514 /* Start CCA immediately */
kadonotakashi 0:8fdf9a60065b 515 rf_mac_timers_disable_trig_event();
kadonotakashi 0:8fdf9a60065b 516
kadonotakashi 0:8fdf9a60065b 517 while (MACHWREG->TIMER != 0x0) MACHWREG->TIMER = 0x0; // HW ISSUE: field is not set immediately
kadonotakashi 0:8fdf9a60065b 518
kadonotakashi 0:8fdf9a60065b 519 /* Enable tx irq, reset protocol timer and start tx sequence */
kadonotakashi 0:8fdf9a60065b 520 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 521 MACHWREG->SEQUENCER = MAC_SEQUENCE_TX;
kadonotakashi 0:8fdf9a60065b 522
kadonotakashi 0:8fdf9a60065b 523 }
kadonotakashi 0:8fdf9a60065b 524
kadonotakashi 0:8fdf9a60065b 525
kadonotakashi 0:8fdf9a60065b 526 static void rf_mac_ed_state_enable(void) {
kadonotakashi 0:8fdf9a60065b 527 rf_mac_state = MAC_RF_ED_SCAN;
kadonotakashi 0:8fdf9a60065b 528 /** Enable Energy scan state and event complete interrupt */
kadonotakashi 0:8fdf9a60065b 529 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 530 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 531 MACHWREG->SEQUENCER = MAC_SEQUENCE_ED;
kadonotakashi 0:8fdf9a60065b 532 }
kadonotakashi 0:8fdf9a60065b 533
kadonotakashi 0:8fdf9a60065b 534
kadonotakashi 0:8fdf9a60065b 535 static void rf_mac_rx_enable(void) {
kadonotakashi 0:8fdf9a60065b 536 rf_mac_state = MAC_RF_RX_ON;
kadonotakashi 0:8fdf9a60065b 537
kadonotakashi 0:8fdf9a60065b 538 /** Enable rx irqs, reset protocol timer and start rx sequence */
kadonotakashi 0:8fdf9a60065b 539 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_COMPLETE | MAC_IRQ_FRAME_MATCH | MAC_IRQ_DATA;
kadonotakashi 0:8fdf9a60065b 540 while (MACHWREG->TIMER != 0x0) MACHWREG->TIMER = 0x0; // HW ISSUE: field is not set immediately
kadonotakashi 0:8fdf9a60065b 541 MACHWREG->SEQUENCER = MAC_SEQUENCE_RX;
kadonotakashi 0:8fdf9a60065b 542 return;
kadonotakashi 0:8fdf9a60065b 543 }
kadonotakashi 0:8fdf9a60065b 544
kadonotakashi 0:8fdf9a60065b 545
kadonotakashi 0:8fdf9a60065b 546 static void rf_mac_reset(void) {
kadonotakashi 0:8fdf9a60065b 547 uint32_t macHwDivider;
kadonotakashi 0:8fdf9a60065b 548
kadonotakashi 0:8fdf9a60065b 549 /** Recommended abort sequence (with synchronous reset) */
kadonotakashi 0:8fdf9a60065b 550
kadonotakashi 0:8fdf9a60065b 551 /** 1. Set clock divider to minimum (for single clock response) */
kadonotakashi 0:8fdf9a60065b 552 macHwDivider = MACHWREG->DIVIDER.WORD;
kadonotakashi 0:8fdf9a60065b 553 /** (to cope with protocol timer and ed REVB silicon issues it is required
kadonotakashi 0:8fdf9a60065b 554 * to set protocol timer to 1 and not to 0 as suggested in macHw specification) */
kadonotakashi 0:8fdf9a60065b 555 /* PK !!!MAC_REVD RevB -> RevD change list Item 25: protocol timer */
kadonotakashi 0:8fdf9a60065b 556 MACHWREG->DIVIDER.WORD = 1;
kadonotakashi 0:8fdf9a60065b 557
kadonotakashi 0:8fdf9a60065b 558 /** 2. Disable interrupts */
kadonotakashi 0:8fdf9a60065b 559 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_NONE;
kadonotakashi 0:8fdf9a60065b 560
kadonotakashi 0:8fdf9a60065b 561 /** 3. Clear interrupts */
kadonotakashi 0:8fdf9a60065b 562 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_ALL;
kadonotakashi 0:8fdf9a60065b 563
kadonotakashi 0:8fdf9a60065b 564 NVIC_ClearPendingIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 565
kadonotakashi 0:8fdf9a60065b 566 /** 4. Clear previous sequence type (write no-op sequence) */
kadonotakashi 0:8fdf9a60065b 567 MACHWREG->SEQUENCER = MAC_SEQUENCE_NOP;
kadonotakashi 0:8fdf9a60065b 568
kadonotakashi 0:8fdf9a60065b 569 /** 5. Move all MAC state machines to idle state (on, with synchronous reset) */
kadonotakashi 0:8fdf9a60065b 570 MACHWREG->CONTROL.WORD = 0x00000003;
kadonotakashi 0:8fdf9a60065b 571
kadonotakashi 0:8fdf9a60065b 572 /** 6. Release reset */
kadonotakashi 0:8fdf9a60065b 573 MACHWREG->CONTROL.WORD = 0x00000002;
kadonotakashi 0:8fdf9a60065b 574
kadonotakashi 0:8fdf9a60065b 575 /** 7. Disable start, stop timers */
kadonotakashi 0:8fdf9a60065b 576 rf_mac_timers_disable_trig_event();
kadonotakashi 0:8fdf9a60065b 577
kadonotakashi 0:8fdf9a60065b 578 /** 8. Return clock dividers to original value */
kadonotakashi 0:8fdf9a60065b 579 MACHWREG->DIVIDER.WORD = macHwDivider;
kadonotakashi 0:8fdf9a60065b 580
kadonotakashi 0:8fdf9a60065b 581 MACHWREG->SEQ_OPTIONS.BITS.BEA_ENABLE = False;
kadonotakashi 0:8fdf9a60065b 582 MACHWREG->SEQ_OPTIONS.BITS.DATA_ENABLE = False;
kadonotakashi 0:8fdf9a60065b 583 MACHWREG->SEQ_OPTIONS.BITS.CMD_ENABLE = False;
kadonotakashi 0:8fdf9a60065b 584
kadonotakashi 0:8fdf9a60065b 585 /** Set MAC_HW state */
kadonotakashi 0:8fdf9a60065b 586 rf_mac_state = MAC_RF_TRX_OFF;
kadonotakashi 0:8fdf9a60065b 587 }
kadonotakashi 0:8fdf9a60065b 588
kadonotakashi 0:8fdf9a60065b 589 static uint8_t rf_mac_convert_rssi(uint8_t scale) {
kadonotakashi 0:8fdf9a60065b 590 /* RSSI Value: The value is captured at the end of packet reception or at the end of ED/CCA
kadonotakashi 0:8fdf9a60065b 591 * measurements and is interpreted in dBm as follows:
kadonotakashi 0:8fdf9a60065b 592 * 1xxxxxxx: not used
kadonotakashi 0:8fdf9a60065b 593 * 01111111: 0 dBm (or above)
kadonotakashi 0:8fdf9a60065b 594 * 01111110: -1 dBm
kadonotakashi 0:8fdf9a60065b 595 * 01111101: -2 dBm
kadonotakashi 0:8fdf9a60065b 596 * -
kadonotakashi 0:8fdf9a60065b 597 * 00000010: -125 dBm
kadonotakashi 0:8fdf9a60065b 598 * 00000001: -126 dBm
kadonotakashi 0:8fdf9a60065b 599 * 00000000: -127 dBm (or below)
kadonotakashi 0:8fdf9a60065b 600 */
kadonotakashi 0:8fdf9a60065b 601
kadonotakashi 0:8fdf9a60065b 602 /* check rssi is well in spec range */
kadonotakashi 0:8fdf9a60065b 603 //ASSERT ((DMDREG->DMD_STATUS.BITS.RSSI_VALUE & 0x80) != 0x80);
kadonotakashi 0:8fdf9a60065b 604 if (DMDREG->DMD_STATUS.BITS.RSSI_VALUE & 0x80) {
kadonotakashi 0:8fdf9a60065b 605 return 0;
kadonotakashi 0:8fdf9a60065b 606 }
kadonotakashi 0:8fdf9a60065b 607
kadonotakashi 0:8fdf9a60065b 608 /* convert rssi in sign char: translate 01111111 into 0 and following alike, make negative */
kadonotakashi 0:8fdf9a60065b 609 signed char rssi_value = -1 * (DMDREG->DMD_STATUS.BITS.RSSI_VALUE ^ 0x7F);
kadonotakashi 0:8fdf9a60065b 610
kadonotakashi 0:8fdf9a60065b 611 if (scale == MAC_RSSI_TO_ED ) {
kadonotakashi 0:8fdf9a60065b 612 /**
kadonotakashi 0:8fdf9a60065b 613 * For ED (IEEE 6.9.7) "The ED result shall be reported to the MLME as an 8 bit integer
kadonotakashi 0:8fdf9a60065b 614 * ranging from 0x00 to 0xff. The minimum ED value (zero) shall indicate received power less than 10 dB
kadonotakashi 0:8fdf9a60065b 615 * above the specified receiver sensitivity (see 6.5.3.3 and 6.6.3.4), and the range of received power spanned by
kadonotakashi 0:8fdf9a60065b 616 * the ED values shall be at least 40 dB. Within this range, the mapping from the received power in decibels to
kadonotakashi 0:8fdf9a60065b 617 * ED value shall be linear with an accuracy of � 6 dB."
kadonotakashi 0:8fdf9a60065b 618 * (-85dBm receiver sensitivity will be targeted => zero ED value is associated to -75dBm)
kadonotakashi 0:8fdf9a60065b 619 * (span will have 51dBm range from 0x0=-75dBm to 0xff=-24dBm)
kadonotakashi 0:8fdf9a60065b 620 */
kadonotakashi 0:8fdf9a60065b 621
kadonotakashi 0:8fdf9a60065b 622 /* Clip maximal and minimal rssi value reported by ED */
kadonotakashi 0:8fdf9a60065b 623 if (rssi_value < -75) rssi_value = -75;
kadonotakashi 0:8fdf9a60065b 624 if (rssi_value > -24) rssi_value = -24;
kadonotakashi 0:8fdf9a60065b 625
kadonotakashi 0:8fdf9a60065b 626 /* scale the span -75dBm --> -24dBm to 0x00 --> 0xFF
kadonotakashi 0:8fdf9a60065b 627 * Attention: This scaling implies that granularity of the result is changing from 1dBm per unit to 1/5 dBm per unit
kadonotakashi 0:8fdf9a60065b 628 * 0xFF: -24 dBm (or above)
kadonotakashi 0:8fdf9a60065b 629 * 0xFE - 0xFB: (impossible code)
kadonotakashi 0:8fdf9a60065b 630 * 0xFA: -25 dBm
kadonotakashi 0:8fdf9a60065b 631 * 0xF9 - 0xF6: (impossible code)
kadonotakashi 0:8fdf9a60065b 632 * 0xF5: -26 dBm
kadonotakashi 0:8fdf9a60065b 633 * ...
kadonotakashi 0:8fdf9a60065b 634 * 0x05: -74 dBm
kadonotakashi 0:8fdf9a60065b 635 * 0x01 - 0x04: (impossible code)
kadonotakashi 0:8fdf9a60065b 636 * 0x00: -75 dBm (or below)
kadonotakashi 0:8fdf9a60065b 637 */
kadonotakashi 0:8fdf9a60065b 638 return (rssi_value + 75) * 5;
kadonotakashi 0:8fdf9a60065b 639 } else {
kadonotakashi 0:8fdf9a60065b 640
kadonotakashi 0:8fdf9a60065b 641 /**
kadonotakashi 0:8fdf9a60065b 642 * For LQI: (IEEE 6.9.7) "The LQI measurement shall be performed for each received packet, and the result shall be reported to the
kadonotakashi 0:8fdf9a60065b 643 * MAC sublayer using PD-DATA.indication (see 6.2.1.3) as an integer ranging from 0x00 to 0xff. The
kadonotakashi 0:8fdf9a60065b 644 * minimum and maximum LQI values (0x00 and 0xff) should be associated with the lowest and highest
kadonotakashi 0:8fdf9a60065b 645 * quality compliant signals detectable by the receiver, and LQI values in between should be uniformly
kadonotakashi 0:8fdf9a60065b 646 * distributed between these two limits. At least eight unique values of LQI shall be used."
kadonotakashi 0:8fdf9a60065b 647 * (-85dBm sensitivity will be targeted => zero LQI value will be associated to -85dBm)
kadonotakashi 0:8fdf9a60065b 648 * (span will have 64dBm range from 0x0=-85dBm to 0xff=-21dBm)
kadonotakashi 0:8fdf9a60065b 649 */
kadonotakashi 0:8fdf9a60065b 650
kadonotakashi 0:8fdf9a60065b 651 /* Clip maximal and minimal rssi value reported by LQI */
kadonotakashi 0:8fdf9a60065b 652 if (rssi_value < -85) rssi_value = -85;
kadonotakashi 0:8fdf9a60065b 653 if (rssi_value > -21) rssi_value = -21;
kadonotakashi 0:8fdf9a60065b 654
kadonotakashi 0:8fdf9a60065b 655 /* scale the span -85dBm --> -21,25dBm to 0x00 --> 0xFF
kadonotakashi 0:8fdf9a60065b 656 * Attention: This scaling implies that granularity of the result is changing from 1dBm per unit to 1/4 dBm per unit
kadonotakashi 0:8fdf9a60065b 657 * 0xFF: -21,25 dBm (or above)
kadonotakashi 0:8fdf9a60065b 658 * 0xFE: (impossible code)
kadonotakashi 0:8fdf9a60065b 659 * 0xFD: (impossible code)
kadonotakashi 0:8fdf9a60065b 660 * 0xFC: -22 dBm
kadonotakashi 0:8fdf9a60065b 661 * 0xFB: (impossible code)
kadonotakashi 0:8fdf9a60065b 662 * 0xFA: (impossible code)
kadonotakashi 0:8fdf9a60065b 663 * 0xF9: (impossible code)
kadonotakashi 0:8fdf9a60065b 664 * 0xF8: -23 dBm
kadonotakashi 0:8fdf9a60065b 665 * ...
kadonotakashi 0:8fdf9a60065b 666 * 0x05: (impossible code)
kadonotakashi 0:8fdf9a60065b 667 * 0x04: - 84dBm
kadonotakashi 0:8fdf9a60065b 668 * 0x03: (impossible code)
kadonotakashi 0:8fdf9a60065b 669 * 0x02: (impossible code)
kadonotakashi 0:8fdf9a60065b 670 * 0x01: (impossible code)
kadonotakashi 0:8fdf9a60065b 671 * 0x00: - 85dBm
kadonotakashi 0:8fdf9a60065b 672 */
kadonotakashi 0:8fdf9a60065b 673 if (rssi_value == -21)
kadonotakashi 0:8fdf9a60065b 674 return ((rssi_value + 85) * 4) - 1;
kadonotakashi 0:8fdf9a60065b 675 else
kadonotakashi 0:8fdf9a60065b 676 return (rssi_value + 85) * 4;
kadonotakashi 0:8fdf9a60065b 677 }
kadonotakashi 0:8fdf9a60065b 678 }
kadonotakashi 0:8fdf9a60065b 679
kadonotakashi 0:8fdf9a60065b 680 static int8_t rf_mac_get_rssi(void) {
kadonotakashi 0:8fdf9a60065b 681 int8_t rssi_value = -1 * (DMDREG->DMD_STATUS.BITS.RSSI_VALUE ^ 0x7F);
kadonotakashi 0:8fdf9a60065b 682 return rssi_value;
kadonotakashi 0:8fdf9a60065b 683 }
kadonotakashi 0:8fdf9a60065b 684
kadonotakashi 0:8fdf9a60065b 685 static void rf_rx_ed_scan_interrupt() {
kadonotakashi 0:8fdf9a60065b 686 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 687 if (MACHWREG->STATUS.BITS.CODE == MAC_STATUS_SUCCESS) {
kadonotakashi 0:8fdf9a60065b 688 uint8_t ed = rf_mac_convert_rssi(MAC_RSSI_TO_ED);
kadonotakashi 0:8fdf9a60065b 689 if (ed) {
kadonotakashi 0:8fdf9a60065b 690 if (ed > rf_ed_value) {
kadonotakashi 0:8fdf9a60065b 691 rf_ed_value = ed;
kadonotakashi 0:8fdf9a60065b 692 }
kadonotakashi 0:8fdf9a60065b 693 }
kadonotakashi 0:8fdf9a60065b 694 }
kadonotakashi 0:8fdf9a60065b 695
kadonotakashi 0:8fdf9a60065b 696 MACHWREG->MASK_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 697 MACHWREG->SEQUENCER = MAC_SEQUENCE_ED;
kadonotakashi 0:8fdf9a60065b 698 }
kadonotakashi 0:8fdf9a60065b 699
kadonotakashi 0:8fdf9a60065b 700 static void rf_rx_interrupt() {
kadonotakashi 0:8fdf9a60065b 701 // Frame match is used for association and data frames
kadonotakashi 0:8fdf9a60065b 702 uint8_t seqSts = MACHWREG->STATUS.BITS.CODE;
kadonotakashi 0:8fdf9a60065b 703
kadonotakashi 0:8fdf9a60065b 704 if (MACHWREG->IRQ_STATUS.BITS.FM) {
kadonotakashi 0:8fdf9a60065b 705 if (!rf_ack_pending_state) {
kadonotakashi 0:8fdf9a60065b 706 MACHWREG->OPTIONS.BITS.TFP = 0;
kadonotakashi 0:8fdf9a60065b 707 MACHWREG->OPTIONS.BITS.TFPO = 1;
kadonotakashi 0:8fdf9a60065b 708 } else {
kadonotakashi 0:8fdf9a60065b 709 MACHWREG->OPTIONS.BITS.TFP = 1;
kadonotakashi 0:8fdf9a60065b 710 MACHWREG->OPTIONS.BITS.TFPO = 1;
kadonotakashi 0:8fdf9a60065b 711 }
kadonotakashi 0:8fdf9a60065b 712
kadonotakashi 0:8fdf9a60065b 713 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_FRAME_MATCH;
kadonotakashi 0:8fdf9a60065b 714 return;
kadonotakashi 0:8fdf9a60065b 715 }
kadonotakashi 0:8fdf9a60065b 716
kadonotakashi 0:8fdf9a60065b 717 /** RR: Process the event complete IRQ */
kadonotakashi 0:8fdf9a60065b 718 if (MACHWREG->IRQ_STATUS.BITS.EC || MACHWREG->IRQ_STATUS.BITS.DATA) {
kadonotakashi 0:8fdf9a60065b 719 /** Clear the event */
kadonotakashi 0:8fdf9a60065b 720 if (MACHWREG->IRQ_STATUS.BITS.EC) {
kadonotakashi 0:8fdf9a60065b 721 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 722 }
kadonotakashi 0:8fdf9a60065b 723
kadonotakashi 0:8fdf9a60065b 724 if (MACHWREG->IRQ_STATUS.BITS.DATA) {
kadonotakashi 0:8fdf9a60065b 725 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_DATA;
kadonotakashi 0:8fdf9a60065b 726 }
kadonotakashi 0:8fdf9a60065b 727
kadonotakashi 0:8fdf9a60065b 728 /** Build frame (containing received frame or timeout) */
kadonotakashi 0:8fdf9a60065b 729
kadonotakashi 0:8fdf9a60065b 730 volatile uint8_t *rxRam = MACRXREG;
kadonotakashi 0:8fdf9a60065b 731 uint8_t length;
kadonotakashi 0:8fdf9a60065b 732 int8_t rssi;
kadonotakashi 0:8fdf9a60065b 733 uint8_t lqi;
kadonotakashi 0:8fdf9a60065b 734
kadonotakashi 0:8fdf9a60065b 735 /** Return directly in case of timeout */
kadonotakashi 0:8fdf9a60065b 736 if (seqSts == MAC_STATUS_TIMEOUT) {
kadonotakashi 0:8fdf9a60065b 737 /* Initialize frame status */
kadonotakashi 0:8fdf9a60065b 738 return;
kadonotakashi 0:8fdf9a60065b 739 }
kadonotakashi 0:8fdf9a60065b 740
kadonotakashi 0:8fdf9a60065b 741 length = *rxRam++;
kadonotakashi 0:8fdf9a60065b 742 if (length < 5){
kadonotakashi 0:8fdf9a60065b 743 rf_mac_rx_enable();
kadonotakashi 0:8fdf9a60065b 744 return;
kadonotakashi 0:8fdf9a60065b 745 }
kadonotakashi 0:8fdf9a60065b 746 length -= 2; //Cut CRC OUT
kadonotakashi 0:8fdf9a60065b 747
kadonotakashi 0:8fdf9a60065b 748 /* Initialize frame status */
kadonotakashi 0:8fdf9a60065b 749 for (uint8_t i=0; i < length; i++) {
kadonotakashi 0:8fdf9a60065b 750 PHYPAYLOAD[i] = *rxRam++;
kadonotakashi 0:8fdf9a60065b 751 }
kadonotakashi 0:8fdf9a60065b 752
kadonotakashi 0:8fdf9a60065b 753 lqi = rf_mac_convert_rssi(MAC_RSSI_TO_LQI);
kadonotakashi 0:8fdf9a60065b 754 rssi = rf_mac_get_rssi();
kadonotakashi 0:8fdf9a60065b 755 rf_mac_rx_enable();
kadonotakashi 0:8fdf9a60065b 756 //Call ARM API
kadonotakashi 0:8fdf9a60065b 757 if( device_driver.phy_rx_cb ){
kadonotakashi 0:8fdf9a60065b 758 device_driver.phy_rx_cb(PHYPAYLOAD, length, lqi, rssi, rf_radio_driver_id);
kadonotakashi 0:8fdf9a60065b 759 }
kadonotakashi 0:8fdf9a60065b 760 }
kadonotakashi 0:8fdf9a60065b 761 }
kadonotakashi 0:8fdf9a60065b 762
kadonotakashi 0:8fdf9a60065b 763 static void rf_mac_tx_interrupt(void)
kadonotakashi 0:8fdf9a60065b 764 {
kadonotakashi 0:8fdf9a60065b 765 phy_link_tx_status_e status;
kadonotakashi 0:8fdf9a60065b 766 /** Clear the event complete IRQ */
kadonotakashi 0:8fdf9a60065b 767 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 768 /* This IRQ means that Data Request is complete; check the status */
kadonotakashi 0:8fdf9a60065b 769 uint8_t sharedSeqSts = MACHWREG->STATUS.BITS.CODE;
kadonotakashi 0:8fdf9a60065b 770
kadonotakashi 0:8fdf9a60065b 771 rf_mac_set_rx_on_state(true);
kadonotakashi 0:8fdf9a60065b 772
kadonotakashi 0:8fdf9a60065b 773 switch (sharedSeqSts) {
kadonotakashi 0:8fdf9a60065b 774 case MAC_STATUS_SUCCESS: /* Positive */
kadonotakashi 0:8fdf9a60065b 775 //SET Success
kadonotakashi 0:8fdf9a60065b 776 if (rf_mac_ack_requsted) {
kadonotakashi 0:8fdf9a60065b 777 status = PHY_LINK_TX_DONE;
kadonotakashi 0:8fdf9a60065b 778 } else {
kadonotakashi 0:8fdf9a60065b 779 status = PHY_LINK_TX_SUCCESS;
kadonotakashi 0:8fdf9a60065b 780 }
kadonotakashi 0:8fdf9a60065b 781 break;
kadonotakashi 0:8fdf9a60065b 782
kadonotakashi 0:8fdf9a60065b 783 case MAC_STATUS_RXACK_PENDING: /* Positive for broadcast */
kadonotakashi 0:8fdf9a60065b 784 status = PHY_LINK_TX_DONE_PENDING;
kadonotakashi 0:8fdf9a60065b 785 break;
kadonotakashi 0:8fdf9a60065b 786
kadonotakashi 0:8fdf9a60065b 787
kadonotakashi 0:8fdf9a60065b 788 case MAC_STATUS_BUSY:
kadonotakashi 0:8fdf9a60065b 789 status = PHY_LINK_CCA_FAIL;
kadonotakashi 0:8fdf9a60065b 790 break;
kadonotakashi 0:8fdf9a60065b 791
kadonotakashi 0:8fdf9a60065b 792 default:
kadonotakashi 0:8fdf9a60065b 793 status = PHY_LINK_TX_FAIL;
kadonotakashi 0:8fdf9a60065b 794 break;
kadonotakashi 0:8fdf9a60065b 795 }
kadonotakashi 0:8fdf9a60065b 796 rf_mac_ack_requsted = false;
kadonotakashi 0:8fdf9a60065b 797 //Call RX TX complete
kadonotakashi 0:8fdf9a60065b 798 if( device_driver.phy_tx_done_cb ) {
kadonotakashi 0:8fdf9a60065b 799 device_driver.phy_tx_done_cb(rf_radio_driver_id, rf_mac_handle, status, 1, 1);
kadonotakashi 0:8fdf9a60065b 800 }
kadonotakashi 0:8fdf9a60065b 801 }
kadonotakashi 0:8fdf9a60065b 802
kadonotakashi 0:8fdf9a60065b 803 /**
kadonotakashi 0:8fdf9a60065b 804 * RF MAC Interrupt handler
kadonotakashi 0:8fdf9a60065b 805 */
kadonotakashi 0:8fdf9a60065b 806 extern "C" void fIrqMacHwHandler(void)
kadonotakashi 0:8fdf9a60065b 807 {
kadonotakashi 0:8fdf9a60065b 808 NVIC_DisableIRQ(MacHw_IRQn);
kadonotakashi 0:8fdf9a60065b 809 rf_thread.signal_set(SIGNAL_COUNT_RADIO);
kadonotakashi 0:8fdf9a60065b 810 }
kadonotakashi 0:8fdf9a60065b 811
kadonotakashi 0:8fdf9a60065b 812 static void handle_IRQ_events(void)
kadonotakashi 0:8fdf9a60065b 813 {
kadonotakashi 0:8fdf9a60065b 814 /** Set MAC timers to initial state */
kadonotakashi 0:8fdf9a60065b 815 MACHWREG->TIMER_ENABLE.BITS.START = false;
kadonotakashi 0:8fdf9a60065b 816 MACHWREG->TIMER_ENABLE.BITS.STOP = false;
kadonotakashi 0:8fdf9a60065b 817 MACHWREG->TIMER_DISABLE.BITS.START = false;
kadonotakashi 0:8fdf9a60065b 818 MACHWREG->TIMER_DISABLE.BITS.STOP = false;
kadonotakashi 0:8fdf9a60065b 819
kadonotakashi 0:8fdf9a60065b 820 /** Disarm start/stop timers, disable and clear irq (event_complete) */
kadonotakashi 0:8fdf9a60065b 821 rf_mac_timers_disable_trig_event();
kadonotakashi 0:8fdf9a60065b 822 /** REVD changes to sequence tracking register. Sequence register can be used instead of rf_mac_state */
kadonotakashi 0:8fdf9a60065b 823
kadonotakashi 0:8fdf9a60065b 824 if (rf_mac_state == MAC_RF_RX_ON) {
kadonotakashi 0:8fdf9a60065b 825 rf_rx_interrupt();
kadonotakashi 0:8fdf9a60065b 826 } else if(rf_mac_state == MAC_RF_TX_ON) {
kadonotakashi 0:8fdf9a60065b 827 rf_mac_tx_interrupt();
kadonotakashi 0:8fdf9a60065b 828 } else if (rf_mac_state == MAC_RF_ED_SCAN){
kadonotakashi 0:8fdf9a60065b 829 rf_rx_ed_scan_interrupt();
kadonotakashi 0:8fdf9a60065b 830 } else {
kadonotakashi 0:8fdf9a60065b 831 /** Clear the event complete IRQ */
kadonotakashi 0:8fdf9a60065b 832 MACHWREG->CLEAR_IRQ.WORD = MAC_IRQ_COMPLETE;
kadonotakashi 0:8fdf9a60065b 833 uint8_t sharedSeqSts = MACHWREG->STATUS.BITS.CODE;
kadonotakashi 0:8fdf9a60065b 834 }
kadonotakashi 0:8fdf9a60065b 835 }
kadonotakashi 0:8fdf9a60065b 836
kadonotakashi 0:8fdf9a60065b 837 NanostackRfPhyNcs36510::NanostackRfPhyNcs36510()
kadonotakashi 0:8fdf9a60065b 838 {
kadonotakashi 0:8fdf9a60065b 839 memcpy(MAC64_addr, MAC64_addr_default, sizeof(MAC64_addr));
kadonotakashi 0:8fdf9a60065b 840 }
kadonotakashi 0:8fdf9a60065b 841
kadonotakashi 0:8fdf9a60065b 842 NanostackRfPhyNcs36510::~NanostackRfPhyNcs36510()
kadonotakashi 0:8fdf9a60065b 843 {
kadonotakashi 0:8fdf9a60065b 844 // Do nothing
kadonotakashi 0:8fdf9a60065b 845 }
kadonotakashi 0:8fdf9a60065b 846
kadonotakashi 0:8fdf9a60065b 847 int8_t NanostackRfPhyNcs36510::rf_register()
kadonotakashi 0:8fdf9a60065b 848 {
kadonotakashi 0:8fdf9a60065b 849 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 850
kadonotakashi 0:8fdf9a60065b 851 if (rf != NULL) {
kadonotakashi 0:8fdf9a60065b 852 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 853 error("Multiple registrations of NanostackRfPhyNcs36510 not supported");
kadonotakashi 0:8fdf9a60065b 854 return -1;
kadonotakashi 0:8fdf9a60065b 855 }
kadonotakashi 0:8fdf9a60065b 856
kadonotakashi 0:8fdf9a60065b 857 rf = this;
kadonotakashi 0:8fdf9a60065b 858 int8_t radio_id = rf_device_register();
kadonotakashi 0:8fdf9a60065b 859 if (radio_id < 0) {
kadonotakashi 0:8fdf9a60065b 860 rf = NULL;
kadonotakashi 0:8fdf9a60065b 861 }
kadonotakashi 0:8fdf9a60065b 862
kadonotakashi 0:8fdf9a60065b 863 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 864 return radio_id;
kadonotakashi 0:8fdf9a60065b 865 }
kadonotakashi 0:8fdf9a60065b 866
kadonotakashi 0:8fdf9a60065b 867 void NanostackRfPhyNcs36510::rf_unregister()
kadonotakashi 0:8fdf9a60065b 868 {
kadonotakashi 0:8fdf9a60065b 869 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 870
kadonotakashi 0:8fdf9a60065b 871 if (rf != this) {
kadonotakashi 0:8fdf9a60065b 872 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 873 return;
kadonotakashi 0:8fdf9a60065b 874 }
kadonotakashi 0:8fdf9a60065b 875
kadonotakashi 0:8fdf9a60065b 876 rf_device_unregister();
kadonotakashi 0:8fdf9a60065b 877 rf = NULL;
kadonotakashi 0:8fdf9a60065b 878
kadonotakashi 0:8fdf9a60065b 879 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 880 }
kadonotakashi 0:8fdf9a60065b 881
kadonotakashi 0:8fdf9a60065b 882 void NanostackRfPhyNcs36510::get_mac_address(uint8_t *mac)
kadonotakashi 0:8fdf9a60065b 883 {
kadonotakashi 0:8fdf9a60065b 884 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 885
kadonotakashi 0:8fdf9a60065b 886 memcpy((void*)mac, (void*)MAC64_addr, sizeof(MAC64_addr));
kadonotakashi 0:8fdf9a60065b 887
kadonotakashi 0:8fdf9a60065b 888 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 889 }
kadonotakashi 0:8fdf9a60065b 890
kadonotakashi 0:8fdf9a60065b 891 void NanostackRfPhyNcs36510::set_mac_address(uint8_t *mac)
kadonotakashi 0:8fdf9a60065b 892 {
kadonotakashi 0:8fdf9a60065b 893 platform_enter_critical();
kadonotakashi 0:8fdf9a60065b 894
kadonotakashi 0:8fdf9a60065b 895 if (NULL != rf) {
kadonotakashi 0:8fdf9a60065b 896 error("NanostackRfPhyNcs36510 cannot change mac address when running");
kadonotakashi 0:8fdf9a60065b 897 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 898 return;
kadonotakashi 0:8fdf9a60065b 899 }
kadonotakashi 0:8fdf9a60065b 900 memcpy((void*)MAC64_addr, (void*)mac, sizeof(MAC64_addr));
kadonotakashi 0:8fdf9a60065b 901
kadonotakashi 0:8fdf9a60065b 902 platform_exit_critical();
kadonotakashi 0:8fdf9a60065b 903 }
kadonotakashi 0:8fdf9a60065b 904
kadonotakashi 0:8fdf9a60065b 905 NanostackRfPhy &NanostackRfPhy::get_default_instance()
kadonotakashi 0:8fdf9a60065b 906 {
kadonotakashi 0:8fdf9a60065b 907 static NanostackRfPhyNcs36510 rf_phy;
kadonotakashi 0:8fdf9a60065b 908 return rf_phy;
kadonotakashi 0:8fdf9a60065b 909 }