drivers: ieee802154: rf2xx: Rem trx_state variable

The rx timeout timer callback need update trx_state variable and this
variable is protected by a mutex. Because of that, when compiling the
system with CONFIG_ASSERT=y the system reports 'ASSERTION FAIL
[!arch_is_in_isr()] @ ZEPHYR_BASE/kernel/include/ksched.h:262'.

This refactor the driver remove trx_state variable dependency and
consequently removes phy_mutex and rx timeout timer to be compliant
with kernel rules.

Fixes: #23198

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
Gerson Fernando Budke 2020-03-03 20:47:59 -03:00 committed by Johan Hedberg
commit 2cfb11e050
2 changed files with 21 additions and 70 deletions

View file

@ -77,16 +77,6 @@ static inline void trx_isr_handler(struct device *port,
k_sem_give(&ctx->trx_isr_lock); k_sem_give(&ctx->trx_isr_lock);
} }
static void trx_isr_timeout(struct k_timer *timer_id)
{
struct rf2xx_context *ctx = (struct rf2xx_context *)
k_timer_user_data_get(timer_id);
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
k_mutex_unlock(&ctx->phy_mutex);
}
static void rf2xx_trx_set_state(struct device *dev, static void rf2xx_trx_set_state(struct device *dev,
enum rf2xx_trx_state_cmd_t state) enum rf2xx_trx_state_cmd_t state)
{ {
@ -113,6 +103,9 @@ static void rf2xx_trx_set_tx_state(struct device *dev)
* Datasheet: Chapter 7.2.3 RX_AACK_ON Receive with Automatic ACK * Datasheet: Chapter 7.2.3 RX_AACK_ON Receive with Automatic ACK
* Datasheet: Figure 7-13. Timing Example of an RX_AACK Transaction * Datasheet: Figure 7-13. Timing Example of an RX_AACK Transaction
* for Slotted Operation. * for Slotted Operation.
*
* This will create a spin lock that wait transceiver be free from
* current receive frame process
*/ */
do { do {
status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) & status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
@ -120,6 +113,8 @@ static void rf2xx_trx_set_tx_state(struct device *dev)
} while (status == RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK || } while (status == RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK ||
status == RF2XX_TRX_PHY_STATUS_STATE_TRANSITION); status == RF2XX_TRX_PHY_STATUS_STATE_TRANSITION);
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TX_ARET_ON); rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TX_ARET_ON);
} }
@ -218,8 +213,6 @@ static void rf2xx_process_rx_frame(struct device *dev)
{ {
struct rf2xx_context *ctx = dev->driver_data; struct rf2xx_context *ctx = dev->driver_data;
k_timer_stop(&ctx->trx_isr_timeout);
if (ctx->trx_model != RF2XX_TRX_MODEL_231) { if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
rf2xx_trx_rx(dev); rf2xx_trx_rx(dev);
} else { } else {
@ -252,14 +245,14 @@ static void rf2xx_process_tx_frame(struct device *dev)
static void rf2xx_process_trx_end(struct device *dev) static void rf2xx_process_trx_end(struct device *dev)
{ {
struct rf2xx_context *ctx = dev->driver_data; u8_t trx_status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
RF2XX_TRX_PHY_STATUS_MASK);
if (ctx->trx_state == RF2XX_TRX_PHY_BUSY_RX) { if (trx_status == RF2XX_TRX_PHY_STATUS_TX_ARET_ON) {
rf2xx_process_rx_frame(dev);
} else {
rf2xx_process_tx_frame(dev); rf2xx_process_tx_frame(dev);
} else {
rf2xx_process_rx_frame(dev);
} }
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
} }
static void rf2xx_thread_main(void *arg) static void rf2xx_thread_main(void *arg)
@ -270,9 +263,9 @@ static void rf2xx_thread_main(void *arg)
while (true) { while (true) {
k_sem_take(&ctx->trx_isr_lock, K_FOREVER); k_sem_take(&ctx->trx_isr_lock, K_FOREVER);
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
isr_status = rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG); isr_status = rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
/* /*
* IRQ_7 (BAT_LOW) Indicates a supply voltage below the * IRQ_7 (BAT_LOW) Indicates a supply voltage below the
* programmed threshold. 9.5.4 * programmed threshold. 9.5.4
@ -300,16 +293,12 @@ static void rf2xx_thread_main(void *arg)
* IRQ_0 (PLL_LOCK) Indicates PLL lock. * IRQ_0 (PLL_LOCK) Indicates PLL lock.
*/ */
if (isr_status & (1 << RF2XX_RX_START)) { if (isr_status & (1 << RF2XX_RX_START)) {
ctx->trx_state = RF2XX_TRX_PHY_BUSY_RX;
k_timer_start(&ctx->trx_isr_timeout, K_MSEC(10), 0);
if (ctx->trx_model != RF2XX_TRX_MODEL_231) { if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
rf2xx_iface_sram_read(dev, 0, &ctx->rx_phr, 1); rf2xx_iface_sram_read(dev, 0, &ctx->rx_phr, 1);
} }
} else if (isr_status & (1 << RF2XX_TRX_END)) { } else if (isr_status & (1 << RF2XX_TRX_END)) {
rf2xx_process_trx_end(dev); rf2xx_process_trx_end(dev);
} }
k_mutex_unlock(&ctx->phy_mutex);
} }
} }
@ -483,33 +472,14 @@ static int rf2xx_tx(struct device *dev,
ARG_UNUSED(pkt); ARG_UNUSED(pkt);
struct rf2xx_context *ctx = dev->driver_data; struct rf2xx_context *ctx = dev->driver_data;
bool abort = true;
int response = 0; int response = 0;
k_mutex_lock(&ctx->phy_mutex, K_FOREVER); rf2xx_trx_set_tx_state(dev);
/* Reset semaphore in case ACK was received after timeout */ rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
k_sem_reset(&ctx->trx_tx_sync); k_sem_reset(&ctx->trx_tx_sync);
rf2xx_iface_frame_write(dev, frag->data, frag->len);
if (ctx->trx_state == RF2XX_TRX_PHY_STATE_IDLE) { rf2xx_iface_phy_tx_start(dev);
ctx->trx_state = RF2XX_TRX_PHY_BUSY_TX;
abort = false;
rf2xx_trx_set_tx_state(dev);
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
rf2xx_iface_frame_write(dev, frag->data, frag->len);
rf2xx_iface_phy_tx_start(dev);
}
k_mutex_unlock(&ctx->phy_mutex);
if (abort) {
LOG_DBG("TX Abort, TRX isn't idle!");
return -EBUSY;
}
/**
* Wait transceiver...
*/
k_sem_take(&ctx->trx_tx_sync, K_FOREVER); k_sem_take(&ctx->trx_tx_sync, K_FOREVER);
switch (ctx->trx_trac) { switch (ctx->trx_trac) {
@ -551,11 +521,11 @@ static int rf2xx_start(struct device *dev)
const struct rf2xx_config *conf = dev->config->config_info; const struct rf2xx_config *conf = dev->config->config_info;
struct rf2xx_context *ctx = dev->driver_data; struct rf2xx_context *ctx = dev->driver_data;
k_mutex_lock(&ctx->phy_mutex, K_FOREVER); rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin, gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin,
GPIO_INT_EDGE_TO_ACTIVE); GPIO_INT_EDGE_TO_ACTIVE);
rf2xx_trx_set_rx_state(dev); rf2xx_trx_set_rx_state(dev);
k_mutex_unlock(&ctx->phy_mutex);
return 0; return 0;
} }
@ -565,11 +535,10 @@ static int rf2xx_stop(struct device *dev)
const struct rf2xx_config *conf = dev->config->config_info; const struct rf2xx_config *conf = dev->config->config_info;
struct rf2xx_context *ctx = dev->driver_data; struct rf2xx_context *ctx = dev->driver_data;
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin, gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin,
GPIO_INT_DISABLE); GPIO_INT_DISABLE);
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF); rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
k_mutex_unlock(&ctx->phy_mutex); rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
return 0; return 0;
} }
@ -590,8 +559,6 @@ static int power_on_and_setup(struct device *dev)
struct rf2xx_context *ctx = dev->driver_data; struct rf2xx_context *ctx = dev->driver_data;
u8_t config; u8_t config;
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
rf2xx_iface_phy_rst(dev); rf2xx_iface_phy_rst(dev);
/* Sync transceiver state */ /* Sync transceiver state */
@ -766,11 +733,8 @@ static int rf2xx_init(struct device *dev)
LOG_DBG("\nInitialize RF2XX Transceiver\n"); LOG_DBG("\nInitialize RF2XX Transceiver\n");
k_mutex_init(&ctx->phy_mutex);
k_sem_init(&ctx->trx_tx_sync, 0, 1); k_sem_init(&ctx->trx_tx_sync, 0, 1);
k_sem_init(&ctx->trx_isr_lock, 0, 1); k_sem_init(&ctx->trx_isr_lock, 0, 1);
k_timer_init(&ctx->trx_isr_timeout, trx_isr_timeout, NULL);
k_timer_user_data_set(&ctx->trx_isr_timeout, ctx);
if (configure_gpios(dev) != 0) { if (configure_gpios(dev) != 0) {
LOG_ERR("Configuring GPIOS failed"); LOG_ERR("Configuring GPIOS failed");
@ -905,12 +869,10 @@ static struct ieee802154_radio_api rf2xx_radio_api = {
.spi.cs.devname = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_CONTROLLER, \ .spi.cs.devname = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_CONTROLLER, \
.spi.cs.pin = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_PIN, \ .spi.cs.pin = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_PIN, \
.spi.cs.flags = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_FLAGS, \ .spi.cs.flags = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_FLAGS, \
} };
#define IEEE802154_RF2XX_DEVICE_DATA(n) \ #define IEEE802154_RF2XX_DEVICE_DATA(n) \
static struct rf2xx_context rf2xx_ctx_data_##n = { \ static struct rf2xx_context rf2xx_ctx_data_##n;
.trx_state = RF2XX_TRX_PHY_STATE_INITIAL, \
}
#define IEEE802154_RF2XX_RAW_DEVICE_INIT(n) \ #define IEEE802154_RF2XX_RAW_DEVICE_INIT(n) \
DEVICE_AND_API_INIT( \ DEVICE_AND_API_INIT( \

View file

@ -65,14 +65,6 @@ enum rf2xx_trx_state_trac_t {
RF2XX_TRX_PHY_STATE_TRAC_INVALID = 0x07, RF2XX_TRX_PHY_STATE_TRAC_INVALID = 0x07,
}; };
enum rf2xx_trx_state_t {
RF2XX_TRX_PHY_STATE_INITIAL,
RF2XX_TRX_PHY_STATE_IDLE,
RF2XX_TRX_PHY_STATE_SLEEP,
RF2XX_TRX_PHY_BUSY_RX,
RF2XX_TRX_PHY_BUSY_TX,
};
enum rf2xx_trx_model_t { enum rf2xx_trx_model_t {
RF2XX_TRX_MODEL_INV = 0x00, RF2XX_TRX_MODEL_INV = 0x00,
RF2XX_TRX_MODEL_230 = 0x02, RF2XX_TRX_MODEL_230 = 0x02,
@ -127,11 +119,8 @@ struct rf2xx_context {
CONFIG_IEEE802154_RF2XX_RX_STACK_SIZE); CONFIG_IEEE802154_RF2XX_RX_STACK_SIZE);
struct k_sem trx_isr_lock; struct k_sem trx_isr_lock;
struct k_sem trx_tx_sync; struct k_sem trx_tx_sync;
struct k_timer trx_isr_timeout;
struct k_mutex phy_mutex;
enum rf2xx_trx_model_t trx_model; enum rf2xx_trx_model_t trx_model;
enum rf2xx_trx_state_t trx_state;
enum rf2xx_trx_state_trac_t trx_trac; enum rf2xx_trx_state_trac_t trx_trac;
u8_t mac_addr[8]; u8_t mac_addr[8];