nrf_libuarte_drv.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. /**
  2. * Copyright (c) 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. #include "sdk_config.h"
  41. #include "nrf_libuarte_drv.h"
  42. #include "nrf_uarte.h"
  43. #include "nrf_gpio.h"
  44. #include <nrfx_gpiote.h>
  45. #include <../src/prs/nrfx_prs.h>
  46. #define NRF_LOG_MODULE_NAME libUARTE
  47. #if NRF_LIBUARTE_CONFIG_LOG_ENABLED
  48. #define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
  49. #define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
  50. #define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
  51. #else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
  52. #define NRF_LOG_LEVEL 0
  53. #endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
  54. #include "nrf_log.h"
  55. NRF_LOG_MODULE_REGISTER();
  56. #define MAX_DMA_XFER_LEN ((1UL << UARTE0_EASYDMA_MAXCNT_SIZE) - 1)
  57. #define INTERRUPTS_MASK \
  58. (NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_RXSTARTED_MASK | NRF_UARTE_INT_ERROR_MASK | \
  59. NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_TXSTOPPED_MASK)
  60. static const nrf_libuarte_drv_t * m_libuarte_instance[2];
  61. /* if it is defined it means that PRS for uart is not used. */
  62. #ifdef nrfx_uarte_0_irq_handler
  63. #define libuarte_0_irq_handler UARTE0_UART0_IRQHandler
  64. #endif
  65. #if NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE0)
  66. void libuarte_0_irq_handler(void);
  67. #endif
  68. #if NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE1)
  69. void libuarte_1_irq_handler(void);
  70. #endif
  71. #if defined(NRF_LIBUARTE_DRV_HWFC_ENABLED)
  72. #define LIBUARTE_DRV_WITH_HWFC NRF_LIBUARTE_DRV_HWFC_ENABLED
  73. #else
  74. #define LIBUARTE_DRV_WITH_HWFC 1
  75. #endif
  76. #define RTS_PIN_DISABLED 0xff
  77. /** @brief Macro executes given function on every allocated channel in the list between provided
  78. * indexes.
  79. */
  80. #define PPI_CHANNEL_FOR_M_N(p_libuarte, m, n, func) \
  81. for (int i = m; i < n; i++) \
  82. { \
  83. if (p_libuarte->ctrl_blk->ppi_channels[i] < PPI_CH_NUM) \
  84. { func(&p_libuarte->ctrl_blk->ppi_channels[i]); } \
  85. }
  86. /** @brief Macro executes provided function on every allocated PPI channel. */
  87. #define PPI_CHANNEL_FOR_ALL(p_libuarte, func) \
  88. PPI_CHANNEL_FOR_M_N(p_libuarte, 0, NRF_LIBUARTE_DRV_PPI_CH_MAX, func)
  89. /** @brief Macro executes provided function on every allocated group in the list. */
  90. #define PPI_GROUP_FOR_ALL(p_libuarte, func) \
  91. for (int i = 0; i < NRF_LIBUARTE_DRV_PPI_GROUP_MAX; i++) \
  92. { \
  93. if (p_libuarte->ctrl_blk->ppi_groups[i] < PPI_GROUP_NUM) \
  94. { func(&p_libuarte->ctrl_blk->ppi_groups[i]); } \
  95. }
  96. /** @brief Allocate and configure PPI channel. Fork is optional and it's not set if NULL.
  97. * Channel parameter is field by the function.
  98. */
  99. static ret_code_t ppi_channel_configure(nrf_ppi_channel_t * p_ch, uint32_t evt,
  100. uint32_t task, uint32_t fork)
  101. {
  102. nrfx_err_t err;
  103. err = nrfx_ppi_channel_alloc(p_ch);
  104. if (err != NRFX_SUCCESS)
  105. {
  106. return NRF_ERROR_NO_MEM;
  107. }
  108. err = nrfx_ppi_channel_assign(*p_ch, evt, task);
  109. if (err != NRFX_SUCCESS)
  110. {
  111. return NRF_ERROR_INTERNAL;
  112. }
  113. if (fork)
  114. {
  115. err = nrfx_ppi_channel_fork_assign(*p_ch, fork);
  116. if (err != NRFX_SUCCESS)
  117. {
  118. return NRF_ERROR_INTERNAL;
  119. }
  120. }
  121. return NRF_SUCCESS;
  122. }
  123. /** @brief Allocate and configure group with one channel. Fetch addresses of enable/disable tasks.*/
  124. static ret_code_t ppi_group_configure(nrf_ppi_channel_group_t * p_ppi_group, nrf_ppi_channel_t ch,
  125. uint32_t * p_en_task, uint32_t * p_dis_task, bool en)
  126. {
  127. nrfx_err_t err;
  128. err = nrfx_ppi_group_alloc(p_ppi_group);
  129. if (err != NRFX_SUCCESS)
  130. {
  131. return NRF_ERROR_NO_MEM;
  132. }
  133. err = nrfx_ppi_channel_include_in_group(ch, *p_ppi_group);
  134. if (err != NRFX_SUCCESS)
  135. {
  136. return NRF_ERROR_INTERNAL;
  137. }
  138. if (en)
  139. {
  140. err = nrfx_ppi_group_enable(*p_ppi_group);
  141. if (err != NRFX_SUCCESS)
  142. {
  143. return NRF_ERROR_INTERNAL;
  144. }
  145. }
  146. *p_en_task = nrfx_ppi_task_addr_group_enable_get(*p_ppi_group);
  147. *p_dis_task = nrfx_ppi_task_addr_group_disable_get(*p_ppi_group);
  148. return NRF_SUCCESS;
  149. }
  150. /** @brief Disable and free PPI channel. */
  151. static void ppi_ch_free(nrf_ppi_channel_t * p_ch)
  152. {
  153. nrfx_err_t err;
  154. err = nrfx_ppi_channel_disable(*p_ch);
  155. ASSERT(err == NRFX_SUCCESS);
  156. err = nrfx_ppi_channel_free(*p_ch);
  157. ASSERT(err == NRFX_SUCCESS);
  158. *p_ch = (nrf_ppi_channel_t)PPI_CH_NUM;
  159. }
  160. /** @brief Disable and free PPI group. */
  161. static void ppi_group_free(nrf_ppi_channel_group_t * p_group)
  162. {
  163. nrfx_err_t err;
  164. err = nrfx_ppi_group_free(*p_group);
  165. ASSERT(err == NRFX_SUCCESS);
  166. *p_group = (nrf_ppi_channel_group_t)PPI_GROUP_NUM;
  167. }
  168. /** @brief Free all channels. */
  169. static void ppi_free(const nrf_libuarte_drv_t * const p_libuarte)
  170. {
  171. PPI_CHANNEL_FOR_ALL(p_libuarte, ppi_ch_free);
  172. PPI_GROUP_FOR_ALL(p_libuarte, ppi_group_free);
  173. }
  174. /** @brief Enable PPI channel. */
  175. static void ppi_ch_enable(nrf_ppi_channel_t * p_ch)
  176. {
  177. nrfx_err_t err;
  178. err = nrfx_ppi_channel_enable(*p_ch);
  179. ASSERT(err == NRFX_SUCCESS);
  180. }
  181. /** @brief Disable PPI channel. */
  182. static void ppi_ch_disable(nrf_ppi_channel_t * p_ch)
  183. {
  184. nrfx_err_t err;
  185. err = nrfx_ppi_channel_disable(*p_ch);
  186. ASSERT(err == NRFX_SUCCESS);
  187. }
  188. /** @brief Enable PPI channels for RX. */
  189. static void rx_ppi_enable(const nrf_libuarte_drv_t * const p_libuarte)
  190. {
  191. PPI_CHANNEL_FOR_M_N(p_libuarte, 0, NRF_LIBUARTE_DRV_PPI_CH_RX_GROUP_MAX, ppi_ch_enable);
  192. }
  193. /** @brief Disable PPI channels for RX. */
  194. static void rx_ppi_disable(const nrf_libuarte_drv_t * const p_libuarte)
  195. {
  196. PPI_CHANNEL_FOR_M_N(p_libuarte, 0, NRF_LIBUARTE_DRV_PPI_CH_RX_GROUP_MAX, ppi_ch_disable);
  197. }
  198. /** @brief Enable PPI channels for TX. */
  199. static void tx_ppi_enable(const nrf_libuarte_drv_t * const p_libuarte)
  200. {
  201. PPI_CHANNEL_FOR_M_N(p_libuarte, NRF_LIBUARTE_DRV_PPI_CH_RX_GROUP_MAX,
  202. NRF_LIBUARTE_DRV_PPI_CH_MAX, ppi_ch_enable);
  203. }
  204. /** @brief Disable PPI channels for TX. */
  205. static void tx_ppi_disable(const nrf_libuarte_drv_t * const p_libuarte)
  206. {
  207. PPI_CHANNEL_FOR_M_N(p_libuarte, NRF_LIBUARTE_DRV_PPI_CH_RX_GROUP_MAX,
  208. NRF_LIBUARTE_DRV_PPI_CH_MAX, ppi_ch_disable);
  209. }
  210. static ret_code_t ppi_configure(const nrf_libuarte_drv_t * const p_libuarte,
  211. nrf_libuarte_drv_config_t * p_config)
  212. {
  213. ret_code_t ret;
  214. uint32_t gr0_en_task = 0;
  215. uint32_t gr0_dis_task = 0;
  216. uint32_t gr1_en_task = 0;
  217. uint32_t gr1_dis_task = 0;
  218. for (int i = 0; i < NRF_LIBUARTE_DRV_PPI_CH_MAX; i++)
  219. {
  220. /* set to invalid value */
  221. p_libuarte->ctrl_blk->ppi_channels[i] = (nrf_ppi_channel_t)PPI_CH_NUM;
  222. }
  223. for (int i = 0; i < NRF_LIBUARTE_DRV_PPI_GROUP_MAX; i++)
  224. {
  225. /* set to invalid value */
  226. p_libuarte->ctrl_blk->ppi_groups[i] = (nrf_ppi_channel_group_t)PPI_GROUP_NUM;
  227. }
  228. if (MAX_DMA_XFER_LEN < UINT16_MAX)
  229. {
  230. ret = ppi_channel_configure(
  231. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_ENDTX_STARTTX],
  232. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX),
  233. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTTX),
  234. 0);
  235. if (ret != NRF_SUCCESS)
  236. {
  237. goto complete_config;
  238. }
  239. }
  240. ret = ppi_channel_configure(
  241. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_RXRDY_TIMER_COUNT],
  242. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_RXDRDY),
  243. nrfx_timer_task_address_get(&p_libuarte->timer, NRF_TIMER_TASK_COUNT),
  244. 0);
  245. if (ret != NRF_SUCCESS)
  246. {
  247. goto complete_config;
  248. }
  249. ret = ppi_channel_configure(
  250. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_ENDRX_STARTRX],
  251. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX),
  252. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX),
  253. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 0));
  254. if (ret != NRF_SUCCESS)
  255. {
  256. goto complete_config;
  257. }
  258. if (p_config->endrx_evt && p_config->rxdone_tsk)
  259. {
  260. ret = ppi_channel_configure(
  261. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_ENDRX_EXT_TSK],
  262. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX),
  263. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 0),
  264. p_config->rxdone_tsk);
  265. if (ret != NRF_SUCCESS)
  266. {
  267. goto complete_config;
  268. }
  269. ret = ppi_group_configure(&p_libuarte->ctrl_blk->ppi_groups[NRF_LIBUARTE_DRV_PPI_GROUP_ENDRX_STARTRX],
  270. p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_ENDRX_STARTRX],
  271. &gr0_en_task, &gr0_dis_task, true);
  272. if (ret != NRF_SUCCESS)
  273. {
  274. goto complete_config;
  275. }
  276. ret = ppi_group_configure(&p_libuarte->ctrl_blk->ppi_groups[NRF_LIBUARTE_DRV_PPI_GROUP_ENDRX_EXT_RXDONE_TSK],
  277. p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_ENDRX_EXT_TSK],
  278. &gr1_en_task, &gr1_dis_task, false);
  279. if (ret != NRF_SUCCESS)
  280. {
  281. goto complete_config;
  282. }
  283. ret = ppi_channel_configure(
  284. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_EXT_STOP_STOPRX],
  285. p_config->endrx_evt,
  286. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STOPRX),
  287. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 1));
  288. if (ret != NRF_SUCCESS)
  289. {
  290. goto complete_config;
  291. }
  292. ret = ppi_channel_configure(
  293. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_EXT_STOP_GROUPS_EN],
  294. p_config->endrx_evt,
  295. gr0_dis_task,
  296. gr1_en_task);
  297. if (ret != NRF_SUCCESS)
  298. {
  299. goto complete_config;
  300. }
  301. }
  302. if (p_config->rxstarted_tsk || gr1_dis_task)
  303. {
  304. ret = ppi_channel_configure(
  305. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_RXSTARTED_EXT_TSK],
  306. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED),
  307. gr1_dis_task ? gr1_dis_task : p_config->rxstarted_tsk,
  308. gr1_dis_task ? p_config->rxstarted_tsk : 0);
  309. if (ret != NRF_SUCCESS)
  310. {
  311. goto complete_config;
  312. }
  313. }
  314. if (p_config->startrx_evt)
  315. {
  316. ret = ppi_channel_configure(
  317. &p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX],
  318. p_config->startrx_evt,
  319. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX),
  320. gr0_en_task);
  321. if (ret != NRF_SUCCESS)
  322. {
  323. goto complete_config;
  324. }
  325. }
  326. if (p_config->endrx_evt)
  327. {
  328. }
  329. if (LIBUARTE_DRV_WITH_HWFC && (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED))
  330. {
  331. ret = ppi_channel_configure(&p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_DRV_PPI_CH_RTS_PIN],
  332. nrfx_timer_compare_event_address_get(&p_libuarte->timer, 2),
  333. nrfx_gpiote_set_task_addr_get(p_config->rts_pin),
  334. 0);
  335. if (ret != NRF_SUCCESS)
  336. {
  337. goto complete_config;
  338. }
  339. }
  340. complete_config:
  341. if (ret == NRF_SUCCESS)
  342. {
  343. return ret;
  344. }
  345. ppi_free(p_libuarte);
  346. return ret;
  347. }
  348. void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
  349. {
  350. UNUSED_PARAMETER(event_type);
  351. UNUSED_PARAMETER(p_context);
  352. }
  353. ret_code_t nrf_libuarte_drv_init(const nrf_libuarte_drv_t * const p_libuarte,
  354. nrf_libuarte_drv_config_t * p_config,
  355. nrf_libuarte_drv_evt_handler_t evt_handler,
  356. void * context)
  357. {
  358. ret_code_t ret;
  359. IRQn_Type irqn = nrfx_get_irq_number(p_libuarte->uarte);
  360. p_libuarte->ctrl_blk->evt_handler = evt_handler;
  361. p_libuarte->ctrl_blk->p_cur_rx = NULL;
  362. p_libuarte->ctrl_blk->p_next_rx = NULL;
  363. p_libuarte->ctrl_blk->p_next_next_rx = NULL;
  364. p_libuarte->ctrl_blk->p_tx = NULL;
  365. p_libuarte->ctrl_blk->context = context;
  366. m_libuarte_instance[p_libuarte->uarte == NRF_UARTE0 ? 0 : 1] = p_libuarte;
  367. //UART init
  368. nrf_gpio_pin_set(p_config->tx_pin);
  369. nrf_gpio_cfg_output(p_config->tx_pin);
  370. nrf_gpio_cfg_input(p_config->rx_pin, p_config->pullup_rx ?
  371. NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL);
  372. nrf_uarte_baudrate_set(p_libuarte->uarte, p_config->baudrate);
  373. nrf_uarte_configure(p_libuarte->uarte, p_config->parity, p_config->hwfc);
  374. nrf_uarte_txrx_pins_set(p_libuarte->uarte, p_config->tx_pin, p_config->rx_pin);
  375. if (LIBUARTE_DRV_WITH_HWFC && (p_config->hwfc == NRF_UARTE_HWFC_ENABLED))
  376. {
  377. if (p_config->cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
  378. {
  379. nrf_gpio_cfg_input(p_config->cts_pin, NRF_GPIO_PIN_PULLUP);
  380. }
  381. if (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
  382. {
  383. nrfx_gpiote_out_config_t out_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
  384. nrfx_err_t err = nrfx_gpiote_init();
  385. if ((err != NRFX_SUCCESS) && (err != NRFX_ERROR_INVALID_STATE))
  386. {
  387. return err;
  388. }
  389. err = nrfx_gpiote_out_init(p_config->rts_pin, &out_config);
  390. if (err != NRFX_SUCCESS)
  391. {
  392. return NRF_ERROR_INTERNAL;
  393. }
  394. nrfx_gpiote_out_task_enable(p_config->rts_pin);
  395. nrf_gpio_cfg_output(p_config->rts_pin);
  396. p_libuarte->ctrl_blk->rts_pin = p_config->rts_pin;
  397. }
  398. else
  399. {
  400. p_libuarte->ctrl_blk->rts_pin = RTS_PIN_DISABLED;
  401. }
  402. nrf_uarte_hwfc_pins_set(p_libuarte->uarte, NRF_UARTE_PSEL_DISCONNECTED, p_config->cts_pin);
  403. }
  404. else if ((p_config->hwfc == NRF_UARTE_HWFC_ENABLED) && !LIBUARTE_DRV_WITH_HWFC)
  405. {
  406. return NRFX_ERROR_INVALID_PARAM;
  407. }
  408. #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE0)
  409. if (irqn == UARTE0_UART0_IRQn)
  410. {
  411. if (nrfx_prs_acquire(p_libuarte->uarte, libuarte_0_irq_handler) != NRFX_SUCCESS)
  412. {
  413. return NRF_ERROR_BUSY;
  414. }
  415. }
  416. #endif // NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE0)
  417. nrf_uarte_int_enable(p_libuarte->uarte, INTERRUPTS_MASK);
  418. NVIC_SetPriority(irqn, p_config->irq_priority);
  419. NVIC_ClearPendingIRQ(irqn);
  420. NVIC_EnableIRQ(irqn);
  421. nrf_uarte_enable(p_libuarte->uarte);
  422. nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
  423. tmr_config.mode = NRF_TIMER_MODE_COUNTER;
  424. tmr_config.bit_width = NRF_TIMER_BIT_WIDTH_32;
  425. ret = nrfx_timer_init(&p_libuarte->timer, &tmr_config, tmr_evt_handler);
  426. if (ret != NRFX_SUCCESS)
  427. {
  428. return NRF_ERROR_INTERNAL;
  429. }
  430. return ppi_configure(p_libuarte, p_config);
  431. }
  432. void nrf_libuarte_drv_uninit(const nrf_libuarte_drv_t * const p_libuarte)
  433. {
  434. IRQn_Type irqn = nrfx_get_irq_number(p_libuarte->uarte);
  435. NVIC_DisableIRQ(irqn);
  436. nrf_uarte_int_disable(p_libuarte->uarte, 0xFFFFFFFF);
  437. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  438. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPTX);
  439. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPRX);
  440. nrf_uarte_int_disable(p_libuarte->uarte, 0xFFFFFFFF);
  441. nrf_uarte_disable(p_libuarte->uarte);
  442. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  443. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  444. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX);
  445. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX);
  446. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED);
  447. #if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE0)
  448. if (irqn == UARTE0_UART0_IRQn)
  449. {
  450. nrfx_prs_release(p_libuarte->uarte);
  451. }
  452. #endif // NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRF_LIBUARTE_DRV_UARTE0)
  453. nrfx_timer_disable(&p_libuarte->timer);
  454. nrfx_timer_uninit(&p_libuarte->timer);
  455. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  456. {
  457. nrfx_gpiote_out_uninit(p_libuarte->ctrl_blk->rts_pin);
  458. }
  459. ppi_free(p_libuarte);
  460. }
  461. ret_code_t nrf_libuarte_drv_tx(const nrf_libuarte_drv_t * const p_libuarte,
  462. uint8_t * p_data, size_t len)
  463. {
  464. if (p_libuarte->ctrl_blk->p_tx)
  465. {
  466. return NRF_ERROR_BUSY;
  467. }
  468. p_libuarte->ctrl_blk->p_tx = p_data;
  469. p_libuarte->ctrl_blk->tx_len = len;
  470. p_libuarte->ctrl_blk->tx_cur_idx = 0;
  471. uint16_t first_chunk;
  472. if ((MAX_DMA_XFER_LEN <= UINT16_MAX) && (len <= MAX_DMA_XFER_LEN))
  473. {
  474. first_chunk = len;
  475. p_libuarte->ctrl_blk->tx_chunk8 = 0;
  476. }
  477. else
  478. {
  479. uint32_t num_of_chunks = CEIL_DIV(len, MAX_DMA_XFER_LEN);
  480. p_libuarte->ctrl_blk->tx_chunk8 = len/num_of_chunks;
  481. first_chunk = p_libuarte->ctrl_blk->tx_chunk8 + len%p_libuarte->ctrl_blk->tx_chunk8;
  482. }
  483. NRF_LOG_WARNING("Started TX total length:%d, first chunk:%d", len, first_chunk);
  484. nrf_uarte_tx_buffer_set(p_libuarte->uarte, p_data, first_chunk);
  485. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  486. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STARTTX);
  487. if ((MAX_DMA_XFER_LEN <= UINT16_MAX) && (len > MAX_DMA_XFER_LEN))
  488. {
  489. while(nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED) == 0)
  490. {
  491. }
  492. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  493. tx_ppi_enable(p_libuarte);
  494. nrf_uarte_tx_buffer_set(p_libuarte->uarte, &p_libuarte->ctrl_blk->p_tx[first_chunk], p_libuarte->ctrl_blk->tx_chunk8);
  495. }
  496. return NRF_SUCCESS;
  497. }
  498. ret_code_t nrf_libuarte_drv_rx_start(const nrf_libuarte_drv_t * const p_libuarte,
  499. uint8_t * p_data, size_t len, bool ext_trigger_en)
  500. {
  501. p_libuarte->ctrl_blk->chunk_size = len;
  502. ASSERT(len <= MAX_DMA_XFER_LEN);
  503. if (p_data)
  504. {
  505. p_libuarte->ctrl_blk->p_cur_rx = p_data;
  506. nrf_uarte_rx_buffer_set(p_libuarte->uarte, p_data, len);
  507. }
  508. /* Reset byte counting */
  509. nrfx_timer_enable(&p_libuarte->timer);
  510. nrfx_timer_clear(&p_libuarte->timer);
  511. p_libuarte->ctrl_blk->last_rx_byte_cnt = 0;
  512. p_libuarte->ctrl_blk->last_pin_rx_byte_cnt = 0;
  513. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX);
  514. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED);
  515. rx_ppi_enable(p_libuarte);
  516. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  517. {
  518. uint32_t rx_limit = len - NRF_LIBUARTE_DRV_HWFC_BYTE_LIMIT;
  519. *(uint32_t *)nrfx_gpiote_clr_task_addr_get(p_libuarte->ctrl_blk->rts_pin) = 1;
  520. nrfx_timer_compare(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL2, rx_limit, false);
  521. }
  522. if (!ext_trigger_en)
  523. {
  524. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX);
  525. }
  526. NRF_LOG_DEBUG("Start continues RX. Provided buffer:0x%08X", p_data);
  527. return NRF_SUCCESS;
  528. }
  529. void nrf_libuarte_drv_rx_buf_rsp(const nrf_libuarte_drv_t * const p_libuarte,
  530. uint8_t * p_data, size_t len)
  531. {
  532. if (p_libuarte->ctrl_blk->p_next_rx == NULL)
  533. {
  534. p_libuarte->ctrl_blk->p_next_rx = p_data;
  535. NRF_LOG_DEBUG("RX buf response (next). Provided buffer:0x%08X", p_data);
  536. nrf_uarte_rx_buffer_set(p_libuarte->uarte, p_data, len);
  537. }
  538. else
  539. {
  540. NRF_LOG_DEBUG("RX buf response (mp_next_rx not NULL:0x%08X), Provided buffer:0x%08X",
  541. p_libuarte->ctrl_blk->p_next_rx, p_data);
  542. p_libuarte->ctrl_blk->p_next_next_rx = p_data;
  543. }
  544. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  545. {
  546. uint32_t rx_limit = nrfx_timer_capture_get(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL0) +
  547. 2*len - NRF_LIBUARTE_DRV_HWFC_BYTE_LIMIT;
  548. nrfx_timer_compare(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL2, rx_limit, false);
  549. if (p_libuarte->ctrl_blk->rts_manual == false)
  550. {
  551. *(uint32_t *)nrfx_gpiote_clr_task_addr_get(p_libuarte->ctrl_blk->rts_pin) = 1;
  552. }
  553. }
  554. }
  555. void nrf_libuarte_drv_rx_stop(const nrf_libuarte_drv_t * const p_libuarte)
  556. {
  557. rx_ppi_disable(p_libuarte);
  558. NRF_LOG_DEBUG("RX stopped.");
  559. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  560. {
  561. *(uint32_t *)nrfx_gpiote_set_task_addr_get(p_libuarte->ctrl_blk->rts_pin) = 1;
  562. }
  563. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPRX);
  564. }
  565. void nrf_libuarte_drv_rts_clear(const nrf_libuarte_drv_t * const p_libuarte)
  566. {
  567. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  568. {
  569. *(uint32_t *)nrfx_gpiote_clr_task_addr_get(p_libuarte->ctrl_blk->rts_pin) = 1;
  570. p_libuarte->ctrl_blk->rts_manual = false;
  571. }
  572. }
  573. void nrf_libuarte_drv_rts_set(const nrf_libuarte_drv_t * const p_libuarte)
  574. {
  575. if (LIBUARTE_DRV_WITH_HWFC && (p_libuarte->ctrl_blk->rts_pin != RTS_PIN_DISABLED))
  576. {
  577. p_libuarte->ctrl_blk->rts_manual = true;
  578. *(uint32_t *)nrfx_gpiote_set_task_addr_get(p_libuarte->ctrl_blk->rts_pin) = 1;
  579. }
  580. }
  581. static void irq_handler(const nrf_libuarte_drv_t * const p_libuarte)
  582. {
  583. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ERROR))
  584. {
  585. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ERROR);
  586. nrf_libuarte_drv_evt_t evt = {
  587. .type = NRF_LIBUARTE_DRV_EVT_ERROR,
  588. .data = { .errorsrc = nrf_uarte_errorsrc_get_and_clear(p_libuarte->uarte) }
  589. };
  590. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  591. }
  592. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED))
  593. {
  594. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED);
  595. nrf_libuarte_drv_evt_t evt = {
  596. .type = NRF_LIBUARTE_DRV_EVT_RX_BUF_REQ,
  597. };
  598. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  599. }
  600. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX))
  601. {
  602. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX);
  603. uint32_t endrx_byte_cnt = nrfx_timer_capture_get(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL0);
  604. uint32_t stop_byte_cnt = nrfx_timer_capture_get(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL1);
  605. uint32_t dma_amount = endrx_byte_cnt - p_libuarte->ctrl_blk->last_rx_byte_cnt;
  606. uint32_t pin_amount = stop_byte_cnt - p_libuarte->ctrl_blk->last_pin_rx_byte_cnt;
  607. NRF_LOG_DEBUG("(evt) RX dma_cnt:%d, endrx_cnt:%d, stop_cnt:%d",
  608. dma_amount,
  609. endrx_byte_cnt,
  610. stop_byte_cnt);
  611. p_libuarte->ctrl_blk->last_rx_byte_cnt = endrx_byte_cnt;
  612. p_libuarte->ctrl_blk->last_pin_rx_byte_cnt = stop_byte_cnt;
  613. if (dma_amount || pin_amount)
  614. {
  615. uint32_t chunk0 = (dma_amount > p_libuarte->ctrl_blk->chunk_size) ?
  616. p_libuarte->ctrl_blk->chunk_size : dma_amount;
  617. uint32_t chunk1 = dma_amount - chunk0;
  618. NRF_LOG_DEBUG("RX END chunk0:%d, chunk1:%d, data[0]=%d %d",
  619. chunk0,
  620. chunk1,
  621. p_libuarte->ctrl_blk->p_cur_rx[0],
  622. p_libuarte->ctrl_blk->p_cur_rx[1]);
  623. nrf_libuarte_drv_evt_t evt = {
  624. .type = NRF_LIBUARTE_DRV_EVT_RX_DATA,
  625. .data = {
  626. .rxtx = {
  627. .p_data = p_libuarte->ctrl_blk->p_cur_rx,
  628. .length = chunk0
  629. }
  630. }
  631. };
  632. p_libuarte->ctrl_blk->p_cur_rx = p_libuarte->ctrl_blk->p_next_rx;
  633. p_libuarte->ctrl_blk->p_next_rx = NULL;
  634. if (p_libuarte->ctrl_blk->p_next_next_rx)
  635. {
  636. p_libuarte->ctrl_blk->p_next_rx = p_libuarte->ctrl_blk->p_next_next_rx;
  637. p_libuarte->ctrl_blk->p_next_next_rx = NULL;
  638. nrf_uarte_rx_buffer_set(p_libuarte->uarte,
  639. p_libuarte->ctrl_blk->p_next_rx,
  640. p_libuarte->ctrl_blk->chunk_size);
  641. }
  642. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  643. if ( chunk1 ||
  644. ((dma_amount == p_libuarte->ctrl_blk->chunk_size) && (endrx_byte_cnt == stop_byte_cnt)))
  645. {
  646. NRF_LOG_WARNING("RX END Chunk1:%d", chunk1);
  647. nrf_libuarte_drv_evt_t err_evt = {
  648. .type = NRF_LIBUARTE_DRV_EVT_OVERRUN_ERROR,
  649. .data = {
  650. .overrun_err = {
  651. .overrun_length = chunk1
  652. }
  653. }
  654. };
  655. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &err_evt);
  656. p_libuarte->ctrl_blk->p_cur_rx = p_libuarte->ctrl_blk->p_next_rx;
  657. p_libuarte->ctrl_blk->p_next_rx = NULL;
  658. }
  659. }
  660. }
  661. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED))
  662. {
  663. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  664. nrf_libuarte_drv_evt_t evt = {
  665. .type = NRF_LIBUARTE_DRV_EVT_TX_DONE,
  666. .data = {
  667. .rxtx = {
  668. .p_data = p_libuarte->ctrl_blk->p_tx,
  669. .length = p_libuarte->ctrl_blk->tx_len
  670. }
  671. }
  672. };
  673. p_libuarte->ctrl_blk->p_tx = NULL;
  674. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  675. }
  676. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX))
  677. {
  678. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX);
  679. size_t amount = nrf_uarte_tx_amount_get(p_libuarte->uarte);
  680. NRF_LOG_DEBUG("(evt) TX completed (%d)", amount);
  681. p_libuarte->ctrl_blk->tx_cur_idx += amount;
  682. if (p_libuarte->ctrl_blk->tx_cur_idx == p_libuarte->ctrl_blk->tx_len)
  683. {
  684. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  685. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPTX);
  686. }
  687. else
  688. {
  689. size_t rem_len = (p_libuarte->ctrl_blk->tx_len - p_libuarte->ctrl_blk->tx_cur_idx);
  690. if ( rem_len <= MAX_DMA_XFER_LEN)
  691. {
  692. tx_ppi_disable(p_libuarte);
  693. }
  694. else
  695. {
  696. uint8_t * p_buffer = &p_libuarte->ctrl_blk->p_tx[
  697. p_libuarte->ctrl_blk->tx_cur_idx +
  698. p_libuarte->ctrl_blk->tx_chunk8];
  699. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED) == 0)
  700. {
  701. NRF_LOG_ERROR("Tx not started yet!");
  702. ASSERT(false);
  703. }
  704. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  705. nrf_uarte_tx_buffer_set(p_libuarte->uarte,
  706. p_buffer,
  707. p_libuarte->ctrl_blk->tx_chunk8);
  708. }
  709. }
  710. }
  711. }
  712. #if NRF_LIBUARTE_DRV_UARTE0
  713. void libuarte_0_irq_handler(void)
  714. {
  715. irq_handler(m_libuarte_instance[0]);
  716. }
  717. #endif
  718. #if NRF_LIBUARTE_DRV_UARTE1
  719. void UARTE1_IRQHandler(void)
  720. {
  721. irq_handler(m_libuarte_instance[1]);
  722. }
  723. #endif