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