drivers: lora: Add user_data to lora_recv_async

The LoRa driver does not allow to pass void* user_data to callback in
lora_recv_async function. This leads to complex way of using the API. This
commit fixes the issue and adds the field to the function and to the
callback.

Signed-off-by: Aleksander Dejewski <aleksander.dejewski@gmail.com>
This commit is contained in:
Aleksander Dejewski 2024-12-18 16:40:38 +01:00 committed by Benjamin Cabé
parent d739c20eb3
commit a4e31487d5
6 changed files with 29 additions and 12 deletions

View file

@ -369,6 +369,13 @@ MCUmgr
Modem
=====
LoRa
====
* The function :c:func:`lora_recv_async` and callback ``lora_recv_cb`` now include an
additional ``user_data`` parameter, which is a void pointer. This parameter can be used to reference
any user-defined data structure. To maintain the current behavior, set this parameter to ``NULL``.
Architectures
*************

View file

@ -102,6 +102,7 @@ struct rylr_data {
uint8_t pending_async_flags;
struct k_poll_signal *async_tx_signal;
lora_recv_cb async_rx_cb;
void *async_user_data;
const struct device *dev;
uint8_t msgq_buffer[CONFIG_RYLRXXX_UNSOLICITED_RX_MSGQ_SIZE];
struct modem_pipe *modem_pipe;
@ -170,7 +171,8 @@ static void on_rx(struct modem_chat *chat, char **argv, uint16_t argc, void *use
msg.snr = atoi(argv[5]);
if (RYLR_IS_RX_PENDING(driver_data->pending_async_flags)) {
driver_data->async_rx_cb(driver_data->dev, msg.data, msg.length, msg.rssi, msg.snr);
driver_data->async_rx_cb(driver_data->dev, msg.data, msg.length, msg.rssi, msg.snr,
driver_data->async_user_data);
} else {
err = k_msgq_put(&driver_data->rx_msgq, &msg, K_NO_WAIT);
if (err != 0) {
@ -515,7 +517,7 @@ exit:
return ret;
}
int rylr_recv_async(const struct device *dev, lora_recv_cb cb)
int rylr_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data)
{
int err = 0;
struct rylr_data *data = dev->data;
@ -538,6 +540,7 @@ int rylr_recv_async(const struct device *dev, lora_recv_cb cb)
}
data->async_rx_cb = cb;
data->async_user_data = user_data;
if (RYLR_IS_ASYNC_OP_PENDING(data->pending_async_flags)) {
LOG_ERR("pending async opperation");
err = -EBUSY;

View file

@ -33,6 +33,7 @@ static struct sx12xx_data {
const struct device *dev;
struct k_poll_signal *operation_done;
lora_recv_cb async_rx_cb;
void *async_user_data;
RadioEvents_t events;
struct lora_modem_config tx_cfg;
atomic_t modem_usage;
@ -106,7 +107,8 @@ static void sx12xx_ev_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
/* Start receiving again */
Radio.Rx(0);
/* Run the callback */
dev_data.async_rx_cb(dev_data.dev, payload, size, rssi, snr);
dev_data.async_rx_cb(dev_data.dev, payload, size, rssi, snr,
dev_data.async_user_data);
/* Don't run the synchronous code */
return;
}
@ -305,7 +307,7 @@ int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size,
return size;
}
int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb)
int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data)
{
/* Cancel ongoing reception */
if (cb == NULL) {
@ -323,6 +325,7 @@ int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb)
/* Store parameters */
dev_data.async_rx_cb = cb;
dev_data.async_user_data = user_data;
/* Start reception */
Radio.SetMaxPayloadLength(MODEM_LORA, 255);

View file

@ -29,7 +29,7 @@ int sx12xx_lora_send_async(const struct device *dev, uint8_t *data,
int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size,
k_timeout_t timeout, int16_t *rssi, int8_t *snr);
int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb);
int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data);
int sx12xx_lora_config(const struct device *dev,
struct lora_modem_config *config);

View file

@ -121,7 +121,7 @@ struct lora_modem_config {
* @see lora_recv() for argument descriptions.
*/
typedef void (*lora_recv_cb)(const struct device *dev, uint8_t *data, uint16_t size,
int16_t rssi, int8_t snr);
int16_t rssi, int8_t snr, void *user_data);
/**
* @typedef lora_api_config()
@ -168,7 +168,8 @@ typedef int (*lora_api_recv)(const struct device *dev, uint8_t *data,
* @param dev Modem to receive data on.
* @param cb Callback to run on receiving data.
*/
typedef int (*lora_api_recv_async)(const struct device *dev, lora_recv_cb cb);
typedef int (*lora_api_recv_async)(const struct device *dev, lora_recv_cb cb,
void *user_data);
/**
* @typedef lora_api_test_cw()
@ -286,14 +287,16 @@ static inline int lora_recv(const struct device *dev, uint8_t *data,
* @param dev Modem to receive data on.
* @param cb Callback to run on receiving data. If NULL, any pending
* asynchronous receptions will be cancelled.
* @param user_data User data passed to callback
* @return 0 when reception successfully setup, negative on error
*/
static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb)
static inline int lora_recv_async(const struct device *dev, lora_recv_cb cb,
void *user_data)
{
const struct lora_driver_api *api =
(const struct lora_driver_api *)dev->api;
return api->recv_async(dev, cb);
return api->recv_async(dev, cb, user_data);
}
/**

View file

@ -21,12 +21,13 @@ BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(DEFAULT_RADIO_NODE),
LOG_MODULE_REGISTER(lora_receive);
void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
int16_t rssi, int8_t snr)
int16_t rssi, int8_t snr, void *user_data)
{
static int cnt;
ARG_UNUSED(dev);
ARG_UNUSED(size);
ARG_UNUSED(user_data);
LOG_INF("LoRa RX RSSI: %d dBm, SNR: %d dB", rssi, snr);
LOG_HEXDUMP_INF(data, size, "LoRa RX payload");
@ -34,7 +35,7 @@ void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
/* Stop receiving after 10 packets */
if (++cnt == 10) {
LOG_INF("Stopping packet receptions");
lora_recv_async(dev, NULL);
lora_recv_async(dev, NULL, NULL);
}
}
@ -85,7 +86,7 @@ int main(void)
/* Enable asynchronous reception */
LOG_INF("Asynchronous reception");
lora_recv_async(lora_dev, lora_receive_cb);
lora_recv_async(lora_dev, lora_receive_cb, NULL);
k_sleep(K_FOREVER);
return 0;
}