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