Update Atmel 802.15.4 RF driver

Update to version v3.1.0.
pull/12754/head
Arto Kinnunen 2020-04-03 15:23:11 +03:00
parent 78abc43c32
commit 64d879b540
6 changed files with 1536 additions and 36 deletions

View File

@ -24,6 +24,9 @@
#include "NanostackRfPhy.h"
// Uncomment to use testing gpios attached to TX/RX processes
// #define TEST_GPIOS_ENABLED
// Arduino pin defaults for convenience
#if !defined(ATMEL_SPI_MOSI)
#define ATMEL_SPI_MOSI D11
@ -52,8 +55,24 @@
#if !defined(ATMEL_I2C_SCL)
#define ATMEL_I2C_SCL D15
#endif
#if !defined(TEST_PIN_TX)
#define TEST_PIN_TX D6
#endif
#if !defined(TEST_PIN_RX)
#define TEST_PIN_RX D3
#endif
#if !defined(TEST_PIN_CSMA)
#define TEST_PIN_CSMA D4
#endif
#if !defined(TEST_PIN_SPARE_1)
#define TEST_PIN_SPARE_1 D2
#endif
#if !defined(TEST_PIN_SPARE_2)
#define TEST_PIN_SPARE_2 D8
#endif
class RFBits;
class TestPins;
class NanostackRfPhyAtmel : public NanostackRfPhy {
public:
@ -70,6 +89,7 @@ private:
AT24Mac _mac;
uint8_t _mac_addr[8];
RFBits *_rf;
TestPins *_test_pins;
bool _mac_set;
const PinName _spi_mosi;
@ -81,5 +101,31 @@ private:
const PinName _spi_irq;
};
#ifdef TEST_GPIOS_ENABLED
#define TEST_TX_STARTED test_pins->TEST1 = 1;
#define TEST_TX_DONE test_pins->TEST1 = 0;
#define TEST_RX_STARTED test_pins->TEST2 = 1;
#define TEST_RX_DONE test_pins->TEST2 = 0;
#define TEST_CSMA_STARTED test_pins->TEST3 = 1;
#define TEST_CSMA_DONE test_pins->TEST3 = 0;
#define TEST_SPARE_1_ON test_pins->TEST4 = 1;
#define TEST_SPARE_1_OFF test_pins->TEST4 = 0;
#define TEST_SPARE_2_ON test_pins->TEST5 = 1;
#define TEST_SPARE_2_OFF test_pins->TEST5 = 0;
extern void (*fhss_uc_switch)(void);
extern void (*fhss_bc_switch)(void);
#else
#define TEST_TX_STARTED
#define TEST_TX_DONE
#define TEST_RX_STARTED
#define TEST_RX_DONE
#define TEST_CSMA_STARTED
#define TEST_CSMA_DONE
#define TEST_SPARE_1_ON
#define TEST_SPARE_1_OFF
#define TEST_SPARE_2_ON
#define TEST_SPARE_2_OFF
#endif //TEST_GPIOS_ENABLED
#endif /* MBED_CONF_NANOSTACK_CONFIGURATION */
#endif /* NANOSTACK_RF_PHY_ATMEL_H_ */

View File

