6LowPAN mesh-based network support for mbedConnectorInterface. The Atmel-based mbed 6LowPAN shield is the assumed network hardware.

Dependencies:   libnsdl Nanostack_lib

Committer:
ansond
Date:
Sun Feb 01 18:26:13 2015 +0000
Revision:
0:2a5a48a8b4d4
Child:
6:f6288e89b02a
revamped

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