nrf_serial.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /**
  2. * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #ifndef NRF_SERIAL_H__
  41. #define NRF_SERIAL_H__
  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif
  45. #include <stdint.h>
  46. #include <stdbool.h>
  47. #include "nrf_drv_uart.h"
  48. #include "nrf_queue.h"
  49. #include "nrf_mtx.h"
  50. #include "app_timer.h"
  51. /**@file
  52. *
  53. * @defgroup nrf_serial Serial port abstraction layer
  54. * @{
  55. * @ingroup app_common
  56. *
  57. * @brief Serial module interface.
  58. * @details This module is more sophisticated than @ref nrf_drv_uart. It internally uses
  59. * mutex, queues, and app_timer. You can configure it to work in three different modes
  60. * (polling, interrupt, DMA). API can be configured to work in synchronous mode. Both read and write
  61. * methods have a timeout parameter. Asynchronous mode is available by passing 0 as the
  62. * timeout parameter.
  63. * @warning Do not use synchronous API (timeout_ms parameter > 0) in IRQ
  64. * context. It may lead to a deadlock because the timeout interrupt cannot
  65. * preempt the current IRQ context.
  66. */
  67. typedef struct nrf_serial_s nrf_serial_t;
  68. /**
  69. * @brief Serial port mode.
  70. * */
  71. typedef enum {
  72. NRF_SERIAL_MODE_POLLING, /**< Polling mode.*/
  73. NRF_SERIAL_MODE_IRQ, /**< Interrupt mode.*/
  74. NRF_SERIAL_MODE_DMA, /**< DMA mode.*/
  75. } nrf_serial_mode_t;
  76. /**
  77. * @brief Creates an instance of @ref nrf_drv_uart_config_t.
  78. *
  79. * @param _name Instance name.
  80. * @param _rx_pin RX pin number.
  81. * @param _tx_pin TX pin number.
  82. * @param _rts_pin RTS pin number.
  83. * @param _cts_pin CTS pin number.
  84. * @param _flow_control Flow control enable/disable (@ref nrf_uart_hwfc_t).
  85. * @param _parity Parity enable/disable (@ref nrf_uart_parity_t).
  86. * @param _baud_rate Baud rate (@ref nrf_uart_baudrate_t).
  87. * @param _irq_prio Interrupt priority.
  88. *
  89. * */
  90. #define NRF_SERIAL_DRV_UART_CONFIG_DEF(_name, \
  91. _rx_pin, \
  92. _tx_pin, \
  93. _rts_pin, \
  94. _cts_pin, \
  95. _flow_control, \
  96. _parity, \
  97. _baud_rate, \
  98. _irq_prio) \
  99. static const nrf_drv_uart_config_t _name = { \
  100. .pselrxd = _rx_pin, \
  101. .pseltxd = _tx_pin, \
  102. .pselrts = _rts_pin, \
  103. .pselcts = _cts_pin, \
  104. .hwfc = _flow_control, \
  105. .parity = _parity, \
  106. .baudrate = _baud_rate, \
  107. .interrupt_priority = _irq_prio, \
  108. }
  109. /**
  110. * @brief Serial port RX and TX queues.
  111. *
  112. * @note Use the @ref NRF_SERIAL_QUEUES_DEF macro to create an instance of this
  113. * structure.
  114. * */
  115. typedef struct {
  116. nrf_queue_t const * p_rxq; //!< Receive queue handle.
  117. nrf_queue_t const * p_txq; //!< Transmit queue handle.
  118. } nrf_serial_queues_t;
  119. /**
  120. * @brief Creates an instance of serial port queues.
  121. *
  122. * @param _name Instance name.
  123. * @param _tx_size TX queue size.
  124. * @param _rx_size RX queue size.
  125. * */
  126. #define NRF_SERIAL_QUEUES_DEF(_name, _tx_size, _rx_size) \
  127. NRF_QUEUE_DEF(uint8_t, _name##_rxq, _rx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
  128. NRF_QUEUE_DEF(uint8_t, _name##_txq, _tx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
  129. static const nrf_serial_queues_t _name = { \
  130. .p_rxq = &_name##_rxq, \
  131. .p_txq = &_name##_txq, \
  132. }
  133. /**
  134. * @brief Serial buffers. Data slices used by @ref nrf_drv_uart_tx and
  135. * @ref nrf_drv_uart_rx.
  136. *
  137. * @note Use the @ref NRF_SERIAL_BUFFERS_DEF macro to create an instance of this
  138. * structure.
  139. * */
  140. typedef struct {
  141. void * p_txb; //!< TX buffer.
  142. void * p_rxb; //!< RX buffer.
  143. uint8_t tx_size; //!< TX buffer size.
  144. uint8_t rx_size; //!< RX buffer size.
  145. } nrf_serial_buffers_t;
  146. /**
  147. * @brief Creates an instance of serial port buffers.
  148. *
  149. * @param _name Instance name.
  150. * @param _tx_size TX buffer size.
  151. * @param _rx_size RX buffer size.
  152. * */
  153. #define NRF_SERIAL_BUFFERS_DEF(_name, _tx_size, _rx_size) \
  154. STATIC_ASSERT((_tx_size) <= UINT8_MAX); \
  155. STATIC_ASSERT((_rx_size) <= UINT8_MAX); \
  156. static uint8_t _name##_txb[_tx_size]; \
  157. static uint8_t _name##_rxb[_rx_size]; \
  158. static const nrf_serial_buffers_t _name = { \
  159. .p_txb = _name##_txb, \
  160. .p_rxb = _name##_rxb, \
  161. .tx_size = sizeof(_name##_txb), \
  162. .rx_size = sizeof(_name##_rxb), \
  163. }
  164. /**
  165. * @brief Events generated by this module.
  166. * */
  167. typedef enum {
  168. NRF_SERIAL_EVENT_TX_DONE, //!< Chunk of data has been sent.
  169. NRF_SERIAL_EVENT_RX_DATA, //!< New chunk of data has been received.
  170. NRF_SERIAL_EVENT_DRV_ERR, //!< Internal driver error.
  171. NRF_SERIAL_EVENT_FIFO_ERR, //!< RX FIFO overrun.
  172. } nrf_serial_event_t;
  173. /**
  174. * @brief Event handler type.
  175. * */
  176. typedef void (*nrf_serial_evt_handler_t)(struct nrf_serial_s const * p_serial,
  177. nrf_serial_event_t event);
  178. /**
  179. * @brief Sleep handler type.
  180. * */
  181. typedef void (*nrf_serial_sleep_handler_t)(void);
  182. /**
  183. * @brief Configuration of UART serial interface.
  184. *
  185. * @note Use the @ref NRF_SERIAL_CONFIG_DEF macro to create an instance of this
  186. * structure.
  187. *
  188. */
  189. typedef struct {
  190. nrf_serial_mode_t mode; //!< Serial port mode.
  191. nrf_serial_queues_t const * p_queues; //!< Serial port queues.
  192. nrf_serial_buffers_t const * p_buffers; //!< DMA buffers.
  193. nrf_serial_evt_handler_t ev_handler; //!< Event handler.
  194. nrf_serial_sleep_handler_t sleep_handler; //!< Sleep mode handler.
  195. } nrf_serial_config_t;
  196. /**
  197. * @brief Creates an instance of serial port configuration.
  198. *
  199. * @param _name Instance name.
  200. * @param _mode Serial port mode.
  201. * @param _queues Serial port queues. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
  202. * @param _buffers Serial port buffers. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
  203. * @param _ev_handler Serial port event handler. NULL can be passed in any mode.
  204. * @param _sleep Serial port sleep handler. NULL can be passed in any mode.
  205. * */
  206. #define NRF_SERIAL_CONFIG_DEF(_name, _mode, _queues, _buffers, _ev_handler, _sleep) \
  207. static const nrf_serial_config_t _name = { \
  208. .mode = _mode, \
  209. .p_queues = _queues, \
  210. .p_buffers = _buffers, \
  211. .ev_handler = _ev_handler, \
  212. .sleep_handler = _sleep, \
  213. }
  214. #define NRF_SERIAL_RX_ENABLED_FLAG (1u << 0) //!< Receiver enable flag.
  215. #define NRF_SERIAL_TX_ENABLED_FLAG (1u << 1) //!< Transmitter enable flag.
  216. /**
  217. * @brief Serial port context. Contains all data structures that need
  218. * to be stored in RAM memory.
  219. * */
  220. typedef struct {
  221. nrf_serial_config_t const * p_config; //!< Serial port configuration.
  222. nrf_mtx_t write_lock; //!< Write operation lock.
  223. nrf_mtx_t read_lock; //!< Read operation lock.
  224. uint8_t flags; //!< Transmitter/receiver enable flags.
  225. } nrf_serial_ctx_t;
  226. /**
  227. * @brief Serial port instance declaration.
  228. *
  229. * @note Use @ref NRF_SERIAL_UART_DEF macro to create an instance of this
  230. * structure.
  231. * */
  232. struct nrf_serial_s {
  233. nrf_drv_uart_t instance; //!< Driver instance.
  234. nrf_serial_ctx_t * p_ctx; //!< Driver context.
  235. app_timer_id_t const * p_tx_timer; //!< TX timeout timer.
  236. app_timer_id_t const * p_rx_timer; //!< RX timeout timer.
  237. };
  238. /**
  239. * @brief Creates an instance of a serial port.
  240. *
  241. * @param _name Instance name.
  242. * @param _instance_number Driver instance number (@ref NRF_DRV_UART_INSTANCE).
  243. * */
  244. #define NRF_SERIAL_UART_DEF(_name, _instance_number) \
  245. APP_TIMER_DEF(_name##_rx_timer); \
  246. APP_TIMER_DEF(_name##_tx_timer); \
  247. static nrf_serial_ctx_t _name##_ctx; \
  248. static const nrf_serial_t _name = { \
  249. .instance = NRF_DRV_UART_INSTANCE(_instance_number), \
  250. .p_ctx = &_name##_ctx, \
  251. .p_tx_timer = &_name##_tx_timer, \
  252. .p_rx_timer = &_name##_rx_timer, \
  253. }
  254. /**
  255. * @brief Maximum value of timeout. API might be blocked indefinitely if this value is
  256. * not set.*/
  257. #define NRF_SERIAL_MAX_TIMEOUT UINT32_MAX
  258. /**
  259. * @brief Function for initializing a serial port. Serial port can be initialized
  260. * in various modes that are defined by nrf_serial_mode_t.
  261. * - NRF_SERIAL_MODE_POLLING - Simple polling mode. API calls will be
  262. * synchronous. There is no need to define queues or buffers.
  263. * No events will be generated.
  264. * - NRF_SERIAL_MODE_IRQ - Interrupt mode. API can be set to work in synchronous or
  265. * asynchronous mode. Queues and buffers must be passed
  266. * during initialization. Events will be generated if
  267. * a non NULL handler is passed as the ev_handler parameter.
  268. * - NRF_SERIAL_MODE_DMA - Similar to @ref NRF_SERIAL_MODE_IRQ. Uses EasyDMA.
  269. *
  270. *
  271. * @param p_serial Serial port instance.
  272. * @param p_drv_uart_config UART driver configuration. Cannot be NULL.
  273. * @param p_config Serial port configuration. Cannot be NULL. This object must be created
  274. * using the @ref NRF_SERIAL_CONFIG_DEF macro.
  275. *
  276. * @return Standard error code.
  277. * */
  278. ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
  279. nrf_drv_uart_config_t const * p_drv_uart_config,
  280. nrf_serial_config_t const * p_config);
  281. /**
  282. * @brief Function for uninitializing a serial port.
  283. *
  284. * @param p_serial Serial port instance.
  285. *
  286. * @return Standard error code.
  287. * */
  288. ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial);
  289. /**
  290. * @brief Function for writing to a serial port.
  291. *
  292. * @param p_serial Serial port instance.
  293. * @param p_data Transmit buffer pointer.
  294. * @param size Transmit buffer size.
  295. * @param p_written Amount of data actually written to the serial port.
  296. * NULL pointer can be passed.
  297. * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
  298. * non blocking mode.
  299. *
  300. * @return Standard error code.
  301. * */
  302. ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
  303. void const * p_data,
  304. size_t size,
  305. size_t * p_written,
  306. uint32_t timeout_ms);
  307. /**
  308. * @brief Function for reading from a serial port.
  309. *
  310. * @param p_serial Serial port instance.
  311. * @param p_data Receive buffer pointer.
  312. * @param size Receive buffer size.
  313. * @param p_read Amount of data actually read from the serial port.
  314. * NULL pointer can be passed.
  315. * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
  316. * non blocking mode.
  317. *
  318. * @return Standard error code.
  319. * */
  320. ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
  321. void * p_data,
  322. size_t size,
  323. size_t * p_read,
  324. uint32_t timeout_ms);
  325. /**
  326. * @brief Function for flushing a serial port TX queue.
  327. *
  328. * @param p_serial Serial port instance.
  329. * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
  330. * non blocking mode.
  331. * @return Standard error code.
  332. * */
  333. ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms);
  334. /**
  335. * @brief Function for aborting a serial port transmission.
  336. * Aborts the current ongoing transmission and resets TX FIFO.
  337. *
  338. * @param p_serial Serial port instance.
  339. *
  340. * @return Standard error code.
  341. * */
  342. ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial);
  343. /**
  344. * @brief Function for draining the serial port receive RX FIFO.
  345. * Drains HW FIFO and resets RX FIFO.
  346. *
  347. * @param p_serial Serial port instance.
  348. *
  349. * @return Standard error code.
  350. * */
  351. ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial);
  352. /** @} */
  353. #ifdef __cplusplus
  354. }
  355. #endif
  356. #endif /* NRF_SERIAL_H__ */