LCOV - code coverage report
Current view: top level - zephyr/drivers/serial - uart_async_to_irq.h Coverage Total Hit
Test: new.info Lines: 50.0 % 8 4
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2023 Nordic Semiconductor ASA
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_
       8              : #define ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_
       9              : 
      10              : #include <zephyr/drivers/uart.h>
      11              : #include <zephyr/logging/log.h>
      12              : #include <zephyr/spinlock.h>
      13              : #include <zephyr/sys/util.h>
      14              : #include <zephyr/drivers/serial/uart_async_rx.h>
      15              : 
      16              : /**
      17              :  * @brief UART Asynchronous to Interrupt driven API adaptation layer
      18              :  * @ingroup uart_interface
      19              :  * @{
      20              :  */
      21              : 
      22              : #ifdef __cplusplus
      23              : extern "C" {
      24              : #endif
      25              : 
      26              : /* Forward declarations. */
      27              : 
      28              : /** @brief Data structure used by the adaptation layer.
      29              :  *
      30              :  * Pointer to that data must be the first element of the UART device data structure.
      31              :  */
      32              : struct uart_async_to_irq_data;
      33              : 
      34              : /** @brief Configuration structure used by the adaptation layer.
      35              :  *
      36              :  * Pointer to this data must be the first element of the UART device configuration structure.
      37              :  */
      38              : struct uart_async_to_irq_config;
      39              : 
      40              : /* @brief Function that triggers trampoline to the interrupt context.
      41              :  *
      42              :  * This context is used to call user UART interrupt handler. It is to used to
      43              :  * fulfill the requirement that UART interrupt driven API shall be called from
      44              :  * the UART interrupt. Trampoline context shall have the same priority as UART.
      45              :  *
      46              :  * One option may be to use k_timer configured to expire immediately.
      47              :  */
      48            0 : typedef void (*uart_async_to_irq_trampoline)(const struct device *dev);
      49              : 
      50              : /** @brief Callback to be called from trampoline context.
      51              :  *
      52              :  * @param dev UART device.
      53              :  */
      54            1 : void uart_async_to_irq_trampoline_cb(const struct device *dev);
      55              : 
      56              : /** @brief Interrupt driven API initializer.
      57              :  *
      58              :  * It should be used in the initialization of the UART API structure in the
      59              :  * driver to provide interrupt driven API functions.
      60              :  */
      61            1 : #define UART_ASYNC_TO_IRQ_API_INIT()                            \
      62              :         .fifo_fill        = z_uart_async_to_irq_fifo_fill,      \
      63              :         .fifo_read        = z_uart_async_to_irq_fifo_read,      \
      64              :         .irq_tx_enable    = z_uart_async_to_irq_irq_tx_enable,  \
      65              :         .irq_tx_disable   = z_uart_async_to_irq_irq_tx_disable, \
      66              :         .irq_tx_ready     = z_uart_async_to_irq_irq_tx_ready,   \
      67              :         .irq_rx_enable    = z_uart_async_to_irq_irq_rx_enable,  \
      68              :         .irq_rx_disable   = z_uart_async_to_irq_irq_rx_disable, \
      69              :         .irq_tx_complete  = z_uart_async_to_irq_irq_tx_complete,\
      70              :         .irq_rx_ready     = z_uart_async_to_irq_irq_rx_ready,   \
      71              :         .irq_err_enable   = z_uart_async_to_irq_irq_err_enable, \
      72              :         .irq_err_disable  = z_uart_async_to_irq_irq_err_disable,\
      73              :         .irq_is_pending   = z_uart_async_to_irq_irq_is_pending, \
      74              :         .irq_update       = z_uart_async_to_irq_irq_update,     \
      75              :         .irq_callback_set = z_uart_async_to_irq_irq_callback_set
      76              : 
      77              : /** @brief Configuration structure initializer.
      78              :  *
      79              :  * @param _api Structure with UART asynchronous API.
      80              :  * @param _trampoline Function that trampolines to the interrupt context.
      81              :  * @param _baudrate UART baudrate.
      82              :  * @param _tx_buf TX buffer.
      83              :  * @param _tx_len TX buffer length.
      84              :  * @param _rx_buf RX buffer.
      85              :  * @param _rx_len RX buffer length.
      86              :  * @param _rx_cnt Number of chunks into which RX buffer is divided.
      87              :  * @param _log Logging instance, if not provided (empty) then default is used.
      88              :  */
      89              : #define UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(_api, _trampoline, _baudrate, _tx_buf,         \
      90            1 :                                                  _tx_len, _rx_buf, _rx_len, _rx_cnt, _log)      \
      91              :         {                                                                                       \
      92              :                 .tx_buf = _tx_buf,                                                              \
      93              :                 .tx_len = _tx_len,                                                              \
      94              :                 .async_rx = {                                                                   \
      95              :                         .buffer = _rx_buf,                                                      \
      96              :                         .length = _rx_len,                                                      \
      97              :                         .buf_cnt = _rx_cnt                                                      \
      98              :                 },                                                                              \
      99              :                 .api = _api,                                                                    \
     100              :                 .trampoline = _trampoline,                                                      \
     101              :                 .baudrate = _baudrate,                                                          \
     102              :                 LOG_OBJECT_PTR_INIT(log,                                                        \
     103              :                                 COND_CODE_1(IS_EMPTY(_log),                                     \
     104              :                                             (LOG_OBJECT_PTR(UART_ASYNC_TO_IRQ_LOG_NAME)),       \
     105              :                                             (_log)                                              \
     106              :                                            )                                                    \
     107              :                                    )                                                            \
     108              :         }
     109              : 
     110              : /** @brief Initialize the adaptation layer.
     111              :  *
     112              :  * @param dev UART device. Device must support asynchronous API.
     113              :  *
     114              :  * @retval 0 On successful initialization.
     115              :  */
     116            1 : int uart_async_to_irq_init(const struct device *dev);
     117              : 
     118              : /* @brief Enable RX for interrupt driven API.
     119              :  *
     120              :  * @param dev UART device. Device must support asynchronous API.
     121              :  *
     122              :  * @retval 0 on successful operation.
     123              :  * @retval -EINVAL if adaption layer has wrong configuration.
     124              :  * @retval negative value Error reported by the UART API.
     125              :  */
     126            0 : int uart_async_to_irq_rx_enable(const struct device *dev);
     127              : 
     128              : /* @brief Disable RX for interrupt driven API.
     129              :  *
     130              :  * @param dev UART device. Device must support asynchronous API.
     131              :  *
     132              :  * @retval 0 on successful operation.
     133              :  * @retval -EINVAL if adaption layer has wrong configuration.
     134              :  * @retval negative value Error reported by the UART API.
     135              :  */
     136            0 : int uart_async_to_irq_rx_disable(const struct device *dev);
     137              : 
     138              : /* Starting from here API is internal only. */
     139              : 
     140              : /** @cond INTERNAL_HIDDEN
     141              :  * @brief Structure used by the adaptation layer.
     142              :  */
     143              : struct uart_async_to_irq_config {
     144              :         /** Pointer to the TX buffer. */
     145              :         uint8_t *tx_buf;
     146              : 
     147              :         /** TX buffer length. */
     148              :         size_t tx_len;
     149              : 
     150              :         /** UART Asynchronous RX helper configuration. */
     151              :         struct uart_async_rx_config async_rx;
     152              : 
     153              :         /** Async API used by the a2i layer. */
     154              :         const struct uart_async_to_irq_async_api *api;
     155              : 
     156              :         /** Trampoline callback. */
     157              :         uart_async_to_irq_trampoline trampoline;
     158              : 
     159              :         /** Initial baudrate. */
     160              :         uint32_t baudrate;
     161              : 
     162              :         /** Instance logging handler. */
     163              :         LOG_INSTANCE_PTR_DECLARE(log);
     164              : };
     165              : 
     166              : /** @brief Asynchronous API used by the adaptation layer. */
     167              : struct uart_async_to_irq_async_api {
     168              :         int (*callback_set)(const struct device *dev,
     169              :                             uart_callback_t callback,
     170              :                             void *user_data);
     171              : 
     172              :         int (*tx)(const struct device *dev, const uint8_t *buf, size_t len,
     173              :                   int32_t timeout);
     174              :         int (*tx_abort)(const struct device *dev);
     175              : 
     176              :         int (*rx_enable)(const struct device *dev, uint8_t *buf, size_t len,
     177              :                          int32_t timeout);
     178              :         int (*rx_buf_rsp)(const struct device *dev, uint8_t *buf, size_t len);
     179              :         int (*rx_disable)(const struct device *dev);
     180              : };
     181              : 
     182              : /** @brief Structure holding receiver data. */
     183              : struct uart_async_to_irq_rx_data {
     184              :         /** Asynchronous RX helper data. */
     185              :         struct uart_async_rx async_rx;
     186              : 
     187              :         /** Semaphore for pending on RX disable. */
     188              :         struct k_sem sem;
     189              : 
     190              :         /** Number of pending buffer requests which weren't handled because lack of free buffers. */
     191              :         atomic_t pending_buf_req;
     192              : };
     193              : 
     194              : /** @brief Structure holding transmitter data. */
     195              : struct uart_async_to_irq_tx_data {
     196              :         /** TX buffer. */
     197              :         uint8_t *buf;
     198              : 
     199              :         /** Length of the buffer. */
     200              :         size_t len;
     201              : };
     202              : 
     203              : /** @brief Data associated with the asynchronous to the interrupt driven API adaptation layer. */
     204              : struct uart_async_to_irq_data {
     205              :         /** User callback for interrupt driven API. */
     206              :         uart_irq_callback_user_data_t callback;
     207              : 
     208              :         /** User data. */
     209              :         void *user_data;
     210              : 
     211              :         /** Interrupt request counter. */
     212              :         atomic_t irq_req;
     213              : 
     214              :         /** RX specific data. */
     215              :         struct uart_async_to_irq_rx_data rx;
     216              : 
     217              :         /** TX specific data. */
     218              :         struct uart_async_to_irq_tx_data tx;
     219              : 
     220              :         /** Spinlock. */
     221              :         struct k_spinlock lock;
     222              : 
     223              :         /** Internally used flags for holding the state of the a2i layer. */
     224              :         atomic_t flags;
     225              : };
     226              : 
     227              : /** Interrupt driven FIFO fill function. */
     228              : int z_uart_async_to_irq_fifo_fill(const struct device *dev,
     229              :                                   const uint8_t *buf,
     230              :                                   int len);
     231              : 
     232              : /** Interrupt driven FIFO read function. */
     233              : int z_uart_async_to_irq_fifo_read(const struct device *dev,
     234              :                                   uint8_t *buf,
     235              :                                   const int len);
     236              : 
     237              : /** Interrupt driven transfer enabling function. */
     238              : void z_uart_async_to_irq_irq_tx_enable(const struct device *dev);
     239              : 
     240              : /** Interrupt driven transfer disabling function */
     241              : void z_uart_async_to_irq_irq_tx_disable(const struct device *dev);
     242              : 
     243              : /** Interrupt driven transfer ready function */
     244              : int z_uart_async_to_irq_irq_tx_ready(const struct device *dev);
     245              : 
     246              : /** Interrupt driven receiver enabling function */
     247              : void z_uart_async_to_irq_irq_rx_enable(const struct device *dev);
     248              : 
     249              : /** Interrupt driven receiver disabling function */
     250              : void z_uart_async_to_irq_irq_rx_disable(const struct device *dev);
     251              : 
     252              : /** Interrupt driven transfer complete function */
     253              : int z_uart_async_to_irq_irq_tx_complete(const struct device *dev);
     254              : 
     255              : /** Interrupt driven receiver ready function */
     256              : int z_uart_async_to_irq_irq_rx_ready(const struct device *dev);
     257              : 
     258              : /** Interrupt driven error enabling function */
     259              : void z_uart_async_to_irq_irq_err_enable(const struct device *dev);
     260              : 
     261              : /** Interrupt driven error disabling function */
     262              : void z_uart_async_to_irq_irq_err_disable(const struct device *dev);
     263              : 
     264              : /** Interrupt driven pending status function */
     265              : int z_uart_async_to_irq_irq_is_pending(const struct device *dev);
     266              : 
     267              : /** Interrupt driven interrupt update function */
     268              : int z_uart_async_to_irq_irq_update(const struct device *dev);
     269              : 
     270              : /** Set the irq callback function */
     271              : void z_uart_async_to_irq_irq_callback_set(const struct device *dev,
     272              :                          uart_irq_callback_user_data_t cb,
     273              :                          void *user_data);
     274              : 
     275              : /** @endcond */
     276              : 
     277              : #ifdef __cplusplus
     278              : }
     279              : #endif
     280              : 
     281              : /** @} */
     282              : 
     283              : #endif /* ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ */
        

Generated by: LCOV version 2.0-1