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