@ -0,0 +1,262 @@
/*
* Copyright (c) 2020 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 AT86RF215REG_H_
#define AT86RF215REG_H_
#ifdef __cplusplus
extern "C" {
#endif
/*Register addresses*/
#define RF09_IRQS 0x00
#define RF24_IRQS 0x01
#define BBC0_IRQS 0x02
#define BBC1_IRQS 0x03
#define RF_CFG 0x06
#define RF_IQIFC1 0x0B
#define RF_PN 0x0D
#define RF_VN 0x0E
#define RF_IRQM 0x00
#define RF_STATE 0x02
#define RF_CMD 0x03
#define RF_CS 0x04
#define RF_CCF0L 0x05
#define RF_CCF0H 0x06
#define RF_CNL 0x07
#define RF_CNM 0x08
#define RF_RXBWC 0x09
#define RF_RXDFE 0x0A
#define RF_AGCC 0x0B
#define RF_AGCS 0x0C
#define RF_RSSI 0x0D
#define RF_EDC 0x0E
#define RF_EDV 0x10
#define RF_TXCUTC 0x12
#define RF_TXDFE 0x13
#define BBC_IRQM 0x00
#define BBC_PC 0x01
#define BBC_RXFLL 0x04
#define BBC_RXFLH 0x05
#define BBC_TXFLL 0x06
#define BBC_TXFLH 0x07
#define BBC_FBLL 0x08
#define BBC_FBLH 0x09
#define BBC_OQPSKC0 0x10
#define BBC_OQPSKC1 0x11
#define BBC_OQPSKC2 0x12
#define BBC_OQPSKC3 0x13
#define BBC_OQPSKPHRTX 0x14
#define BBC_OQPSKPHRRX 0x15
#define BBC_AFC0 0x20
#define BBC_AFFTM 0x22
#define BBC_MACEA0 0x25
#define BBC_MACPID0F0 0x2D
#define BBC_MACSHA0F0 0x2F
#define BBC_AMCS 0x40
#define BBC_AMEDT 0x41
#define BBC_AMAACKTL 0x43
#define BBC_AMAACKTH 0x44
#define BBC_FSKC0 0x60
#define BBC_FSKC1 0x61
#define BBC_FSKC2 0x62
#define BBC_FSKC3 0x63
#define BBC_FSKPLL 0x65
#define BBC_FSKPHRTX 0x6A
#define BBC_FSKPHRRX 0x6B
#define BBC0_FBRXS 0x2000
#define BBC0_FBTXS 0x2800
#define BBC1_FBRXS 0x3000
#define BBC1_FBTXS 0x3800
// RF_AGCC
#define AGCI (1 << 6)
#define AVGS 0x30
#define AVGS_8_SAMPLES (0 << 4)
// RF_AGCS
#define TGT 0xE0
#define TGT_1 (1 << 5)
// RF_RXBWC
#define BW 0x0F
#define RF_BW2000KHZ_IF2000KHZ (11 << 0)
#define RF_BW1600KHZ_IF2000KHZ (10 << 0)
#define RF_BW1250KHZ_IF2000KHZ (9 << 0)
#define RF_BW1000KHZ_IF1000KHZ (8 << 0)
#define RF_BW800KHZ_IF1000KHZ (7 << 0)
#define RF_BW630KHZ_IF1000KHZ (6 << 0)
#define RF_BW500KHZ_IF500KHZ (5 << 0)
#define RF_BW400KHZ_IF500KHZ (4 << 0)
#define RF_BW320KHZ_IF500KHZ (3 << 0)
#define RF_BW250KHZ_IF250KHZ (2 << 0)
#define RF_BW200KHZ_IF250KHZ (1 << 0)
#define RF_BW160KHZ_IF250KHZ (0 << 0)
#define IFS (1 << 4)
// RF_TXCUTC
#define PARAMP 0xC0
#define RF_PARAMP32U (3 << 6)
#define RF_PARAMP16U (2 << 6)
#define RF_PARAMP8U (1 << 6)
#define RF_PARAMP4U (0 << 6)
#define LPFCUT 0x0F
#define RF_FLC80KHZ (0 << 0)
#define RF_FLC100KHZ (1 << 0)
#define RF_FLC125KHZ (2 << 0)
#define RF_FLC160KHZ (3 << 0)
#define RF_FLC200KHZ (4 << 0)
#define RF_FLC250KHZ (5 << 0)
#define RF_FLC315KHZ (6 << 0)
#define RF_FLC400KHZ (7 << 0)
#define RF_FLC500KHZ (8 << 0)
#define RF_FLC625KHZ (9 << 0)
#define RF_FLC800KHZ (10 << 0)
#define RF_FLC1000KHZ (11 << 0)
// RF_TXDFE, RF_RXDFE
#define RCUT 0xE0
#define RCUT_4 (4 << 5)
#define RCUT_2 (2 << 5)
#define RCUT_1 (1 << 5)
#define RCUT_0 (0 << 5)
#define SR 0x0F
#define SR_10 (10 << 0)
#define SR_8 (8 << 0)
#define SR_6 (6 << 0)
#define SR_5 (5 << 0)
#define SR_4 (4 << 0)
#define SR_3 (3 << 0)
#define SR_2 (2 << 0)
#define SR_1 (1 << 0)
// BBC_FSKC0
#define BT 0xC0
#define BT_20 (3 << 6)
#define BT_10 (1 << 6)
#define MIDXS 0x30
#define MIDXS_0 (0 << 4)
#define MIDX 0x0E
#define MIDX_10 (3 << 1)
#define MIDX_075 (2 << 1)
#define MIDX_05 (1 << 1)
#define MIDX_0375 (0 << 1)
// BBC_FSKC1
#define SRATE 0x0F
#define SRATE_400KHZ (5 << 0)
#define SRATE_300KHZ (4 << 0)
#define SRATE_200KHZ (3 << 0)
#define SRATE_150KHZ (2 << 0)
#define SRATE_100KHZ (1 << 0)
#define SRATE_50KHZ (0 << 0)
// BBC_FSKC2
#define RXO 0x60
#define RXO_DIS (0 << 5)
#define FECIE (1 << 0)
// BBC_FSKC3
#define SFDT 0xF0
#define PDT 0x0F
#define PDT_6 (6 << 0)
// BBC_AFFTM
#define TYPE_2 (1 << 2)
// BBC_AFC0
#define PM (1 << 4)
#define AFEN3 (1 << 3)
#define AFEN2 (1 << 2)
#define AFEN1 (1 << 1)
#define AFEN0 (1 << 0)
// BBC_OQPSKPHRTX
#define LEG (1 << 0)
// BBC_OQPSKC0
#define FCHIP 0x03
#define BB_FCHIP100 (0 << 0)
#define BB_FCHIP200 (1 << 0)
#define BB_FCHIP1000 (2 << 0)
#define BB_FCHIP2000 (3 << 0)
// BBC_OQPSKC2
#define FCSTLEG 0x04
#define RXM 0x03
#define FCS_16 (1 << 2)
#define RXM_2 (2 << 0)
// BBC_IRQS, BBC_IRQM
#define FBLI (1 << 7)
#define AGCR (1 << 6)
#define AGCH (1 << 5)
#define TXFE (1 << 4)
#define RXEM (1 << 3)
#define RXAM (1 << 2)
#define RXFE (1 << 1)
#define RXFS (1 << 0)
//BBC_PC
#define BBEN (1 << 2)
#define PT 0x03
#define BB_PHYOFF (0 << 0)
#define BB_MRFSK (1 << 0)
#define BB_MROFDM (2 << 0)
#define BB_MROQPSK (3 << 0)
#define FCSOK (1 << 5)
#define TXAFCS (1 << 4)
#define FCST (1 << 3)
#define FCSFE (1 << 6)
//BBC_AMCS
#define AACKFT (1 << 7)
#define AACK (1 << 3)
#define CCAED (1 << 2)
// RF_IQIFC1
#define CHPM 0x70
#define RF_MODE_BBRF (0 << 4)
#define RF_MODE_RF (1 << 4)
#define RF_MODE_BBRF09 (4 << 4)
#define RF_MODE_BBRF24 (5 << 4)
/*RF_CFG bits*/
#define IRQMM 0x08
#define IRQP 0x04
/*RFn_IRQM bits*/
#define TRXRDY (1 << 1)
#define EDC (1 << 2)
/*RFn_EDC bits*/
#define EDM 0x03
#define RF_EDAUTO (0 << 0)
#define RF_EDSINGLE (1 << 0)
#define RF_EDCONT (2 << 0)
#define RF_EDOFF (3 << 0)
/*Masks*/
#define CNH 0x01
#define EDM 0x03
#define CHPM 0x70
#ifdef __cplusplus
}
#endif
#endif /* AT86RF215REG_H_ */

