LCOV - code coverage report
Current view: top level - zephyr/drivers/serial - uart_async_to_irq.h Hit Total Coverage
Test: new.info Lines: 4 8 50.0 %
Date: 2025-01-09 21:13:38

          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 1.14