Sync 802.15.4 RF drivers from master repos

-Sync STM S2LP with v0.0.6 in master repo
-Sync Atmel with v3.0.8 in master repo
-Sync MCR20A with v1.0.6 in master repo
pull/10624/head
Arto Kinnunen 2019-05-20 15:03:01 +03:00
parent 9687f59555
commit f03e51a23d
5 changed files with 261 additions and 60 deletions

View File

@ -79,7 +79,6 @@ extern void (*fhss_bc_switch)(void);
#define MAC_TYPE_ACK (2)
#define MAC_TYPE_COMMAND (3)
#define MAC_DATA_PENDING 0x10
#define MAC_FRAME_VERSION_2 (2)
#define FC_DST_MODE 0x0C
#define FC_SRC_MODE 0xC0
#define FC_DST_ADDR_NONE 0x00
@ -99,8 +98,6 @@ extern void (*fhss_bc_switch)(void);
#define CS_SELECT() {rf->CS = 0;}
#define CS_RELEASE() {rf->CS = 1;}
extern const uint8_t ADDR_UNSPECIFIED[16];
typedef enum {
RF_MODE_NORMAL = 0,
RF_MODE_SNIFFER = 1
@ -183,6 +180,7 @@ static void rf_backup_timer_stop(void);
static void rf_rx_ready_handler(void);
static uint32_t read_irq_status(void);
static bool rf_rx_filter(uint8_t *mac_header, uint8_t *mac_64bit_addr, uint8_t *mac_16bit_addr, uint8_t *pan_id);
static void rf_cca_timer_start(uint32_t slots);
static RFPins *rf;
static phy_device_driver_s device_driver;
@ -210,6 +208,7 @@ static uint8_t s2lp_MAC[8];
static rf_mode_e rf_mode = RF_MODE_NORMAL;
static bool rf_update_config = false;
static uint16_t cur_packet_len = 0xffff;
static uint32_t receiver_ready_timestamp;
/* Channel configurations for sub-GHz */
static phy_rf_channel_configuration_s phy_subghz = {
@ -748,16 +747,26 @@ static void rf_start_tx(void)
rf_backup_timer_start(MAX_PACKET_SENDING_TIME);
}
static int rf_cca_check(void)
{
uint32_t time_from_receiver_ready = rf_get_timestamp() - receiver_ready_timestamp;
if (time_from_receiver_ready < RSSI_SETTLING_TIME) {
wait_us(RSSI_SETTLING_TIME - time_from_receiver_ready);
}
return (rf_read_register(LINK_QUALIF1) & CARRIER_SENSE);
}
static void rf_cca_timer_interrupt(void)
{
if (device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_PREPARE, 0, 0) != 0) {
int8_t status = device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_PREPARE, 0, 0);
if (status == PHY_TX_NOT_ALLOWED) {
rf_flush_tx_fifo();
if (rf_state == RF_CSMA_STARTED) {
rf_state = RF_IDLE;
}
return;
}
if ((cca_enabled == true) && ((rf_state != RF_CSMA_STARTED && rf_state != RF_IDLE) || (read_irq_status() & (1 << SYNC_WORD)) || (rf_read_register(LINK_QUALIF1) & CARRIER_SENSE))) {
if ((cca_enabled == true) && ((rf_state != RF_CSMA_STARTED && rf_state != RF_IDLE) || (read_irq_status() & (1 << SYNC_WORD)) || rf_cca_check())) {
if (rf_state == RF_CSMA_STARTED) {
rf_state = RF_IDLE;
}
@ -767,9 +776,23 @@ static void rf_cca_timer_interrupt(void)
device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 0, 0);
}
} else {
rf_start_tx();
rf_state = RF_TX_STARTED;
TEST_TX_STARTED
if (status == PHY_RESTART_CSMA) {
if (device_driver.phy_tx_done_cb) {
device_driver.phy_tx_done_cb(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_OK, 0, 0);
}
if (tx_time) {
uint32_t backoff_time = tx_time - rf_get_timestamp();
// Max. time to TX can be 65ms, otherwise time has passed already -> send immediately
if (backoff_time > 65000) {
backoff_time = 1;
}
rf_cca_timer_start(backoff_time);
}
} else {
rf_start_tx();
rf_state = RF_TX_STARTED;
TEST_TX_STARTED
}
}
}
@ -931,6 +954,8 @@ static void rf_sync_detected_handler(void)
rf_state = RF_RX_STARTED;
TEST_RX_STARTED
rf_disable_interrupt(SYNC_WORD);
rf_enable_interrupt(RX_FIFO_ALMOST_FULL);
rf_enable_interrupt(RX_DATA_READY);
rf_backup_timer_start(MAX_PACKET_SENDING_TIME);
}
@ -953,15 +978,14 @@ static void rf_receive(uint8_t rx_channel)
rf_rx_channel = rf_new_channel = rx_channel;
}
rf_send_command(S2LP_CMD_RX);
rf_poll_state_change(S2LP_STATE_RX);
rf_enable_interrupt(SYNC_WORD);
rf_enable_interrupt(RX_FIFO_ALMOST_FULL);
rf_enable_interrupt(RX_DATA_READY);
rf_enable_interrupt(RX_FIFO_UNF_OVF);
rx_data_length = 0;
if (rf_state != RF_CSMA_STARTED) {
rf_state = RF_IDLE;
}
rf_poll_state_change(S2LP_STATE_RX);
receiver_ready_timestamp = rf_get_timestamp();
rf_unlock();
}
@ -1158,14 +1182,25 @@ int8_t NanostackRfPhys2lp::rf_register()
error("Multiple registrations of NanostackRfPhyAtmel not supported");
return -1;
}
if (memcmp(_mac_addr, ADDR_UNSPECIFIED, 8) == 0) {
if (!_mac_set) {
#ifdef AT24MAC
int ret = _mac.read_eui64((void *)s2lp_MAC);
if (ret < 0) {
rf = NULL;
rf_unlock();
return -1;
}
#else
randLIB_seed_random();
randLIB_get_n_bytes_random(s2lp_MAC, 8);
s2lp_MAC[0] |= 2; //Set Local Bit
s2lp_MAC[0] &= ~1; //Clear multicast bit
tr_info("Generated random MAC %s", trace_array(s2lp_MAC, 8));
#endif
set_mac_address(s2lp_MAC);
tr_info("MAC address: %s", trace_array(_mac_addr, 8));
}
rf = _rf;
int8_t radio_id = rf_device_register(_mac_addr);
@ -1188,12 +1223,20 @@ void NanostackRfPhys2lp::rf_unregister()
rf_unlock();
}
NanostackRfPhys2lp::NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn,
NanostackRfPhys2lp::NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn
#ifdef TEST_GPIOS_ENABLED
PinName spi_test1, PinName spi_test2, PinName spi_test3, PinName spi_test4, PinName spi_test5,
,PinName spi_test1, PinName spi_test2, PinName spi_test3, PinName spi_test4, PinName spi_test5
#endif //TEST_GPIOS_ENABLED
PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3)
: _mac_addr(), _rf(NULL), _mac_set(false),
,PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3
#ifdef AT24MAC
,PinName i2c_sda, PinName i2c_scl
#endif //AT24MAC
)
:
#ifdef AT24MAC
_mac(i2c_sda, i2c_scl),
#endif //AT24MAC
_mac_addr(), _rf(NULL), _mac_set(false),
_spi_sdi(spi_sdi), _spi_sdo(spi_sdo), _spi_sclk(spi_sclk), _spi_cs(spi_cs), _spi_sdn(spi_sdn),
#ifdef TEST_GPIOS_ENABLED
_spi_test1(spi_test1), _spi_test2(spi_test2), _spi_test3(spi_test3), _spi_test4(spi_test4), _spi_test5(spi_test5),
@ -1236,20 +1279,6 @@ static bool rf_panid_filter_common(uint8_t *panid_start, uint8_t *pan_id, uint8_
return retval;
}
static bool rf_panid_v2_filter(uint8_t *ptr, uint8_t *pan_id, uint8_t dst_mode, uint8_t src_mode, uint8_t seq_compressed, uint8_t panid_compressed, uint8_t frame_type)
{
if ((dst_mode == FC_DST_ADDR_NONE) && (frame_type == MAC_TYPE_DATA || frame_type == MAC_TYPE_COMMAND)) {
return true;
}
if ((dst_mode == FC_DST_64_BITS) && (src_mode == FC_SRC_64_BITS) && panid_compressed) {
return true;
}
if (seq_compressed) {
ptr--;
}
return rf_panid_filter_common(ptr, pan_id, frame_type);
}
static bool rf_panid_v1_v0_filter(uint8_t *ptr, uint8_t *pan_id, uint8_t frame_type)
{
return rf_panid_filter_common(ptr, pan_id, frame_type);
@ -1298,17 +1327,6 @@ static bool rf_addr_filter_common(uint8_t *ptr, uint8_t addr_mode, uint8_t *mac_
return retval;
}
static bool rf_addr_v2_filter(uint8_t *ptr, uint8_t *mac_64bit_addr, uint8_t *mac_16bit_addr, uint8_t dst_mode, uint8_t seq_compressed, uint8_t panid_compressed)
{
if (seq_compressed) {
ptr--;
}
if (panid_compressed) {
ptr -= 2;
}
return rf_addr_filter_common(ptr, dst_mode, mac_64bit_addr, mac_16bit_addr);
}
static bool rf_addr_v1_v0_filter(uint8_t *ptr, uint8_t *mac_64bit_addr, uint8_t *mac_16bit_addr, uint8_t dst_mode)
{
return rf_addr_filter_common(ptr, dst_mode, mac_64bit_addr, mac_16bit_addr);
@ -1317,19 +1335,9 @@ static bool rf_addr_v1_v0_filter(uint8_t *ptr, uint8_t *mac_64bit_addr, uint8_t
static bool rf_rx_filter(uint8_t *mac_header, uint8_t *mac_64bit_addr, uint8_t *mac_16bit_addr, uint8_t *pan_id)
{
uint8_t dst_mode = (mac_header[1] & FC_DST_MODE);
uint8_t src_mode = (mac_header[1] & FC_SRC_MODE);
uint8_t seq_compressed = ((mac_header[1] & FC_SEQUENCE_COMPRESSION) >> SHIFT_SEQ_COMP_FIELD);
uint8_t panid_compressed = ((mac_header[0] & FC_PAN_ID_COMPRESSION) >> SHIFT_PANID_COMP_FIELD);
uint8_t frame_type = mac_header[0] & MAC_FRAME_TYPE_MASK;
uint8_t version = ((mac_header[1] & VERSION_FIELD_MASK) >> SHIFT_VERSION_FIELD);
if (version == MAC_FRAME_VERSION_2) {
if (!rf_panid_v2_filter(mac_header + OFFSET_DST_PAN_ID, pan_id, dst_mode, src_mode, seq_compressed, panid_compressed, frame_type)) {
return false;
}
if (!rf_addr_v2_filter(mac_header + OFFSET_DST_ADDR, mac_64bit_addr, mac_16bit_addr, dst_mode, seq_compressed, panid_compressed)) {
return false;
}
} else {
if (version != MAC_FRAME_VERSION_2) {
if (!rf_panid_v1_v0_filter(mac_header + OFFSET_DST_PAN_ID, pan_id, frame_type)) {
return false;
}
@ -1474,11 +1482,15 @@ static void rf_print_registers(void)
#if MBED_CONF_S2LP_PROVIDE_DEFAULT
NanostackRfPhy &NanostackRfPhy::get_default_instance()
{
static NanostackRfPhys2lp rf_phy(S2LP_SPI_SDI, S2LP_SPI_SDO, S2LP_SPI_SCLK, S2LP_SPI_CS, S2LP_SPI_SDN,
static NanostackRfPhys2lp rf_phy(S2LP_SPI_SDI, S2LP_SPI_SDO, S2LP_SPI_SCLK, S2LP_SPI_CS, S2LP_SPI_SDN
#ifdef TEST_GPIOS_ENABLED
S2LP_SPI_TEST1, S2LP_SPI_TEST2, S2LP_SPI_TEST3, S2LP_SPI_TEST4, S2LP_SPI_TEST5,
,S2LP_SPI_TEST1, S2LP_SPI_TEST2, S2LP_SPI_TEST3, S2LP_SPI_TEST4, S2LP_SPI_TEST5
#endif //TEST_GPIOS_ENABLED
S2LP_SPI_GPIO0, S2LP_SPI_GPIO1, S2LP_SPI_GPIO2, S2LP_SPI_GPIO3);
,S2LP_SPI_GPIO0, S2LP_SPI_GPIO1, S2LP_SPI_GPIO2, S2LP_SPI_GPIO3
#ifdef AT24MAC
,S2LP_I2C_SDA, S2LP_I2C_SCL
#endif //AT24MAC
);
return rf_phy;
}
#endif // MBED_CONF_S2LP_PROVIDE_DEFAULT

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2019-2019 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "NanostackRfPhys2lp.h"
#include "at24mac_s2lp.h"
#if DEVICE_I2C
#ifdef AT24MAC
/* Device addressing */
#define AT24MAC_EEPROM_ADDRESS (0x0A<<4)
#define AT24MAC_RW_PROTECT_ADDRESS (0x06<<4)
#define AT24MAC_SERIAL_ADDRESS (0x0B<<4)
/* Known memory blocks */
#define AT24MAC_SERIAL_OFFSET (0x80)
#define AT24MAC_EUI64_OFFSET (0x98)
#define AT24MAC_EUI48_OFFSET (0x9A)
#define SERIAL_LEN 16
#define EUI64_LEN 8
#define EUI48_LEN 6
using namespace mbed;
AT24Mac_s2lp::AT24Mac_s2lp(PinName sda, PinName scl) : _i2c(sda, scl)
{
// Do nothing
}
int AT24Mac_s2lp::read_serial(void *buf)
{
char offset = AT24MAC_SERIAL_OFFSET;
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
return -1; //No ACK
}
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, SERIAL_LEN);
}
int AT24Mac_s2lp::read_eui64(void *buf)
{
char offset = AT24MAC_EUI64_OFFSET;
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
return -1; //No ACK
}
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, EUI64_LEN);
}
int AT24Mac_s2lp::read_eui48(void *buf)
{
char offset = AT24MAC_EUI48_OFFSET;
if (_i2c.write(AT24MAC_SERIAL_ADDRESS, &offset, 1, true)) {
return -1; //No ACK
}
return _i2c.read(AT24MAC_SERIAL_ADDRESS, (char *)buf, EUI48_LEN);
}
#endif /* AT24MAC */
#endif /* DEVICE_I2C */

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2019-2019 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AT24MAC_S2LP_H
#define AT24MAC_S2LP_H
#include "PinNames.h"
#if DEVICE_I2C
#ifdef AT24MAC
#include "I2C.h"
#include "drivers/DigitalInOut.h"
#include "platform/mbed_wait_api.h"
/*
* AT24MAC drivers.
*
* This is a EEPROM chip designed to contain factory programmed read-only EUI-64 or EUI-48,
* a 128bit serial number and some user programmable EEPROM.
*
* AT24MAC602 contains EUI-64, use read_eui64()
* AT24MAC402 contains EUI-64, use read_eui48()
*
* NOTE: You cannot use both EUI-64 and EUI-48. Chip contains only one of those.
*/
class AT24Mac_s2lp {
public:
AT24Mac_s2lp(PinName sda, PinName scl);
/**
* Read unique serial number from chip.
* \param buf pointer to write serial number to. Must have space for 16 bytes.
* \return zero on success, negative number on failure
*/
int read_serial(void *buf);
/**
* Read EUI-64 from chip.
* \param buf pointer to write EUI-64 to. Must have space for 8 bytes.
* \return zero on success, negative number on failure
*/
int read_eui64(void *buf);
/**
* Read EUI-48 from chip.
* \param buf pointer to write EUI-48 to. Must have space for 6 bytes.
* \return zero on success, negative number on failure
*/
int read_eui48(void *buf);
private:
mbed::I2C _i2c;
};
#endif /* AT24MAC */
#endif /* DEVICE_I2C */
#endif /* AT24MAC_S2LP_H */

View File

@ -25,6 +25,7 @@ extern "C" {
#define VERSION 0xC1
#define FIFO_SIZE 128
#define SPI_HEADER_LENGTH 2
#define RSSI_SETTLING_TIME 250
#define S2LP_GPIO0 0
#define S2LP_GPIO1 1

View File

@ -28,6 +28,42 @@
// Uncomment to use testing gpios attached to TX/RX processes
//#define TEST_GPIOS_ENABLED
#if defined(TARGET_MTB_STM_S2LP)
#if !defined(S2LP_SPI_SDI)
#define S2LP_SPI_SDI PA_7
#endif
#if !defined(S2LP_SPI_SDO)
#define S2LP_SPI_SDO PA_6
#endif
#if !defined(S2LP_SPI_SCLK)
#define S2LP_SPI_SCLK PA_5
#endif
#if !defined(S2LP_SPI_CS)
#define S2LP_SPI_CS PC_0
#endif
#if !defined(S2LP_SPI_SDN)
#define S2LP_SPI_SDN PF_13
#endif
#if !defined(S2LP_SPI_GPIO0)
#define S2LP_SPI_GPIO0 PA_3
#endif
#if !defined(S2LP_SPI_GPIO1)
#define S2LP_SPI_GPIO1 PC_3
#endif
#if !defined(S2LP_SPI_GPIO2)
#define S2LP_SPI_GPIO2 PF_3
#endif
#if !defined(S2LP_SPI_GPIO3)
#define S2LP_SPI_GPIO3 PF_10
#endif
#if !defined(S2LP_I2C_SDA)
#define S2LP_I2C_SDA PB_7
#endif
#if !defined(S2LP_I2C_SCL)
#define S2LP_I2C_SCL PB_6
#endif
#define AT24MAC
#else
#if !defined(S2LP_SPI_SDI)
#define S2LP_SPI_SDI D11
#endif
@ -70,17 +106,23 @@
#if !defined(S2LP_SPI_GPIO3)
#define S2LP_SPI_GPIO3 A5
#endif
#endif
#include "at24mac_s2lp.h"
class RFPins;
class NanostackRfPhys2lp : public NanostackRfPhy {
public:
NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo,
PinName spi_sclk, PinName spi_cs, PinName spi_sdn,
NanostackRfPhys2lp(PinName spi_sdi, PinName spi_sdo, PinName spi_sclk, PinName spi_cs, PinName spi_sdn
#ifdef TEST_GPIOS_ENABLED
PinName spi_test1, PinName spi_test2, PinName spi_test3, PinName spi_test4, PinName spi_test5,
,PinName spi_test1, PinName spi_test2, PinName spi_test3, PinName spi_test4, PinName spi_test5
#endif //TEST_GPIOS_ENABLED
PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3);
,PinName spi_gpio0, PinName spi_gpio1, PinName spi_gpio2, PinName spi_gpio3
#ifdef AT24MAC
,PinName i2c_sda, PinName i2c_scl
#endif //AT24MAC
);
virtual ~NanostackRfPhys2lp();
virtual int8_t rf_register();
virtual void rf_unregister();
@ -88,6 +130,9 @@ public:
virtual void set_mac_address(uint8_t *mac);
private:
#ifdef AT24MAC
AT24Mac_s2lp _mac;
#endif //AT24MAC
uint8_t _mac_addr[8];
RFPins *_rf;
bool _mac_set;