1 /*
2  * Copyright (c) 2023, Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Note that the function prototypes are taken from the NRFx HAL
7  */
8 
9 #include <stdint.h>
10 #include "hal/nrf_uarte.h"
11 #include "bs_tracing.h"
12 #include "NHW_UART.h"
13 
uarte_number_from_ptr(NRF_UARTE_Type * p_reg)14 static int uarte_number_from_ptr(NRF_UARTE_Type * p_reg){
15   int i = ( (int)p_reg - (int)NRF_UARTE_regs ) / sizeof(NRF_UARTE_Type);
16   return i;
17 }
18 
nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg,nrf_uarte_task_t task)19 void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
20 {
21   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
22 
23   int i = uarte_number_from_ptr(p_reg);
24 
25 #define CASE_TASK(x) \
26   case NRF_UARTE_TASK_##x: nhw_UARTE_regw_sideeffects_TASKS_##x(i); break
27 
28   switch (task) {
29     CASE_TASK(STARTRX);
30     CASE_TASK(STOPRX);
31     CASE_TASK(STARTTX);
32     CASE_TASK(STOPTX);
33     CASE_TASK(FLUSHRX);
34 #if 0 /*NHW_UARTE_HAS_MATCH*/ /* Not yet supported by nrf HAL, task name is a guess */
35     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_0: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_ENABLEMATCH(i, 0); break;
36     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_1: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_ENABLEMATCH(i, 1); break;
37     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_2: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_ENABLEMATCH(i, 2); break;
38     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_3: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_ENABLEMATCH(i, 3); break;
39     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_0: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_DISABLEMATCH(i, 0); break;
40     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_1: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_DISABLEMATCH(i, 1); break;
41     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_2: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_DISABLEMATCH(i, 2); break;
42     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_3: nhw_UARTE_regw_sideeffects_TASKS_DMA_RX_DISABLEMATCH(i, 3); break;
43 #endif
44     default:
45       bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
46       break;
47   }
48 #undef CASE_TASK
49 }
50 
nrf_uarte_int_enable(NRF_UARTE_Type * p_reg,uint32_t mask)51 void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t mask)
52 {
53   int i = uarte_number_from_ptr(p_reg);
54   p_reg->INTENSET = mask;
55   nhw_UARTE_regw_sideeffects_INTENSET(i);
56 }
57 
nrf_uarte_int_disable(NRF_UARTE_Type * p_reg,uint32_t mask)58 void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t mask)
59 {
60   int i = uarte_number_from_ptr(p_reg);
61   p_reg->INTENCLR = mask;
62   nhw_UARTE_regw_sideeffects_INTENCLR(i);
63 }
64 
nrf_uarte_event_clear(NRF_UARTE_Type * p_reg,nrf_uarte_event_t event)65 void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
66 {
67   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
68   int i = uarte_number_from_ptr(p_reg);
69   nhw_UARTE_regw_sideeffects_EVENTS_all(i);
70 }
71 
nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)72 uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)
73 {
74   int i = uarte_number_from_ptr(p_reg);
75   return nhw_UARTE_regr_sideeffects_ERRORSRC(i);
76 }
77 
nrf_uarte_enable(NRF_UARTE_Type * p_reg)78 void nrf_uarte_enable(NRF_UARTE_Type * p_reg)
79 {
80   int i = uarte_number_from_ptr(p_reg);
81   p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
82   nhw_UARTE_regw_sideeffects_ENABLE(i);
83 }
84 
nrf_uarte_disable(NRF_UARTE_Type * p_reg)85 void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
86 {
87   int i = uarte_number_from_ptr(p_reg);
88   p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled;
89   nhw_UARTE_regw_sideeffects_ENABLE(i);
90 }
91 
nrf_uarte_configure(NRF_UARTE_Type * p_reg,nrf_uarte_config_t const * p_cfg)92 void nrf_uarte_configure(NRF_UARTE_Type           * p_reg,
93                          nrf_uarte_config_t const * p_cfg)
94 {
95   int i = uarte_number_from_ptr(p_reg);
96   p_reg->CONFIG = (uint32_t)p_cfg->parity
97 #if defined(UARTE_CONFIG_STOP_Msk)
98                   | (uint32_t)p_cfg->stop
99 #endif
100 #if defined(UARTE_CONFIG_PARITYTYPE_Msk)
101                   | (uint32_t)p_cfg->paritytype
102 #endif
103 #if NRF_UARTE_HAS_FRAME_TIMEOUT
104                   | (uint32_t)p_cfg->frame_timeout
105 #endif
106                   | (uint32_t)p_cfg->hwfc;
107   nhw_UARTE_regw_sideeffects_CONFIG(i);
108 }
109 
110 #if defined(DPPI_PRESENT)
111 
nrf_uarte_subscribe_common(NRF_UARTE_Type * p_reg,nrf_uarte_task_t task)112 static void nrf_uarte_subscribe_common(NRF_UARTE_Type * p_reg,
113                                        nrf_uarte_task_t task)
114 {
115   int i = uarte_number_from_ptr(p_reg);
116 
117 #define CASE_TASK(TASKN) \
118   case NRF_UARTE_TASK_##TASKN: nhw_UARTE_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
119 
120   switch (task) {
121     CASE_TASK(STARTRX);
122     CASE_TASK(STOPRX);
123     CASE_TASK(STARTTX);
124     CASE_TASK(STOPTX);
125     CASE_TASK(FLUSHRX);
126 #if 0 /*NHW_UARTE_HAS_MATCH*/ /* Not yet supported by nrf HAL, task name is a guess */
127     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_0: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_ENABLEMATCH(i, 0); break;
128     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_1: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_ENABLEMATCH(i, 1); break;
129     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_2: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_ENABLEMATCH(i, 2); break;
130     case NRF_UARTE_TASK_DMA_RX_ENABLEMATCH_3: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_ENABLEMATCH(i, 3); break;
131     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_0: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_DISABLEMATCH(i, 0); break;
132     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_1: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_DISABLEMATCH(i, 1); break;
133     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_2: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_DISABLEMATCH(i, 2); break;
134     case NRF_UARTE_TASK_DMA_RX_DISABLEMATCH_3: nhw_UARTE_regw_sideeffects_SUBSCRIBE_DMA_RX_DISABLEMATCH(i, 3); break;
135 #endif
136     default:
137       bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_uart(%i)\n",
138                                 task);
139       break;
140   }
141 #undef CASE_TASK
142 }
143 
nrf_uarte_subscribe_set(NRF_UARTE_Type * p_reg,nrf_uarte_task_t task,uint8_t channel)144 void nrf_uarte_subscribe_set(NRF_UARTE_Type * p_reg,
145                              nrf_uarte_task_t task,
146                              uint8_t          channel)
147 {
148     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
149             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
150     nrf_uarte_subscribe_common(p_reg, task);
151 }
152 
nrf_uarte_subscribe_clear(NRF_UARTE_Type * p_reg,nrf_uarte_task_t task)153 void nrf_uarte_subscribe_clear(NRF_UARTE_Type * p_reg,
154                                nrf_uarte_task_t task)
155 {
156     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
157     nrf_uarte_subscribe_common(p_reg, task);
158 }
159 #endif /* defined(DPPI_PRESENT) */
160