123r

Dependencies:   WNC14A2AInterface

Committer:
m_ahsan
Date:
Thu May 02 13:15:26 2019 +0000
Revision:
7:c8e4e62c5fa7
Parent:
0:2563b0415d1f
123

Who changed what in which revision?

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