View File

@ -47,6 +47,7 @@ extern "C" {
#define PART_AT86RF231 0x03
#define PART_AT86RF212 0x07
#define PART_AT86RF233 0x0B
#define PART_AT86RF215 0x34
#define VERSION_AT86RF212 0x01
#define VERSION_AT86RF212B 0x03

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include "NanostackRfPhyAtmel.h"
#include "randLIB.h"
#include "AT86RFReg.h"
#include "AT86RF215Reg.h"
#include "nanostack/platform/arm_hal_phy.h"
#include "mbed_trace.h"
#include "mbed_toolchain.h"
@ -244,34 +245,8 @@ static void rf_if_irq_task_process_irq();
#endif
// HW pins to RF chip
#include "rfbits.h"
class UnlockedSPI : public SPI {
public:
UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
SPI(mosi, miso, sclk) { }
virtual void lock() { }
virtual void unlock() { }
};
class RFBits {
public:
RFBits(PinName spi_mosi, PinName spi_miso,
PinName spi_sclk, PinName spi_cs,
PinName spi_rst, PinName spi_slp, PinName spi_irq);
UnlockedSPI spi;
DigitalOut CS;
DigitalOut RST;
DigitalOut SLP_TR;
InterruptIn IRQ;
Timeout ack_timer;
Timeout cal_timer;
Timeout cca_timer;
#ifdef MBED_CONF_RTOS_PRESENT
Thread irq_thread;
Mutex mutex;
void rf_if_irq_task();
#endif
};
RFBits::RFBits(PinName spi_mosi, PinName spi_miso,
PinName spi_sclk, PinName spi_cs,
@ -282,7 +257,8 @@ RFBits::RFBits(PinName spi_mosi, PinName spi_miso,
SLP_TR(spi_slp),
IRQ(spi_irq)
#ifdef MBED_CONF_RTOS_PRESENT
, irq_thread(osPriorityRealtime, MBED_CONF_ATMEL_RF_IRQ_THREAD_STACK_SIZE, NULL, "atmel_irq_thread")
, irq_thread(osPriorityRealtime, MBED_CONF_ATMEL_RF_IRQ_THREAD_STACK_SIZE, NULL, "atmel_irq_thread"),
irq_thread_215(osPriorityRealtime, MBED_CONF_ATMEL_RF_IRQ_THREAD_STACK_SIZE, NULL, "atmel_215_irq_thread")
#endif
{
#ifdef MBED_CONF_RTOS_PRESENT
@ -290,7 +266,17 @@ RFBits::RFBits(PinName spi_mosi, PinName spi_miso,
#endif
}
TestPins::TestPins(PinName test_pin_1, PinName test_pin_2, PinName test_pin_3, PinName test_pin_4, PinName test_pin_5)
: TEST1(test_pin_1),
TEST2(test_pin_2),
TEST3(test_pin_3),
TEST4(test_pin_4),
TEST5(test_pin_5)
{
}
static RFBits *rf;
static TestPins *test_pins;
static uint8_t rf_part_num = 0;
/*TODO: RSSI Base value setting*/
static int8_t rf_rssi_base_val = -91;
@ -652,6 +638,10 @@ static void rf_if_write_set_tx_power_register(uint8_t value)
*/
static uint8_t rf_if_read_part_num(void)
{
// Part number is already set
if (rf_part_num) {
return rf_part_num;
}
return rf_if_read_register(PART_NUM);
}
@ -664,9 +654,6 @@ static uint8_t rf_if_read_part_num(void)
*/
static void rf_if_write_rf_settings(void)
{
/*Reset RF module*/
rf_if_reset_radio();
rf_part_num = rf_if_read_part_num();
rf_if_write_register(XAH_CTRL_0, 0);
@ -675,7 +662,9 @@ static void rf_if_write_rf_settings(void)
rf_if_write_register(TRX_CTRL_1, TX_AUTO_CRC_ON | SPI_CMD_MODE_TRX_STATUS);
rf_if_write_register(IRQ_MASK, CCA_ED_DONE | TRX_END | TRX_UR);
#ifdef TEST_GPIOS_ENABLED
rf_if_set_bit(IRQ_MASK, RX_START, RX_START);
#endif
xah_ctrl_1 = rf_if_read_register(XAH_CTRL_1);
/*Read transceiver PART_NUM*/
@ -1024,6 +1013,11 @@ static void rf_if_interrupt_handler(void)
/*Read and clear interrupt flag, and pick up trx_status*/
irq_status = rf_if_read_register_with_status(IRQ_STATUS, &full_trx_status);
#ifdef TEST_GPIOS_ENABLED
if (irq_status & RX_START) {
TEST_RX_STARTED
}
#endif
/*Frame end interrupt (RX and TX)*/
if (irq_status & TRX_END) {
rf_trx_states_t trx_status = rf_if_trx_status_from_full(full_trx_status);
@ -1384,7 +1378,6 @@ static void rf_channel_set(uint8_t ch)
rf_if_unlock();
}
/*
* \brief Function initialises the radio driver and resets the radio.
*
@ -1526,6 +1519,7 @@ static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_h
rf_tx_length = data_length;
/*Start CCA timeout*/
rf_cca_timer_start(RF_CCA_BASE_BACKOFF + randLIB_get_random_in_range(0, RF_CCA_RANDOM_BACKOFF));
TEST_CSMA_STARTED
/*Store TX handle*/
mac_tx_handle = tx_handle;
rf_if_unlock();
@ -1544,6 +1538,7 @@ static int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_h
*/
static void rf_cca_abort(void)
{
TEST_CSMA_DONE
rf_cca_timer_stop();
rf_flags_clear(RFF_CCA);
}
@ -1585,6 +1580,7 @@ static bool rf_start_tx()
rf_flags_set(RFF_TX);
/*RF state change: SLP_TR pulse triggers PLL_ON->BUSY_TX*/
rf_if_enable_slptr();
TEST_TX_STARTED
/*Chip permits us to write frame buffer while it is transmitting*/
/*As long as first byte of data is in within 176us of TX start, we're good */
rf_if_write_frame_buffer(rf_tx_data, rf_tx_length);
@ -1601,6 +1597,7 @@ static bool rf_start_tx()
*/
static void rf_receive(rf_trx_states_t trx_status)
{
TEST_RX_DONE
uint16_t while_counter = 0;
if (rf_flags_check(RFF_ON) == 0) {
rf_on();
@ -1765,6 +1762,7 @@ static void rf_handle_ack(uint8_t seq_number, uint8_t data_pending)
*/
static void rf_handle_rx_end(rf_trx_states_t trx_status)
{
TEST_RX_DONE
/*Frame received interrupt*/
if (!rf_flags_check(RFF_RX)) {
return;
@ -1827,6 +1825,7 @@ static void rf_shutdown(void)
*/
static void rf_handle_tx_end(rf_trx_states_t trx_status)
{
TEST_TX_DONE
rf_rx_mode = 0;
/*If ACK is needed for this transmission*/
if ((rf_tx_data[0] & 0x20) && rf_flags_check(RFF_TX)) {
@ -1853,6 +1852,7 @@ static void rf_handle_tx_end(rf_trx_states_t trx_status)
*/
static void rf_handle_cca_ed_done(uint8_t full_trx_status)
{
TEST_CSMA_DONE
if (!rf_flags_check(RFF_CCA)) {
return;
}
@ -2168,11 +2168,14 @@ static uint8_t rf_scale_lqi(int8_t rssi)
NanostackRfPhyAtmel::NanostackRfPhyAtmel(PinName spi_mosi, PinName spi_miso,
PinName spi_sclk, PinName spi_cs, PinName spi_rst, PinName spi_slp, PinName spi_irq,
PinName i2c_sda, PinName i2c_scl)
: _mac(i2c_sda, i2c_scl), _mac_addr(), _rf(NULL), _mac_set(false),
: _mac(i2c_sda, i2c_scl), _mac_addr(), _rf(NULL), _test_pins(NULL), _mac_set(false),
_spi_mosi(spi_mosi), _spi_miso(spi_miso), _spi_sclk(spi_sclk),
_spi_cs(spi_cs), _spi_rst(spi_rst), _spi_slp(spi_slp), _spi_irq(spi_irq)
{
_rf = new RFBits(_spi_mosi, _spi_miso, _spi_sclk, _spi_cs, _spi_rst, _spi_slp, _spi_irq);
#ifdef TEST_GPIOS_ENABLED
_test_pins = new TestPins(TEST_PIN_TX, TEST_PIN_RX, TEST_PIN_CSMA, TEST_PIN_SPARE_1, TEST_PIN_SPARE_2);
#endif
}
NanostackRfPhyAtmel::~NanostackRfPhyAtmel()
@ -2196,6 +2199,7 @@ int8_t NanostackRfPhyAtmel::rf_register()
// Read the mac address if it hasn't been set by a user
rf = _rf;
test_pins = _test_pins;
if (!_mac_set) {
int ret = _mac.read_eui64((void *)_mac_addr);
if (ret < 0) {
@ -2204,9 +2208,20 @@ int8_t NanostackRfPhyAtmel::rf_register()
return -1;
}
}
int8_t radio_id = rf_device_register(_mac_addr);
/*Reset RF module*/
rf_if_reset_radio();
rf_part_num = rf_if_read_part_num();
int8_t radio_id = -1;
if (rf_part_num != PART_AT86RF231 && rf_part_num != PART_AT86RF233 && rf_part_num != PART_AT86RF212) {
// Register RF type 215. Jumps to AT86RF215 driver.
radio_id = rf->init_215_driver(_rf, _test_pins, _mac_addr, &rf_part_num);
} else {
// Register other RF types.
radio_id = rf_device_register(_mac_addr);
}
tr_info("RF part number: %x", rf_part_num);
if (radio_id < 0) {
tr_err("RF registration failed");
rf = NULL;
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020 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 RFBITS_H_
#define RFBITS_H_
#include "DigitalIn.h"
#include "DigitalOut.h"
#include "InterruptIn.h"
#include "SPI.h"
#include <Timer.h>
#include "Timeout.h"
#include "rtos.h"
using namespace mbed;
using namespace rtos;
class UnlockedSPI : public SPI {
public:
UnlockedSPI(PinName mosi, PinName miso, PinName sclk) :
SPI(mosi, miso, sclk) { }
virtual void lock() { }
virtual void unlock() { }
};
class RFBits {
public:
RFBits(PinName spi_mosi, PinName spi_miso,
PinName spi_sclk, PinName spi_cs,
PinName spi_rst, PinName spi_slp, PinName spi_irq);
UnlockedSPI spi;
DigitalOut CS;
DigitalOut RST;
DigitalOut SLP_TR;
InterruptIn IRQ;
Timeout ack_timer;
Timeout cal_timer;
Timeout cca_timer;
Timer tx_timer;
int init_215_driver(RFBits *_rf, TestPins *_test_pins, const uint8_t mac[8], uint8_t *rf_part_num);
#ifdef MBED_CONF_RTOS_PRESENT
Thread irq_thread;
Thread irq_thread_215;
Mutex mutex;
void rf_if_irq_task();
void rf_irq_task();
#endif
};
class TestPins {
public:
TestPins(PinName test_pin_1, PinName test_pin_2, PinName test_pin_3, PinName test_pin_4, PinName test_pin_5);
DigitalOut TEST1;
DigitalOut TEST2;
DigitalOut TEST3;
DigitalOut TEST4;
DigitalOut TEST5;
};
#endif /* RFBITS_H_ */