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).
mbed_driver_api.cpp@11:b769d6caad82, 2016-10-26 (annotated)
- Committer:
- Wolfgang Betz
- Date:
- Wed Oct 26 15:08:44 2016 +0200
- Revision:
- 11:b769d6caad82
- Parent:
- 10:dedd44d58c0f
- Child:
- 12:b8056eda4028
Extend nanostack interface
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 |
10:dedd44d58c0f | 3 | |
| Wolfgang Betz |
11:b769d6caad82 | 4 | /*Atmel RF Part Type*/ |
| Wolfgang Betz |
11:b769d6caad82 | 5 | // betzw - TODO |
| Wolfgang Betz |
11:b769d6caad82 | 6 | typedef enum |
| Wolfgang Betz |
11:b769d6caad82 | 7 | { |
| Wolfgang Betz |
11:b769d6caad82 | 8 | ATMEL_UNKNOW_DEV = 0, |
| Wolfgang Betz |
11:b769d6caad82 | 9 | ATMEL_AT86RF212, |
| Wolfgang Betz |
11:b769d6caad82 | 10 | ATMEL_AT86RF231, |
| Wolfgang Betz |
11:b769d6caad82 | 11 | ATMEL_AT86RF233 |
| Wolfgang Betz |
11:b769d6caad82 | 12 | }rf_trx_part_e; |
| Wolfgang Betz |
11:b769d6caad82 | 13 | |
| Wolfgang Betz |
10:dedd44d58c0f | 14 | static uint8_t mac_address[8] = { |
| Wolfgang Betz |
10:dedd44d58c0f | 15 | MBED_CONF_SPIRIT1_MAC_ADDRESS_0, |
| Wolfgang Betz |
10:dedd44d58c0f | 16 | MBED_CONF_SPIRIT1_MAC_ADDRESS_1, |
| Wolfgang Betz |
10:dedd44d58c0f | 17 | MBED_CONF_SPIRIT1_MAC_ADDRESS_2, |
| Wolfgang Betz |
10:dedd44d58c0f | 18 | MBED_CONF_SPIRIT1_MAC_ADDRESS_3, |
| Wolfgang Betz |
10:dedd44d58c0f | 19 | MBED_CONF_SPIRIT1_MAC_ADDRESS_4, |
| Wolfgang Betz |
10:dedd44d58c0f | 20 | MBED_CONF_SPIRIT1_MAC_ADDRESS_5, |
| Wolfgang Betz |
10:dedd44d58c0f | 21 | MBED_CONF_SPIRIT1_MAC_ADDRESS_6, |
| Wolfgang Betz |
10:dedd44d58c0f | 22 | MBED_CONF_SPIRIT1_MAC_ADDRESS_7 |
| Wolfgang Betz |
10:dedd44d58c0f | 23 | }; |
| Wolfgang Betz |
10:dedd44d58c0f | 24 | static phy_device_driver_s device_driver; |
| Wolfgang Betz |
10:dedd44d58c0f | 25 | static int8_t rf_radio_driver_id = -1; |
| Wolfgang Betz |
11:b769d6caad82 | 26 | static uint8_t rf_rnd_rssi = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 27 | |
| Wolfgang Betz |
10:dedd44d58c0f | 28 | const phy_rf_channel_configuration_s phy_subghz = {868000000, 1000000, 250000, 11, M_GFSK}; |
| Wolfgang Betz |
10:dedd44d58c0f | 29 | |
| Wolfgang Betz |
10:dedd44d58c0f | 30 | static phy_device_channel_page_s phy_channel_pages[] = { |
| Wolfgang Betz |
10:dedd44d58c0f | 31 | {CHANNEL_PAGE_2, &phy_subghz}, |
| Wolfgang Betz |
10:dedd44d58c0f | 32 | {CHANNEL_PAGE_0, NULL} |
| Wolfgang Betz |
10:dedd44d58c0f | 33 | }; |
| Wolfgang Betz |
10:dedd44d58c0f | 34 | |
| Wolfgang Betz |
10:dedd44d58c0f | 35 | static uint8_t tx_sequence = 0xff; |
| Wolfgang Betz |
10:dedd44d58c0f | 36 | static uint8_t mac_tx_handle = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 37 | |
| Wolfgang Betz |
10:dedd44d58c0f | 38 | static SimpleSpirit1 *rf_device = NULL; |
| Wolfgang Betz |
10:dedd44d58c0f | 39 | static uint8_t rf_rx_buf[MAX_PACKET_LEN]; |
| Wolfgang Betz |
10:dedd44d58c0f | 40 | |
| Wolfgang Betz |
10:dedd44d58c0f | 41 | static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle, data_protocol_e data_protocol) |
| Wolfgang Betz |
10:dedd44d58c0f | 42 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 43 | /*Check if transmitter is busy*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 44 | if((rf_device->get_receiving_packet()) || (rf_device->channel_clear() == 0)) { |
| Wolfgang Betz |
10:dedd44d58c0f | 45 | /*Return busy*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 46 | return -1; |
| Wolfgang Betz |
10:dedd44d58c0f | 47 | } else { |
| Wolfgang Betz |
10:dedd44d58c0f | 48 | /*Store the sequence number for ACK handling*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 49 | tx_sequence = *(data_ptr + 2); |
| Wolfgang Betz |
10:dedd44d58c0f | 50 | |
| Wolfgang Betz |
10:dedd44d58c0f | 51 | /*Store TX handle*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 52 | mac_tx_handle = tx_handle; |
| Wolfgang Betz |
10:dedd44d58c0f | 53 | |
| Wolfgang Betz |
10:dedd44d58c0f | 54 | /*Send the packet*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 55 | rf_device->send(data_ptr, data_length); |
| Wolfgang Betz |
10:dedd44d58c0f | 56 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 57 | |
| Wolfgang Betz |
10:dedd44d58c0f | 58 | /*Return success*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 59 | return 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 60 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 61 | |
| Wolfgang Betz |
10:dedd44d58c0f | 62 | static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) |
| Wolfgang Betz |
10:dedd44d58c0f | 63 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 64 | int8_t ret_val = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 65 | switch (new_state) |
| Wolfgang Betz |
10:dedd44d58c0f | 66 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 67 | /*Reset PHY driver and set to idle*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 68 | case PHY_INTERFACE_RESET: |
| Wolfgang Betz |
10:dedd44d58c0f | 69 | rf_device->reset_board(); |
| Wolfgang Betz |
10:dedd44d58c0f | 70 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 71 | /*Disable PHY Interface driver*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 72 | case PHY_INTERFACE_DOWN: |
| Wolfgang Betz |
10:dedd44d58c0f | 73 | ret_val = rf_device->off(); |
| Wolfgang Betz |
10:dedd44d58c0f | 74 | if(ret_val != 0) ret_val = -1; |
| Wolfgang Betz |
10:dedd44d58c0f | 75 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 76 | /*Enable PHY Interface driver*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 77 | case PHY_INTERFACE_UP: |
| Wolfgang Betz |
10:dedd44d58c0f | 78 | ret_val = rf_device->on(); |
| Wolfgang Betz |
10:dedd44d58c0f | 79 | if(ret_val != 0) { |
| Wolfgang Betz |
10:dedd44d58c0f | 80 | ret_val = -1; |
| Wolfgang Betz |
10:dedd44d58c0f | 81 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 82 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 83 | rf_device->set_channel(rf_channel); |
| Wolfgang Betz |
10:dedd44d58c0f | 84 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 85 | /*Enable wireless interface ED scan mode*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 86 | case PHY_INTERFACE_RX_ENERGY_STATE: |
| Wolfgang Betz |
10:dedd44d58c0f | 87 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 88 | /*Enable Sniffer state*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 89 | case PHY_INTERFACE_SNIFFER_STATE: |
| Wolfgang Betz |
10:dedd44d58c0f | 90 | // TODO - if we really need this - WAS: rf_setup_sniffer(rf_channel); |
| Wolfgang Betz |
10:dedd44d58c0f | 91 | ret_val = -1; |
| Wolfgang Betz |
10:dedd44d58c0f | 92 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 93 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 94 | return ret_val; |
| Wolfgang Betz |
10:dedd44d58c0f | 95 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 96 | |
| Wolfgang Betz |
10:dedd44d58c0f | 97 | static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) |
| Wolfgang Betz |
10:dedd44d58c0f | 98 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 99 | switch (extension_type) |
| Wolfgang Betz |
10:dedd44d58c0f | 100 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 101 | /*Control MAC pending bit for Indirect data transmission*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 102 | case PHY_EXTENSION_CTRL_PENDING_BIT: |
| Wolfgang Betz |
11:b769d6caad82 | 103 | break; |
| Wolfgang Betz |
11:b769d6caad82 | 104 | |
| Wolfgang Betz |
10:dedd44d58c0f | 105 | /*Return frame pending status*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 106 | case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: |
| Wolfgang Betz |
10:dedd44d58c0f | 107 | // TODO: *data_ptr = rf_if_last_acked_pending(); |
| Wolfgang Betz |
11:b769d6caad82 | 108 | *data_ptr = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 109 | break; |
| Wolfgang Betz |
11:b769d6caad82 | 110 | |
| Wolfgang Betz |
10:dedd44d58c0f | 111 | /*Set channel, used for setting channel for energy scan*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 112 | case PHY_EXTENSION_SET_CHANNEL: |
| Wolfgang Betz |
10:dedd44d58c0f | 113 | break; |
| Wolfgang Betz |
11:b769d6caad82 | 114 | |
| Wolfgang Betz |
10:dedd44d58c0f | 115 | /*Read energy on the channel*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 116 | case PHY_EXTENSION_READ_CHANNEL_ENERGY: |
| Wolfgang Betz |
10:dedd44d58c0f | 117 | // TODO: *data_ptr = rf_get_channel_energy(); |
| Wolfgang Betz |
11:b769d6caad82 | 118 | *data_ptr = rf_device->get_last_rssi_dbm(); |
| Wolfgang Betz |
10:dedd44d58c0f | 119 | break; |
| Wolfgang Betz |
11:b769d6caad82 | 120 | |
| Wolfgang Betz |
10:dedd44d58c0f | 121 | /*Read status of the link*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 122 | case PHY_EXTENSION_READ_LINK_STATUS: |
| Wolfgang Betz |
10:dedd44d58c0f | 123 | // TODO: *data_ptr = rf_get_link_status(); |
| Wolfgang Betz |
11:b769d6caad82 | 124 | *data_ptr = rf_device->get_last_lqi(); |
| Wolfgang Betz |
10:dedd44d58c0f | 125 | break; |
| Wolfgang Betz |
11:b769d6caad82 | 126 | |
| Wolfgang Betz |
10:dedd44d58c0f | 127 | default: |
| Wolfgang Betz |
10:dedd44d58c0f | 128 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 129 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 130 | return 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 131 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 132 | |
| Wolfgang Betz |
10:dedd44d58c0f | 133 | static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) |
| Wolfgang Betz |
10:dedd44d58c0f | 134 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 135 | |
| Wolfgang Betz |
11:b769d6caad82 | 136 | #if 0 // TODO - if we really need this - WAS |
| Wolfgang Betz |
10:dedd44d58c0f | 137 | switch (address_type) |
| Wolfgang Betz |
10:dedd44d58c0f | 138 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 139 | /*Set 48-bit address*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 140 | case PHY_MAC_48BIT: |
| Wolfgang Betz |
10:dedd44d58c0f | 141 | /* Not used in this example */ |
| Wolfgang Betz |
10:dedd44d58c0f | 142 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 143 | /*Set 64-bit address*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 144 | case PHY_MAC_64BIT: |
| Wolfgang Betz |
10:dedd44d58c0f | 145 | rf_set_mac_address(address_ptr); |
| Wolfgang Betz |
10:dedd44d58c0f | 146 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 147 | /*Set 16-bit address*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 148 | case PHY_MAC_16BIT: |
| Wolfgang Betz |
10:dedd44d58c0f | 149 | rf_set_short_adr(address_ptr); |
| Wolfgang Betz |
10:dedd44d58c0f | 150 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 151 | /*Set PAN Id*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 152 | case PHY_MAC_PANID: |
| Wolfgang Betz |
10:dedd44d58c0f | 153 | rf_set_pan_id(address_ptr); |
| Wolfgang Betz |
10:dedd44d58c0f | 154 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 155 | } |
| Wolfgang Betz |
11:b769d6caad82 | 156 | #endif // 0 |
| Wolfgang Betz |
10:dedd44d58c0f | 157 | |
| Wolfgang Betz |
10:dedd44d58c0f | 158 | return 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 159 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 160 | |
| Wolfgang Betz |
10:dedd44d58c0f | 161 | /* Note: we are in IRQ context */ |
| Wolfgang Betz |
10:dedd44d58c0f | 162 | static void rf_handle_ack(uint8_t seq_number, uint8_t data_pending) |
| Wolfgang Betz |
10:dedd44d58c0f | 163 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 164 | phy_link_tx_status_e phy_status; |
| Wolfgang Betz |
10:dedd44d58c0f | 165 | |
| Wolfgang Betz |
10:dedd44d58c0f | 166 | // TODO - if we really need this - WAS: rf_if_lock(); |
| Wolfgang Betz |
10:dedd44d58c0f | 167 | |
| Wolfgang Betz |
10:dedd44d58c0f | 168 | /*Received ACK sequence must be equal with transmitted packet sequence*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 169 | if(tx_sequence == seq_number) |
| Wolfgang Betz |
10:dedd44d58c0f | 170 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 171 | /*When data pending bit in ACK frame is set, inform NET library*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 172 | if(data_pending) |
| Wolfgang Betz |
10:dedd44d58c0f | 173 | phy_status = PHY_LINK_TX_DONE_PENDING; |
| Wolfgang Betz |
10:dedd44d58c0f | 174 | else |
| Wolfgang Betz |
10:dedd44d58c0f | 175 | phy_status = PHY_LINK_TX_DONE; |
| Wolfgang Betz |
10:dedd44d58c0f | 176 | |
| Wolfgang Betz |
10:dedd44d58c0f | 177 | /*Call PHY TX Done API*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 178 | if(device_driver.phy_tx_done_cb){ |
| Wolfgang Betz |
10:dedd44d58c0f | 179 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1); |
| Wolfgang Betz |
10:dedd44d58c0f | 180 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 181 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 182 | |
| Wolfgang Betz |
10:dedd44d58c0f | 183 | // TODO - if we really need this - WAS: rf_if_unlock(); |
| Wolfgang Betz |
10:dedd44d58c0f | 184 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 185 | |
| Wolfgang Betz |
10:dedd44d58c0f | 186 | /* Note: we are in IRQ context */ |
| Wolfgang Betz |
10:dedd44d58c0f | 187 | static inline void rf_handle_rx_end(void) |
| Wolfgang Betz |
10:dedd44d58c0f | 188 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 189 | uint8_t rf_lqi; |
| Wolfgang Betz |
10:dedd44d58c0f | 190 | int8_t rf_rssi; |
| Wolfgang Betz |
10:dedd44d58c0f | 191 | uint16_t rf_buffer_len; |
| Wolfgang Betz |
10:dedd44d58c0f | 192 | |
| Wolfgang Betz |
10:dedd44d58c0f | 193 | /* Get received data */ |
| Wolfgang Betz |
10:dedd44d58c0f | 194 | rf_buffer_len = rf_device->read(rf_rx_buf, MAX_PACKET_LEN); |
| Wolfgang Betz |
10:dedd44d58c0f | 195 | if(!rf_buffer_len) |
| Wolfgang Betz |
10:dedd44d58c0f | 196 | return; |
| Wolfgang Betz |
10:dedd44d58c0f | 197 | |
| Wolfgang Betz |
10:dedd44d58c0f | 198 | /* If waiting for ACK, check here if the packet is an ACK to a message previously sent */ |
| Wolfgang Betz |
10:dedd44d58c0f | 199 | if((rf_buffer_len == 3) && ((rf_rx_buf[0] & 0x07) == 0x02)) { |
| Wolfgang Betz |
10:dedd44d58c0f | 200 | uint8_t pending = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 201 | |
| Wolfgang Betz |
10:dedd44d58c0f | 202 | /*Check if data is pending*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 203 | if ((rf_rx_buf[0] & 0x10)) { |
| Wolfgang Betz |
10:dedd44d58c0f | 204 | pending=1; |
| Wolfgang Betz |
10:dedd44d58c0f | 205 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 206 | |
| Wolfgang Betz |
10:dedd44d58c0f | 207 | /*Send sequence number in ACK handler*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 208 | rf_handle_ack(rf_rx_buf[2], pending); |
| Wolfgang Betz |
10:dedd44d58c0f | 209 | return; |
| Wolfgang Betz |
10:dedd44d58c0f | 210 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 211 | |
| Wolfgang Betz |
10:dedd44d58c0f | 212 | /* Get link information */ |
| Wolfgang Betz |
10:dedd44d58c0f | 213 | rf_rssi = (int8_t)rf_device->get_last_rssi_dbm(); |
| Wolfgang Betz |
10:dedd44d58c0f | 214 | rf_lqi = (uint8_t)rf_device->get_last_lqi(); |
| Wolfgang Betz |
10:dedd44d58c0f | 215 | |
| Wolfgang Betz |
10:dedd44d58c0f | 216 | /* Note: Checksum of the packet must be checked and removed before entering here */ |
| Wolfgang Betz |
10:dedd44d58c0f | 217 | |
| Wolfgang Betz |
10:dedd44d58c0f | 218 | /* Send received data and link information to the network stack */ |
| Wolfgang Betz |
10:dedd44d58c0f | 219 | if( device_driver.phy_rx_cb ){ |
| Wolfgang Betz |
10:dedd44d58c0f | 220 | device_driver.phy_rx_cb(rf_rx_buf, rf_buffer_len, rf_lqi, rf_rssi, rf_radio_driver_id); |
| Wolfgang Betz |
10:dedd44d58c0f | 221 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 222 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 223 | |
| Wolfgang Betz |
10:dedd44d58c0f | 224 | /* Note: we are in IRQ context */ |
| Wolfgang Betz |
10:dedd44d58c0f | 225 | static inline void rf_handle_tx_end(void) |
| Wolfgang Betz |
10:dedd44d58c0f | 226 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 227 | phy_link_tx_status_e phy_status = PHY_LINK_TX_SUCCESS; |
| Wolfgang Betz |
10:dedd44d58c0f | 228 | |
| Wolfgang Betz |
10:dedd44d58c0f | 229 | /*Call PHY TX Done API*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 230 | if(device_driver.phy_tx_done_cb){ |
| Wolfgang Betz |
10:dedd44d58c0f | 231 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1); |
| Wolfgang Betz |
10:dedd44d58c0f | 232 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 233 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 234 | |
| Wolfgang Betz |
10:dedd44d58c0f | 235 | /* Note: we are in IRQ context */ |
| Wolfgang Betz |
10:dedd44d58c0f | 236 | static inline void rf_handle_tx_err(void) { |
| Wolfgang Betz |
10:dedd44d58c0f | 237 | phy_link_tx_status_e phy_status = PHY_LINK_TX_FAIL; |
| Wolfgang Betz |
10:dedd44d58c0f | 238 | |
| Wolfgang Betz |
10:dedd44d58c0f | 239 | /*Call PHY TX Done API*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 240 | if(device_driver.phy_tx_done_cb){ |
| Wolfgang Betz |
10:dedd44d58c0f | 241 | device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1); |
| Wolfgang Betz |
10:dedd44d58c0f | 242 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 243 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 244 | |
| Wolfgang Betz |
10:dedd44d58c0f | 245 | /* Note: we are in IRQ context */ |
| Wolfgang Betz |
10:dedd44d58c0f | 246 | static void rf_callback_func(int event) { |
| Wolfgang Betz |
10:dedd44d58c0f | 247 | switch(event) { |
| Wolfgang Betz |
10:dedd44d58c0f | 248 | case SimpleSpirit1::RX_DONE: |
| Wolfgang Betz |
10:dedd44d58c0f | 249 | rf_handle_rx_end(); |
| Wolfgang Betz |
10:dedd44d58c0f | 250 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 251 | case SimpleSpirit1::TX_DONE: |
| Wolfgang Betz |
10:dedd44d58c0f | 252 | rf_handle_tx_end(); |
| Wolfgang Betz |
10:dedd44d58c0f | 253 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 254 | case SimpleSpirit1::TX_ERR: |
| Wolfgang Betz |
10:dedd44d58c0f | 255 | rf_handle_tx_err(); |
| Wolfgang Betz |
10:dedd44d58c0f | 256 | break; |
| Wolfgang Betz |
10:dedd44d58c0f | 257 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 258 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 259 | |
| Wolfgang Betz |
10:dedd44d58c0f | 260 | static void rf_init(void) { |
| Wolfgang Betz |
10:dedd44d58c0f | 261 | rf_device = &SimpleSpirit1::CreateInstance(D11, D12, D13, D9, D10, D2); |
| Wolfgang Betz |
10:dedd44d58c0f | 262 | rf_device->attach_irq_callback(rf_callback_func); |
| Wolfgang Betz |
10:dedd44d58c0f | 263 | } |
| Wolfgang Betz |
10:dedd44d58c0f | 264 | |
| Wolfgang Betz |
11:b769d6caad82 | 265 | extern "C" int8_t rf_device_register(void) |
| Wolfgang Betz |
10:dedd44d58c0f | 266 | { |
| Wolfgang Betz |
10:dedd44d58c0f | 267 | /* Do some initialization */ |
| Wolfgang Betz |
10:dedd44d58c0f | 268 | rf_init(); |
| Wolfgang Betz |
10:dedd44d58c0f | 269 | |
| Wolfgang Betz |
10:dedd44d58c0f | 270 | /* Set pointer to MAC address */ |
| Wolfgang Betz |
10:dedd44d58c0f | 271 | device_driver.PHY_MAC = mac_address; |
| Wolfgang Betz |
10:dedd44d58c0f | 272 | |
| Wolfgang Betz |
10:dedd44d58c0f | 273 | /* Set driver Name */ |
| Wolfgang Betz |
10:dedd44d58c0f | 274 | device_driver.driver_description = (char*)"Spirit1 Sub-GHz RF"; |
| Wolfgang Betz |
10:dedd44d58c0f | 275 | |
| Wolfgang Betz |
10:dedd44d58c0f | 276 | /*Type of RF PHY is SubGHz*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 277 | device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE; |
| Wolfgang Betz |
10:dedd44d58c0f | 278 | |
| Wolfgang Betz |
10:dedd44d58c0f | 279 | /*Maximum size of payload is 255*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 280 | device_driver.phy_MTU = MAX_PACKET_LEN; |
| Wolfgang Betz |
11:b769d6caad82 | 281 | |
| Wolfgang Betz |
10:dedd44d58c0f | 282 | /*No header in PHY*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 283 | device_driver.phy_header_length = 0; |
| Wolfgang Betz |
11:b769d6caad82 | 284 | |
| Wolfgang Betz |
10:dedd44d58c0f | 285 | /*No tail in PHY*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 286 | device_driver.phy_tail_length = 0; |
| Wolfgang Betz |
10:dedd44d58c0f | 287 | |
| Wolfgang Betz |
10:dedd44d58c0f | 288 | /*Set up driver functions*/ |
| Wolfgang Betz |
11:b769d6caad82 | 289 | device_driver.address_write = &rf_address_write; |
| Wolfgang Betz |
10:dedd44d58c0f | 290 | device_driver.extension = &rf_extension; |
| Wolfgang Betz |
10:dedd44d58c0f | 291 | device_driver.state_control = &rf_interface_state_control; |
| Wolfgang Betz |
10:dedd44d58c0f | 292 | device_driver.tx = &rf_start_cca; |
| Wolfgang Betz |
10:dedd44d58c0f | 293 | |
| Wolfgang Betz |
10:dedd44d58c0f | 294 | /*Set supported channel pages*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 295 | device_driver.phy_channel_pages = phy_channel_pages; |
| Wolfgang Betz |
10:dedd44d58c0f | 296 | |
| Wolfgang Betz |
10:dedd44d58c0f | 297 | //Nullify rx/tx callbacks |
| Wolfgang Betz |
10:dedd44d58c0f | 298 | device_driver.phy_rx_cb = NULL; |
| Wolfgang Betz |
10:dedd44d58c0f | 299 | device_driver.phy_tx_done_cb = NULL; |
| Wolfgang Betz |
10:dedd44d58c0f | 300 | device_driver.arm_net_virtual_rx_cb = NULL; |
| Wolfgang Betz |
10:dedd44d58c0f | 301 | device_driver.arm_net_virtual_tx_cb = NULL; |
| Wolfgang Betz |
10:dedd44d58c0f | 302 | |
| Wolfgang Betz |
10:dedd44d58c0f | 303 | /*Register device driver*/ |
| Wolfgang Betz |
10:dedd44d58c0f | 304 | rf_radio_driver_id = arm_net_phy_register(&device_driver); |
| Wolfgang Betz |
10:dedd44d58c0f | 305 | |
| Wolfgang Betz |
10:dedd44d58c0f | 306 | return rf_radio_driver_id; |
| Wolfgang Betz |
10:dedd44d58c0f | 307 | } |
| Wolfgang Betz |
11:b769d6caad82 | 308 | |
| Wolfgang Betz |
11:b769d6caad82 | 309 | /* |
| Wolfgang Betz |
11:b769d6caad82 | 310 | * \brief Function reads the MAC address array. |
| Wolfgang Betz |
11:b769d6caad82 | 311 | * |
| Wolfgang Betz |
11:b769d6caad82 | 312 | * \param ptr Pointer to read array |
| Wolfgang Betz |
11:b769d6caad82 | 313 | * |
| Wolfgang Betz |
11:b769d6caad82 | 314 | * \return none |
| Wolfgang Betz |
11:b769d6caad82 | 315 | */ |
| Wolfgang Betz |
11:b769d6caad82 | 316 | extern "C" void rf_read_mac_address(uint8_t *ptr) |
| Wolfgang Betz |
11:b769d6caad82 | 317 | { |
| Wolfgang Betz |
11:b769d6caad82 | 318 | memcpy(ptr, mac_address, 8); |
| Wolfgang Betz |
11:b769d6caad82 | 319 | } |
| Wolfgang Betz |
11:b769d6caad82 | 320 | |
| Wolfgang Betz |
11:b769d6caad82 | 321 | /* |
| Wolfgang Betz |
11:b769d6caad82 | 322 | * \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 | 323 | * |
| Wolfgang Betz |
11:b769d6caad82 | 324 | * \param none |
| Wolfgang Betz |
11:b769d6caad82 | 325 | * |
| Wolfgang Betz |
11:b769d6caad82 | 326 | * \return random RSSI value |
| Wolfgang Betz |
11:b769d6caad82 | 327 | */ |
| Wolfgang Betz |
11:b769d6caad82 | 328 | extern "C" int8_t rf_read_random(void) |
| Wolfgang Betz |
11:b769d6caad82 | 329 | { |
| Wolfgang Betz |
11:b769d6caad82 | 330 | return rf_rnd_rssi; |
| Wolfgang Betz |
11:b769d6caad82 | 331 | } |
| Wolfgang Betz |
11:b769d6caad82 | 332 | |
| Wolfgang Betz |
11:b769d6caad82 | 333 | /* |
| Wolfgang Betz |
11:b769d6caad82 | 334 | * \brief Read connected radio part. |
| Wolfgang Betz |
11:b769d6caad82 | 335 | * |
| Wolfgang Betz |
11:b769d6caad82 | 336 | * This function only return valid information when rf_init() is called |
| Wolfgang Betz |
11:b769d6caad82 | 337 | * |
| Wolfgang Betz |
11:b769d6caad82 | 338 | * \return |
| Wolfgang Betz |
11:b769d6caad82 | 339 | */ |
| Wolfgang Betz |
11:b769d6caad82 | 340 | extern "C" rf_trx_part_e rf_radio_type_read(void) |
| Wolfgang Betz |
11:b769d6caad82 | 341 | { |
| Wolfgang Betz |
11:b769d6caad82 | 342 | return ATMEL_UNKNOW_DEV; |
| Wolfgang Betz |
11:b769d6caad82 | 343 | } |
X-NUCLEO-IDS01A4 Sub-1GHz RF Expansion Board