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_uart.h"
11 #include "bs_tracing.h"
12 #include "NHW_UART.h"
13 
uart_number_from_ptr(NRF_UART_Type * p_reg)14 static int uart_number_from_ptr(NRF_UART_Type * p_reg){
15   int i = ( (int)p_reg - (int)NRF_UARTE_regs ) / sizeof(NRF_UARTE_Type);
16   return i;
17 }
18 
nrf_uart_task_trigger(NRF_UART_Type * p_reg,nrf_uart_task_t task)19 void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task)
20 {
21   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
22 
23   int i = uart_number_from_ptr(p_reg);
24 
25 #define CASE_TASK(x) \
26   case NRF_UART_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(SUSPEND);
34     default:
35       bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
36       break;
37   }
38 #undef CASE_TASK
39 }
40 
nrf_uart_int_enable(NRF_UART_Type * p_reg,uint32_t mask)41 void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t mask)
42 {
43   int i = uart_number_from_ptr(p_reg);
44   p_reg->INTENSET = mask;
45   nhw_UARTE_regw_sideeffects_INTENSET(i);
46 }
47 
nrf_uart_int_disable(NRF_UART_Type * p_reg,uint32_t mask)48 void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t mask)
49 {
50   int i = uart_number_from_ptr(p_reg);
51   p_reg->INTENCLR = mask;
52   nhw_UARTE_regw_sideeffects_INTENCLR(i);
53 }
54 
nrf_uart_event_clear(NRF_UART_Type * p_reg,nrf_uart_event_t event)55 void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event)
56 {
57   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
58   int i = uart_number_from_ptr(p_reg);
59   nhw_UARTE_regw_sideeffects_EVENTS_all(i);
60 }
61 
nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg)62 uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg)
63 {
64   int i = uart_number_from_ptr(p_reg);
65   return nhw_UARTE_regr_sideeffects_ERRORSRC(i);
66 }
67 
nrf_uart_rxd_get(NRF_UART_Type const * p_reg)68 uint8_t nrf_uart_rxd_get(NRF_UART_Type const * p_reg)
69 {
70   int i = uart_number_from_ptr((NRF_UART_Type *)p_reg);
71   return nhw_UARTE_regr_sideeffects_RXD(i);
72 }
73 
nrf_uart_txd_set(NRF_UART_Type * p_reg,uint8_t txd)74 void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd)
75 {
76   p_reg->TXD = txd;
77   int i = uart_number_from_ptr(p_reg);
78   nhw_UARTE_regw_sideeffects_TXD(i);
79 }
80 
nrf_uart_disable(NRF_UART_Type * p_reg)81 void nrf_uart_disable(NRF_UART_Type * p_reg)
82 {
83   int i = uart_number_from_ptr(p_reg);
84   p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled;
85   nhw_UARTE_regw_sideeffects_ENABLE(i);
86 }
87 
nrf_uart_enable(NRF_UART_Type * p_reg)88 void nrf_uart_enable(NRF_UART_Type * p_reg)
89 {
90   int i = uart_number_from_ptr(p_reg);
91   p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled;
92   nhw_UARTE_regw_sideeffects_ENABLE(i);
93 }
94 
nrf_uart_configure(NRF_UART_Type * p_reg,nrf_uart_config_t const * p_cfg)95 void nrf_uart_configure(NRF_UART_Type           * p_reg,
96                         nrf_uart_config_t const * p_cfg)
97 {
98   int i = uart_number_from_ptr(p_reg);
99   p_reg->CONFIG = (uint32_t)p_cfg->parity
100 #if defined(UART_CONFIG_STOP_Msk)
101                   | (uint32_t)p_cfg->stop
102 #endif
103 #if defined(UART_CONFIG_PARITYTYPE_Msk)
104                   | (uint32_t)p_cfg->paritytype
105 #endif
106                   | (uint32_t)p_cfg->hwfc;
107   nhw_UARTE_regw_sideeffects_CONFIG(i);
108 }
109 
110 #if defined(DPPI_PRESENT)
111 
nrf_uart_subscribe_common(NRF_UART_Type * p_reg,nrf_uart_task_t task)112 static void nrf_uart_subscribe_common(NRF_UART_Type * p_reg,
113                                        nrf_uart_task_t task)
114 {
115   int i = uart_number_from_ptr(p_reg);
116 
117 #define CASE_TASK(TASKN) \
118   case NRF_UART_TASK_##TASKN: nhw_uart_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(SUSPEND);
126     default:
127       bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_uart(%i)\n",
128                                 task);
129       break;
130   }
131 #undef CASE_TASK
132 }
133 
nrf_uart_subscribe_set(NRF_UART_Type * p_reg,nrf_uart_task_t task,uint8_t channel)134 void nrf_uart_subscribe_set(NRF_UART_Type * p_reg,
135                              nrf_uart_task_t task,
136                              uint8_t          channel)
137 {
138     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
139             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
140     nrf_uart_subscribe_common(p_reg, task);
141 }
142 
nrf_uart_subscribe_clear(NRF_UART_Type * p_reg,nrf_uart_task_t task)143 void nrf_uart_subscribe_clear(NRF_UART_Type * p_reg,
144                                nrf_uart_task_t task)
145 {
146     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
147     nrf_uart_subscribe_common(p_reg, task);
148 }
149 #endif /* defined(DPPI_PRESENT) */
150