Skip to content

Commit

Permalink
drivers: mbox: mbox_esp32: fix mbox callback call
Browse files Browse the repository at this point in the history
Fixes the mailbox notification callback that was not
being called from the ISR when the other side sends
something.

Signed-off-by: Felipe Neves <ryukokki.felipe@gmail.com>
  • Loading branch information
uLipe authored and nashif committed Sep 19, 2024
1 parent a421f33 commit 4713707
Showing 1 changed file with 41 additions and 53 deletions.
94 changes: 41 additions & 53 deletions drivers/mbox/mbox_esp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
LOG_MODULE_REGISTER(mbox_esp32, CONFIG_MBOX_LOG_LEVEL);

#define ESP32_MBOX_LOCK_FREE_VAL 0xB33FFFFF
#define ESP32_MBOX_NOOP_VAL 0xFF
#define ESP32_MBOX_NOOP_VAL 0xFF

__packed struct esp32_mbox_control {
uint16_t dest_cpu_msg_id[2];
Expand Down Expand Up @@ -50,6 +50,7 @@ struct esp32_mbox_data {
IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
{
struct esp32_mbox_data *dev_data = (struct esp32_mbox_data *)dev->data;
struct mbox_msg msg;
uint32_t core_id = dev_data->this_core_id;

/* clear interrupt flag */
Expand All @@ -68,25 +69,27 @@ IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
}

/* first of all take the ownership of the shared memory */
while (!atomic_cas(&dev_data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL, dev_data->this_core_id))
while (!atomic_cas(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id))
;

if (dev_data->cb) {
/* For ESP32 soft mbox driver, the message parameter of the callback holds
* the portion of shared memory that belongs to the current core ID.
*/
msg.data = (dev_data->this_core_id == 0) ? (const void *)dev_data->shm.pro_cpu_shm
: (const void *)dev_data->shm.app_cpu_shm;
msg.size = dev_data->shm_size;

volatile void *shm = dev_data->shm.pro_cpu_shm;

if (core_id != 0) {
shm = dev_data->shm.app_cpu_shm;
}
dev_data->cb(dev, dev_data->other_core_id, dev_data->user_data, &msg);
}

/* unlock the shared memory */
atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
}

static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
const struct mbox_msg *msg)
const struct mbox_msg *msg)
{
ARG_UNUSED(msg);

Expand All @@ -100,9 +103,8 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
uint32_t key = irq_lock();

/* try to lock the shared memory */
while (!atomic_cas(&dev_data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id)) {
while (!atomic_cas(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
dev_data->this_core_id)) {
k_msleep(1);
}

Expand Down Expand Up @@ -135,7 +137,7 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
}

static int esp32_mbox_register_callback(const struct device *dev, mbox_channel_id_t channel,
mbox_callback_t cb, void *user_data)
mbox_callback_t cb, void *user_data)
{
ARG_UNUSED(channel);

Expand Down Expand Up @@ -183,14 +185,13 @@ static int esp32_mbox_set_enabled(const struct device *dev, mbox_channel_id_t ch
return 0;
}


static int esp32_mbox_init(const struct device *dev)
{
struct esp32_mbox_data *data = (struct esp32_mbox_data *)dev->data;
struct esp32_mbox_config *cfg = (struct esp32_mbox_config *)dev->config;

data->this_core_id = esp_core_id();
data->other_core_id = (data->this_core_id == 0) ? 1 : 0;
data->other_core_id = (data->this_core_id == 0) ? 1 : 0;

LOG_DBG("Size of MBOX shared memory: %d", data->shm_size);
LOG_DBG("Address of PRO_CPU MBOX shared memory: %p", data->shm.pro_cpu_shm);
Expand All @@ -199,32 +200,25 @@ static int esp32_mbox_init(const struct device *dev)

/* pro_cpu is responsible to initialize the lock of shared memory */
if (data->this_core_id == 0) {
esp_intr_alloc(cfg->irq_source_pro_cpu,
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr,
(void *)dev,
NULL);
esp_intr_alloc(cfg->irq_source_pro_cpu, ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);

atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
} else {
/* app_cpu wait for initialization from pro_cpu, then takes it,
* after that releases
*/
esp_intr_alloc(cfg->irq_source_app_cpu,
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr,
(void *)dev,
NULL);
esp_intr_alloc(cfg->irq_source_app_cpu, ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);

LOG_DBG("Waiting CPU0 to sync");
while (!atomic_cas(&data->control->lock,
ESP32_MBOX_LOCK_FREE_VAL, data->this_core_id))
while (!atomic_cas(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
data->this_core_id))
;

atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);

LOG_DBG("Synchronization done");

}

return 0;
Expand All @@ -238,30 +232,24 @@ static const struct mbox_driver_api esp32_mbox_driver_api = {
.set_enabled = esp32_mbox_set_enabled,
};

#define ESP32_MBOX_SHM_SIZE_BY_IDX(idx) \
DT_INST_PROP(idx, shared_memory_size) \

#define ESP32_MBOX_SHM_ADDR_BY_IDX(idx) \
DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(idx), shared_memory)) \

#define ESP32_MBOX_INIT(idx) \
\
static struct esp32_mbox_config esp32_mbox_device_cfg_##idx = { \
.irq_source_pro_cpu = DT_INST_IRQN(idx), \
.irq_source_app_cpu = DT_INST_IRQN(idx) + 1, \
}; \
\
static struct esp32_mbox_data esp32_mbox_device_data_##idx = { \
.shm_size = ESP32_MBOX_SHM_SIZE_BY_IDX(idx), \
.shm.pro_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx), \
.shm.app_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx) + \
ESP32_MBOX_SHM_SIZE_BY_IDX(idx)/2, \
.control = (struct esp32_mbox_control *)DT_INST_REG_ADDR(idx), \
}; \
\
DEVICE_DT_INST_DEFINE(idx, &esp32_mbox_init, NULL, \
&esp32_mbox_device_data_##idx, &esp32_mbox_device_cfg_##idx, \
PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&esp32_mbox_driver_api); \
#define ESP32_MBOX_SHM_SIZE_BY_IDX(idx) DT_INST_PROP(idx, shared_memory_size)

#define ESP32_MBOX_SHM_ADDR_BY_IDX(idx) DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(idx), shared_memory))

#define ESP32_MBOX_INIT(idx) \
static struct esp32_mbox_config esp32_mbox_device_cfg_##idx = { \
.irq_source_pro_cpu = DT_INST_IRQN(idx), \
.irq_source_app_cpu = DT_INST_IRQN(idx) + 1, \
}; \
static struct esp32_mbox_data esp32_mbox_device_data_##idx = { \
.shm_size = ESP32_MBOX_SHM_SIZE_BY_IDX(idx), \
.shm.pro_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx), \
.shm.app_cpu_shm = (uint8_t *)ESP32_MBOX_SHM_ADDR_BY_IDX(idx) + \
ESP32_MBOX_SHM_SIZE_BY_IDX(idx) / 2, \
.control = (struct esp32_mbox_control *)DT_INST_REG_ADDR(idx), \
}; \
DEVICE_DT_INST_DEFINE(idx, &esp32_mbox_init, NULL, &esp32_mbox_device_data_##idx, \
&esp32_mbox_device_cfg_##idx, PRE_KERNEL_2, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &esp32_mbox_driver_api);

DT_INST_FOREACH_STATUS_OKAY(ESP32_MBOX_INIT);

0 comments on commit 4713707

Please sign in to comment.