nrf_libuarte.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /**
  2. * Copyright (c) 2018 - 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.h"
  42. #include "nrf_uarte.h"
  43. #include "nrf_gpio.h"
  44. #define NRF_LOG_MODULE_NAME libUARTE
  45. #if NRF_LIBUARTE_CONFIG_LOG_ENABLED
  46. #define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
  47. #define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
  48. #define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
  49. #else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
  50. #define NRF_LOG_LEVEL 0
  51. #endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
  52. #include "nrf_log.h"
  53. NRF_LOG_MODULE_REGISTER();
  54. #define MAX_DMA_XFER_LEN ((1UL << UARTE0_EASYDMA_MAXCNT_SIZE) - 1)
  55. #define INTERRUPTS_MASK \
  56. (NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_RXSTARTED_MASK | NRF_UARTE_INT_ERROR_MASK | \
  57. NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_TXSTOPPED_MASK)
  58. /** Macro is setting up PPI channel set which consist of event, task and optional fork.
  59. *
  60. * @param _ch Channel.
  61. * @param _evt Event.
  62. * @param _tsk Task.
  63. * @param _fork Fork. If NULL fork is not configured.
  64. */
  65. #define PPI_CH_SETUP(_ch, _evt, _tsk, _fork) \
  66. ret = nrfx_ppi_channel_assign(_ch, _evt, _tsk); \
  67. if (ret != NRFX_SUCCESS) \
  68. { \
  69. return NRF_ERROR_INTERNAL; \
  70. } \
  71. if (_fork) \
  72. { \
  73. ret = nrfx_ppi_channel_fork_assign(_ch, _fork); \
  74. if (ret != NRFX_SUCCESS) \
  75. { \
  76. return NRF_ERROR_INTERNAL; \
  77. } \
  78. }
  79. /** Macro for setting up PPI group with one channel and getting tasks to
  80. * control that group.
  81. *
  82. * @param[in] _ch Channel to be included in the group.
  83. * @param[in] _group Group.
  84. * @param[out] _en_tsk Address of the task to enable group.
  85. * @param[out] _dis_tsk Address of the task to disable group.
  86. */
  87. #define PPI_GROUP_SETUP(_ch, _group, _en_tsk, _dis_tsk) \
  88. ret = nrfx_ppi_channel_include_in_group(_ch, _group); \
  89. if (ret != NRFX_SUCCESS) \
  90. { \
  91. return NRF_ERROR_INTERNAL; \
  92. } \
  93. _en_tsk = nrfx_ppi_task_addr_group_enable_get(_group); \
  94. _dis_tsk = nrfx_ppi_task_addr_group_disable_get(_group)
  95. static const nrf_libuarte_t * m_libuarte_instance[2];
  96. static ret_code_t ppi_configure(const nrf_libuarte_t * const p_libuarte,
  97. nrf_libuarte_config_t * p_config)
  98. {
  99. nrfx_err_t ret;
  100. /*lint -save -e666 */
  101. uint32_t group1_en_tsk = 0;
  102. uint32_t group1_dis_tsk = 0;
  103. uint32_t group2_en_tsk = 0;
  104. uint32_t group2_dis_tsk = 0;
  105. if (p_config->endrx_evt)
  106. {
  107. PPI_GROUP_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDRX_STARTRX],
  108. p_libuarte->ctrl_blk->ppi_groups[NRF_LIBUARTE_PPI_GROUP_ENDRX_STARTRX],
  109. group1_en_tsk, group1_dis_tsk);
  110. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDRX_STARTRX],
  111. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX),
  112. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX),
  113. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 0));
  114. PPI_GROUP_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDRX_EXT_TSK],
  115. p_libuarte->ctrl_blk->ppi_groups[NRF_LIBUARTE_PPI_GROUP_ENDRX_EXT_RXDONE_TSK],
  116. group2_en_tsk, group2_dis_tsk);
  117. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX],
  118. p_config->startrx_evt,
  119. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX),
  120. group1_en_tsk);
  121. }
  122. else
  123. {
  124. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX],
  125. p_config->startrx_evt,
  126. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX),
  127. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 0));
  128. }
  129. if (p_config->endrx_evt && p_config->rxdone_tsk)
  130. {
  131. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDRX_EXT_TSK],
  132. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX),
  133. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 0),
  134. p_config->rxdone_tsk);
  135. }
  136. if (p_config->rxstarted_tsk)
  137. {
  138. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_RXSTARTED_EXT_TSK],
  139. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED),
  140. group2_dis_tsk,
  141. p_config->rxstarted_tsk);
  142. }
  143. if (p_config->endrx_evt)
  144. {
  145. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_EXT_STOP_STOPRX],
  146. p_config->endrx_evt,
  147. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STOPRX),
  148. group2_en_tsk);
  149. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_EXT_STOP_GROUPS_EN],
  150. p_config->endrx_evt,
  151. group1_dis_tsk,
  152. nrfx_timer_capture_task_address_get(&p_libuarte->timer, 1));
  153. }
  154. if (MAX_DMA_XFER_LEN < UINT16_MAX)
  155. {
  156. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDTX_STARTTX],
  157. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX),
  158. nrf_uarte_task_address_get(p_libuarte->uarte, NRF_UARTE_TASK_STARTTX),
  159. 0);
  160. }
  161. PPI_CH_SETUP(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_RXRDY_TIMER_COUNT],
  162. nrf_uarte_event_address_get(p_libuarte->uarte, NRF_UARTE_EVENT_RXDRDY),
  163. nrfx_timer_task_address_get(&p_libuarte->timer, NRF_TIMER_TASK_COUNT),
  164. 0);
  165. if (ret != NRFX_SUCCESS)
  166. {
  167. return NRF_ERROR_INTERNAL;
  168. }
  169. return NRF_SUCCESS;
  170. /*lint -restore */
  171. }
  172. void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
  173. {
  174. UNUSED_PARAMETER(event_type);
  175. UNUSED_PARAMETER(p_context);
  176. }
  177. ret_code_t nrf_libuarte_init(const nrf_libuarte_t * const p_libuarte,
  178. nrf_libuarte_config_t * p_config,
  179. nrf_libuarte_evt_handler_t evt_handler,
  180. void * context)
  181. {
  182. ret_code_t ret;
  183. IRQn_Type irqn = nrfx_get_irq_number(p_libuarte->uarte);
  184. p_libuarte->ctrl_blk->evt_handler = evt_handler;
  185. p_libuarte->ctrl_blk->p_cur_rx = NULL;
  186. p_libuarte->ctrl_blk->p_next_rx = NULL;
  187. p_libuarte->ctrl_blk->p_next_next_rx = NULL;
  188. p_libuarte->ctrl_blk->p_tx = NULL;
  189. p_libuarte->ctrl_blk->context = context;
  190. m_libuarte_instance[p_libuarte->uarte == NRF_UARTE0 ? 0 : 1] = p_libuarte;
  191. //UART init
  192. nrf_gpio_pin_set(p_config->tx_pin);
  193. nrf_gpio_cfg_output(p_config->tx_pin);
  194. nrf_gpio_cfg_input(p_config->rx_pin, NRF_GPIO_PIN_NOPULL);
  195. nrf_uarte_baudrate_set(p_libuarte->uarte, p_config->baudrate);
  196. nrf_uarte_configure(p_libuarte->uarte, p_config->parity, p_config->hwfc);
  197. nrf_uarte_txrx_pins_set(p_libuarte->uarte, p_config->tx_pin, p_config->rx_pin);
  198. if (p_config->hwfc == NRF_UARTE_HWFC_ENABLED)
  199. {
  200. if (p_config->cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
  201. {
  202. nrf_gpio_cfg_input(p_config->cts_pin, NRF_GPIO_PIN_NOPULL);
  203. }
  204. if (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
  205. {
  206. nrf_gpio_pin_set(p_config->rts_pin);
  207. nrf_gpio_cfg_output(p_config->rts_pin);
  208. }
  209. nrf_uarte_hwfc_pins_set(p_libuarte->uarte, p_config->rts_pin, p_config->cts_pin);
  210. }
  211. nrf_uarte_int_enable(p_libuarte->uarte, INTERRUPTS_MASK);
  212. NVIC_SetPriority(irqn, p_config->irq_priority);
  213. NVIC_ClearPendingIRQ(irqn);
  214. NVIC_EnableIRQ(irqn);
  215. nrf_uarte_enable(p_libuarte->uarte);
  216. nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
  217. tmr_config.mode = NRF_TIMER_MODE_COUNTER;
  218. tmr_config.bit_width = NRF_TIMER_BIT_WIDTH_32;
  219. ret = nrfx_timer_init(&p_libuarte->timer, &tmr_config, tmr_evt_handler);
  220. if (ret != NRFX_SUCCESS)
  221. {
  222. return NRF_ERROR_INTERNAL;
  223. }
  224. nrfx_timer_enable(&p_libuarte->timer);
  225. nrfx_timer_clear(&p_libuarte->timer);
  226. p_libuarte->ctrl_blk->last_rx_byte_cnt = 0;
  227. p_libuarte->ctrl_blk->last_pin_rx_byte_cnt = 0;
  228. uint32_t i;
  229. for (i = 0; i < NRF_LIBUARTE_PPI_CH_MAX; i++)
  230. {
  231. if ((p_config->endrx_evt == 0) &&
  232. ((i == NRF_LIBUARTE_PPI_CH_EXT_STOP_STOPRX) ||
  233. (i == NRF_LIBUARTE_PPI_CH_EXT_STOP_GROUPS_EN) ||
  234. (i == NRF_LIBUARTE_PPI_CH_ENDRX_STARTRX) ||
  235. (i == NRF_LIBUARTE_PPI_CH_ENDRX_EXT_TSK)
  236. )
  237. ) {
  238. // skip ppi allocation
  239. p_libuarte->ctrl_blk->ppi_channels[i] = (nrf_ppi_channel_t)PPI_CH_NUM;
  240. }
  241. else if (p_config->rxstarted_tsk == 0 &&
  242. (i == NRF_LIBUARTE_PPI_CH_RXSTARTED_EXT_TSK))
  243. {
  244. p_libuarte->ctrl_blk->ppi_channels[i] = (nrf_ppi_channel_t)PPI_CH_NUM;
  245. }
  246. else if ((MAX_DMA_XFER_LEN >= UINT16_MAX) &&
  247. (i == NRF_LIBUARTE_PPI_CH_ENDTX_STARTTX))
  248. {
  249. p_libuarte->ctrl_blk->ppi_channels[i] = (nrf_ppi_channel_t)PPI_CH_NUM;
  250. }
  251. else
  252. {
  253. ret = nrfx_ppi_channel_alloc(&p_libuarte->ctrl_blk->ppi_channels[i]);
  254. if (ret != NRFX_SUCCESS)
  255. {
  256. //we don't free already allocated channels, system is wrongly configured.
  257. return NRF_ERROR_INTERNAL;
  258. }
  259. }
  260. }
  261. for (i = 0; i < NRF_LIBUARTE_PPI_GROUP_MAX; i++)
  262. {
  263. if (p_config->endrx_evt)
  264. {
  265. ret = nrfx_ppi_group_alloc(&p_libuarte->ctrl_blk->ppi_groups[i]);
  266. if (ret != NRFX_SUCCESS)
  267. {
  268. //we don't free already allocated channels, system is wrongly configured.
  269. return NRF_ERROR_INTERNAL;
  270. }
  271. }
  272. else
  273. {
  274. p_libuarte->ctrl_blk->ppi_groups[i] = (nrf_ppi_channel_group_t)PPI_GROUP_NUM;
  275. }
  276. }
  277. return ppi_configure(p_libuarte, p_config);
  278. }
  279. void nrf_libuarte_uninit(const nrf_libuarte_t * const p_libuarte)
  280. {
  281. IRQn_Type irqn = nrfx_get_irq_number(p_libuarte->uarte);
  282. NVIC_DisableIRQ(irqn);
  283. nrf_uarte_int_disable(p_libuarte->uarte, 0xFFFFFFFF);
  284. nrf_uarte_disable(p_libuarte->uarte);
  285. nrfx_timer_disable(&p_libuarte->timer);
  286. nrfx_timer_uninit(&p_libuarte->timer);
  287. uint32_t i;
  288. ret_code_t ret;
  289. for (i = 0; i < NRF_LIBUARTE_PPI_CH_MAX; i++)
  290. {
  291. if (p_libuarte->ctrl_blk->ppi_channels[i] < PPI_CH_NUM)
  292. {
  293. ret = nrfx_ppi_channel_disable(p_libuarte->ctrl_blk->ppi_channels[i]);
  294. ASSERT(ret == NRFX_SUCCESS)
  295. ret = nrfx_ppi_channel_free(p_libuarte->ctrl_blk->ppi_channels[i]);
  296. ASSERT(ret == NRFX_SUCCESS)
  297. }
  298. }
  299. for (i = 0; i < NRF_LIBUARTE_PPI_GROUP_MAX; i++)
  300. {
  301. if (p_libuarte->ctrl_blk->ppi_groups[i] < PPI_GROUP_NUM)
  302. {
  303. ret = nrfx_ppi_group_free(p_libuarte->ctrl_blk->ppi_groups[i]);
  304. ASSERT(ret == NRFX_SUCCESS)
  305. }
  306. }
  307. }
  308. ret_code_t nrf_libuarte_tx(const nrf_libuarte_t * const p_libuarte, uint8_t * p_data, size_t len)
  309. {
  310. if (p_libuarte->ctrl_blk->p_tx)
  311. {
  312. return NRF_ERROR_BUSY;
  313. }
  314. p_libuarte->ctrl_blk->p_tx = p_data;
  315. p_libuarte->ctrl_blk->tx_len = len;
  316. p_libuarte->ctrl_blk->tx_cur_idx = 0;
  317. uint16_t first_chunk;
  318. if ((MAX_DMA_XFER_LEN <= UINT16_MAX) && (len <= MAX_DMA_XFER_LEN))
  319. {
  320. first_chunk = len;
  321. p_libuarte->ctrl_blk->tx_chunk8 = 0;
  322. }
  323. else
  324. {
  325. uint32_t num_of_chunks = CEIL_DIV(len, MAX_DMA_XFER_LEN);
  326. p_libuarte->ctrl_blk->tx_chunk8 = len/num_of_chunks;
  327. first_chunk = p_libuarte->ctrl_blk->tx_chunk8 + len%p_libuarte->ctrl_blk->tx_chunk8;
  328. }
  329. NRF_LOG_WARNING("Started TX total length:%d, first chunk:%d", len, first_chunk);
  330. nrf_uarte_tx_buffer_set(p_libuarte->uarte, p_data, first_chunk);
  331. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  332. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STARTTX);
  333. if ((MAX_DMA_XFER_LEN <= UINT16_MAX) && (len > MAX_DMA_XFER_LEN))
  334. {
  335. while(nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED) == 0)
  336. {
  337. }
  338. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  339. nrfx_err_t err = nrfx_ppi_channel_enable(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDTX_STARTTX]);
  340. if (err != NRFX_SUCCESS)
  341. {
  342. return NRF_ERROR_INTERNAL;
  343. }
  344. nrf_uarte_tx_buffer_set(p_libuarte->uarte, &p_data[first_chunk], p_libuarte->ctrl_blk->tx_chunk8);
  345. }
  346. return NRF_SUCCESS;
  347. }
  348. ret_code_t nrf_libuarte_rx_start(const nrf_libuarte_t * const p_libuarte,
  349. uint8_t * p_data, size_t len, bool ext_trigger_en)
  350. {
  351. p_libuarte->ctrl_blk->chunk_size = len;
  352. uint32_t i;
  353. for (i = 0; i < NRF_LIBUARTE_PPI_CH_RX_MAX; i++)
  354. {
  355. if (p_libuarte->ctrl_blk->ppi_channels[i] < PPI_CH_NUM)
  356. {
  357. nrfx_err_t err = nrfx_ppi_channel_enable(p_libuarte->ctrl_blk->ppi_channels[i]);
  358. if (err != NRFX_SUCCESS)
  359. {
  360. return NRF_ERROR_INTERNAL;
  361. }
  362. }
  363. }
  364. ASSERT(len <= MAX_DMA_XFER_LEN);
  365. if (p_data)
  366. {
  367. p_libuarte->ctrl_blk->p_cur_rx = p_data;
  368. nrf_uarte_rx_buffer_set(p_libuarte->uarte, p_data, len);
  369. }
  370. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX);
  371. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED);
  372. if (!ext_trigger_en)
  373. {
  374. *(uint32_t *)nrfx_ppi_task_addr_group_enable_get(p_libuarte->ctrl_blk->ppi_groups[NRF_LIBUARTE_PPI_GROUP_ENDRX_STARTRX]) = 1;
  375. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STARTRX);
  376. }
  377. NRF_LOG_DEBUG("Start continues RX. Provided buffer:0x%08X", p_data);
  378. return NRF_SUCCESS;
  379. }
  380. void nrf_libuarte_rx_buf_rsp(const nrf_libuarte_t * const p_libuarte, uint8_t * p_data, size_t len)
  381. {
  382. if (p_libuarte->ctrl_blk->p_next_rx == NULL)
  383. {
  384. p_libuarte->ctrl_blk->p_next_rx = p_data;
  385. NRF_LOG_DEBUG("RX buf response (next). Provided buffer:0x%08X", p_data);
  386. nrf_uarte_rx_buffer_set(p_libuarte->uarte, p_data, len);
  387. }
  388. else
  389. {
  390. NRF_LOG_DEBUG("RX buf response (mp_next_rx not NULL:0x%08X), Provided buffer:0x%08X",
  391. p_libuarte->ctrl_blk->p_next_rx, p_data);
  392. p_libuarte->ctrl_blk->p_next_next_rx = p_data;
  393. }
  394. }
  395. void nrf_libuarte_rx_stop(const nrf_libuarte_t * const p_libuarte)
  396. {
  397. uint32_t i;
  398. for (i = 0; i < NRF_LIBUARTE_PPI_CH_RX_MAX; i++)
  399. {
  400. if (p_libuarte->ctrl_blk->ppi_channels[i] < PPI_CH_NUM)
  401. {
  402. nrfx_err_t err = nrfx_ppi_channel_disable(p_libuarte->ctrl_blk->ppi_channels[i]);
  403. ASSERT(err == NRFX_SUCCESS);
  404. }
  405. }
  406. NRF_LOG_DEBUG("RX stopped.");
  407. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPRX);
  408. }
  409. static void irq_handler(const nrf_libuarte_t * const p_libuarte)
  410. {
  411. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ERROR))
  412. {
  413. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ERROR);
  414. nrf_libuarte_evt_t evt = {
  415. .type = NRF_LIBUARTE_EVT_ERROR
  416. };
  417. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  418. }
  419. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED))
  420. {
  421. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_RXSTARTED);
  422. nrf_libuarte_evt_t evt = {
  423. .type = NRF_LIBUARTE_EVT_RX_BUF_REQ,
  424. };
  425. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  426. }
  427. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX))
  428. {
  429. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDRX);
  430. uint32_t endrx_byte_cnt = nrfx_timer_capture_get(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL0);
  431. uint32_t stop_byte_cnt = nrfx_timer_capture_get(&p_libuarte->timer, NRF_TIMER_CC_CHANNEL1);
  432. uint32_t dma_amount = endrx_byte_cnt - p_libuarte->ctrl_blk->last_rx_byte_cnt;
  433. uint32_t pin_amount = stop_byte_cnt - p_libuarte->ctrl_blk->last_pin_rx_byte_cnt;
  434. NRF_LOG_DEBUG("(evt) RX dma_cnt:%d, endrx_cnt:%d, stop_cnt:%d",
  435. dma_amount,
  436. endrx_byte_cnt,
  437. stop_byte_cnt);
  438. p_libuarte->ctrl_blk->last_rx_byte_cnt = endrx_byte_cnt;
  439. p_libuarte->ctrl_blk->last_pin_rx_byte_cnt = stop_byte_cnt;
  440. if (dma_amount || pin_amount)
  441. {
  442. uint32_t chunk0 = (dma_amount > p_libuarte->ctrl_blk->chunk_size) ?
  443. p_libuarte->ctrl_blk->chunk_size : dma_amount;
  444. uint32_t chunk1 = dma_amount - chunk0;
  445. NRF_LOG_DEBUG("RX END chunk0:%d, chunk1:%d, data[0]=%d %d",
  446. chunk0,
  447. chunk1,
  448. p_libuarte->ctrl_blk->p_cur_rx[0],
  449. p_libuarte->ctrl_blk->p_cur_rx[1]);
  450. nrf_libuarte_evt_t evt = {
  451. .type = NRF_LIBUARTE_EVT_RX_DATA,
  452. .data = {
  453. .rxtx = {
  454. .p_data = p_libuarte->ctrl_blk->p_cur_rx,
  455. .length = chunk0
  456. }
  457. }
  458. };
  459. p_libuarte->ctrl_blk->p_cur_rx = p_libuarte->ctrl_blk->p_next_rx;
  460. p_libuarte->ctrl_blk->p_next_rx = NULL;
  461. if (p_libuarte->ctrl_blk->p_next_next_rx)
  462. {
  463. p_libuarte->ctrl_blk->p_next_rx = p_libuarte->ctrl_blk->p_next_next_rx;
  464. p_libuarte->ctrl_blk->p_next_next_rx = NULL;
  465. nrf_uarte_rx_buffer_set(p_libuarte->uarte,
  466. p_libuarte->ctrl_blk->p_next_rx,
  467. p_libuarte->ctrl_blk->chunk_size);
  468. }
  469. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  470. if ( chunk1 ||
  471. ((dma_amount == p_libuarte->ctrl_blk->chunk_size) && (endrx_byte_cnt == stop_byte_cnt)))
  472. {
  473. NRF_LOG_WARNING("RX END Chunk1:%d", chunk1);
  474. evt.data.rxtx.length = chunk1;
  475. evt.data.rxtx.p_data = p_libuarte->ctrl_blk->p_cur_rx;
  476. p_libuarte->ctrl_blk->p_cur_rx = p_libuarte->ctrl_blk->p_next_rx;
  477. p_libuarte->ctrl_blk->p_next_rx = NULL;
  478. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  479. }
  480. }
  481. }
  482. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED))
  483. {
  484. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  485. nrf_libuarte_evt_t evt = {
  486. .type = NRF_LIBUARTE_EVT_TX_DONE,
  487. .data = {
  488. .rxtx = {
  489. .p_data = p_libuarte->ctrl_blk->p_tx,
  490. .length = p_libuarte->ctrl_blk->tx_len
  491. }
  492. }
  493. };
  494. p_libuarte->ctrl_blk->p_tx = NULL;
  495. p_libuarte->ctrl_blk->evt_handler(p_libuarte->ctrl_blk->context, &evt);
  496. }
  497. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX))
  498. {
  499. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_ENDTX);
  500. size_t amount = nrf_uarte_tx_amount_get(p_libuarte->uarte);
  501. NRF_LOG_DEBUG("(evt) TX completed (%d)", amount);
  502. p_libuarte->ctrl_blk->tx_cur_idx += amount;
  503. if (p_libuarte->ctrl_blk->tx_cur_idx == p_libuarte->ctrl_blk->tx_len)
  504. {
  505. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTOPPED);
  506. nrf_uarte_task_trigger(p_libuarte->uarte, NRF_UARTE_TASK_STOPTX);
  507. }
  508. else
  509. {
  510. size_t rem_len = (p_libuarte->ctrl_blk->tx_len - p_libuarte->ctrl_blk->tx_cur_idx);
  511. if ( rem_len <= MAX_DMA_XFER_LEN)
  512. {
  513. nrfx_err_t err =
  514. nrfx_ppi_channel_disable(p_libuarte->ctrl_blk->ppi_channels[NRF_LIBUARTE_PPI_CH_ENDTX_STARTTX]);
  515. ASSERT(err == NRFX_SUCCESS);
  516. }
  517. else
  518. {
  519. uint8_t * p_buffer = &p_libuarte->ctrl_blk->p_tx[
  520. p_libuarte->ctrl_blk->tx_cur_idx +
  521. p_libuarte->ctrl_blk->tx_chunk8];
  522. if (nrf_uarte_event_check(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED) == 0)
  523. {
  524. NRF_LOG_ERROR("Tx not started yet!");
  525. ASSERT(false);
  526. }
  527. nrf_uarte_event_clear(p_libuarte->uarte, NRF_UARTE_EVENT_TXSTARTED);
  528. nrf_uarte_tx_buffer_set(p_libuarte->uarte,
  529. p_buffer,
  530. p_libuarte->ctrl_blk->tx_chunk8);
  531. }
  532. }
  533. }
  534. }
  535. #if NRF_LIBUARTE_UARTE0
  536. void UARTE0_UART0_IRQHandler(void)
  537. {
  538. irq_handler(m_libuarte_instance[0]);
  539. }
  540. #endif
  541. #if NRF_LIBUARTE_UARTE1
  542. void UARTE1_IRQHandler(void)
  543. {
  544. irq_handler(m_libuarte_instance[1]);
  545. }
  546. #endif