diff --git a/atmel-rf-driver/NanostackRfPhyAtmel.h b/atmel-rf-driver/NanostackRfPhyAtmel.h index d6fab5cf5d1..5a0d13164ab 100644 --- a/atmel-rf-driver/NanostackRfPhyAtmel.h +++ b/atmel-rf-driver/NanostackRfPhyAtmel.h @@ -28,52 +28,99 @@ // #define TEST_GPIOS_ENABLED // Arduino pin defaults for convenience -#if !defined(ATMEL_SPI_MOSI) -#define ATMEL_SPI_MOSI D11 +#if defined(MBED_CONF_ATMEL_RF_SPI_MOSI) +#define ATMEL_SPI_MOSI MBED_CONF_ATMEL_RF_SPI_MOSI +#else +#define ATMEL_SPI_MOSI D11 #endif -#if !defined(ATMEL_SPI_MISO) -#define ATMEL_SPI_MISO D12 + +#if defined(MBED_CONF_ATMEL_RF_SPI_MISO) +#define ATMEL_SPI_MISO MBED_CONF_ATMEL_RF_SPI_MISO +#else +#define ATMEL_SPI_MISO D12 #endif -#if !defined(ATMEL_SPI_SCLK) -#define ATMEL_SPI_SCLK D13 + +#if defined(MBED_CONF_ATMEL_RF_SPI_SCLK) +#define ATMEL_SPI_SCLK MBED_CONF_ATMEL_RF_SPI_SCLK +#else +#define ATMEL_SPI_SCLK D13 #endif -#if !defined(ATMEL_SPI_CS) -#define ATMEL_SPI_CS D10 + +#if defined(MBED_CONF_ATMEL_RF_SPI_CS) +#define ATMEL_SPI_CS MBED_CONF_ATMEL_RF_SPI_CS +#else +#define ATMEL_SPI_CS D10 #endif -#if !defined(ATMEL_SPI_RST) -#define ATMEL_SPI_RST D5 + +#if defined(MBED_CONF_ATMEL_RF_SPI_RST) +#define ATMEL_SPI_RST MBED_CONF_ATMEL_RF_SPI_RST +#else +#define ATMEL_SPI_RST D5 #endif -#if !defined(ATMEL_SPI_SLP) -#define ATMEL_SPI_SLP D7 + +#if defined(MBED_CONF_ATMEL_RF_SPI_SLP) +#define ATMEL_SPI_SLP MBED_CONF_ATMEL_RF_SPI_SLP +#else +#define ATMEL_SPI_SLP D7 #endif -#if !defined(ATMEL_SPI_IRQ) -#define ATMEL_SPI_IRQ D9 + +#if defined(MBED_CONF_ATMEL_RF_SPI_IRQ) +#define ATMEL_SPI_IRQ MBED_CONF_ATMEL_RF_SPI_IRQ +#else +#define ATMEL_SPI_IRQ D9 #endif -#if !defined(ATMEL_I2C_SDA) -#define ATMEL_I2C_SDA D14 + +#if defined(MBED_CONF_ATMEL_RF_I2C_SDA) +#define ATMEL_I2C_SDA MBED_CONF_ATMEL_RF_I2C_SDA +#else +#define ATMEL_I2C_SDA D14 #endif -#if !defined(ATMEL_I2C_SCL) -#define ATMEL_I2C_SCL D15 + +#if defined(MBED_CONF_ATMEL_RF_I2C_SCL) +#define ATMEL_I2C_SCL MBED_CONF_ATMEL_RF_I2C_SCL +#else +#define ATMEL_I2C_SCL D15 #endif -#if !defined(TEST_PIN_TX) -#define TEST_PIN_TX D6 + +#if defined(MBED_CONF_ATMEL_RF_TEST_PIN_TX) +#define TEST_PIN_TX MBED_CONF_ATMEL_RF_TEST_PIN_TX +#else +#define TEST_PIN_TX D6 #endif -#if !defined(TEST_PIN_RX) -#define TEST_PIN_RX D3 + +#if defined(MBED_CONF_ATMEL_RF_TEST_PIN_RX) +#define TEST_PIN_RX MBED_CONF_ATMEL_RF_TEST_PIN_RX +#else +#define TEST_PIN_RX D3 #endif -#if !defined(TEST_PIN_CSMA) -#define TEST_PIN_CSMA D4 + +#if defined(MBED_CONF_ATMEL_RF_TEST_PIN_CSMA) +#define TEST_PIN_CSMA MBED_CONF_ATMEL_RF_TEST_PIN_CSMA +#else +#define TEST_PIN_CSMA D4 #endif -#if !defined(TEST_PIN_SPARE_1) + +#if defined(MBED_CONF_ATMEL_RF_TEST_PIN_SPARE_1) +#define TEST_PIN_SPARE_1 MBED_CONF_ATMEL_RF_TEST_PIN_SPARE_1 +#else #define TEST_PIN_SPARE_1 D2 #endif -#if !defined(TEST_PIN_SPARE_2) + +#if defined(MBED_CONF_ATMEL_RF_TEST_PIN_SPARE_2) +#define TEST_PIN_SPARE_2 MBED_CONF_ATMEL_RF_TEST_PIN_SPARE_2 +#else #define TEST_PIN_SPARE_2 D8 #endif -#if !defined(SE2435L_CSD) -#define SE2435L_CSD D2 + +#if defined(MBED_CONF_ATMEL_RF_SE2435L_CSD) +#define SE2435L_CSD MBED_CONF_ATMEL_RF_SE2435L_CSD +#else +#define SE2435L_CSD D2 #endif -#if !defined(SE2435L_ANT_SEL) + +#if defined(MBED_CONF_ATMEL_RF_SE2435L_ANT_SEL) +#define SE2435L_ANT_SEL MBED_CONF_ATMEL_RF_SE2435L_ANT_SEL +#else #define SE2435L_ANT_SEL D8 #endif diff --git a/mbed_lib.json b/mbed_lib.json index e44a0dc527f..625ed90b86c 100644 --- a/mbed_lib.json +++ b/mbed_lib.json @@ -1,6 +1,70 @@ { "name": "atmel-rf", "config": { + "SPI_MOSI": { + "help": "SPI_MOSI pin configured for SPI connection.", + "value": null + }, + "SPI_MISO": { + "help": "SPI_MISO pin configured for SPI connection.", + "value": null + }, + "SPI_SCLK": { + "help": "SPI_SCLK pin configured for SPI connection.", + "value": null + }, + "SPI_CS": { + "help": "SPI_CS pin configured for SPI connection.", + "value": null + }, + "SPI_RST": { + "help": "SPI_RST pin configured for SPI connection.", + "value": null + }, + "SPI_SLP": { + "help": "SPI_SLP pin configured for SPI connection.", + "value": null + }, + "SPI_IRQ": { + "help": "SPI_IRQ pin configured for SPI connection.", + "value": null + }, + "I2C_SDA": { + "help": "I2C_SDA pin configured for I2C connection.", + "value": null + }, + "I2C_SCL": { + "help": "I2C_SCL pin configured for I2C connection.", + "value": null + }, + "TEST_PIN_TX": { + "help": "TEST_PIN_TX pin configured for TX.", + "value": null + }, + "TEST_PIN_RX": { + "help": "TEST_PIN_RX pin configured for RX.", + "value": null + }, + "TEST_PIN_CSMA": { + "help": "TEST_PIN_CSMA pin configured for CSMA.", + "value": null + }, + "TEST_PIN_SPARE_1": { + "help": "TEST_PIN_SPARE_1.", + "value": null + }, + "TEST_PIN_SPARE_2": { + "help": "TEST_PIN_SPARE_2.", + "value": null + }, + "SE2435L_CSD": { + "help": "SE2435L_CSD pin configuration.", + "value": null + }, + "SE2435L_ANT_SEL": { + "help": "SE2435L_ANT_SEL pin confuguration.", + "value": null + }, "full-spi-speed": { "help": "Maximum SPI clock speed (Hz), as long as sufficient inter-byte spacing", "value": 7500000 diff --git a/source/AT86RF215Reg.h b/source/AT86RF215Reg.h index 6836b0cb3fb..6846845cb07 100644 --- a/source/AT86RF215Reg.h +++ b/source/AT86RF215Reg.h @@ -97,6 +97,9 @@ extern "C" { // RF_PAC #define TXPWR 0x1F #define TXPWR_11 (11 << 0) +#define TXPWR_0 (0 << 0) +#define TXPWR_31 (31 << 0) + // RF_PADFE #define PADFE 0xC0 @@ -165,6 +168,9 @@ extern "C" { #define SR_2 (2 << 0) #define SR_1 (1 << 0) +// BBC_FSKPHRTX +#define DW (1 << 2) + // BBC_OFDMPHRTX #define MCS 0x07 #define MCS_0 (0 << 0) diff --git a/source/NanostackRfPhyAT86RF215.cpp b/source/NanostackRfPhyAT86RF215.cpp index 488b337527a..7c42547d83a 100644 --- a/source/NanostackRfPhyAT86RF215.cpp +++ b/source/NanostackRfPhyAT86RF215.cpp @@ -103,6 +103,7 @@ static int rf_set_fsk_symbol_rate_configuration(uint32_t symbol_rate, rf_modules static int rf_configure_by_ofdm_bandwidth_option(uint8_t option, uint32_t data_rate, rf_modules_e module); static void rf_calculate_symbol_rate(uint32_t baudrate, phy_modulation_e modulation); static void rf_conf_set_cca_threshold(uint8_t percent); +static bool rf_conf_set_tx_power(uint8_t percent); // Defined register read/write functions #define rf_read_bbc_register(x, y) rf_read_rf_register(x, (rf_modules_e)(y + 2)) #define rf_read_common_register(x) rf_read_rf_register(x, COMMON) @@ -134,7 +135,10 @@ static uint8_t bbc0_irq_mask = 0; static uint8_t bbc1_irq_mask = 0; static bool rf_update_config = false; +static bool rf_update_tx_power = false; static int8_t cca_threshold = -80; +static uint8_t rf_tx_power = TXPWR_31; +static bool data_whitening_enabled = true; static bool cca_enabled = true; static uint32_t rf_symbol_rate; @@ -303,9 +307,25 @@ static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_pt case PHY_EXTENSION_SET_CCA_THRESHOLD: rf_conf_set_cca_threshold(*data_ptr); break; + case PHY_EXTENSION_SET_TX_POWER: + if (*data_ptr > 100) { + return -1; + } + rf_update_tx_power = rf_conf_set_tx_power(*data_ptr); + if (rf_update_tx_power && (rf_state == RF_IDLE)) { + rf_receive(rf_rx_channel, rf_module); + } + break; case PHY_EXTENSION_SET_CHANNEL_CCA_THRESHOLD: cca_threshold = (int8_t) *data_ptr; // *NOPAD* break; + case PHY_EXTENSION_SET_DATA_WHITENING: + data_whitening_enabled = (bool) *data_ptr; // *NOPAD* + rf_update_config = true; + if (rf_state == RF_IDLE) { + rf_receive(rf_rx_channel, rf_module); + } + break; case PHY_EXTENSION_SET_802_15_4_MODE: mac_mode = (phy_802_15_4_mode_t) *data_ptr; // *NOPAD* if (mac_mode == IEEE_802_15_4_2011) { @@ -418,6 +438,12 @@ static void rf_init_registers(rf_modules_e module) rf_write_bbc_register_field(BBC_AFC0, module, AFEN0, 0); // Enable FSK if (phy_current_config.modulation == M_2FSK) { + // Enable or disable data whitening + if (data_whitening_enabled) { + rf_write_bbc_register_field(BBC_FSKPHRTX, module, DW, DW); + } else { + rf_write_bbc_register_field(BBC_FSKPHRTX, module, DW, 0); + } rf_write_bbc_register_field(BBC_PC, module, PT, BB_MRFSK); // Set bandwidth time product rf_write_bbc_register_field(BBC_FSKC0, module, BT, BT_20); @@ -474,8 +500,10 @@ static void rf_init_registers(rf_modules_e module) // Enable external front end with configuration 3 rf_write_rf_register_field(RF_PADFE, module, PADFE, RF_FEMODE3); // Output power at 900MHz: 0 dBm with FSK/QPSK, less than -5 dBm with OFDM - rf_write_rf_register_field(RF_PAC, module, TXPWR, TXPWR_11); + rf_tx_power = TXPWR_11; } + // Set TX output power + rf_write_rf_register_field(RF_PAC, module, TXPWR, rf_tx_power); // Enable analog voltage regulator rf_write_rf_register_field(RF_AUXS, module, AVEN, AVEN); // Disable filtering FCS @@ -695,7 +723,7 @@ static void rf_handle_rx_start(void) static void rf_receive(uint16_t rx_channel, rf_modules_e module) { - if ((receiver_enabled == true) && (rf_update_config == false) && (rx_channel == rf_rx_channel)) { + if ((receiver_enabled == true) && (rf_update_config == false) && (rf_update_tx_power == false) && (rx_channel == rf_rx_channel)) { return; } TEST_RX_DONE @@ -706,6 +734,12 @@ static void rf_receive(uint16_t rx_channel, rf_modules_e module) rf_init_registers(module); rf_change_state(RF_TXPREP, module); } + if (rf_update_tx_power == true) { + rf_update_tx_power = false; + rf_change_state(RF_TRX_OFF, module); + rf_write_rf_register_field(RF_PAC, module, TXPWR, rf_tx_power); + rf_change_state(RF_TXPREP, module); + } if (rx_channel != rf_rx_channel) { rf_change_state(RF_TXPREP, module); rf_set_channel(rx_channel, module); @@ -1170,6 +1204,17 @@ static void rf_conf_set_cca_threshold(uint8_t percent) cca_threshold = MIN_CCA_THRESHOLD + (step * percent) / 100; } +static bool rf_conf_set_tx_power(uint8_t percent) +{ + uint8_t step = (TXPWR_31 - TXPWR_0); + uint8_t new_value = TXPWR_0 + (step * percent) / 100; + if (rf_tx_power != new_value) { + rf_tx_power = new_value; + return true; + } + return false; +} + static void rf_calculate_symbol_rate(uint32_t baudrate, phy_modulation_e modulation) { uint8_t bits_in_symbols = 4; diff --git a/source/NanostackRfPhyAtmel.cpp b/source/NanostackRfPhyAtmel.cpp index ef3ce7f4479..9cce0a0dd25 100644 --- a/source/NanostackRfPhyAtmel.cpp +++ b/source/NanostackRfPhyAtmel.cpp @@ -34,6 +34,21 @@ #include "inttypes.h" #include "Timeout.h" #include "platform/mbed_error.h" +#include "platform/mbed_version.h" + +#if (MBED_VERSION > MBED_ENCODE_VERSION(6, 0, 0)) +/* Mbed OS 6.0 introduces support for chrono time management */ +using namespace std::chrono; + #define ATMEL_RF_TIME_50US 50us + #define ATMEL_RF_TIME_2MS 2ms + #define ATMEL_RF_TIME_10MS 10ms + #define ATMEL_RF_ATTACH(timer_ref, signal_ref, timeout_ref) timer_ref.attach(signal_ref, timeout_ref) +#else + #define ATMEL_RF_TIME_50US 50 + #define ATMEL_RF_TIME_2MS 2 + #define ATMEL_RF_TIME_10MS 10 + #define ATMEL_RF_ATTACH(timer_ref, signal_ref, timeout_ref) timer_ref.attach_us(signal_ref, timeout_ref) +#endif #define TRACE_GROUP "AtRF" @@ -345,7 +360,6 @@ static rf_trx_part_e rf_radio_type_read(void) return ret_val; } - /* * \brief Function starts the ACK wait timeout. * @@ -356,9 +370,9 @@ static rf_trx_part_e rf_radio_type_read(void) static void rf_if_ack_wait_timer_start(uint16_t slots) { #ifdef MBED_CONF_RTOS_PRESENT - rf->ack_timer.attach_us(rf_if_ack_timer_signal, slots * 50); + ATMEL_RF_ATTACH(rf->ack_timer, rf_if_ack_timer_signal, slots * ATMEL_RF_TIME_50US); #else - rf->ack_timer.attach_us(rf_ack_wait_timer_interrupt, slots * 50); + ATMEL_RF_ATTACH(rf->ack_timer, rf_ack_wait_timer_interrupt, slots * ATMEL_RF_TIME_50US); #endif } @@ -372,9 +386,9 @@ static void rf_if_ack_wait_timer_start(uint16_t slots) static void rf_if_calibration_timer_start(uint32_t slots) { #ifdef MBED_CONF_RTOS_PRESENT - rf->cal_timer.attach_us(rf_if_cal_timer_signal, slots * 50); + ATMEL_RF_ATTACH(rf->cal_timer, rf_if_cal_timer_signal, slots * ATMEL_RF_TIME_50US); #else - rf->cal_timer.attach_us(rf_calibration_timer_interrupt, slots * 50); + ATMEL_RF_ATTACH(rf->cal_timer, rf_calibration_timer_interrupt, slots * ATMEL_RF_TIME_50US); #endif } @@ -388,9 +402,9 @@ static void rf_if_calibration_timer_start(uint32_t slots) static void rf_if_cca_timer_start(uint32_t slots) { #ifdef MBED_CONF_RTOS_PRESENT - rf->cca_timer.attach_us(rf_if_cca_timer_signal, slots * 50); + ATMEL_RF_ATTACH(rf->cca_timer, rf_if_cca_timer_signal, slots * ATMEL_RF_TIME_50US); #else - rf->cca_timer.attach_us(rf_cca_timer_interrupt, slots * 50); + ATMEL_RF_ATTACH(rf->cca_timer, rf_cca_timer_interrupt, slots * ATMEL_RF_TIME_50US); #endif } @@ -519,14 +533,14 @@ static void rf_if_reset_radio(void) #endif rf->IRQ.rise(nullptr); rf->RST = 1; - ThisThread::sleep_for(2); + ThisThread::sleep_for(ATMEL_RF_TIME_2MS); rf->RST = 0; - ThisThread::sleep_for(10); + ThisThread::sleep_for(ATMEL_RF_TIME_10MS); CS_RELEASE(); rf->SLP_TR = 0; - ThisThread::sleep_for(10); + ThisThread::sleep_for(ATMEL_RF_TIME_10MS); rf->RST = 1; - ThisThread::sleep_for(10); + ThisThread::sleep_for(ATMEL_RF_TIME_10MS); rf->IRQ.rise(&rf_if_interrupt_handler); }