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