observe fixes

Dependencies:   nsdl_lib Nanostack_lib

Fork of mbedEndpointNetwork by Michael Koster

Committer:
michaeljkoster
Date:
Thu Apr 23 02:57:56 2015 +0000
Revision:
10:da76961ba3e9
Parent:
6:f6288e89b02a
use prebuilt nsdl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:2a5a48a8b4d4 1 /*
ansond 0:2a5a48a8b4d4 2 * driverRFPhy.c
ansond 0:2a5a48a8b4d4 3 *
ansond 0:2a5a48a8b4d4 4 * Created on: 14 July 2014
ansond 0:2a5a48a8b4d4 5 * Author: mBed team
ansond 0:2a5a48a8b4d4 6 */
ansond 0:2a5a48a8b4d4 7 #include "arm_hal_interrupt.h"
ansond 0:2a5a48a8b4d4 8 #include "arm_hal_phy.h"
ansond 0:2a5a48a8b4d4 9 #include "driverRFPhy.h"
ansond 0:2a5a48a8b4d4 10 #include "driverAtmelRFInterface.h"
ansond 0:2a5a48a8b4d4 11 #include <string.h>
ansond 0:2a5a48a8b4d4 12
ansond 0:2a5a48a8b4d4 13 #include <stdio.h>
ansond 0:2a5a48a8b4d4 14
ansond 0:2a5a48a8b4d4 15 #include "configuration.h"
ansond 0:2a5a48a8b4d4 16
ansond 0:2a5a48a8b4d4 17 /*RF receive buffer*/
ansond 0:2a5a48a8b4d4 18 static uint8_t rf_buffer[RF_BUFFER_SIZE];
ansond 0:2a5a48a8b4d4 19 /*RF ACK receive buffer*/
ansond 0:2a5a48a8b4d4 20 static uint8_t ack_rx_buf[5];
ansond 0:2a5a48a8b4d4 21 /*ACK wait duration changes depending on data rate*/
ansond 0:2a5a48a8b4d4 22 static uint16_t rf_ack_wait_duration = RF_ACK_WAIT_TIMEOUT;
ansond 0:2a5a48a8b4d4 23
ansond 6:f6288e89b02a 24 // TUNABLES
ansond 6:f6288e89b02a 25 extern uint8_t rf_channel;
ansond 6:f6288e89b02a 26
ansond 0:2a5a48a8b4d4 27 static uint8_t radio_tx_power = 0x07;
ansond 0:2a5a48a8b4d4 28 static uint8_t rf_tuned = 1;
ansond 0:2a5a48a8b4d4 29 static uint8_t radio_rpc_value = 0xef;
ansond 0:2a5a48a8b4d4 30 static uint8_t rf_use_front_end = 0;
ansond 0:2a5a48a8b4d4 31 static uint8_t rf_use_antenna_diversity = 0;
ansond 0:2a5a48a8b4d4 32 static uint8_t rf_csd_port = 0;
ansond 0:2a5a48a8b4d4 33 static uint8_t rf_csd_pin = 0;
ansond 0:2a5a48a8b4d4 34 static uint8_t rf_cps_port = 0;
ansond 0:2a5a48a8b4d4 35 static uint8_t rf_cps_pin = 0;
ansond 0:2a5a48a8b4d4 36 static uint8_t tx_sequence = 0xff;
ansond 0:2a5a48a8b4d4 37 static uint8_t need_ack = 0;
ansond 0:2a5a48a8b4d4 38 static uint8_t rf_rx_mode = 0;
ansond 0:2a5a48a8b4d4 39 static uint8_t rf_flags = 0;
ansond 0:2a5a48a8b4d4 40 static uint8_t rf_rnd_rssi = 0;
ansond 0:2a5a48a8b4d4 41 static int8_t rf_radio_driver_id = -1;
ansond 0:2a5a48a8b4d4 42 static phy_device_driver_s device_driver;
ansond 0:2a5a48a8b4d4 43 static uint8_t atmel_MAC[8];
ansond 0:2a5a48a8b4d4 44 static phy_device_channel_info_s channel_info;
ansond 0:2a5a48a8b4d4 45 static uint8_t mac_tx_handle = 0;
ansond 0:2a5a48a8b4d4 46
ansond 0:2a5a48a8b4d4 47 /*
ansond 0:2a5a48a8b4d4 48 * \brief Function sets given RF flag on.
ansond 0:2a5a48a8b4d4 49 *
ansond 0:2a5a48a8b4d4 50 * \param x Given RF flag
ansond 0:2a5a48a8b4d4 51 *
ansond 0:2a5a48a8b4d4 52 * \return none
ansond 0:2a5a48a8b4d4 53 */
ansond 0:2a5a48a8b4d4 54 void rf_flags_set(uint8_t x)
ansond 0:2a5a48a8b4d4 55 {
ansond 0:2a5a48a8b4d4 56 rf_flags |= x;
ansond 0:2a5a48a8b4d4 57 }
ansond 0:2a5a48a8b4d4 58
ansond 0:2a5a48a8b4d4 59 /*
ansond 0:2a5a48a8b4d4 60 * \brief Function clears given RF flag on.
ansond 0:2a5a48a8b4d4 61 *
ansond 0:2a5a48a8b4d4 62 * \param x Given RF flag
ansond 0:2a5a48a8b4d4 63 *
ansond 0:2a5a48a8b4d4 64 * \return none
ansond 0:2a5a48a8b4d4 65 */
ansond 0:2a5a48a8b4d4 66 void rf_flags_clear(uint8_t x)
ansond 0:2a5a48a8b4d4 67 {
ansond 0:2a5a48a8b4d4 68 rf_flags &= ~x;
ansond 0:2a5a48a8b4d4 69 }
ansond 0:2a5a48a8b4d4 70
ansond 0:2a5a48a8b4d4 71 /*
ansond 0:2a5a48a8b4d4 72 * \brief Function checks if given RF flag is on.
ansond 0:2a5a48a8b4d4 73 *
ansond 0:2a5a48a8b4d4 74 * \param x Given RF flag
ansond 0:2a5a48a8b4d4 75 *
ansond 0:2a5a48a8b4d4 76 * \return states of the given flags
ansond 0:2a5a48a8b4d4 77 */
ansond 0:2a5a48a8b4d4 78 uint8_t rf_flags_check(uint8_t x)
ansond 0:2a5a48a8b4d4 79 {
ansond 0:2a5a48a8b4d4 80 return (rf_flags & x);
ansond 0:2a5a48a8b4d4 81 }
ansond 0:2a5a48a8b4d4 82
ansond 0:2a5a48a8b4d4 83 /*
ansond 0:2a5a48a8b4d4 84 * \brief Function clears all RF flags.
ansond 0:2a5a48a8b4d4 85 *
ansond 0:2a5a48a8b4d4 86 * \param none
ansond 0:2a5a48a8b4d4 87 *
ansond 0:2a5a48a8b4d4 88 * \return none
ansond 0:2a5a48a8b4d4 89 */
ansond 0:2a5a48a8b4d4 90 void rf_flags_reset(void)
ansond 0:2a5a48a8b4d4 91 {
ansond 0:2a5a48a8b4d4 92 rf_flags = 0;
ansond 0:2a5a48a8b4d4 93 }
ansond 0:2a5a48a8b4d4 94
ansond 0:2a5a48a8b4d4 95 /*
ansond 0:2a5a48a8b4d4 96 * \brief Function sets CPS and CSD pins of the Front end.
ansond 0:2a5a48a8b4d4 97 *
ansond 0:2a5a48a8b4d4 98 * \param none
ansond 0:2a5a48a8b4d4 99 *
ansond 0:2a5a48a8b4d4 100 * \return none
ansond 0:2a5a48a8b4d4 101 */
ansond 0:2a5a48a8b4d4 102 void rf_front_end_rx_lna(void)
ansond 0:2a5a48a8b4d4 103 {
ansond 0:2a5a48a8b4d4 104 /* not supported in this version */
ansond 0:2a5a48a8b4d4 105 }
ansond 0:2a5a48a8b4d4 106
ansond 0:2a5a48a8b4d4 107 /*
ansond 0:2a5a48a8b4d4 108 * \brief Function clears CPS and CSD pins of the Front end.
ansond 0:2a5a48a8b4d4 109 *
ansond 0:2a5a48a8b4d4 110 * \param none
ansond 0:2a5a48a8b4d4 111 *
ansond 0:2a5a48a8b4d4 112 * \return none
ansond 0:2a5a48a8b4d4 113 */
ansond 0:2a5a48a8b4d4 114 void rf_front_end_sleep(void)
ansond 0:2a5a48a8b4d4 115 {
ansond 0:2a5a48a8b4d4 116 /* not supported in this version */
ansond 0:2a5a48a8b4d4 117 }
ansond 0:2a5a48a8b4d4 118
ansond 0:2a5a48a8b4d4 119 /*
ansond 0:2a5a48a8b4d4 120 * \brief Function initialises and registers the RF driver.
ansond 0:2a5a48a8b4d4 121 *
ansond 0:2a5a48a8b4d4 122 * \param none
ansond 0:2a5a48a8b4d4 123 *
ansond 0:2a5a48a8b4d4 124 * \return rf_radio_driver_id Driver ID given by NET library
ansond 0:2a5a48a8b4d4 125 */
ansond 0:2a5a48a8b4d4 126 int8_t rf_device_register(void)
ansond 0:2a5a48a8b4d4 127 {
ansond 0:2a5a48a8b4d4 128 rf_init();
ansond 0:2a5a48a8b4d4 129 /*Set pointer to MAC address*/
ansond 0:2a5a48a8b4d4 130 device_driver.PHY_MAC = atmel_MAC;
ansond 0:2a5a48a8b4d4 131 device_driver.driver_description = "ATMEL_MAC";
ansond 0:2a5a48a8b4d4 132 #if PHY_LINK_15_4_2_4GHZ_TYPE
ansond 0:2a5a48a8b4d4 133 /*Number of channels in PHY*/
ansond 0:2a5a48a8b4d4 134 channel_info.channel_count = 16;
ansond 0:2a5a48a8b4d4 135 /*Channel mask 26-11*/
ansond 0:2a5a48a8b4d4 136 channel_info.channel_mask = 0x07FFF800;
ansond 0:2a5a48a8b4d4 137 /*Type of RF PHY is SubGHz*/
ansond 0:2a5a48a8b4d4 138 device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE;
ansond 0:2a5a48a8b4d4 139 device_driver.link_channel_info = &channel_info;
ansond 0:2a5a48a8b4d4 140 #else
ansond 0:2a5a48a8b4d4 141 /*Number of channels in PHY*/
ansond 0:2a5a48a8b4d4 142 channel_info.channel_count = 11;
ansond 0:2a5a48a8b4d4 143 /*Channel mask 0-10*/
ansond 0:2a5a48a8b4d4 144 channel_info.channel_mask = 0x000007ff;
ansond 0:2a5a48a8b4d4 145 /*Type of RF PHY is SubGHz*/
ansond 0:2a5a48a8b4d4 146 device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
ansond 0:2a5a48a8b4d4 147 device_driver.link_channel_info = &channel_info;
ansond 0:2a5a48a8b4d4 148 #endif
ansond 0:2a5a48a8b4d4 149 /*Maximum size of payload is 127*/
ansond 0:2a5a48a8b4d4 150 device_driver.phy_MTU = 127;
ansond 0:2a5a48a8b4d4 151 /*No header in PHY*/
ansond 0:2a5a48a8b4d4 152 device_driver.phy_header_length = 0;
ansond 0:2a5a48a8b4d4 153 /*No tail in PHY*/
ansond 0:2a5a48a8b4d4 154 device_driver.phy_tail_length = 0;
ansond 0:2a5a48a8b4d4 155 /*Set address write function*/
ansond 0:2a5a48a8b4d4 156 device_driver.phy_xx_address_write = &rf_address_write;
ansond 0:2a5a48a8b4d4 157 /*Set RF extension function*/
ansond 0:2a5a48a8b4d4 158 device_driver.phy_xx_extension = &rf_extension;
ansond 0:2a5a48a8b4d4 159 /*Set RF state control function*/
ansond 0:2a5a48a8b4d4 160 device_driver.phy_xx_state_control = &rf_interface_state_control;
ansond 0:2a5a48a8b4d4 161 /*Set transmit function*/
ansond 0:2a5a48a8b4d4 162 device_driver.phy_xx_tx = &rf_start_cca;
ansond 0:2a5a48a8b4d4 163 printf("RF Device Registration...");
ansond 0:2a5a48a8b4d4 164 /*Register device driver*/
ansond 0:2a5a48a8b4d4 165 rf_radio_driver_id = arm_net_phy_register(&device_driver);
ansond 0:2a5a48a8b4d4 166 printf("OK\r\n");
ansond 0:2a5a48a8b4d4 167 return rf_radio_driver_id;
ansond 0:2a5a48a8b4d4 168 }
ansond 0:2a5a48a8b4d4 169
ansond 0:2a5a48a8b4d4 170 /*
ansond 0:2a5a48a8b4d4 171 * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator. This value was generated by reading noise from RF channel in RF initialisation.
ansond 0:2a5a48a8b4d4 172 *
ansond 0:2a5a48a8b4d4 173 * \param none
ansond 0:2a5a48a8b4d4 174 *
ansond 0:2a5a48a8b4d4 175 * \return random RSSI value
ansond 0:2a5a48a8b4d4 176 */
ansond 0:2a5a48a8b4d4 177 int8_t rf_read_random(void)
ansond 0:2a5a48a8b4d4 178 {
ansond 0:2a5a48a8b4d4 179 return rf_rnd_rssi;
ansond 0:2a5a48a8b4d4 180 }
ansond 0:2a5a48a8b4d4 181
ansond 0:2a5a48a8b4d4 182 /*
ansond 0:2a5a48a8b4d4 183 * \brief Function is a call back for ACK wait timeout.
ansond 0:2a5a48a8b4d4 184 *
ansond 0:2a5a48a8b4d4 185 * \param none
ansond 0:2a5a48a8b4d4 186 *
ansond 0:2a5a48a8b4d4 187 * \return none
ansond 0:2a5a48a8b4d4 188 */
ansond 0:2a5a48a8b4d4 189 void rf_ack_wait_timer_interrupt(void)
ansond 0:2a5a48a8b4d4 190 {
ansond 0:2a5a48a8b4d4 191 arm_enter_critical();
ansond 0:2a5a48a8b4d4 192 /*Force PLL state*/
ansond 0:2a5a48a8b4d4 193 rf_if_change_trx_state(FORCE_PLL_ON);
ansond 0:2a5a48a8b4d4 194 rf_poll_trx_state_change(PLL_ON);
ansond 0:2a5a48a8b4d4 195 /*Start receiver in RX_AACK_ON state*/
ansond 0:2a5a48a8b4d4 196 rf_rx_mode = 0;
ansond 0:2a5a48a8b4d4 197 rf_flags_clear(RFF_RX);
ansond 0:2a5a48a8b4d4 198 rf_receive();
ansond 0:2a5a48a8b4d4 199 arm_exit_critical();
ansond 0:2a5a48a8b4d4 200 }
ansond 0:2a5a48a8b4d4 201
ansond 0:2a5a48a8b4d4 202 /*
ansond 0:2a5a48a8b4d4 203 * \brief Function is a call back for calibration interval timer.
ansond 0:2a5a48a8b4d4 204 *
ansond 0:2a5a48a8b4d4 205 * \param none
ansond 0:2a5a48a8b4d4 206 *
ansond 0:2a5a48a8b4d4 207 * \return none
ansond 0:2a5a48a8b4d4 208 */
ansond 0:2a5a48a8b4d4 209 void rf_calibration_timer_interrupt(void)
ansond 0:2a5a48a8b4d4 210 {
ansond 0:2a5a48a8b4d4 211 /*Calibrate RF*/
ansond 0:2a5a48a8b4d4 212 rf_calibration_cb();
ansond 0:2a5a48a8b4d4 213 /*Start new calibration timeout*/
ansond 0:2a5a48a8b4d4 214 rf_calibration_timer_start(RF_CALIBRATION_INTERVAL);
ansond 0:2a5a48a8b4d4 215 }
ansond 0:2a5a48a8b4d4 216
ansond 0:2a5a48a8b4d4 217 /*
ansond 0:2a5a48a8b4d4 218 * \brief Function initialises the RF timer for ACK wait and calibration.
ansond 0:2a5a48a8b4d4 219 *
ansond 0:2a5a48a8b4d4 220 * \param none
ansond 0:2a5a48a8b4d4 221 *
ansond 0:2a5a48a8b4d4 222 * \return none
ansond 0:2a5a48a8b4d4 223 */
ansond 0:2a5a48a8b4d4 224 void rf_timer_init(void)
ansond 0:2a5a48a8b4d4 225 {
ansond 0:2a5a48a8b4d4 226 rf_if_timer_init();
ansond 0:2a5a48a8b4d4 227 }
ansond 0:2a5a48a8b4d4 228
ansond 0:2a5a48a8b4d4 229 /*
ansond 0:2a5a48a8b4d4 230 * \brief Function starts the ACK wait timeout.
ansond 0:2a5a48a8b4d4 231 *
ansond 0:2a5a48a8b4d4 232 * \param slots Given slots, resolution 50us
ansond 0:2a5a48a8b4d4 233 *
ansond 0:2a5a48a8b4d4 234 * \return none
ansond 0:2a5a48a8b4d4 235 */
ansond 0:2a5a48a8b4d4 236 void rf_ack_wait_timer_start(uint16_t slots)
ansond 0:2a5a48a8b4d4 237 {
ansond 0:2a5a48a8b4d4 238 rf_if_ack_wait_timer_start(slots);
ansond 0:2a5a48a8b4d4 239 }
ansond 0:2a5a48a8b4d4 240
ansond 0:2a5a48a8b4d4 241 /*
ansond 0:2a5a48a8b4d4 242 * \brief Function starts the calibration interval.
ansond 0:2a5a48a8b4d4 243 *
ansond 0:2a5a48a8b4d4 244 * \param slots Given slots, resolution 50us
ansond 0:2a5a48a8b4d4 245 *
ansond 0:2a5a48a8b4d4 246 * \return none
ansond 0:2a5a48a8b4d4 247 */
ansond 0:2a5a48a8b4d4 248 void rf_calibration_timer_start(uint32_t slots)
ansond 0:2a5a48a8b4d4 249 {
ansond 0:2a5a48a8b4d4 250 rf_if_calibration_timer_start(slots);
ansond 0:2a5a48a8b4d4 251 }
ansond 0:2a5a48a8b4d4 252
ansond 0:2a5a48a8b4d4 253 /*
ansond 0:2a5a48a8b4d4 254 * \brief Function stops the ACK wait timeout.
ansond 0:2a5a48a8b4d4 255 *
ansond 0:2a5a48a8b4d4 256 * \param none
ansond 0:2a5a48a8b4d4 257 *
ansond 0:2a5a48a8b4d4 258 * \return none
ansond 0:2a5a48a8b4d4 259 */
ansond 0:2a5a48a8b4d4 260 void rf_ack_wait_timer_stop(void)
ansond 0:2a5a48a8b4d4 261 {
ansond 0:2a5a48a8b4d4 262 rf_if_ack_wait_timer_stop();
ansond 0:2a5a48a8b4d4 263 }
ansond 0:2a5a48a8b4d4 264
ansond 0:2a5a48a8b4d4 265 /*
ansond 0:2a5a48a8b4d4 266 * \brief Function reads the MAC address array.
ansond 0:2a5a48a8b4d4 267 *
ansond 0:2a5a48a8b4d4 268 * \param ptr Pointer to read array
ansond 0:2a5a48a8b4d4 269 *
ansond 0:2a5a48a8b4d4 270 * \return none
ansond 0:2a5a48a8b4d4 271 */
ansond 0:2a5a48a8b4d4 272 void rf_read_mac_address(uint8_t *ptr)
ansond 0:2a5a48a8b4d4 273 {
ansond 0:2a5a48a8b4d4 274 memcpy(ptr, atmel_MAC, 8);
ansond 0:2a5a48a8b4d4 275 }
ansond 0:2a5a48a8b4d4 276
ansond 0:2a5a48a8b4d4 277 /*
ansond 0:2a5a48a8b4d4 278 * \brief Function sets the MAC address array.
ansond 0:2a5a48a8b4d4 279 *
ansond 0:2a5a48a8b4d4 280 * \param ptr Pointer to given MAC address array
ansond 0:2a5a48a8b4d4 281 *
ansond 0:2a5a48a8b4d4 282 * \return none
ansond 0:2a5a48a8b4d4 283 */
ansond 0:2a5a48a8b4d4 284 void rf_set_mac_address(const uint8_t *ptr)
ansond 0:2a5a48a8b4d4 285 {
ansond 0:2a5a48a8b4d4 286 memcpy(atmel_MAC,ptr,8);
ansond 0:2a5a48a8b4d4 287 }
ansond 0:2a5a48a8b4d4 288
ansond 0:2a5a48a8b4d4 289 /*
ansond 0:2a5a48a8b4d4 290 * \brief Function writes various RF settings in startup.
ansond 0:2a5a48a8b4d4 291 *
ansond 0:2a5a48a8b4d4 292 * \param none
ansond 0:2a5a48a8b4d4 293 *
ansond 0:2a5a48a8b4d4 294 * \return none
ansond 0:2a5a48a8b4d4 295 */
ansond 0:2a5a48a8b4d4 296 void rf_write_settings(void)
ansond 0:2a5a48a8b4d4 297 {
ansond 0:2a5a48a8b4d4 298 arm_enter_critical();
ansond 0:2a5a48a8b4d4 299
ansond 0:2a5a48a8b4d4 300 //printf("RF Write Settings: 1\r\n");
ansond 0:2a5a48a8b4d4 301 rf_if_write_rf_settings();
ansond 0:2a5a48a8b4d4 302
ansond 0:2a5a48a8b4d4 303 //printf("RF Write Settings: 2\r\n");
ansond 0:2a5a48a8b4d4 304 /*Set output power*/
ansond 0:2a5a48a8b4d4 305 rf_if_write_set_tx_power_register(radio_tx_power);
ansond 0:2a5a48a8b4d4 306
ansond 0:2a5a48a8b4d4 307 //printf("RF Write Settings: 3\r\n");
ansond 0:2a5a48a8b4d4 308 /*Set RPC register*/
ansond 0:2a5a48a8b4d4 309 rf_if_write_set_trx_rpc_register(radio_rpc_value);
ansond 0:2a5a48a8b4d4 310
ansond 0:2a5a48a8b4d4 311 //printf("RF Write Settings: 4\r\n");
ansond 0:2a5a48a8b4d4 312 /*Initialise Front end*/
ansond 0:2a5a48a8b4d4 313 if(rf_use_front_end)
ansond 0:2a5a48a8b4d4 314 {
ansond 0:2a5a48a8b4d4 315 printf("RF Front End used\r\n");
ansond 0:2a5a48a8b4d4 316 rf_if_enable_pa_ext();
ansond 0:2a5a48a8b4d4 317 /* not supported in this version */
ansond 0:2a5a48a8b4d4 318 }
ansond 0:2a5a48a8b4d4 319
ansond 0:2a5a48a8b4d4 320 //printf("RF Write Settings: 5\r\n");
ansond 0:2a5a48a8b4d4 321 /*Initialise Antenna Diversity*/
ansond 0:2a5a48a8b4d4 322 if(rf_use_antenna_diversity) {
ansond 0:2a5a48a8b4d4 323 printf("RF Antenna diversity\r\n");
ansond 0:2a5a48a8b4d4 324 rf_if_write_antenna_diversity_settings();
ansond 0:2a5a48a8b4d4 325 }
ansond 0:2a5a48a8b4d4 326
ansond 0:2a5a48a8b4d4 327 printf("RF Write Settings: 7\r\n");
ansond 0:2a5a48a8b4d4 328 arm_exit_critical();
ansond 0:2a5a48a8b4d4 329 printf("RF Write Settings End\r\n");
ansond 0:2a5a48a8b4d4 330 }
ansond 0:2a5a48a8b4d4 331
ansond 0:2a5a48a8b4d4 332 /*
ansond 0:2a5a48a8b4d4 333 * \brief Function writes 16-bit address in RF address filter.
ansond 0:2a5a48a8b4d4 334 *
ansond 0:2a5a48a8b4d4 335 * \param short_address Given short address
ansond 0:2a5a48a8b4d4 336 *
ansond 0:2a5a48a8b4d4 337 * \return none
ansond 0:2a5a48a8b4d4 338 */
ansond 0:2a5a48a8b4d4 339 void rf_set_short_adr(uint8_t * short_address)
ansond 0:2a5a48a8b4d4 340 {
ansond 0:2a5a48a8b4d4 341 uint8_t rf_off_flag = 0;
ansond 0:2a5a48a8b4d4 342 arm_enter_critical();
ansond 0:2a5a48a8b4d4 343 /*Wake up RF if sleeping*/
ansond 0:2a5a48a8b4d4 344 if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F)
ansond 0:2a5a48a8b4d4 345 {
ansond 0:2a5a48a8b4d4 346 rf_if_disable_slptr();
ansond 0:2a5a48a8b4d4 347 rf_off_flag = 1;
ansond 0:2a5a48a8b4d4 348 rf_poll_trx_state_change(TRX_OFF);
ansond 0:2a5a48a8b4d4 349 }
ansond 0:2a5a48a8b4d4 350 /*Write address filter registers*/
ansond 0:2a5a48a8b4d4 351 rf_if_write_short_addr_registers(short_address);
ansond 0:2a5a48a8b4d4 352 /*RF back to sleep*/
ansond 0:2a5a48a8b4d4 353 if(rf_off_flag)
ansond 0:2a5a48a8b4d4 354 rf_if_enable_slptr();
ansond 0:2a5a48a8b4d4 355 arm_exit_critical();
ansond 0:2a5a48a8b4d4 356 }
ansond 0:2a5a48a8b4d4 357
ansond 0:2a5a48a8b4d4 358 /*
ansond 0:2a5a48a8b4d4 359 * \brief Function writes PAN Id in RF PAN Id filter.
ansond 0:2a5a48a8b4d4 360 *
ansond 0:2a5a48a8b4d4 361 * \param pan_id Given PAN Id
ansond 0:2a5a48a8b4d4 362 *
ansond 0:2a5a48a8b4d4 363 * \return none
ansond 0:2a5a48a8b4d4 364 */
ansond 0:2a5a48a8b4d4 365 void rf_set_pan_id(uint8_t *pan_id)
ansond 0:2a5a48a8b4d4 366 {
ansond 0:2a5a48a8b4d4 367 uint8_t rf_off_flag = 0;
ansond 0:2a5a48a8b4d4 368
ansond 0:2a5a48a8b4d4 369 arm_enter_critical();
ansond 0:2a5a48a8b4d4 370 /*Wake up RF if sleeping*/
ansond 0:2a5a48a8b4d4 371 if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F)
ansond 0:2a5a48a8b4d4 372 {
ansond 0:2a5a48a8b4d4 373 rf_if_disable_slptr();
ansond 0:2a5a48a8b4d4 374 rf_off_flag = 1;
ansond 0:2a5a48a8b4d4 375 rf_poll_trx_state_change(TRX_OFF);
ansond 0:2a5a48a8b4d4 376 }
ansond 0:2a5a48a8b4d4 377 /*Write address filter registers*/
ansond 0:2a5a48a8b4d4 378 rf_if_write_pan_id_registers(pan_id);
ansond 0:2a5a48a8b4d4 379 /*RF back to sleep*/
ansond 0:2a5a48a8b4d4 380 if(rf_off_flag)
ansond 0:2a5a48a8b4d4 381 rf_if_enable_slptr();
ansond 0:2a5a48a8b4d4 382 arm_exit_critical();
ansond 0:2a5a48a8b4d4 383 }
ansond 0:2a5a48a8b4d4 384
ansond 0:2a5a48a8b4d4 385 /*
ansond 0:2a5a48a8b4d4 386 * \brief Function writes 64-bit address in RF address filter.
ansond 0:2a5a48a8b4d4 387 *
ansond 0:2a5a48a8b4d4 388 * \param address Given 64-bit address
ansond 0:2a5a48a8b4d4 389 *
ansond 0:2a5a48a8b4d4 390 * \return none
ansond 0:2a5a48a8b4d4 391 */
ansond 0:2a5a48a8b4d4 392 void rf_set_address(uint8_t *address)
ansond 0:2a5a48a8b4d4 393 {
ansond 0:2a5a48a8b4d4 394 uint8_t rf_off_flag = 0;
ansond 0:2a5a48a8b4d4 395
ansond 0:2a5a48a8b4d4 396 arm_enter_critical();
ansond 0:2a5a48a8b4d4 397 /*Wake up RF if sleeping*/
ansond 0:2a5a48a8b4d4 398 if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F)
ansond 0:2a5a48a8b4d4 399 {
ansond 0:2a5a48a8b4d4 400 rf_if_disable_slptr();
ansond 0:2a5a48a8b4d4 401 rf_off_flag = 1;
ansond 0:2a5a48a8b4d4 402 rf_poll_trx_state_change(TRX_OFF);
ansond 0:2a5a48a8b4d4 403 }
ansond 0:2a5a48a8b4d4 404 /*Write address filter registers*/
ansond 0:2a5a48a8b4d4 405 rf_if_write_ieee_addr_registers(address);
ansond 0:2a5a48a8b4d4 406 /*RF back to sleep*/
ansond 0:2a5a48a8b4d4 407 if(rf_off_flag)
ansond 0:2a5a48a8b4d4 408 rf_if_enable_slptr();
ansond 0:2a5a48a8b4d4 409
ansond 0:2a5a48a8b4d4 410 arm_exit_critical();
ansond 0:2a5a48a8b4d4 411 }
ansond 0:2a5a48a8b4d4 412
ansond 0:2a5a48a8b4d4 413 /*
ansond 0:2a5a48a8b4d4 414 * \brief Function sets the RF channel.
ansond 0:2a5a48a8b4d4 415 *
ansond 0:2a5a48a8b4d4 416 * \param ch New channel
ansond 0:2a5a48a8b4d4 417 *
ansond 0:2a5a48a8b4d4 418 * \return none
ansond 0:2a5a48a8b4d4 419 */
ansond 0:2a5a48a8b4d4 420 void rf_channel_set(uint8_t ch)
ansond 0:2a5a48a8b4d4 421 {
ansond 0:2a5a48a8b4d4 422 arm_enter_critical();
ansond 0:2a5a48a8b4d4 423 rf_channel = ch;
ansond 0:2a5a48a8b4d4 424 if(ch < 0x1f)
ansond 0:2a5a48a8b4d4 425 rf_if_set_channel_register(ch);
ansond 0:2a5a48a8b4d4 426 arm_exit_critical();
ansond 0:2a5a48a8b4d4 427 }
ansond 0:2a5a48a8b4d4 428
ansond 0:2a5a48a8b4d4 429
ansond 0:2a5a48a8b4d4 430 /*
ansond 0:2a5a48a8b4d4 431 * \brief Function initialises the radio driver and resets the radio.
ansond 0:2a5a48a8b4d4 432 *
ansond 0:2a5a48a8b4d4 433 * \param none
ansond 0:2a5a48a8b4d4 434 *
ansond 0:2a5a48a8b4d4 435 * \return none
ansond 0:2a5a48a8b4d4 436 */
ansond 0:2a5a48a8b4d4 437 void rf_init(void)
ansond 0:2a5a48a8b4d4 438 {
ansond 0:2a5a48a8b4d4 439 printf("RF Init Start\r\n");
ansond 0:2a5a48a8b4d4 440 /*Initialise timers*/
ansond 0:2a5a48a8b4d4 441 rf_timer_init(); //TODO
ansond 0:2a5a48a8b4d4 442 rf_channel = RF_DEFAULT_CHANNEL;
ansond 0:2a5a48a8b4d4 443 printf("RF Reset\r\n");
ansond 0:2a5a48a8b4d4 444 /*Reset RF module*/
ansond 0:2a5a48a8b4d4 445 rf_if_reset_radio();
ansond 0:2a5a48a8b4d4 446 printf("RF Write Settings\r\n");
ansond 0:2a5a48a8b4d4 447 /*Write RF settings*/
ansond 0:2a5a48a8b4d4 448 rf_write_settings();
ansond 0:2a5a48a8b4d4 449 printf("RF Init PHY Mode\r\n");
ansond 0:2a5a48a8b4d4 450 /*Initialise PHY mode*/
ansond 0:2a5a48a8b4d4 451 rf_init_phy_mode();
ansond 0:2a5a48a8b4d4 452 /*Clear RF flags*/
ansond 0:2a5a48a8b4d4 453 rf_flags_reset();
ansond 0:2a5a48a8b4d4 454 /*Set RF in TRX OFF state*/
ansond 0:2a5a48a8b4d4 455 rf_if_change_trx_state(TRX_OFF);
ansond 0:2a5a48a8b4d4 456 /*Set RF in PLL_ON state*/
ansond 0:2a5a48a8b4d4 457 rf_if_change_trx_state(PLL_ON);
ansond 0:2a5a48a8b4d4 458 /*Start receiver*/
ansond 0:2a5a48a8b4d4 459 rf_receive();
ansond 0:2a5a48a8b4d4 460 /*Read random variable. This will be used when seeding pseudo-random generator*/
ansond 0:2a5a48a8b4d4 461 rf_rnd_rssi = rf_if_read_rnd();
ansond 0:2a5a48a8b4d4 462 /*Start RF calibration timer*/
ansond 0:2a5a48a8b4d4 463 rf_calibration_timer_start(RF_CALIBRATION_INTERVAL); //ACA!
ansond 0:2a5a48a8b4d4 464 printf("RF Init End\r\n");
ansond 0:2a5a48a8b4d4 465 }
ansond 0:2a5a48a8b4d4 466
ansond 0:2a5a48a8b4d4 467 /**
ansond 0:2a5a48a8b4d4 468 * \brief Function gets called when MAC is setting radio off.
ansond 0:2a5a48a8b4d4 469 *
ansond 0:2a5a48a8b4d4 470 * \param none
ansond 0:2a5a48a8b4d4 471 *
ansond 0:2a5a48a8b4d4 472 * \return none
ansond 0:2a5a48a8b4d4 473 */
ansond 0:2a5a48a8b4d4 474 void rf_off(void)
ansond 0:2a5a48a8b4d4 475 {
ansond 0:2a5a48a8b4d4 476 if(rf_flags_check(RFF_ON))
ansond 0:2a5a48a8b4d4 477 {
ansond 0:2a5a48a8b4d4 478 rf_cca_abort();
ansond 0:2a5a48a8b4d4 479 uint16_t while_counter = 0;
ansond 0:2a5a48a8b4d4 480 /*Wait while receiving*/
ansond 0:2a5a48a8b4d4 481 while(rf_if_read_trx_state() == BUSY_RX_AACK || rf_if_read_trx_state() == BUSY_RX)
ansond 0:2a5a48a8b4d4 482 {
ansond 0:2a5a48a8b4d4 483 while_counter++;
ansond 0:2a5a48a8b4d4 484 if(while_counter == 0xffff)
ansond 0:2a5a48a8b4d4 485 break;
ansond 0:2a5a48a8b4d4 486 }
ansond 0:2a5a48a8b4d4 487 /*RF state change: RX_AACK_ON->PLL_ON->TRX_OFF->SLEEP*/
ansond 0:2a5a48a8b4d4 488 if(rf_if_read_trx_state() == RX_AACK_ON)
ansond 0:2a5a48a8b4d4 489 {
ansond 0:2a5a48a8b4d4 490 rf_if_change_trx_state(PLL_ON);
ansond 0:2a5a48a8b4d4 491 }
ansond 0:2a5a48a8b4d4 492 rf_if_change_trx_state(TRX_OFF);
ansond 0:2a5a48a8b4d4 493 rf_if_enable_slptr();
ansond 0:2a5a48a8b4d4 494 rf_flags_clear(~RFF_ON);
ansond 0:2a5a48a8b4d4 495 /*Front end in sleep*/
ansond 0:2a5a48a8b4d4 496 if(rf_use_front_end)
ansond 0:2a5a48a8b4d4 497 {
ansond 0:2a5a48a8b4d4 498 rf_if_disable_pa_ext();
ansond 0:2a5a48a8b4d4 499 rf_front_end_sleep();
ansond 0:2a5a48a8b4d4 500 }
ansond 0:2a5a48a8b4d4 501 /*Disable Antenna Diversity*/
ansond 0:2a5a48a8b4d4 502 if(rf_use_antenna_diversity)
ansond 0:2a5a48a8b4d4 503 rf_if_disable_ant_div();
ansond 0:2a5a48a8b4d4 504 }
ansond 0:2a5a48a8b4d4 505 }
ansond 0:2a5a48a8b4d4 506
ansond 0:2a5a48a8b4d4 507 /*
ansond 0:2a5a48a8b4d4 508 * \brief Function polls the RF state until it has changed to desired state.
ansond 0:2a5a48a8b4d4 509 *
ansond 0:2a5a48a8b4d4 510 * \param trx_state RF state
ansond 0:2a5a48a8b4d4 511 *
ansond 0:2a5a48a8b4d4 512 * \return none
ansond 0:2a5a48a8b4d4 513 */
ansond 0:2a5a48a8b4d4 514 void rf_poll_trx_state_change(rf_trx_states_t trx_state)
ansond 0:2a5a48a8b4d4 515 {
ansond 0:2a5a48a8b4d4 516 uint16_t while_counter = 0;
ansond 0:2a5a48a8b4d4 517 arm_enter_critical();
ansond 0:2a5a48a8b4d4 518
ansond 0:2a5a48a8b4d4 519 if(trx_state != RF_TX_START)
ansond 0:2a5a48a8b4d4 520 {
ansond 0:2a5a48a8b4d4 521 if(trx_state == FORCE_PLL_ON)
ansond 0:2a5a48a8b4d4 522 trx_state = PLL_ON;
ansond 0:2a5a48a8b4d4 523 else if(trx_state == FORCE_TRX_OFF)
ansond 0:2a5a48a8b4d4 524 trx_state = TRX_OFF;
ansond 0:2a5a48a8b4d4 525
ansond 0:2a5a48a8b4d4 526 while(rf_if_read_trx_state() != trx_state)
ansond 0:2a5a48a8b4d4 527 {
ansond 0:2a5a48a8b4d4 528 while_counter++;
ansond 0:2a5a48a8b4d4 529 if(while_counter == 0x1ff)
ansond 0:2a5a48a8b4d4 530 break;
ansond 0:2a5a48a8b4d4 531 }
ansond 0:2a5a48a8b4d4 532 }
ansond 0:2a5a48a8b4d4 533 arm_exit_critical();
ansond 0:2a5a48a8b4d4 534 }
ansond 0:2a5a48a8b4d4 535
ansond 0:2a5a48a8b4d4 536 /*
ansond 0:2a5a48a8b4d4 537 * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO.
ansond 0:2a5a48a8b4d4 538 *
ansond 0:2a5a48a8b4d4 539 * \param data_ptr Pointer to TX data
ansond 0:2a5a48a8b4d4 540 * \param data_length Length of the TX data
ansond 0:2a5a48a8b4d4 541 * \param tx_handle Handle to transmission
ansond 0:2a5a48a8b4d4 542 * \return 0 Success
ansond 0:2a5a48a8b4d4 543 * \return -1 Busy
ansond 0:2a5a48a8b4d4 544 */
ansond 0:2a5a48a8b4d4 545 int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle)
ansond 0:2a5a48a8b4d4 546 {
ansond 0:2a5a48a8b4d4 547 /*Check if transmitter is busy*/
ansond 0:2a5a48a8b4d4 548 if((rf_if_read_trx_state() == BUSY_RX_AACK) || (rf_if_read_trx_state() == BUSY_RX))
ansond 0:2a5a48a8b4d4 549 {
ansond 0:2a5a48a8b4d4 550 /*Return busy*/
ansond 0:2a5a48a8b4d4 551 return -1;
ansond 0:2a5a48a8b4d4 552 }
ansond 0:2a5a48a8b4d4 553 else
ansond 0:2a5a48a8b4d4 554 {
ansond 0:2a5a48a8b4d4 555 arm_enter_critical();
ansond 0:2a5a48a8b4d4 556 /*Check if transmitted data needs to be acked*/
ansond 0:2a5a48a8b4d4 557 if(*data_ptr & 0x20)
ansond 0:2a5a48a8b4d4 558 need_ack = 1;
ansond 0:2a5a48a8b4d4 559 else
ansond 0:2a5a48a8b4d4 560 need_ack = 0;
ansond 0:2a5a48a8b4d4 561 /*Store the sequence number for ACK handling*/
ansond 0:2a5a48a8b4d4 562 tx_sequence = *(data_ptr + 2);
ansond 0:2a5a48a8b4d4 563 /*Set radio in RX state to read channel*/
ansond 0:2a5a48a8b4d4 564 rf_receive();
ansond 0:2a5a48a8b4d4 565 /*Write TX FIFO*/
ansond 0:2a5a48a8b4d4 566 rf_if_write_frame_buffer(data_ptr, (uint8_t)data_length);
ansond 0:2a5a48a8b4d4 567 rf_flags_set(RFF_CCA);
ansond 0:2a5a48a8b4d4 568 /*Start CCA process*/
ansond 0:2a5a48a8b4d4 569 rf_if_enable_cca_ed_done_interrupt();
ansond 0:2a5a48a8b4d4 570 rf_if_start_cca_process();
ansond 0:2a5a48a8b4d4 571 /*Store TX handle*/
ansond 0:2a5a48a8b4d4 572 mac_tx_handle = tx_handle;
ansond 0:2a5a48a8b4d4 573 arm_exit_critical();
ansond 0:2a5a48a8b4d4 574 }
ansond 0:2a5a48a8b4d4 575
ansond 0:2a5a48a8b4d4 576 /*Return success*/
ansond 0:2a5a48a8b4d4 577 return 0;
ansond 0:2a5a48a8b4d4 578 }
ansond 0:2a5a48a8b4d4 579
ansond 0:2a5a48a8b4d4 580 /*
ansond 0:2a5a48a8b4d4 581 * \brief Function aborts CCA process.
ansond 0:2a5a48a8b4d4 582 *
ansond 0:2a5a48a8b4d4 583 * \param none
ansond 0:2a5a48a8b4d4 584 *
ansond 0:2a5a48a8b4d4 585 * \return none
ansond 0:2a5a48a8b4d4 586 */
ansond 0:2a5a48a8b4d4 587 void rf_cca_abort(void)
ansond 0:2a5a48a8b4d4 588 {
ansond 0:2a5a48a8b4d4 589 /*Clear RFF_CCA RF flag*/
ansond 0:2a5a48a8b4d4 590 rf_flags_clear(RFF_CCA);
ansond 0:2a5a48a8b4d4 591 }
ansond 0:2a5a48a8b4d4 592
ansond 0:2a5a48a8b4d4 593
ansond 0:2a5a48a8b4d4 594
ansond 0:2a5a48a8b4d4 595 /*
ansond 0:2a5a48a8b4d4 596 * \brief Function starts the transmission of the frame.
ansond 0:2a5a48a8b4d4 597 *
ansond 0:2a5a48a8b4d4 598 * \param none
ansond 0:2a5a48a8b4d4 599 *
ansond 0:2a5a48a8b4d4 600 * \return none
ansond 0:2a5a48a8b4d4 601 */
ansond 0:2a5a48a8b4d4 602 void rf_start_tx(void)
ansond 0:2a5a48a8b4d4 603 {
ansond 0:2a5a48a8b4d4 604 /*Only start transmitting from RX state*/
ansond 0:2a5a48a8b4d4 605 uint8_t trx_state = rf_if_read_trx_state();
ansond 0:2a5a48a8b4d4 606 if((trx_state != RX_AACK_ON) && (trx_state != RX_ON))
ansond 0:2a5a48a8b4d4 607 {
ansond 0:2a5a48a8b4d4 608 arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
ansond 0:2a5a48a8b4d4 609 }
ansond 0:2a5a48a8b4d4 610 else
ansond 0:2a5a48a8b4d4 611 {
ansond 0:2a5a48a8b4d4 612 /*RF state change: ->PLL_ON->RF_TX_START*/
ansond 0:2a5a48a8b4d4 613 rf_if_change_trx_state(FORCE_PLL_ON);
ansond 0:2a5a48a8b4d4 614 rf_flags_clear(RFF_RX);
ansond 0:2a5a48a8b4d4 615 rf_if_enable_tx_end_interrupt();
ansond 0:2a5a48a8b4d4 616 rf_flags_set(RFF_TX);
ansond 0:2a5a48a8b4d4 617 rf_if_change_trx_state(RF_TX_START);
ansond 0:2a5a48a8b4d4 618 }
ansond 0:2a5a48a8b4d4 619 }
ansond 0:2a5a48a8b4d4 620
ansond 0:2a5a48a8b4d4 621 /*
ansond 0:2a5a48a8b4d4 622 * \brief Function sets the RF in RX state.
ansond 0:2a5a48a8b4d4 623 *
ansond 0:2a5a48a8b4d4 624 * \param none
ansond 0:2a5a48a8b4d4 625 *
ansond 0:2a5a48a8b4d4 626 * \return none
ansond 0:2a5a48a8b4d4 627 */
ansond 0:2a5a48a8b4d4 628 void rf_receive(void)
ansond 0:2a5a48a8b4d4 629 {
ansond 0:2a5a48a8b4d4 630 uint16_t while_counter = 0;
ansond 0:2a5a48a8b4d4 631 if(rf_flags_check(RFF_ON) == 0)
ansond 0:2a5a48a8b4d4 632 {
ansond 0:2a5a48a8b4d4 633 rf_on();
ansond 0:2a5a48a8b4d4 634 }
ansond 0:2a5a48a8b4d4 635 /*If not yet in RX state set it*/
ansond 0:2a5a48a8b4d4 636 if(rf_flags_check(RFF_RX) == 0)
ansond 0:2a5a48a8b4d4 637 {
ansond 0:2a5a48a8b4d4 638 arm_enter_critical();
ansond 0:2a5a48a8b4d4 639 /*Wait while receiving data*/
ansond 0:2a5a48a8b4d4 640 while((rf_if_read_trx_state() == BUSY_RX) || (rf_if_read_trx_state() == BUSY_RX_AACK))
ansond 0:2a5a48a8b4d4 641 {
ansond 0:2a5a48a8b4d4 642 while_counter++;
ansond 0:2a5a48a8b4d4 643 if(while_counter == 0xffff)
ansond 0:2a5a48a8b4d4 644 {
ansond 0:2a5a48a8b4d4 645 break;
ansond 0:2a5a48a8b4d4 646 }
ansond 0:2a5a48a8b4d4 647 }
ansond 0:2a5a48a8b4d4 648 /*Wake up from sleep state*/
ansond 0:2a5a48a8b4d4 649 if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1f)
ansond 0:2a5a48a8b4d4 650 {
ansond 0:2a5a48a8b4d4 651 rf_if_disable_slptr();
ansond 0:2a5a48a8b4d4 652 rf_poll_trx_state_change(TRX_OFF);
ansond 0:2a5a48a8b4d4 653 }
ansond 0:2a5a48a8b4d4 654
ansond 0:2a5a48a8b4d4 655 rf_if_change_trx_state(PLL_ON);
ansond 0:2a5a48a8b4d4 656 /*ACK is always received in RX_ON state to bypass address filters*/
ansond 0:2a5a48a8b4d4 657 if(rf_rx_mode)
ansond 0:2a5a48a8b4d4 658 {
ansond 0:2a5a48a8b4d4 659 rf_rx_mode = 0;
ansond 0:2a5a48a8b4d4 660 rf_if_change_trx_state(RX_ON);
ansond 0:2a5a48a8b4d4 661 }
ansond 0:2a5a48a8b4d4 662 else
ansond 0:2a5a48a8b4d4 663 {
ansond 0:2a5a48a8b4d4 664 rf_if_change_trx_state(RX_AACK_ON);
ansond 0:2a5a48a8b4d4 665 /*If calibration timer was unable to calibrate the RF, run calibration now*/
ansond 0:2a5a48a8b4d4 666 if(!rf_tuned)
ansond 0:2a5a48a8b4d4 667 {
ansond 0:2a5a48a8b4d4 668 /*Start calibration. This can be done in states TRX_OFF, PLL_ON or in any receive state*/
ansond 0:2a5a48a8b4d4 669 rf_if_calibration();
ansond 0:2a5a48a8b4d4 670 /*RF is tuned now*/
ansond 0:2a5a48a8b4d4 671 rf_tuned = 1;
ansond 0:2a5a48a8b4d4 672 }
ansond 0:2a5a48a8b4d4 673 }
ansond 0:2a5a48a8b4d4 674 rf_channel_set(rf_channel);
ansond 0:2a5a48a8b4d4 675 rf_flags_set(RFF_RX);
ansond 0:2a5a48a8b4d4 676 rf_if_enable_rx_end_interrupt();
ansond 0:2a5a48a8b4d4 677 /*Enable LNA if Front end used*/
ansond 0:2a5a48a8b4d4 678 if(rf_use_front_end)
ansond 0:2a5a48a8b4d4 679 rf_front_end_rx_lna();
ansond 0:2a5a48a8b4d4 680 arm_exit_critical();
ansond 0:2a5a48a8b4d4 681 }
ansond 0:2a5a48a8b4d4 682 /*Stop the running CCA process*/
ansond 0:2a5a48a8b4d4 683 if(rf_flags_check(RFF_CCA))
ansond 0:2a5a48a8b4d4 684 rf_cca_abort();
ansond 0:2a5a48a8b4d4 685 }
ansond 0:2a5a48a8b4d4 686
ansond 0:2a5a48a8b4d4 687 /*
ansond 0:2a5a48a8b4d4 688 * \brief Function calibrates the radio.
ansond 0:2a5a48a8b4d4 689 *
ansond 0:2a5a48a8b4d4 690 * \param none
ansond 0:2a5a48a8b4d4 691 *
ansond 0:2a5a48a8b4d4 692 * \return none
ansond 0:2a5a48a8b4d4 693 */
ansond 0:2a5a48a8b4d4 694 void rf_calibration_cb(void)
ansond 0:2a5a48a8b4d4 695 {
ansond 0:2a5a48a8b4d4 696 /*clear tuned flag to start tuning in rf_receive*/
ansond 0:2a5a48a8b4d4 697 rf_tuned = 0;
ansond 0:2a5a48a8b4d4 698 /*If RF is in default receive state, start calibration*/
ansond 0:2a5a48a8b4d4 699 if(rf_if_read_trx_state() == RX_AACK_ON)
ansond 0:2a5a48a8b4d4 700 {
ansond 0:2a5a48a8b4d4 701 arm_enter_critical();
ansond 0:2a5a48a8b4d4 702 /*Set RF in PLL_ON state*/
ansond 0:2a5a48a8b4d4 703 rf_if_change_trx_state(PLL_ON);
ansond 0:2a5a48a8b4d4 704 /*Set RF in TRX_OFF state to start PLL tuning*/
ansond 0:2a5a48a8b4d4 705 rf_if_change_trx_state(TRX_OFF);
ansond 0:2a5a48a8b4d4 706 /*Set RF in RX_ON state to calibrate*/
ansond 0:2a5a48a8b4d4 707 rf_if_change_trx_state(RX_ON);
ansond 0:2a5a48a8b4d4 708 /*Calibrate FTN*/
ansond 0:2a5a48a8b4d4 709 rf_if_calibration();
ansond 0:2a5a48a8b4d4 710 /*RF is tuned now*/
ansond 0:2a5a48a8b4d4 711 rf_tuned = 1;
ansond 0:2a5a48a8b4d4 712 /*Back to default receive state*/
ansond 0:2a5a48a8b4d4 713 rf_flags_clear(RFF_RX);
ansond 0:2a5a48a8b4d4 714 rf_receive();
ansond 0:2a5a48a8b4d4 715 arm_exit_critical();
ansond 0:2a5a48a8b4d4 716 }
ansond 0:2a5a48a8b4d4 717 }
ansond 0:2a5a48a8b4d4 718
ansond 0:2a5a48a8b4d4 719 /*
ansond 0:2a5a48a8b4d4 720 * \brief Function sets RF_ON flag when radio is powered.
ansond 0:2a5a48a8b4d4 721 *
ansond 0:2a5a48a8b4d4 722 * \param none
ansond 0:2a5a48a8b4d4 723 *
ansond 0:2a5a48a8b4d4 724 * \return none
ansond 0:2a5a48a8b4d4 725 */
ansond 0:2a5a48a8b4d4 726 void rf_on(void)
ansond 0:2a5a48a8b4d4 727 {
ansond 0:2a5a48a8b4d4 728 /*Set RFF_ON flag*/
ansond 0:2a5a48a8b4d4 729 if(rf_flags_check(RFF_ON) == 0)
ansond 0:2a5a48a8b4d4 730 {
ansond 0:2a5a48a8b4d4 731 rf_flags_set(RFF_ON);
ansond 0:2a5a48a8b4d4 732 /*Wake up Front end*/
ansond 0:2a5a48a8b4d4 733 if(rf_use_front_end)
ansond 0:2a5a48a8b4d4 734 {
ansond 0:2a5a48a8b4d4 735 /*Set PA_EXT_EN to enable controlling of external front end*/
ansond 0:2a5a48a8b4d4 736 rf_if_enable_pa_ext();
ansond 0:2a5a48a8b4d4 737 rf_front_end_rx_lna();
ansond 0:2a5a48a8b4d4 738 }
ansond 0:2a5a48a8b4d4 739 /*Enable Antenna diversity*/
ansond 0:2a5a48a8b4d4 740 if(rf_use_antenna_diversity)
ansond 0:2a5a48a8b4d4 741 /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/
ansond 0:2a5a48a8b4d4 742 rf_if_enable_ant_div();
ansond 0:2a5a48a8b4d4 743 }
ansond 0:2a5a48a8b4d4 744 }
ansond 0:2a5a48a8b4d4 745
ansond 0:2a5a48a8b4d4 746 /*
ansond 0:2a5a48a8b4d4 747 * \brief Function handles the received ACK frame.
ansond 0:2a5a48a8b4d4 748 *
ansond 0:2a5a48a8b4d4 749 * \param seq_number Sequence number of received ACK
ansond 0:2a5a48a8b4d4 750 * \param data_pending Pending bit state in received ACK
ansond 0:2a5a48a8b4d4 751 *
ansond 0:2a5a48a8b4d4 752 * \return none
ansond 0:2a5a48a8b4d4 753 */
ansond 0:2a5a48a8b4d4 754 void rf_handle_ack(uint8_t seq_number, uint8_t data_pending)
ansond 0:2a5a48a8b4d4 755 {
ansond 0:2a5a48a8b4d4 756 phy_link_tx_status_e phy_status;
ansond 0:2a5a48a8b4d4 757 arm_enter_critical();
ansond 0:2a5a48a8b4d4 758 /*Received ACK sequence must be equal with transmitted packet sequence*/
ansond 0:2a5a48a8b4d4 759 if(tx_sequence == seq_number)
ansond 0:2a5a48a8b4d4 760 {
ansond 0:2a5a48a8b4d4 761 rf_ack_wait_timer_stop();
ansond 0:2a5a48a8b4d4 762 /*When data pending bit in ACK frame is set, inform NET library*/
ansond 0:2a5a48a8b4d4 763 if(data_pending)
ansond 0:2a5a48a8b4d4 764 phy_status = PHY_LINK_TX_DONE_PENDING;
ansond 0:2a5a48a8b4d4 765 else
ansond 0:2a5a48a8b4d4 766 phy_status = PHY_LINK_TX_DONE;
ansond 0:2a5a48a8b4d4 767 /*Call PHY TX Done API*/
ansond 0:2a5a48a8b4d4 768 arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle,phy_status, 1, 1);
ansond 0:2a5a48a8b4d4 769 }
ansond 0:2a5a48a8b4d4 770 arm_exit_critical();
ansond 0:2a5a48a8b4d4 771 }
ansond 0:2a5a48a8b4d4 772
ansond 0:2a5a48a8b4d4 773 /*
ansond 0:2a5a48a8b4d4 774 * \brief Function is a call back for RX end interrupt.
ansond 0:2a5a48a8b4d4 775 *
ansond 0:2a5a48a8b4d4 776 * \param none
ansond 0:2a5a48a8b4d4 777 *
ansond 0:2a5a48a8b4d4 778 * \return none
ansond 0:2a5a48a8b4d4 779 */
ansond 0:2a5a48a8b4d4 780 void rf_handle_rx_end(void)
ansond 0:2a5a48a8b4d4 781 {
ansond 0:2a5a48a8b4d4 782 uint8_t rf_lqi;
ansond 0:2a5a48a8b4d4 783
ansond 0:2a5a48a8b4d4 784 /*Frame received interrupt*/
ansond 0:2a5a48a8b4d4 785 if(rf_flags_check(RFF_RX))
ansond 0:2a5a48a8b4d4 786 {
ansond 0:2a5a48a8b4d4 787 /*Check CRC_valid bit*/
ansond 0:2a5a48a8b4d4 788 if(rf_if_check_crc())
ansond 0:2a5a48a8b4d4 789 {
ansond 0:2a5a48a8b4d4 790 uint8_t *rf_rx_ptr;
ansond 0:2a5a48a8b4d4 791 uint8_t receiving_ack = 0;
ansond 0:2a5a48a8b4d4 792 /*Read length*/
ansond 0:2a5a48a8b4d4 793 uint8_t len = rf_if_read_received_frame_length();
ansond 0:2a5a48a8b4d4 794 /*Not ACK frame*/
ansond 0:2a5a48a8b4d4 795 if(len > 5)
ansond 0:2a5a48a8b4d4 796 {
ansond 0:2a5a48a8b4d4 797 rf_rx_ptr = rf_buffer;
ansond 0:2a5a48a8b4d4 798 }
ansond 0:2a5a48a8b4d4 799 /*ACK received*/
ansond 0:2a5a48a8b4d4 800 else
ansond 0:2a5a48a8b4d4 801 {
ansond 0:2a5a48a8b4d4 802 /*Read ACK in static ACK buffer*/
ansond 0:2a5a48a8b4d4 803 receiving_ack = 1;
ansond 0:2a5a48a8b4d4 804 rf_rx_ptr = ack_rx_buf;
ansond 0:2a5a48a8b4d4 805 }
ansond 0:2a5a48a8b4d4 806 /*Check the length is valid*/
ansond 0:2a5a48a8b4d4 807 if(len > 1 && len < RF_BUFFER_SIZE)
ansond 0:2a5a48a8b4d4 808 {
ansond 0:2a5a48a8b4d4 809 /*Read received packet*/
ansond 0:2a5a48a8b4d4 810 rf_if_read_packet(rf_rx_ptr, len);
ansond 0:2a5a48a8b4d4 811 /*Get LQI*/
ansond 0:2a5a48a8b4d4 812 rf_lqi = rf_if_read_lqi();
ansond 0:2a5a48a8b4d4 813 /*Handle received ACK*/
ansond 0:2a5a48a8b4d4 814 if(receiving_ack && ((ack_rx_buf[0] & 0x07) == 0x02))
ansond 0:2a5a48a8b4d4 815 {
ansond 0:2a5a48a8b4d4 816 uint8_t pending = 0;
ansond 0:2a5a48a8b4d4 817 /*Check if data is pending*/
ansond 0:2a5a48a8b4d4 818 if ((ack_rx_buf[0] & 0x10))
ansond 0:2a5a48a8b4d4 819 {
ansond 0:2a5a48a8b4d4 820 pending=1;
ansond 0:2a5a48a8b4d4 821 }
ansond 0:2a5a48a8b4d4 822 /*Send sequence number in ACK handler*/
ansond 0:2a5a48a8b4d4 823 rf_handle_ack(ack_rx_buf[2], pending);
ansond 0:2a5a48a8b4d4 824 }
ansond 0:2a5a48a8b4d4 825 /*Handle received data*/
ansond 0:2a5a48a8b4d4 826 else if(rf_if_read_trx_state() != RX_ON && rf_if_read_trx_state() != BUSY_RX)
ansond 0:2a5a48a8b4d4 827 {
ansond 0:2a5a48a8b4d4 828 arm_net_phy_rx(rf_buffer,len - 2, rf_lqi, rf_radio_driver_id);
ansond 0:2a5a48a8b4d4 829 }
ansond 0:2a5a48a8b4d4 830 }
ansond 0:2a5a48a8b4d4 831 }
ansond 0:2a5a48a8b4d4 832 }
ansond 0:2a5a48a8b4d4 833 /*Start receiver*/
ansond 0:2a5a48a8b4d4 834 rf_flags_clear(RFF_RX);
ansond 0:2a5a48a8b4d4 835 rf_receive();
ansond 0:2a5a48a8b4d4 836 }
ansond 0:2a5a48a8b4d4 837
ansond 0:2a5a48a8b4d4 838 /*
ansond 0:2a5a48a8b4d4 839 * \brief Function is called when MAC is shutting down the radio.
ansond 0:2a5a48a8b4d4 840 *
ansond 0:2a5a48a8b4d4 841 * \param none
ansond 0:2a5a48a8b4d4 842 *
ansond 0:2a5a48a8b4d4 843 * \return none
ansond 0:2a5a48a8b4d4 844 */
ansond 0:2a5a48a8b4d4 845 void rf_shutdown(void)
ansond 0:2a5a48a8b4d4 846 {
ansond 0:2a5a48a8b4d4 847 /*Call RF OFF*/
ansond 0:2a5a48a8b4d4 848 rf_off();
ansond 0:2a5a48a8b4d4 849 /*Clear RF flags*/
ansond 0:2a5a48a8b4d4 850 rf_flags_reset();
ansond 0:2a5a48a8b4d4 851 }
ansond 0:2a5a48a8b4d4 852
ansond 0:2a5a48a8b4d4 853 /*
ansond 0:2a5a48a8b4d4 854 * \brief Function is a call back for TX end interrupt.
ansond 0:2a5a48a8b4d4 855 *
ansond 0:2a5a48a8b4d4 856 * \param none
ansond 0:2a5a48a8b4d4 857 *
ansond 0:2a5a48a8b4d4 858 * \return none
ansond 0:2a5a48a8b4d4 859 */
ansond 0:2a5a48a8b4d4 860 void rf_handle_tx_end(void)
ansond 0:2a5a48a8b4d4 861 {
ansond 0:2a5a48a8b4d4 862 phy_link_tx_status_e phy_status = PHY_LINK_TX_SUCCESS;
ansond 0:2a5a48a8b4d4 863
ansond 0:2a5a48a8b4d4 864 rf_rx_mode = 0;
ansond 0:2a5a48a8b4d4 865 /*If ACK is needed for this transmission*/
ansond 0:2a5a48a8b4d4 866 if(need_ack && rf_flags_check(RFF_TX))
ansond 0:2a5a48a8b4d4 867 {
ansond 0:2a5a48a8b4d4 868 rf_ack_wait_timer_start(rf_ack_wait_duration);
ansond 0:2a5a48a8b4d4 869 rf_rx_mode = 1;
ansond 0:2a5a48a8b4d4 870 }
ansond 0:2a5a48a8b4d4 871 rf_flags_clear(RFF_RX);
ansond 0:2a5a48a8b4d4 872 /*Start receiver*/
ansond 0:2a5a48a8b4d4 873 rf_receive();
ansond 0:2a5a48a8b4d4 874
ansond 0:2a5a48a8b4d4 875 /*Call PHY TX Done API*/
ansond 0:2a5a48a8b4d4 876 arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1);
ansond 0:2a5a48a8b4d4 877 }
ansond 0:2a5a48a8b4d4 878
ansond 0:2a5a48a8b4d4 879 /*
ansond 0:2a5a48a8b4d4 880 * \brief Function is a call back for CCA ED done interrupt.
ansond 0:2a5a48a8b4d4 881 *
ansond 0:2a5a48a8b4d4 882 * \param none
ansond 0:2a5a48a8b4d4 883 *
ansond 0:2a5a48a8b4d4 884 * \return none
ansond 0:2a5a48a8b4d4 885 */
ansond 0:2a5a48a8b4d4 886 void rf_handle_cca_ed_done(void)
ansond 0:2a5a48a8b4d4 887 {
ansond 0:2a5a48a8b4d4 888 rf_flags_clear(RFF_CCA);
ansond 0:2a5a48a8b4d4 889 /*Check the result of CCA process*/
ansond 0:2a5a48a8b4d4 890 if(rf_if_check_cca())
ansond 0:2a5a48a8b4d4 891 {
ansond 0:2a5a48a8b4d4 892 rf_start_tx();
ansond 0:2a5a48a8b4d4 893 }
ansond 0:2a5a48a8b4d4 894 else
ansond 0:2a5a48a8b4d4 895 {
ansond 0:2a5a48a8b4d4 896 /*Send CCA fail notification*/
ansond 0:2a5a48a8b4d4 897 arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1);
ansond 0:2a5a48a8b4d4 898 }
ansond 0:2a5a48a8b4d4 899 }
ansond 0:2a5a48a8b4d4 900
ansond 0:2a5a48a8b4d4 901 /*
ansond 0:2a5a48a8b4d4 902 * \brief Function sets the TX power variable.
ansond 0:2a5a48a8b4d4 903 *
ansond 0:2a5a48a8b4d4 904 * \param power TX power setting
ansond 0:2a5a48a8b4d4 905 *
ansond 0:2a5a48a8b4d4 906 * \return 0 Success
ansond 0:2a5a48a8b4d4 907 * \return -1 Fail
ansond 0:2a5a48a8b4d4 908 */
ansond 0:2a5a48a8b4d4 909 int8_t rf_tx_power_set(uint8_t power)
ansond 0:2a5a48a8b4d4 910 {
ansond 0:2a5a48a8b4d4 911 int8_t ret_val = -1;
ansond 0:2a5a48a8b4d4 912 if(power < 16)
ansond 0:2a5a48a8b4d4 913 {
ansond 0:2a5a48a8b4d4 914 radio_tx_power = power;
ansond 0:2a5a48a8b4d4 915 ret_val = 0;
ansond 0:2a5a48a8b4d4 916 }
ansond 0:2a5a48a8b4d4 917 return ret_val;
ansond 0:2a5a48a8b4d4 918 }
ansond 0:2a5a48a8b4d4 919
ansond 0:2a5a48a8b4d4 920 /*
ansond 0:2a5a48a8b4d4 921 * \brief Function returns the TX power variable.
ansond 0:2a5a48a8b4d4 922 *
ansond 0:2a5a48a8b4d4 923 * \param none
ansond 0:2a5a48a8b4d4 924 *
ansond 0:2a5a48a8b4d4 925 * \return radio_tx_power TX power variable
ansond 0:2a5a48a8b4d4 926 */
ansond 0:2a5a48a8b4d4 927 uint8_t rf_tx_power_get(void)
ansond 0:2a5a48a8b4d4 928 {
ansond 0:2a5a48a8b4d4 929 return radio_tx_power;
ansond 0:2a5a48a8b4d4 930 }
ansond 0:2a5a48a8b4d4 931
ansond 0:2a5a48a8b4d4 932 /*
ansond 0:2a5a48a8b4d4 933 * \brief Function sets the RF RPC variable.
ansond 0:2a5a48a8b4d4 934 *
ansond 0:2a5a48a8b4d4 935 * \param rpc_value RPC setting
ansond 0:2a5a48a8b4d4 936 *
ansond 0:2a5a48a8b4d4 937 * \return 0 Success
ansond 0:2a5a48a8b4d4 938 */
ansond 0:2a5a48a8b4d4 939 int8_t rf_rpc_set(uint8_t rpc_value)
ansond 0:2a5a48a8b4d4 940 {
ansond 0:2a5a48a8b4d4 941 int8_t ret_val = -1;
ansond 0:2a5a48a8b4d4 942 radio_rpc_value = rpc_value;
ansond 0:2a5a48a8b4d4 943 ret_val = 0;
ansond 0:2a5a48a8b4d4 944 return ret_val;
ansond 0:2a5a48a8b4d4 945 }
ansond 0:2a5a48a8b4d4 946
ansond 0:2a5a48a8b4d4 947 /*
ansond 0:2a5a48a8b4d4 948 * \brief Function enables the usage of Front end.
ansond 0:2a5a48a8b4d4 949 *
ansond 0:2a5a48a8b4d4 950 * \param none
ansond 0:2a5a48a8b4d4 951 *
ansond 0:2a5a48a8b4d4 952 * \return 0 Success
ansond 0:2a5a48a8b4d4 953 */
ansond 0:2a5a48a8b4d4 954 int8_t rf_enable_pa(void)
ansond 0:2a5a48a8b4d4 955 {
ansond 0:2a5a48a8b4d4 956 int8_t ret_val = 0;
ansond 0:2a5a48a8b4d4 957 rf_use_front_end = 1;
ansond 0:2a5a48a8b4d4 958 return ret_val;
ansond 0:2a5a48a8b4d4 959 }
ansond 0:2a5a48a8b4d4 960
ansond 0:2a5a48a8b4d4 961 /*
ansond 0:2a5a48a8b4d4 962 * \brief Function enables the usage of Antenna diversity.
ansond 0:2a5a48a8b4d4 963 *
ansond 0:2a5a48a8b4d4 964 * \param none
ansond 0:2a5a48a8b4d4 965 *
ansond 0:2a5a48a8b4d4 966 * \return 0 Success
ansond 0:2a5a48a8b4d4 967 */
ansond 0:2a5a48a8b4d4 968 int8_t rf_enable_antenna_diversity(void)
ansond 0:2a5a48a8b4d4 969 {
ansond 0:2a5a48a8b4d4 970 int8_t ret_val = 0;
ansond 0:2a5a48a8b4d4 971 rf_use_antenna_diversity = 1;
ansond 0:2a5a48a8b4d4 972 return ret_val;
ansond 0:2a5a48a8b4d4 973 }
ansond 0:2a5a48a8b4d4 974
ansond 0:2a5a48a8b4d4 975 /*
ansond 0:2a5a48a8b4d4 976 * \brief Function defines the CSD pin of the Front end.
ansond 0:2a5a48a8b4d4 977 *
ansond 0:2a5a48a8b4d4 978 * \param port CSD port
ansond 0:2a5a48a8b4d4 979 * \param port CSD pin
ansond 0:2a5a48a8b4d4 980 *
ansond 0:2a5a48a8b4d4 981 * \return 0 Success
ansond 0:2a5a48a8b4d4 982 */
ansond 0:2a5a48a8b4d4 983 int8_t rf_set_csd_pin(uint8_t port, uint8_t pin)
ansond 0:2a5a48a8b4d4 984 {
ansond 0:2a5a48a8b4d4 985 int8_t ret_val = -1;
ansond 0:2a5a48a8b4d4 986
ansond 0:2a5a48a8b4d4 987 rf_csd_port = port;
ansond 0:2a5a48a8b4d4 988 rf_csd_pin = pin;
ansond 0:2a5a48a8b4d4 989 ret_val = 0;
ansond 0:2a5a48a8b4d4 990
ansond 0:2a5a48a8b4d4 991 return ret_val;
ansond 0:2a5a48a8b4d4 992 }
ansond 0:2a5a48a8b4d4 993
ansond 0:2a5a48a8b4d4 994 /*
ansond 0:2a5a48a8b4d4 995 * \brief Function defines the CPS pin of the Front end.
ansond 0:2a5a48a8b4d4 996 *
ansond 0:2a5a48a8b4d4 997 * \param port CPS port
ansond 0:2a5a48a8b4d4 998 * \param port CPS pin
ansond 0:2a5a48a8b4d4 999 *
ansond 0:2a5a48a8b4d4 1000 * \return 0 Success
ansond 0:2a5a48a8b4d4 1001 */
ansond 0:2a5a48a8b4d4 1002 int8_t rf_set_cps_pin(uint8_t port, uint8_t pin)
ansond 0:2a5a48a8b4d4 1003 {
ansond 0:2a5a48a8b4d4 1004 int8_t ret_val = -1;
ansond 0:2a5a48a8b4d4 1005
ansond 0:2a5a48a8b4d4 1006 rf_cps_port = port;
ansond 0:2a5a48a8b4d4 1007 rf_cps_pin = pin;
ansond 0:2a5a48a8b4d4 1008 ret_val = 0;
ansond 0:2a5a48a8b4d4 1009
ansond 0:2a5a48a8b4d4 1010 return ret_val;
ansond 0:2a5a48a8b4d4 1011 }
ansond 0:2a5a48a8b4d4 1012
ansond 0:2a5a48a8b4d4 1013 /*
ansond 0:2a5a48a8b4d4 1014 * \brief Function gives the control of RF states to MAC.
ansond 0:2a5a48a8b4d4 1015 *
ansond 0:2a5a48a8b4d4 1016 * \param new_state RF state
ansond 0:2a5a48a8b4d4 1017 * \param rf_channel RF channel
ansond 0:2a5a48a8b4d4 1018 *
ansond 0:2a5a48a8b4d4 1019 * \return 0 Success
ansond 0:2a5a48a8b4d4 1020 */
ansond 0:2a5a48a8b4d4 1021 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
ansond 0:2a5a48a8b4d4 1022 {
ansond 0:2a5a48a8b4d4 1023 int8_t ret_val = 0;
ansond 0:2a5a48a8b4d4 1024 switch (new_state)
ansond 0:2a5a48a8b4d4 1025 {
ansond 0:2a5a48a8b4d4 1026 /*Reset PHY driver and set to idle*/
ansond 0:2a5a48a8b4d4 1027 case PHY_INTERFACE_RESET:
ansond 0:2a5a48a8b4d4 1028 break;
ansond 0:2a5a48a8b4d4 1029 /*Disable PHY Interface driver*/
ansond 0:2a5a48a8b4d4 1030 case PHY_INTERFACE_DOWN:
ansond 0:2a5a48a8b4d4 1031 rf_shutdown();
ansond 0:2a5a48a8b4d4 1032 break;
ansond 0:2a5a48a8b4d4 1033 /*Enable PHY Interface driver*/
ansond 0:2a5a48a8b4d4 1034 case PHY_INTERFACE_UP:
ansond 0:2a5a48a8b4d4 1035 rf_channel_set(rf_channel);
ansond 0:2a5a48a8b4d4 1036 rf_receive();
ansond 0:2a5a48a8b4d4 1037 break;
ansond 0:2a5a48a8b4d4 1038 /*Enable wireless interface ED scan mode*/
ansond 0:2a5a48a8b4d4 1039 case PHY_INTERFACE_RX_ENERGY_STATE:
ansond 0:2a5a48a8b4d4 1040 break;
ansond 0:2a5a48a8b4d4 1041 }
ansond 0:2a5a48a8b4d4 1042 return ret_val;
ansond 0:2a5a48a8b4d4 1043 }
ansond 0:2a5a48a8b4d4 1044
ansond 0:2a5a48a8b4d4 1045 /*
ansond 0:2a5a48a8b4d4 1046 * \brief Function controls the ACK pending, channel setting and energy detection.
ansond 0:2a5a48a8b4d4 1047 *
ansond 0:2a5a48a8b4d4 1048 * \param extension_type Type of control
ansond 0:2a5a48a8b4d4 1049 * \param data_ptr Data from NET library
ansond 0:2a5a48a8b4d4 1050 *
ansond 0:2a5a48a8b4d4 1051 * \return 0 Success
ansond 0:2a5a48a8b4d4 1052 */
ansond 0:2a5a48a8b4d4 1053 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
ansond 0:2a5a48a8b4d4 1054 {
ansond 0:2a5a48a8b4d4 1055 switch (extension_type)
ansond 0:2a5a48a8b4d4 1056 {
ansond 0:2a5a48a8b4d4 1057 /*Control MAC pending bit for Indirect data transmission*/
ansond 0:2a5a48a8b4d4 1058 case PHY_EXTENSION_CTRL_PENDING_BIT:
ansond 0:2a5a48a8b4d4 1059 if(*data_ptr)
ansond 0:2a5a48a8b4d4 1060 {
ansond 0:2a5a48a8b4d4 1061 rf_if_ack_pending_ctrl(1);
ansond 0:2a5a48a8b4d4 1062 }
ansond 0:2a5a48a8b4d4 1063 else
ansond 0:2a5a48a8b4d4 1064 {
ansond 0:2a5a48a8b4d4 1065 rf_if_ack_pending_ctrl(0);
ansond 0:2a5a48a8b4d4 1066 }
ansond 0:2a5a48a8b4d4 1067 break;
ansond 0:2a5a48a8b4d4 1068 /*Return frame pending status*/
ansond 0:2a5a48a8b4d4 1069 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
ansond 0:2a5a48a8b4d4 1070 *data_ptr = rf_if_last_acked_pending();
ansond 0:2a5a48a8b4d4 1071 break;
ansond 0:2a5a48a8b4d4 1072 /*Set channel*/
ansond 0:2a5a48a8b4d4 1073 case PHY_EXTENSION_SET_CHANNEL:
ansond 0:2a5a48a8b4d4 1074 break;
ansond 0:2a5a48a8b4d4 1075 /*Read energy on the channel*/
ansond 0:2a5a48a8b4d4 1076 case PHY_EXTENSION_READ_CHANNEL_ENERGY:
ansond 0:2a5a48a8b4d4 1077 break;
ansond 0:2a5a48a8b4d4 1078 /*Read status of the link*/
ansond 0:2a5a48a8b4d4 1079 case PHY_EXTENSION_READ_LINK_STATUS:
ansond 0:2a5a48a8b4d4 1080 break;
ansond 0:2a5a48a8b4d4 1081 }
ansond 0:2a5a48a8b4d4 1082 return 0;
ansond 0:2a5a48a8b4d4 1083 }
ansond 0:2a5a48a8b4d4 1084
ansond 0:2a5a48a8b4d4 1085 /*
ansond 0:2a5a48a8b4d4 1086 * \brief Function sets the addresses to RF address filters.
ansond 0:2a5a48a8b4d4 1087 *
ansond 0:2a5a48a8b4d4 1088 * \param address_type Type of address
ansond 0:2a5a48a8b4d4 1089 * \param address_ptr Pointer to given address
ansond 0:2a5a48a8b4d4 1090 *
ansond 0:2a5a48a8b4d4 1091 * \return 0 Success
ansond 0:2a5a48a8b4d4 1092 */
ansond 0:2a5a48a8b4d4 1093 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
ansond 0:2a5a48a8b4d4 1094 {
ansond 0:2a5a48a8b4d4 1095 int8_t ret_val = 0;
ansond 0:2a5a48a8b4d4 1096 switch (address_type)
ansond 0:2a5a48a8b4d4 1097 {
ansond 0:2a5a48a8b4d4 1098 /*Set 48-bit address*/
ansond 0:2a5a48a8b4d4 1099 case PHY_MAC_48BIT:
ansond 0:2a5a48a8b4d4 1100 break;
ansond 0:2a5a48a8b4d4 1101 /*Set 64-bit address*/
ansond 0:2a5a48a8b4d4 1102 case PHY_MAC_64BIT:
ansond 0:2a5a48a8b4d4 1103 rf_set_address(address_ptr);
ansond 0:2a5a48a8b4d4 1104 break;
ansond 0:2a5a48a8b4d4 1105 /*Set 16-bit address*/
ansond 0:2a5a48a8b4d4 1106 case PHY_MAC_16BIT:
ansond 0:2a5a48a8b4d4 1107 rf_set_short_adr(address_ptr);
ansond 0:2a5a48a8b4d4 1108 break;
ansond 0:2a5a48a8b4d4 1109 /*Set PAN Id*/
ansond 0:2a5a48a8b4d4 1110 case PHY_MAC_PANID:
ansond 0:2a5a48a8b4d4 1111 rf_set_pan_id(address_ptr);
ansond 0:2a5a48a8b4d4 1112 break;
ansond 0:2a5a48a8b4d4 1113 }
ansond 0:2a5a48a8b4d4 1114 return ret_val;
ansond 0:2a5a48a8b4d4 1115 }
ansond 0:2a5a48a8b4d4 1116
ansond 0:2a5a48a8b4d4 1117 /*
ansond 0:2a5a48a8b4d4 1118 * \brief Function initialises the ACK wait time and returns the used PHY mode.
ansond 0:2a5a48a8b4d4 1119 *
ansond 0:2a5a48a8b4d4 1120 * \param none
ansond 0:2a5a48a8b4d4 1121 *
ansond 0:2a5a48a8b4d4 1122 * \return tmp Used PHY mode
ansond 0:2a5a48a8b4d4 1123 */
ansond 0:2a5a48a8b4d4 1124 uint8_t rf_init_phy_mode(void)
ansond 0:2a5a48a8b4d4 1125 {
ansond 0:2a5a48a8b4d4 1126 uint8_t tmp;
ansond 0:2a5a48a8b4d4 1127 /*Read used PHY Mode*/
ansond 0:2a5a48a8b4d4 1128 tmp = rf_if_read_register(TRX_CTRL_2);
ansond 0:2a5a48a8b4d4 1129 /*Set ACK wait time for used data rate*/
ansond 0:2a5a48a8b4d4 1130 if((tmp & 0x1f) == 0x00)
ansond 0:2a5a48a8b4d4 1131 {
ansond 0:2a5a48a8b4d4 1132 rf_ack_wait_duration = 938;
ansond 0:2a5a48a8b4d4 1133 tmp = BPSK_20;
ansond 0:2a5a48a8b4d4 1134 }
ansond 0:2a5a48a8b4d4 1135 else if((tmp & 0x1f) == 0x04)
ansond 0:2a5a48a8b4d4 1136 {
ansond 0:2a5a48a8b4d4 1137 rf_ack_wait_duration = 469;
ansond 0:2a5a48a8b4d4 1138 tmp = BPSK_40;
ansond 0:2a5a48a8b4d4 1139 }
ansond 0:2a5a48a8b4d4 1140 else if((tmp & 0x1f) == 0x14)
ansond 0:2a5a48a8b4d4 1141 {
ansond 0:2a5a48a8b4d4 1142 rf_ack_wait_duration = 469;
ansond 0:2a5a48a8b4d4 1143 tmp = BPSK_40_ALT;
ansond 0:2a5a48a8b4d4 1144 }
ansond 0:2a5a48a8b4d4 1145 else if((tmp & 0x1f) == 0x08)
ansond 0:2a5a48a8b4d4 1146 {
ansond 0:2a5a48a8b4d4 1147 rf_ack_wait_duration = 100;
ansond 0:2a5a48a8b4d4 1148 tmp = OQPSK_SIN_RC_100;
ansond 0:2a5a48a8b4d4 1149 }
ansond 0:2a5a48a8b4d4 1150 else if((tmp & 0x1f) == 0x09)
ansond 0:2a5a48a8b4d4 1151 {
ansond 0:2a5a48a8b4d4 1152 rf_ack_wait_duration = 50;
ansond 0:2a5a48a8b4d4 1153 tmp = OQPSK_SIN_RC_200;
ansond 0:2a5a48a8b4d4 1154 }
ansond 0:2a5a48a8b4d4 1155 else if((tmp & 0x1f) == 0x18)
ansond 0:2a5a48a8b4d4 1156 {
ansond 0:2a5a48a8b4d4 1157 rf_ack_wait_duration = 100;
ansond 0:2a5a48a8b4d4 1158 tmp = OQPSK_RC_100;
ansond 0:2a5a48a8b4d4 1159 }
ansond 0:2a5a48a8b4d4 1160 else if((tmp & 0x1f) == 0x19)
ansond 0:2a5a48a8b4d4 1161 {
ansond 0:2a5a48a8b4d4 1162 rf_ack_wait_duration = 50;
ansond 0:2a5a48a8b4d4 1163 tmp = OQPSK_RC_200;
ansond 0:2a5a48a8b4d4 1164 }
ansond 0:2a5a48a8b4d4 1165 else if((tmp & 0x1f) == 0x0c)
ansond 0:2a5a48a8b4d4 1166 {
ansond 0:2a5a48a8b4d4 1167 rf_ack_wait_duration = 50;
ansond 0:2a5a48a8b4d4 1168 tmp = OQPSK_SIN_250;
ansond 0:2a5a48a8b4d4 1169 }
ansond 0:2a5a48a8b4d4 1170 else if((tmp & 0x1f) == 0x0d)
ansond 0:2a5a48a8b4d4 1171 {
ansond 0:2a5a48a8b4d4 1172 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1173 tmp = OQPSK_SIN_500;
ansond 0:2a5a48a8b4d4 1174 }
ansond 0:2a5a48a8b4d4 1175 else if((tmp & 0x1f) == 0x0f)
ansond 0:2a5a48a8b4d4 1176 {
ansond 0:2a5a48a8b4d4 1177 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1178 tmp = OQPSK_SIN_500_ALT;
ansond 0:2a5a48a8b4d4 1179 }
ansond 0:2a5a48a8b4d4 1180 else if((tmp & 0x1f) == 0x1c)
ansond 0:2a5a48a8b4d4 1181 {
ansond 0:2a5a48a8b4d4 1182 rf_ack_wait_duration = 50;
ansond 0:2a5a48a8b4d4 1183 tmp = OQPSK_RC_250;
ansond 0:2a5a48a8b4d4 1184 }
ansond 0:2a5a48a8b4d4 1185 else if((tmp & 0x1f) == 0x1d)
ansond 0:2a5a48a8b4d4 1186 {
ansond 0:2a5a48a8b4d4 1187 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1188 tmp = OQPSK_RC_500;
ansond 0:2a5a48a8b4d4 1189 }
ansond 0:2a5a48a8b4d4 1190 else if((tmp & 0x1f) == 0x1f)
ansond 0:2a5a48a8b4d4 1191 {
ansond 0:2a5a48a8b4d4 1192 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1193 tmp = OQPSK_RC_500_ALT;
ansond 0:2a5a48a8b4d4 1194 }
ansond 0:2a5a48a8b4d4 1195 else if((tmp & 0x3f) == 0x2A)
ansond 0:2a5a48a8b4d4 1196 {
ansond 0:2a5a48a8b4d4 1197 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1198 tmp = OQPSK_SIN_RC_400_SCR_ON;
ansond 0:2a5a48a8b4d4 1199 }
ansond 0:2a5a48a8b4d4 1200 else if((tmp & 0x3f) == 0x0A)
ansond 0:2a5a48a8b4d4 1201 {
ansond 0:2a5a48a8b4d4 1202 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1203 tmp = OQPSK_SIN_RC_400_SCR_OFF;
ansond 0:2a5a48a8b4d4 1204 }
ansond 0:2a5a48a8b4d4 1205 else if((tmp & 0x3f) == 0x3A)
ansond 0:2a5a48a8b4d4 1206 {
ansond 0:2a5a48a8b4d4 1207 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1208 tmp = OQPSK_RC_400_SCR_ON;
ansond 0:2a5a48a8b4d4 1209 }
ansond 0:2a5a48a8b4d4 1210 else if((tmp & 0x3f) == 0x1A)
ansond 0:2a5a48a8b4d4 1211 {
ansond 0:2a5a48a8b4d4 1212 rf_ack_wait_duration = 25;
ansond 0:2a5a48a8b4d4 1213 tmp = OQPSK_RC_400_SCR_OFF;
ansond 0:2a5a48a8b4d4 1214 }
ansond 0:2a5a48a8b4d4 1215 else if((tmp & 0x3f) == 0x2E)
ansond 0:2a5a48a8b4d4 1216 {
ansond 0:2a5a48a8b4d4 1217 rf_ack_wait_duration = 13;
ansond 0:2a5a48a8b4d4 1218 tmp = OQPSK_SIN_1000_SCR_ON;
ansond 0:2a5a48a8b4d4 1219 }
ansond 0:2a5a48a8b4d4 1220 else if((tmp & 0x3f) == 0x0E)
ansond 0:2a5a48a8b4d4 1221 {
ansond 0:2a5a48a8b4d4 1222 rf_ack_wait_duration = 13;
ansond 0:2a5a48a8b4d4 1223 tmp = OQPSK_SIN_1000_SCR_OFF;
ansond 0:2a5a48a8b4d4 1224 }
ansond 0:2a5a48a8b4d4 1225 else if((tmp & 0x3f) == 0x3E)
ansond 0:2a5a48a8b4d4 1226 {
ansond 0:2a5a48a8b4d4 1227 rf_ack_wait_duration = 13;
ansond 0:2a5a48a8b4d4 1228 tmp = OQPSK_RC_1000_SCR_ON;
ansond 0:2a5a48a8b4d4 1229 }
ansond 0:2a5a48a8b4d4 1230 else if((tmp & 0x3f) == 0x1E)
ansond 0:2a5a48a8b4d4 1231 {
ansond 0:2a5a48a8b4d4 1232 rf_ack_wait_duration = 13;
ansond 0:2a5a48a8b4d4 1233 tmp = OQPSK_RC_1000_SCR_OFF;
ansond 0:2a5a48a8b4d4 1234 }
ansond 0:2a5a48a8b4d4 1235 return tmp;
ansond 0:2a5a48a8b4d4 1236 }
ansond 0:2a5a48a8b4d4 1237