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:
parent
4c6ee8b3d9
commit
2cfb11e050
2 changed files with 21 additions and 70 deletions
|
@ -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( \
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue