Easily add all supported connectivity methods to your mbed OS project

Dependencies:   type-yd-driver

Committer:
MACRUM
Date:
Wed Jul 12 10:52:58 2017 +0000
Revision:
0:615f90842ce8
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:615f90842ce8 1 #if MBED_CONF_RTOS_PRESENT
MACRUM 0:615f90842ce8 2
MACRUM 0:615f90842ce8 3 #include "NanostackRfPhySpirit1.h"
MACRUM 0:615f90842ce8 4 #include "SimpleSpirit1.h"
MACRUM 0:615f90842ce8 5 #include "nanostack/platform/arm_hal_phy.h"
MACRUM 0:615f90842ce8 6 #include "platform/arm_hal_interrupt.h"
MACRUM 0:615f90842ce8 7
MACRUM 0:615f90842ce8 8 #include "mbed_trace.h"
MACRUM 0:615f90842ce8 9 #define TRACE_GROUP "SPIRIT"
MACRUM 0:615f90842ce8 10
MACRUM 0:615f90842ce8 11 /* Define beyond macro if you want to perform heavy debug tracing (includes tracing in IRQ context) */
MACRUM 0:615f90842ce8 12 // #define HEAVY_TRACING
MACRUM 0:615f90842ce8 13
MACRUM 0:615f90842ce8 14 static phy_device_driver_s device_driver;
MACRUM 0:615f90842ce8 15 static int8_t rf_radio_driver_id = -1;
MACRUM 0:615f90842ce8 16
MACRUM 0:615f90842ce8 17 const phy_rf_channel_configuration_s phy_subghz = {868000000, 1000000, 250000, 11, M_GFSK};
MACRUM 0:615f90842ce8 18
MACRUM 0:615f90842ce8 19 static phy_device_channel_page_s phy_channel_pages[] = {
MACRUM 0:615f90842ce8 20 {CHANNEL_PAGE_2, &phy_subghz},
MACRUM 0:615f90842ce8 21 {CHANNEL_PAGE_0, NULL}
MACRUM 0:615f90842ce8 22 };
MACRUM 0:615f90842ce8 23
MACRUM 0:615f90842ce8 24 static uint8_t tx_sequence = 0xff;
MACRUM 0:615f90842ce8 25 static uint8_t mac_tx_handle = 0;
MACRUM 0:615f90842ce8 26
MACRUM 0:615f90842ce8 27 static SimpleSpirit1 *rf_device = NULL;
MACRUM 0:615f90842ce8 28 static uint8_t rf_rx_buf[MAX_PACKET_LEN];
MACRUM 0:615f90842ce8 29
MACRUM 0:615f90842ce8 30 static uint16_t stored_short_adr;
MACRUM 0:615f90842ce8 31 static uint16_t stored_pan_id;
MACRUM 0:615f90842ce8 32 static uint8_t stored_mac_address[8] = MBED_CONF_SPIRIT1_MAC_ADDRESS;
MACRUM 0:615f90842ce8 33
MACRUM 0:615f90842ce8 34 #define RF_SIG_ACK_NEEDED (1<<0)
MACRUM 0:615f90842ce8 35 #define RF_SIG_CB_TX_DONE (1<<1)
MACRUM 0:615f90842ce8 36 #define RF_SIG_CB_RX_RCVD (1<<2)
MACRUM 0:615f90842ce8 37 static Thread rf_ack_sender(osPriorityRealtime);
MACRUM 0:615f90842ce8 38 static volatile uint8_t rf_rx_sequence;
MACRUM 0:615f90842ce8 39 static volatile bool rf_ack_sent = false;
MACRUM 0:615f90842ce8 40
MACRUM 0:615f90842ce8 41 /* MAC frame helper macros */
MACRUM 0:615f90842ce8 42 #define MAC_FCF_FRAME_TYPE_MASK 0x0007
MACRUM 0:615f90842ce8 43 #define MAC_FCF_FRAME_TYPE_SHIFT 0
MACRUM 0:615f90842ce8 44 #define MAC_FCF_SECURITY_BIT_MASK 0x0008
MACRUM 0:615f90842ce8 45 #define MAC_FCF_SECURITY_BIT_SHIFT 3
MACRUM 0:615f90842ce8 46 #define MAC_FCF_PENDING_BIT_MASK 0x0010
MACRUM 0:615f90842ce8 47 #define MAC_FCF_PENDING_BIT_SHIFT 4
MACRUM 0:615f90842ce8 48 #define MAC_FCF_ACK_REQ_BIT_MASK 0x0020
MACRUM 0:615f90842ce8 49 #define MAC_FCF_ACK_REQ_BIT_SHIFT 5
MACRUM 0:615f90842ce8 50 #define MAC_FCF_INTRA_PANID_MASK 0x0040
MACRUM 0:615f90842ce8 51 #define MAC_FCF_INTRA_PANID_SHIFT 6
MACRUM 0:615f90842ce8 52 #define MAC_FCF_DST_ADDR_MASK 0x0c00
MACRUM 0:615f90842ce8 53 #define MAC_FCF_DST_ADDR_SHIFT 10
MACRUM 0:615f90842ce8 54 #define MAC_FCF_VERSION_MASK 0x3000
MACRUM 0:615f90842ce8 55 #define MAC_FCF_VERSION_SHIFT 12
MACRUM 0:615f90842ce8 56 #define MAC_FCF_SRC_ADDR_MASK 0xc000
MACRUM 0:615f90842ce8 57 #define MAC_FCF_SRC_ADDR_SHIFT 14
MACRUM 0:615f90842ce8 58
MACRUM 0:615f90842ce8 59 /* MAC supported frame types */
MACRUM 0:615f90842ce8 60 #define FC_BEACON_FRAME 0x00
MACRUM 0:615f90842ce8 61 #define FC_DATA_FRAME 0x01
MACRUM 0:615f90842ce8 62 #define FC_ACK_FRAME 0x02
MACRUM 0:615f90842ce8 63 #define FC_CMD_FRAME 0x03
MACRUM 0:615f90842ce8 64
MACRUM 0:615f90842ce8 65 static void rf_if_lock(void)
MACRUM 0:615f90842ce8 66 {
MACRUM 0:615f90842ce8 67 platform_enter_critical();
MACRUM 0:615f90842ce8 68 }
MACRUM 0:615f90842ce8 69
MACRUM 0:615f90842ce8 70 static void rf_if_unlock(void)
MACRUM 0:615f90842ce8 71 {
MACRUM 0:615f90842ce8 72 platform_exit_critical();
MACRUM 0:615f90842ce8 73 }
MACRUM 0:615f90842ce8 74
MACRUM 0:615f90842ce8 75 static inline uint16_t rf_read_16_bit(uint8_t *data_ptr) { // little-endian
MACRUM 0:615f90842ce8 76 uint16_t ret;
MACRUM 0:615f90842ce8 77
MACRUM 0:615f90842ce8 78 ret = ((uint16_t)data_ptr[0]) + (((uint16_t)data_ptr[1]) << 8);
MACRUM 0:615f90842ce8 79 return ret;
MACRUM 0:615f90842ce8 80 }
MACRUM 0:615f90842ce8 81
MACRUM 0:615f90842ce8 82 static int8_t rf_trigger_send(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol)
MACRUM 0:615f90842ce8 83 {
MACRUM 0:615f90842ce8 84 #ifndef NDEBUG
MACRUM 0:615f90842ce8 85 debug_if(!(data_length >= 3), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
MACRUM 0:615f90842ce8 86 #endif
MACRUM 0:615f90842ce8 87
MACRUM 0:615f90842ce8 88 /* Give 'rf_ack_sender' a better chance to run */
MACRUM 0:615f90842ce8 89 Thread::yield();
MACRUM 0:615f90842ce8 90
MACRUM 0:615f90842ce8 91 /* Get Lock */
MACRUM 0:615f90842ce8 92 rf_if_lock();
MACRUM 0:615f90842ce8 93
MACRUM 0:615f90842ce8 94 /*Check if transmitter is busy*/
MACRUM 0:615f90842ce8 95 if(rf_device->is_receiving()) { /* betzw - WAS: (rf_device->channel_clear() != 0)), do NOT use this but rather study and enable automatic CCA */
MACRUM 0:615f90842ce8 96 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 97 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 98 #endif
MACRUM 0:615f90842ce8 99
MACRUM 0:615f90842ce8 100 /* Release Lock */
MACRUM 0:615f90842ce8 101 rf_if_unlock();
MACRUM 0:615f90842ce8 102
MACRUM 0:615f90842ce8 103 /*Return busy*/
MACRUM 0:615f90842ce8 104 return -1;
MACRUM 0:615f90842ce8 105 } else {
MACRUM 0:615f90842ce8 106 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 107 uint16_t fcf = rf_read_16_bit(data_ptr);
MACRUM 0:615f90842ce8 108 uint16_t need_ack;
MACRUM 0:615f90842ce8 109
MACRUM 0:615f90842ce8 110 /*Check if transmitted data needs to be acked*/
MACRUM 0:615f90842ce8 111 if((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT)
MACRUM 0:615f90842ce8 112 need_ack = 1;
MACRUM 0:615f90842ce8 113 else
MACRUM 0:615f90842ce8 114 need_ack = 0;
MACRUM 0:615f90842ce8 115 #endif
MACRUM 0:615f90842ce8 116
MACRUM 0:615f90842ce8 117 /*Store the sequence number for ACK handling*/
MACRUM 0:615f90842ce8 118 tx_sequence = *(data_ptr + 2);
MACRUM 0:615f90842ce8 119
MACRUM 0:615f90842ce8 120 /*Store TX handle*/
MACRUM 0:615f90842ce8 121 mac_tx_handle = tx_handle;
MACRUM 0:615f90842ce8 122
MACRUM 0:615f90842ce8 123 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 124 tr_info("%s (%d), len=%d, tx_handle=%x, tx_seq=%x, need_ack=%d (%x:%x, %x:%x, %x:%x, %x:%x)", __func__, __LINE__,
MACRUM 0:615f90842ce8 125 data_length, tx_handle, tx_sequence, need_ack,
MACRUM 0:615f90842ce8 126 data_ptr[3], data_ptr[4], data_ptr[5], data_ptr[6],
MACRUM 0:615f90842ce8 127 data_ptr[7], data_ptr[8], data_ptr[9], data_ptr[10]);
MACRUM 0:615f90842ce8 128 #endif
MACRUM 0:615f90842ce8 129
MACRUM 0:615f90842ce8 130 /*Send the packet*/
MACRUM 0:615f90842ce8 131 rf_device->send(data_ptr, data_length);
MACRUM 0:615f90842ce8 132
MACRUM 0:615f90842ce8 133 /* Release Lock */
MACRUM 0:615f90842ce8 134 rf_if_unlock();
MACRUM 0:615f90842ce8 135 }
MACRUM 0:615f90842ce8 136
MACRUM 0:615f90842ce8 137 /*Return success*/
MACRUM 0:615f90842ce8 138 return 0;
MACRUM 0:615f90842ce8 139 }
MACRUM 0:615f90842ce8 140
MACRUM 0:615f90842ce8 141 static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel)
MACRUM 0:615f90842ce8 142 {
MACRUM 0:615f90842ce8 143 int8_t ret_val = 0;
MACRUM 0:615f90842ce8 144 switch (new_state)
MACRUM 0:615f90842ce8 145 {
MACRUM 0:615f90842ce8 146 /*Reset PHY driver and set to idle*/
MACRUM 0:615f90842ce8 147 case PHY_INTERFACE_RESET:
MACRUM 0:615f90842ce8 148 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 149 rf_device->reset_board();
MACRUM 0:615f90842ce8 150 break;
MACRUM 0:615f90842ce8 151 /*Disable PHY Interface driver*/
MACRUM 0:615f90842ce8 152 case PHY_INTERFACE_DOWN:
MACRUM 0:615f90842ce8 153 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 154 ret_val = rf_device->off();
MACRUM 0:615f90842ce8 155 if(ret_val != 0) ret_val = -1;
MACRUM 0:615f90842ce8 156 break;
MACRUM 0:615f90842ce8 157 /*Enable PHY Interface driver*/
MACRUM 0:615f90842ce8 158 case PHY_INTERFACE_UP:
MACRUM 0:615f90842ce8 159 ret_val = rf_device->on();
MACRUM 0:615f90842ce8 160 if(ret_val != 0) {
MACRUM 0:615f90842ce8 161 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 162 ret_val = -1;
MACRUM 0:615f90842ce8 163 break;
MACRUM 0:615f90842ce8 164 }
MACRUM 0:615f90842ce8 165 tr_debug("%s (%d) - channel: %d", __func__, __LINE__, (int)rf_channel);
MACRUM 0:615f90842ce8 166 rf_device->set_channel(rf_channel);
MACRUM 0:615f90842ce8 167 break;
MACRUM 0:615f90842ce8 168 /*Enable wireless interface ED scan mode*/
MACRUM 0:615f90842ce8 169 case PHY_INTERFACE_RX_ENERGY_STATE:
MACRUM 0:615f90842ce8 170 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 171 break;
MACRUM 0:615f90842ce8 172 /*Enable Sniffer state*/
MACRUM 0:615f90842ce8 173 case PHY_INTERFACE_SNIFFER_STATE:
MACRUM 0:615f90842ce8 174 // TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel);
MACRUM 0:615f90842ce8 175 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 176 ret_val = -1;
MACRUM 0:615f90842ce8 177 break;
MACRUM 0:615f90842ce8 178 default:
MACRUM 0:615f90842ce8 179 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 180 break;
MACRUM 0:615f90842ce8 181 }
MACRUM 0:615f90842ce8 182 return ret_val;
MACRUM 0:615f90842ce8 183 }
MACRUM 0:615f90842ce8 184
MACRUM 0:615f90842ce8 185 static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr)
MACRUM 0:615f90842ce8 186 {
MACRUM 0:615f90842ce8 187 switch (extension_type)
MACRUM 0:615f90842ce8 188 {
MACRUM 0:615f90842ce8 189 /*Control MAC pending bit for Indirect data transmission*/
MACRUM 0:615f90842ce8 190 case PHY_EXTENSION_CTRL_PENDING_BIT:
MACRUM 0:615f90842ce8 191 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 192 break;
MACRUM 0:615f90842ce8 193
MACRUM 0:615f90842ce8 194 /*Return frame pending status*/
MACRUM 0:615f90842ce8 195 case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS:
MACRUM 0:615f90842ce8 196 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 197 *data_ptr = 0;
MACRUM 0:615f90842ce8 198 break;
MACRUM 0:615f90842ce8 199
MACRUM 0:615f90842ce8 200 /*Set channel, used for setting channel for energy scan*/
MACRUM 0:615f90842ce8 201 case PHY_EXTENSION_SET_CHANNEL:
MACRUM 0:615f90842ce8 202 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 203 break;
MACRUM 0:615f90842ce8 204
MACRUM 0:615f90842ce8 205 /*Read energy on the channel*/
MACRUM 0:615f90842ce8 206 case PHY_EXTENSION_READ_CHANNEL_ENERGY:
MACRUM 0:615f90842ce8 207 // TODO: *data_ptr = rf_get_channel_energy();
MACRUM 0:615f90842ce8 208 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 209 *data_ptr = (int8_t)rf_device->get_last_rssi_dbm();
MACRUM 0:615f90842ce8 210 break;
MACRUM 0:615f90842ce8 211
MACRUM 0:615f90842ce8 212 /*Read status of the link*/
MACRUM 0:615f90842ce8 213 case PHY_EXTENSION_READ_LINK_STATUS:
MACRUM 0:615f90842ce8 214 // TODO: *data_ptr = rf_get_link_status();
MACRUM 0:615f90842ce8 215 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 216 *data_ptr = rf_device->get_last_sqi(); // use SQI as link quality
MACRUM 0:615f90842ce8 217 break;
MACRUM 0:615f90842ce8 218
MACRUM 0:615f90842ce8 219 default:
MACRUM 0:615f90842ce8 220 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 221 break;
MACRUM 0:615f90842ce8 222 }
MACRUM 0:615f90842ce8 223 return 0;
MACRUM 0:615f90842ce8 224 }
MACRUM 0:615f90842ce8 225
MACRUM 0:615f90842ce8 226 static inline void rf_set_mac_address(uint8_t *ptr) {
MACRUM 0:615f90842ce8 227 tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
MACRUM 0:615f90842ce8 228 __func__, __LINE__,
MACRUM 0:615f90842ce8 229 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
MACRUM 0:615f90842ce8 230 for(int i = 0; i < 8; i++) {
MACRUM 0:615f90842ce8 231 stored_mac_address[i] = ptr[i];
MACRUM 0:615f90842ce8 232 }
MACRUM 0:615f90842ce8 233 }
MACRUM 0:615f90842ce8 234
MACRUM 0:615f90842ce8 235 static inline void rf_get_mac_address(uint8_t *ptr) {
MACRUM 0:615f90842ce8 236 for(int i = 0; i < 8; i++) {
MACRUM 0:615f90842ce8 237 ptr[i] = stored_mac_address[i];
MACRUM 0:615f90842ce8 238 }
MACRUM 0:615f90842ce8 239 tr_debug("%s (%d), adr0=%x, adr1=%x, adr2=%x, adr3=%x, adr4=%x, adr5=%x, adr6=%x, adr7=%x",
MACRUM 0:615f90842ce8 240 __func__, __LINE__,
MACRUM 0:615f90842ce8 241 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
MACRUM 0:615f90842ce8 242 }
MACRUM 0:615f90842ce8 243
MACRUM 0:615f90842ce8 244 static inline void rf_set_short_adr(uint8_t *ptr) {
MACRUM 0:615f90842ce8 245 stored_short_adr = (ptr[0] << 8) + ptr[1]; // big-endian
MACRUM 0:615f90842ce8 246 tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
MACRUM 0:615f90842ce8 247 __func__, __LINE__,
MACRUM 0:615f90842ce8 248 ptr[0], ptr[1], stored_short_adr);
MACRUM 0:615f90842ce8 249 }
MACRUM 0:615f90842ce8 250
MACRUM 0:615f90842ce8 251 static inline void rf_set_pan_id(uint8_t *ptr) {
MACRUM 0:615f90842ce8 252 stored_pan_id = (ptr[0] << 8) + ptr[1]; // big-endian
MACRUM 0:615f90842ce8 253 tr_debug("%s (%d), adr0=%x, adr1=%x, val=%d",
MACRUM 0:615f90842ce8 254 __func__, __LINE__,
MACRUM 0:615f90842ce8 255 ptr[0], ptr[1], stored_pan_id);
MACRUM 0:615f90842ce8 256 }
MACRUM 0:615f90842ce8 257
MACRUM 0:615f90842ce8 258 static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr)
MACRUM 0:615f90842ce8 259 {
MACRUM 0:615f90842ce8 260 switch (address_type)
MACRUM 0:615f90842ce8 261 {
MACRUM 0:615f90842ce8 262 /*Set 48-bit address*/
MACRUM 0:615f90842ce8 263 case PHY_MAC_48BIT:
MACRUM 0:615f90842ce8 264 /* Not used in this example */
MACRUM 0:615f90842ce8 265 // betzw - WAS: rf_set_mac_48bit(address_ptr);
MACRUM 0:615f90842ce8 266 break;
MACRUM 0:615f90842ce8 267 /*Set 64-bit address*/
MACRUM 0:615f90842ce8 268 case PHY_MAC_64BIT:
MACRUM 0:615f90842ce8 269 rf_set_mac_address(address_ptr);
MACRUM 0:615f90842ce8 270 break;
MACRUM 0:615f90842ce8 271 /*Set 16-bit address*/
MACRUM 0:615f90842ce8 272 case PHY_MAC_16BIT:
MACRUM 0:615f90842ce8 273 rf_set_short_adr(address_ptr);
MACRUM 0:615f90842ce8 274 break;
MACRUM 0:615f90842ce8 275 /*Set PAN Id*/
MACRUM 0:615f90842ce8 276 case PHY_MAC_PANID:
MACRUM 0:615f90842ce8 277 rf_set_pan_id(address_ptr);
MACRUM 0:615f90842ce8 278 break;
MACRUM 0:615f90842ce8 279 }
MACRUM 0:615f90842ce8 280
MACRUM 0:615f90842ce8 281 return 0;
MACRUM 0:615f90842ce8 282 }
MACRUM 0:615f90842ce8 283
MACRUM 0:615f90842ce8 284 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 285 static inline void rf_send_signal(int32_t signal) {
MACRUM 0:615f90842ce8 286 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 287 tr_info("%s (%d): %d", __func__, __LINE__, signal);
MACRUM 0:615f90842ce8 288 #endif
MACRUM 0:615f90842ce8 289 rf_ack_sender.signal_set(signal);
MACRUM 0:615f90842ce8 290 }
MACRUM 0:615f90842ce8 291
MACRUM 0:615f90842ce8 292 static phy_link_tx_status_e phy_status;
MACRUM 0:615f90842ce8 293 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 294 static void rf_handle_ack(uint8_t seq_number)
MACRUM 0:615f90842ce8 295 {
MACRUM 0:615f90842ce8 296 /*Received ACK sequence must be equal with transmitted packet sequence*/
MACRUM 0:615f90842ce8 297 if(tx_sequence == seq_number)
MACRUM 0:615f90842ce8 298 {
MACRUM 0:615f90842ce8 299 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 300 tr_info("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 301 #endif
MACRUM 0:615f90842ce8 302
MACRUM 0:615f90842ce8 303 /*Call PHY TX Done API*/
MACRUM 0:615f90842ce8 304 if(device_driver.phy_tx_done_cb){
MACRUM 0:615f90842ce8 305 phy_status = PHY_LINK_TX_DONE;
MACRUM 0:615f90842ce8 306 rf_send_signal(RF_SIG_CB_TX_DONE);
MACRUM 0:615f90842ce8 307 }
MACRUM 0:615f90842ce8 308 } else {
MACRUM 0:615f90842ce8 309 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 310 tr_info("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 311 #endif
MACRUM 0:615f90842ce8 312 }
MACRUM 0:615f90842ce8 313 }
MACRUM 0:615f90842ce8 314
MACRUM 0:615f90842ce8 315 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 316 static inline bool rf_check_mac_address(uint8_t *dest) {
MACRUM 0:615f90842ce8 317 for(int i = 0; i < 8; i++) {
MACRUM 0:615f90842ce8 318 if(dest[i] != stored_mac_address[7-i]) return false;
MACRUM 0:615f90842ce8 319 }
MACRUM 0:615f90842ce8 320 return true;
MACRUM 0:615f90842ce8 321 }
MACRUM 0:615f90842ce8 322
MACRUM 0:615f90842ce8 323 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 324 /* Returns true if packet should be accepted */
MACRUM 0:615f90842ce8 325 static bool rf_check_destination(int len, uint8_t *ack_requested) {
MACRUM 0:615f90842ce8 326 uint8_t frame_type;
MACRUM 0:615f90842ce8 327 uint16_t dst_pan_id;
MACRUM 0:615f90842ce8 328 uint16_t dst_short_adr;
MACRUM 0:615f90842ce8 329 uint8_t dst_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
MACRUM 0:615f90842ce8 330 uint8_t src_addr_mode = 0x0; /*0x00 = no address 0x01 = reserved 0x02 = 16-bit short address 0x03 = 64-bit extended address */
MACRUM 0:615f90842ce8 331 uint8_t min_size = 3; // FCF & SeqNr
MACRUM 0:615f90842ce8 332 bool ret = false;
MACRUM 0:615f90842ce8 333 #if defined(HEAVY_TRACING)
MACRUM 0:615f90842ce8 334 bool panid_compr = false;
MACRUM 0:615f90842ce8 335 #endif
MACRUM 0:615f90842ce8 336
MACRUM 0:615f90842ce8 337 if(len < 3) {
MACRUM 0:615f90842ce8 338 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 339 return false;
MACRUM 0:615f90842ce8 340 }
MACRUM 0:615f90842ce8 341
MACRUM 0:615f90842ce8 342 uint16_t fcf = rf_read_16_bit(rf_rx_buf);
MACRUM 0:615f90842ce8 343 frame_type = ((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT);
MACRUM 0:615f90842ce8 344 (*ack_requested) = ((fcf & MAC_FCF_ACK_REQ_BIT_MASK) >> MAC_FCF_ACK_REQ_BIT_SHIFT);
MACRUM 0:615f90842ce8 345 dst_addr_mode = ((fcf & MAC_FCF_DST_ADDR_MASK) >> MAC_FCF_DST_ADDR_SHIFT);
MACRUM 0:615f90842ce8 346 src_addr_mode = ((fcf & MAC_FCF_SRC_ADDR_MASK) >> MAC_FCF_SRC_ADDR_SHIFT);
MACRUM 0:615f90842ce8 347 #if defined(HEAVY_TRACING)
MACRUM 0:615f90842ce8 348 panid_compr = ((fcf & MAC_FCF_INTRA_PANID_MASK) >> MAC_FCF_INTRA_PANID_SHIFT);
MACRUM 0:615f90842ce8 349 #endif
MACRUM 0:615f90842ce8 350
MACRUM 0:615f90842ce8 351 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 352 tr_info("%s (%d): len=%d, ftype=%x, snr=%x, ack=%d, dst=%x, src=%x, intra=%d", __func__, __LINE__, len, frame_type,
MACRUM 0:615f90842ce8 353 rf_rx_buf[2], (*ack_requested), dst_addr_mode, src_addr_mode, panid_compr);
MACRUM 0:615f90842ce8 354 #endif
MACRUM 0:615f90842ce8 355
MACRUM 0:615f90842ce8 356 if(frame_type == FC_ACK_FRAME) { // betzw: we support up to two different forms of ACK frames!
MACRUM 0:615f90842ce8 357 if((len == 3) && (dst_addr_mode == 0x0) && (src_addr_mode == 0x0)) {
MACRUM 0:615f90842ce8 358 ret = true;
MACRUM 0:615f90842ce8 359 }
MACRUM 0:615f90842ce8 360
MACRUM 0:615f90842ce8 361 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 362 tr_info("%s (%d): ret=%d", __func__, __LINE__, ret);
MACRUM 0:615f90842ce8 363 #endif
MACRUM 0:615f90842ce8 364 (*ack_requested) = 0; // Never acknowledge ACK frames
MACRUM 0:615f90842ce8 365 return ret;
MACRUM 0:615f90842ce8 366 }
MACRUM 0:615f90842ce8 367
MACRUM 0:615f90842ce8 368 switch(dst_addr_mode) {
MACRUM 0:615f90842ce8 369 case 0x00:
MACRUM 0:615f90842ce8 370 ret = true; // no check possible;
MACRUM 0:615f90842ce8 371 break;
MACRUM 0:615f90842ce8 372 case 0x02:
MACRUM 0:615f90842ce8 373 min_size += 4; // pan id + short dest adr
MACRUM 0:615f90842ce8 374
MACRUM 0:615f90842ce8 375 if(len < 5) {
MACRUM 0:615f90842ce8 376 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 377 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 378 #endif
MACRUM 0:615f90842ce8 379 return false;
MACRUM 0:615f90842ce8 380 }
MACRUM 0:615f90842ce8 381
MACRUM 0:615f90842ce8 382 dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
MACRUM 0:615f90842ce8 383 if(dst_pan_id == 0xFFFF) {
MACRUM 0:615f90842ce8 384 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 385 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 386 #endif
MACRUM 0:615f90842ce8 387 ret = true;
MACRUM 0:615f90842ce8 388 break;
MACRUM 0:615f90842ce8 389 }
MACRUM 0:615f90842ce8 390
MACRUM 0:615f90842ce8 391 if(dst_pan_id == stored_pan_id) {
MACRUM 0:615f90842ce8 392 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 393 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 394 #endif
MACRUM 0:615f90842ce8 395 ret = true;
MACRUM 0:615f90842ce8 396 break;
MACRUM 0:615f90842ce8 397 } else {
MACRUM 0:615f90842ce8 398 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 399 tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_pan_id, stored_pan_id);
MACRUM 0:615f90842ce8 400 #endif
MACRUM 0:615f90842ce8 401 }
MACRUM 0:615f90842ce8 402
MACRUM 0:615f90842ce8 403 if(len < 7) {
MACRUM 0:615f90842ce8 404 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 405 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 406 #endif
MACRUM 0:615f90842ce8 407 return false;
MACRUM 0:615f90842ce8 408 }
MACRUM 0:615f90842ce8 409
MACRUM 0:615f90842ce8 410 dst_short_adr = rf_read_16_bit(&rf_rx_buf[5]);
MACRUM 0:615f90842ce8 411 if(dst_short_adr == stored_short_adr) {
MACRUM 0:615f90842ce8 412 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 413 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 414 #endif
MACRUM 0:615f90842ce8 415 ret = true;
MACRUM 0:615f90842ce8 416 break;
MACRUM 0:615f90842ce8 417 } else {
MACRUM 0:615f90842ce8 418 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 419 tr_debug("%s (%d): %d!=%d", __func__, __LINE__, dst_short_adr, stored_short_adr);
MACRUM 0:615f90842ce8 420 #endif
MACRUM 0:615f90842ce8 421 }
MACRUM 0:615f90842ce8 422 break;
MACRUM 0:615f90842ce8 423 case 0x03:
MACRUM 0:615f90842ce8 424 min_size += 10; // pan id + dest mac addr
MACRUM 0:615f90842ce8 425
MACRUM 0:615f90842ce8 426 if(len < 5) {
MACRUM 0:615f90842ce8 427 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 428 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 429 #endif
MACRUM 0:615f90842ce8 430 return false;
MACRUM 0:615f90842ce8 431 }
MACRUM 0:615f90842ce8 432
MACRUM 0:615f90842ce8 433 dst_pan_id = rf_read_16_bit(&rf_rx_buf[3]);
MACRUM 0:615f90842ce8 434 if(dst_pan_id == 0xFFFF) {
MACRUM 0:615f90842ce8 435 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 436 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 437 #endif
MACRUM 0:615f90842ce8 438 ret = true;
MACRUM 0:615f90842ce8 439 break;
MACRUM 0:615f90842ce8 440 }
MACRUM 0:615f90842ce8 441
MACRUM 0:615f90842ce8 442 if(dst_pan_id == stored_pan_id) {
MACRUM 0:615f90842ce8 443 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 444 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 445 #endif
MACRUM 0:615f90842ce8 446 ret = true;
MACRUM 0:615f90842ce8 447 break;
MACRUM 0:615f90842ce8 448 }
MACRUM 0:615f90842ce8 449
MACRUM 0:615f90842ce8 450 if(len < 13) {
MACRUM 0:615f90842ce8 451 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 452 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 453 #endif
MACRUM 0:615f90842ce8 454 return false;
MACRUM 0:615f90842ce8 455 }
MACRUM 0:615f90842ce8 456
MACRUM 0:615f90842ce8 457 ret = rf_check_mac_address(&rf_rx_buf[5]);
MACRUM 0:615f90842ce8 458 break;
MACRUM 0:615f90842ce8 459 default:
MACRUM 0:615f90842ce8 460 /* not supported */
MACRUM 0:615f90842ce8 461 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 462 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 463 #endif
MACRUM 0:615f90842ce8 464 return false;
MACRUM 0:615f90842ce8 465 }
MACRUM 0:615f90842ce8 466
MACRUM 0:615f90842ce8 467 if(ret && (*ack_requested)) {
MACRUM 0:615f90842ce8 468 rf_rx_sequence = rf_rx_buf[2];
MACRUM 0:615f90842ce8 469 }
MACRUM 0:615f90842ce8 470
MACRUM 0:615f90842ce8 471 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 472 tr_info("%s (%d), ret=%d, ack=%d", __func__, __LINE__, ret, (*ack_requested));
MACRUM 0:615f90842ce8 473 #endif
MACRUM 0:615f90842ce8 474 return ret;
MACRUM 0:615f90842ce8 475 }
MACRUM 0:615f90842ce8 476
MACRUM 0:615f90842ce8 477 static uint16_t rf_buffer_len = 0;
MACRUM 0:615f90842ce8 478 static uint8_t rf_sqi;
MACRUM 0:615f90842ce8 479 static int8_t rf_rssi;
MACRUM 0:615f90842ce8 480 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 481 static inline void rf_handle_rx_end(void)
MACRUM 0:615f90842ce8 482 {
MACRUM 0:615f90842ce8 483 uint8_t ack_requested = 0;
MACRUM 0:615f90842ce8 484
MACRUM 0:615f90842ce8 485 /* Get received data */
MACRUM 0:615f90842ce8 486 rf_buffer_len = rf_device->read(rf_rx_buf, MAX_PACKET_LEN);
MACRUM 0:615f90842ce8 487 if(!rf_buffer_len)
MACRUM 0:615f90842ce8 488 return;
MACRUM 0:615f90842ce8 489
MACRUM 0:615f90842ce8 490 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 491 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 492 #endif
MACRUM 0:615f90842ce8 493
MACRUM 0:615f90842ce8 494 /* Check if packet should be accepted */
MACRUM 0:615f90842ce8 495 if(!rf_check_destination(rf_buffer_len, &ack_requested)) {
MACRUM 0:615f90842ce8 496 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 497 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 498 #endif
MACRUM 0:615f90842ce8 499 return;
MACRUM 0:615f90842ce8 500 }
MACRUM 0:615f90842ce8 501
MACRUM 0:615f90842ce8 502 /* If waiting for ACK, check here if the packet is an ACK to a message previously sent */
MACRUM 0:615f90842ce8 503 uint16_t fcf = rf_read_16_bit(rf_rx_buf);
MACRUM 0:615f90842ce8 504 if(((fcf & MAC_FCF_FRAME_TYPE_MASK) >> MAC_FCF_FRAME_TYPE_SHIFT) == FC_ACK_FRAME) {
MACRUM 0:615f90842ce8 505 /*Send sequence number in ACK handler*/
MACRUM 0:615f90842ce8 506 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 507 tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
MACRUM 0:615f90842ce8 508 #endif
MACRUM 0:615f90842ce8 509 rf_handle_ack(rf_rx_buf[2]);
MACRUM 0:615f90842ce8 510 return;
MACRUM 0:615f90842ce8 511 }
MACRUM 0:615f90842ce8 512
MACRUM 0:615f90842ce8 513 /* Kick off ACK sending */
MACRUM 0:615f90842ce8 514 if(ack_requested) {
MACRUM 0:615f90842ce8 515 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 516 tr_debug("%s (%d), len=%u", __func__, __LINE__, (unsigned int)rf_buffer_len);
MACRUM 0:615f90842ce8 517 #endif
MACRUM 0:615f90842ce8 518 rf_send_signal(RF_SIG_ACK_NEEDED);
MACRUM 0:615f90842ce8 519 }
MACRUM 0:615f90842ce8 520
MACRUM 0:615f90842ce8 521 /* Get link information */
MACRUM 0:615f90842ce8 522 rf_rssi = (int8_t)rf_device->get_last_rssi_dbm();
MACRUM 0:615f90842ce8 523 rf_sqi = (uint8_t)rf_device->get_last_sqi(); // use SQI as link quality
MACRUM 0:615f90842ce8 524
MACRUM 0:615f90842ce8 525 /* Note: Checksum of the packet must be checked and removed before entering here */
MACRUM 0:615f90842ce8 526 /* TODO - betzw: what to do? */
MACRUM 0:615f90842ce8 527
MACRUM 0:615f90842ce8 528 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 529 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 530 #endif
MACRUM 0:615f90842ce8 531
MACRUM 0:615f90842ce8 532 /* Send received data and link information to the network stack */
MACRUM 0:615f90842ce8 533 if( device_driver.phy_rx_cb ){
MACRUM 0:615f90842ce8 534 rf_send_signal(RF_SIG_CB_RX_RCVD);
MACRUM 0:615f90842ce8 535 }
MACRUM 0:615f90842ce8 536 }
MACRUM 0:615f90842ce8 537
MACRUM 0:615f90842ce8 538 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 539 static inline void rf_handle_tx_end(void)
MACRUM 0:615f90842ce8 540 {
MACRUM 0:615f90842ce8 541 /* Check if this is an ACK sending which is still pending */
MACRUM 0:615f90842ce8 542 if(rf_ack_sent) {
MACRUM 0:615f90842ce8 543 rf_ack_sent = false;
MACRUM 0:615f90842ce8 544 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 545 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 546 #endif
MACRUM 0:615f90842ce8 547 return; // no need to inform stack
MACRUM 0:615f90842ce8 548 }
MACRUM 0:615f90842ce8 549
MACRUM 0:615f90842ce8 550 /*Call PHY TX Done API*/
MACRUM 0:615f90842ce8 551 if(device_driver.phy_tx_done_cb){
MACRUM 0:615f90842ce8 552 phy_status = PHY_LINK_TX_SUCCESS;
MACRUM 0:615f90842ce8 553 rf_send_signal(RF_SIG_CB_TX_DONE);
MACRUM 0:615f90842ce8 554 }
MACRUM 0:615f90842ce8 555 }
MACRUM 0:615f90842ce8 556
MACRUM 0:615f90842ce8 557 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 558 static inline void rf_handle_tx_err(void) {
MACRUM 0:615f90842ce8 559 /*Call PHY TX Done API*/
MACRUM 0:615f90842ce8 560 if(device_driver.phy_tx_done_cb){
MACRUM 0:615f90842ce8 561 phy_status = PHY_LINK_TX_FAIL;
MACRUM 0:615f90842ce8 562 rf_send_signal(RF_SIG_CB_TX_DONE);
MACRUM 0:615f90842ce8 563 }
MACRUM 0:615f90842ce8 564 }
MACRUM 0:615f90842ce8 565
MACRUM 0:615f90842ce8 566 /* Note: we are in IRQ context */
MACRUM 0:615f90842ce8 567 static void rf_callback_func(int event) {
MACRUM 0:615f90842ce8 568 switch(event) {
MACRUM 0:615f90842ce8 569 case SimpleSpirit1::RX_DONE:
MACRUM 0:615f90842ce8 570 rf_handle_rx_end();
MACRUM 0:615f90842ce8 571 break;
MACRUM 0:615f90842ce8 572 case SimpleSpirit1::TX_DONE:
MACRUM 0:615f90842ce8 573 rf_handle_tx_end();
MACRUM 0:615f90842ce8 574 break;
MACRUM 0:615f90842ce8 575 case SimpleSpirit1::TX_ERR:
MACRUM 0:615f90842ce8 576 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 577 tr_debug("%s (%d): TX_ERR!!!", __func__, __LINE__);
MACRUM 0:615f90842ce8 578 #endif
MACRUM 0:615f90842ce8 579 rf_handle_tx_err();
MACRUM 0:615f90842ce8 580 break;
MACRUM 0:615f90842ce8 581 }
MACRUM 0:615f90842ce8 582 }
MACRUM 0:615f90842ce8 583
MACRUM 0:615f90842ce8 584 static void rf_ack_loop(void) {
MACRUM 0:615f90842ce8 585 static uint16_t buffer[2] = {
MACRUM 0:615f90842ce8 586 (FC_ACK_FRAME << MAC_FCF_FRAME_TYPE_SHIFT),
MACRUM 0:615f90842ce8 587 0x0
MACRUM 0:615f90842ce8 588 };
MACRUM 0:615f90842ce8 589
MACRUM 0:615f90842ce8 590 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 591
MACRUM 0:615f90842ce8 592 do {
MACRUM 0:615f90842ce8 593 /* Wait for signal */
MACRUM 0:615f90842ce8 594 osEvent event = rf_ack_sender.signal_wait(0);
MACRUM 0:615f90842ce8 595
MACRUM 0:615f90842ce8 596 if(event.status != osEventSignal) {
MACRUM 0:615f90842ce8 597 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 598 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 599 #endif
MACRUM 0:615f90842ce8 600 continue;
MACRUM 0:615f90842ce8 601 }
MACRUM 0:615f90842ce8 602
MACRUM 0:615f90842ce8 603 int32_t signals = event.value.signals;
MACRUM 0:615f90842ce8 604
MACRUM 0:615f90842ce8 605 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 606 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 607 #endif
MACRUM 0:615f90842ce8 608
MACRUM 0:615f90842ce8 609 /* Get Lock */
MACRUM 0:615f90842ce8 610 rf_if_lock();
MACRUM 0:615f90842ce8 611
MACRUM 0:615f90842ce8 612 if(signals & RF_SIG_ACK_NEEDED) {
MACRUM 0:615f90842ce8 613 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 614 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 615 #endif
MACRUM 0:615f90842ce8 616
MACRUM 0:615f90842ce8 617 /* Prepare payload */
MACRUM 0:615f90842ce8 618 uint8_t *ptr = (uint8_t*)&buffer[1];
MACRUM 0:615f90842ce8 619 ptr[0] = rf_rx_sequence; // Sequence number
MACRUM 0:615f90842ce8 620
MACRUM 0:615f90842ce8 621 /* Wait for device not receiving */
MACRUM 0:615f90842ce8 622 while(rf_device->is_receiving()) {
MACRUM 0:615f90842ce8 623 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 624 tr_info("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 625 #endif
MACRUM 0:615f90842ce8 626 wait_us(10);
MACRUM 0:615f90842ce8 627 }
MACRUM 0:615f90842ce8 628
MACRUM 0:615f90842ce8 629 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 630 tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
MACRUM 0:615f90842ce8 631 #endif
MACRUM 0:615f90842ce8 632
MACRUM 0:615f90842ce8 633 /* Set information that we have sent an ACK */
MACRUM 0:615f90842ce8 634 rf_ack_sent = true;
MACRUM 0:615f90842ce8 635
MACRUM 0:615f90842ce8 636 /*Send the packet*/
MACRUM 0:615f90842ce8 637 rf_device->send((uint8_t*)buffer, 3);
MACRUM 0:615f90842ce8 638
MACRUM 0:615f90842ce8 639 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 640 tr_debug("%s (%d), hdr=%x, nr=%x", __func__, __LINE__, buffer[0], ptr[0]);
MACRUM 0:615f90842ce8 641 #endif
MACRUM 0:615f90842ce8 642 }
MACRUM 0:615f90842ce8 643
MACRUM 0:615f90842ce8 644 if(signals & RF_SIG_CB_TX_DONE) {
MACRUM 0:615f90842ce8 645 device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 0, 0);
MACRUM 0:615f90842ce8 646 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 647 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 648 #endif
MACRUM 0:615f90842ce8 649 }
MACRUM 0:615f90842ce8 650
MACRUM 0:615f90842ce8 651 if(signals & RF_SIG_CB_RX_RCVD) {
MACRUM 0:615f90842ce8 652 device_driver.phy_rx_cb(rf_rx_buf, rf_buffer_len, rf_sqi, rf_rssi, rf_radio_driver_id);
MACRUM 0:615f90842ce8 653 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 654 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 655 #endif
MACRUM 0:615f90842ce8 656 }
MACRUM 0:615f90842ce8 657
MACRUM 0:615f90842ce8 658 /* Release Lock */
MACRUM 0:615f90842ce8 659 rf_if_unlock();
MACRUM 0:615f90842ce8 660
MACRUM 0:615f90842ce8 661 #ifdef HEAVY_TRACING
MACRUM 0:615f90842ce8 662 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 663 #endif
MACRUM 0:615f90842ce8 664 } while(true);
MACRUM 0:615f90842ce8 665 }
MACRUM 0:615f90842ce8 666
MACRUM 0:615f90842ce8 667 void NanostackRfPhySpirit1::rf_init(void) {
MACRUM 0:615f90842ce8 668 #ifndef NDEBUG
MACRUM 0:615f90842ce8 669 osStatus ret;
MACRUM 0:615f90842ce8 670 #endif
MACRUM 0:615f90842ce8 671
MACRUM 0:615f90842ce8 672 if(rf_device == NULL) {
MACRUM 0:615f90842ce8 673 rf_device = &SimpleSpirit1::CreateInstance(_spi_mosi, _spi_miso, _spi_sclk, _dev_irq, _dev_cs, _dev_sdn, _brd_led);
MACRUM 0:615f90842ce8 674 rf_device->attach_irq_callback(rf_callback_func);
MACRUM 0:615f90842ce8 675
MACRUM 0:615f90842ce8 676 #ifndef NDEBUG
MACRUM 0:615f90842ce8 677 ret =
MACRUM 0:615f90842ce8 678 #endif
MACRUM 0:615f90842ce8 679 rf_ack_sender.start(rf_ack_loop);
MACRUM 0:615f90842ce8 680
MACRUM 0:615f90842ce8 681 #ifndef NDEBUG
MACRUM 0:615f90842ce8 682 debug_if(!(ret == osOK), "\n\rassert failed in: %s (%d)\n\r", __func__, __LINE__);
MACRUM 0:615f90842ce8 683 #endif
MACRUM 0:615f90842ce8 684 }
MACRUM 0:615f90842ce8 685 }
MACRUM 0:615f90842ce8 686
MACRUM 0:615f90842ce8 687 NanostackRfPhySpirit1::NanostackRfPhySpirit1(PinName spi_mosi, PinName spi_miso, PinName spi_sclk,
MACRUM 0:615f90842ce8 688 PinName dev_irq, PinName dev_cs, PinName dev_sdn, PinName brd_led) :
MACRUM 0:615f90842ce8 689 _spi_mosi(spi_mosi),
MACRUM 0:615f90842ce8 690 _spi_miso(spi_miso),
MACRUM 0:615f90842ce8 691 _spi_sclk(spi_sclk),
MACRUM 0:615f90842ce8 692 _dev_irq(dev_irq),
MACRUM 0:615f90842ce8 693 _dev_cs(dev_cs),
MACRUM 0:615f90842ce8 694 _dev_sdn(dev_sdn),
MACRUM 0:615f90842ce8 695 _brd_led(brd_led)
MACRUM 0:615f90842ce8 696 {
MACRUM 0:615f90842ce8 697 /* Nothing to do */
MACRUM 0:615f90842ce8 698 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 699 }
MACRUM 0:615f90842ce8 700
MACRUM 0:615f90842ce8 701 NanostackRfPhySpirit1::~NanostackRfPhySpirit1()
MACRUM 0:615f90842ce8 702 {
MACRUM 0:615f90842ce8 703 /* Nothing to do */
MACRUM 0:615f90842ce8 704 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 705 }
MACRUM 0:615f90842ce8 706
MACRUM 0:615f90842ce8 707 int8_t NanostackRfPhySpirit1::rf_register()
MACRUM 0:615f90842ce8 708 {
MACRUM 0:615f90842ce8 709 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 710
MACRUM 0:615f90842ce8 711 /* Get Lock */
MACRUM 0:615f90842ce8 712 rf_if_lock();
MACRUM 0:615f90842ce8 713
MACRUM 0:615f90842ce8 714 /* Do some initialization */
MACRUM 0:615f90842ce8 715 rf_init();
MACRUM 0:615f90842ce8 716
MACRUM 0:615f90842ce8 717 /* Set pointer to MAC address */
MACRUM 0:615f90842ce8 718 device_driver.PHY_MAC = stored_mac_address;
MACRUM 0:615f90842ce8 719
MACRUM 0:615f90842ce8 720 /* Set driver Name */
MACRUM 0:615f90842ce8 721 device_driver.driver_description = (char*)"Spirit1 Sub-GHz RF";
MACRUM 0:615f90842ce8 722
MACRUM 0:615f90842ce8 723 /*Type of RF PHY is SubGHz*/
MACRUM 0:615f90842ce8 724 device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE;
MACRUM 0:615f90842ce8 725
MACRUM 0:615f90842ce8 726 /*Maximum size of payload*/
MACRUM 0:615f90842ce8 727 device_driver.phy_MTU = MAX_PACKET_LEN;
MACRUM 0:615f90842ce8 728
MACRUM 0:615f90842ce8 729 /*No header in PHY*/
MACRUM 0:615f90842ce8 730 device_driver.phy_header_length = 0;
MACRUM 0:615f90842ce8 731
MACRUM 0:615f90842ce8 732 /*No tail in PHY*/
MACRUM 0:615f90842ce8 733 device_driver.phy_tail_length = 0;
MACRUM 0:615f90842ce8 734
MACRUM 0:615f90842ce8 735 /*Set up driver functions*/
MACRUM 0:615f90842ce8 736 device_driver.address_write = &rf_address_write;
MACRUM 0:615f90842ce8 737 device_driver.extension = &rf_extension;
MACRUM 0:615f90842ce8 738 device_driver.state_control = &rf_interface_state_control;
MACRUM 0:615f90842ce8 739 device_driver.tx = &rf_trigger_send;
MACRUM 0:615f90842ce8 740
MACRUM 0:615f90842ce8 741 /*Set supported channel pages*/
MACRUM 0:615f90842ce8 742 device_driver.phy_channel_pages = phy_channel_pages;
MACRUM 0:615f90842ce8 743
MACRUM 0:615f90842ce8 744 //Nullify rx/tx callbacks
MACRUM 0:615f90842ce8 745 device_driver.phy_rx_cb = NULL;
MACRUM 0:615f90842ce8 746 device_driver.phy_tx_done_cb = NULL;
MACRUM 0:615f90842ce8 747 device_driver.arm_net_virtual_rx_cb = NULL;
MACRUM 0:615f90842ce8 748 device_driver.arm_net_virtual_tx_cb = NULL;
MACRUM 0:615f90842ce8 749
MACRUM 0:615f90842ce8 750 /*Register device driver*/
MACRUM 0:615f90842ce8 751 rf_radio_driver_id = arm_net_phy_register(&device_driver);
MACRUM 0:615f90842ce8 752
MACRUM 0:615f90842ce8 753 /* Release Lock */
MACRUM 0:615f90842ce8 754 rf_if_unlock();
MACRUM 0:615f90842ce8 755
MACRUM 0:615f90842ce8 756 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 757 return rf_radio_driver_id;
MACRUM 0:615f90842ce8 758 }
MACRUM 0:615f90842ce8 759
MACRUM 0:615f90842ce8 760 void NanostackRfPhySpirit1::rf_unregister()
MACRUM 0:615f90842ce8 761 {
MACRUM 0:615f90842ce8 762 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 763
MACRUM 0:615f90842ce8 764 /* Get Lock */
MACRUM 0:615f90842ce8 765 rf_if_lock();
MACRUM 0:615f90842ce8 766
MACRUM 0:615f90842ce8 767 if (rf_radio_driver_id >= 0) {
MACRUM 0:615f90842ce8 768 arm_net_phy_unregister(rf_radio_driver_id);
MACRUM 0:615f90842ce8 769 rf_radio_driver_id = -1;
MACRUM 0:615f90842ce8 770 }
MACRUM 0:615f90842ce8 771
MACRUM 0:615f90842ce8 772 /* Release Lock */
MACRUM 0:615f90842ce8 773 rf_if_unlock();
MACRUM 0:615f90842ce8 774 }
MACRUM 0:615f90842ce8 775
MACRUM 0:615f90842ce8 776 void NanostackRfPhySpirit1::get_mac_address(uint8_t *mac)
MACRUM 0:615f90842ce8 777 {
MACRUM 0:615f90842ce8 778 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 779
MACRUM 0:615f90842ce8 780 /* Get Lock */
MACRUM 0:615f90842ce8 781 rf_if_lock();
MACRUM 0:615f90842ce8 782
MACRUM 0:615f90842ce8 783 if(rf_radio_driver_id >= 0) {
MACRUM 0:615f90842ce8 784 rf_get_mac_address(mac);
MACRUM 0:615f90842ce8 785 } else {
MACRUM 0:615f90842ce8 786 error("NanostackRfPhySpirit1 must be registered to read mac address");
MACRUM 0:615f90842ce8 787 }
MACRUM 0:615f90842ce8 788
MACRUM 0:615f90842ce8 789 /* Release Lock */
MACRUM 0:615f90842ce8 790 rf_if_unlock();
MACRUM 0:615f90842ce8 791 }
MACRUM 0:615f90842ce8 792
MACRUM 0:615f90842ce8 793 void NanostackRfPhySpirit1::set_mac_address(uint8_t *mac)
MACRUM 0:615f90842ce8 794 {
MACRUM 0:615f90842ce8 795 tr_debug("%s (%d)", __func__, __LINE__);
MACRUM 0:615f90842ce8 796
MACRUM 0:615f90842ce8 797 /* Get Lock */
MACRUM 0:615f90842ce8 798 rf_if_lock();
MACRUM 0:615f90842ce8 799
MACRUM 0:615f90842ce8 800 if(rf_radio_driver_id < 0) {
MACRUM 0:615f90842ce8 801 rf_set_mac_address(mac);
MACRUM 0:615f90842ce8 802 } else {
MACRUM 0:615f90842ce8 803 error("NanostackRfPhySpirit1 cannot change mac address when running");
MACRUM 0:615f90842ce8 804 }
MACRUM 0:615f90842ce8 805
MACRUM 0:615f90842ce8 806 /* Release Lock */
MACRUM 0:615f90842ce8 807 rf_if_unlock();
MACRUM 0:615f90842ce8 808 }
MACRUM 0:615f90842ce8 809
MACRUM 0:615f90842ce8 810 #endif /* MBED_CONF_RTOS_PRESENT */