drivers: sensor: bmm350: fix handling interrupt race condition

There is a race condition where an interrupt can fire before the
drdy_handler is registered. The drdy_handler will tradionaly
callback the sample get clearing the interrupt... but if it's not
configured and NULL, the interrupt will stay forever latched. Read
the interrupt status to clear the interrupt flag allowing it to
trigger again.

Also, move the serial api function helpers in to the header
allowing them to be used from other c files.

Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
Ryan McClelland 2025-05-20 11:59:35 -07:00 committed by Daniel DeGrasse
parent c7e1f0b3da
commit d2fdf52d43
3 changed files with 37 additions and 25 deletions

View File

@ -14,27 +14,6 @@
LOG_MODULE_REGISTER(BMM350, CONFIG_SENSOR_LOG_LEVEL);
static inline int bmm350_bus_check(const struct device *dev)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->check(&cfg->bus);
}
static inline int bmm350_reg_read(const struct device *dev, uint8_t start, uint8_t *buf, int size)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->read(&cfg->bus, start, buf, size);
}
int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->write(&cfg->bus, reg, val);
}
static int8_t bmm350_read_otp_word(const struct device *dev, uint8_t addr, uint16_t *lsb_msb)
{
int8_t ret = 0;

View File

@ -495,5 +495,27 @@ int bmm350_trigger_mode_init(const struct device *dev);
int bmm350_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
sensor_trigger_handler_t handler);
int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val);
/* inline helper functions */
static inline int bmm350_bus_check(const struct device *dev)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->check(&cfg->bus);
}
static inline int bmm350_reg_read(const struct device *dev, uint8_t start, uint8_t *buf, int size)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->read(&cfg->bus, start, buf, size);
}
static inline int bmm350_reg_write(const struct device *dev, uint8_t reg, uint8_t val)
{
const struct bmm350_config *cfg = dev->config;
return cfg->bus_io->write(&cfg->bus, reg, val);
}
#endif /* __SENSOR_BMM350_H__ */

View File

@ -15,14 +15,25 @@
LOG_MODULE_DECLARE(BMM350, CONFIG_SENSOR_LOG_LEVEL);
static void bmm350_handle_interrupts(const void *arg)
static int bmm350_handle_interrupts(const void *arg)
{
const struct device *dev = (const struct device *)arg;
struct bmm350_data *data = dev->data;
uint8_t intr_status;
int ret;
/* Read interrupt status to clear interrupt */
ret = bmm350_reg_read(dev, BMM350_REG_INT_STATUS, &intr_status, sizeof(intr_status));
if (ret < 0) {
LOG_ERR("%s: failed to read interrupt status", dev->name);
return ret;
}
if (data->drdy_handler) {
data->drdy_handler(dev, data->drdy_trigger);
}
return 0;
}
#ifdef CONFIG_BMM350_TRIGGER_OWN_THREAD
@ -38,7 +49,7 @@ static void bmm350_thread_main(void *arg1, void *unused1, void *unused2)
while (1) {
k_sem_take(&data->sem, K_FOREVER);
bmm350_handle_interrupts(dev);
(void)bmm350_handle_interrupts(dev);
}
}
#endif
@ -48,7 +59,7 @@ static void bmm350_work_handler(struct k_work *work)
{
struct bmm350_data *data = CONTAINER_OF(work, struct bmm350_data, work);
bmm350_handle_interrupts(data->dev);
(void)bmm350_handle_interrupts(data->dev);
}
#endif