Skip to content

Nanostack release for Mbed OS 5.13 #10624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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
}
}
}

Expand Down Expand Up @@ -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);
}

Expand All @@ -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();
}

Expand Down Expand Up @@ -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);
Expand All @@ -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),
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down
72 changes: 72 additions & 0 deletions components/802.15.4_RF/stm-s2lp-rf-driver/source/at24mac_s2lp.cpp
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this copy&paste from Atmel driver, and why was it not working for this device?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a copy and it would work with this device. But I guess we cannot rely we always have atmel drivers compiled when running s2-lp? We should probably have some common driver folder for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then move to common folder.
AT24MAC is not Atmel RF driver specific. So now would be correct time to separate it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting to make it as a separate PR once the change has been properly analysed and correct location/API has been decided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A PR for moving AT24MAC: https://jira.arm.com/browse/IOTTHD-3532


/* 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 */
71 changes: 71 additions & 0 deletions components/802.15.4_RF/stm-s2lp-rf-driver/source/at24mac_s2lp.h
Original file line number Diff line number Diff line change
@@ -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 */
Loading