wifi test

Dependencies:   X_NUCLEO_IKS01A2 mbed-http

Committer:
JMF
Date:
Wed Sep 05 14:28:24 2018 +0000
Revision:
0:24d3eb812fd4
Initial commit

Who changed what in which revision?

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