1 /*
2 * Copyright (c) 2016-2017 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "arm_uart_drv.h"
18
19 #include <stddef.h>
20
21 /* UART register map structure */
22 struct _arm_uart_reg_map_t {
23 volatile uint32_t data; /* Offset: 0x000 (R/W) data register */
24 volatile uint32_t state; /* Offset: 0x004 (R/W) status register */
25 volatile uint32_t ctrl; /* Offset: 0x008 (R/W) control register */
26 union {
27 volatile uint32_t intrstatus; /* Offset: 0x00c (R/ ) interrupt status
28 * register */
29 volatile uint32_t intrclear; /* Offset: 0x00c ( /W) interrupt clear
30 * register */
31 }intr_reg;
32 volatile uint32_t bauddiv; /* Offset: 0x010 (R/W) Baudrate divider
33 * register */
34 };
35
36 /* CTRL Register */
37 #define ARM_UART_TX_EN (1ul << 0)
38 #define ARM_UART_RX_EN (1ul << 1)
39 #define ARM_UART_TX_INTR_EN (1ul << 2)
40 #define ARM_UART_RX_INTR_EN (1ul << 3)
41
42 /* STATE Register */
43 #define ARM_UART_TX_BF (1ul << 0)
44 #define ARM_UART_RX_BF (1ul << 1)
45
46 /* INTSTATUS Register */
47 #define ARM_UART_TX_INTR (1ul << 0)
48 #define ARM_UART_RX_INTR (1ul << 1)
49
50 /* UART state definitions */
51 #define ARM_UART_INITIALIZED (1ul << 0)
52
arm_uart_init(struct arm_uart_dev_t * dev,uint32_t system_clk)53 enum arm_uart_error_t arm_uart_init(struct arm_uart_dev_t* dev,
54 uint32_t system_clk)
55 {
56 struct _arm_uart_reg_map_t* p_uart =
57 (struct _arm_uart_reg_map_t*)dev->cfg->base;
58 if(system_clk == 0) {
59 return ARM_UART_ERR_INVALID_ARG;
60 }
61
62 /* Sets baudrate and system clock */
63 dev->data->system_clk = system_clk;
64 dev->data->baudrate = dev->cfg->default_baudrate;
65
66 /* Sets baudrate */
67 p_uart->bauddiv = (dev->data->system_clk / dev->cfg->default_baudrate);
68
69 /* Enables receiver and transmitter */
70 p_uart->ctrl = ARM_UART_RX_EN | ARM_UART_TX_EN;
71
72 dev->data->state = ARM_UART_INITIALIZED;
73
74 return ARM_UART_ERR_NONE;
75 }
76
arm_uart_set_baudrate(struct arm_uart_dev_t * dev,uint32_t baudrate)77 enum arm_uart_error_t arm_uart_set_baudrate(struct arm_uart_dev_t* dev,
78 uint32_t baudrate)
79 {
80 uint32_t bauddiv;
81 struct _arm_uart_reg_map_t* p_uart =
82 (struct _arm_uart_reg_map_t*)dev->cfg->base;
83
84 if(baudrate == 0) {
85 return ARM_UART_ERR_INVALID_BAUD;
86 }
87
88 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
89 return ARM_UART_ERR_NOT_INIT;
90 }
91
92 /* Sets baudrate */
93 bauddiv = (dev->data->system_clk / baudrate);
94 dev->data->baudrate = baudrate;
95
96 /* Minimum bauddiv value */
97 if(bauddiv < 16) {
98 return ARM_UART_ERR_INVALID_BAUD;
99 }
100
101 p_uart->bauddiv = bauddiv;
102
103 return ARM_UART_ERR_NONE;
104 }
105
arm_uart_get_baudrate(struct arm_uart_dev_t * dev)106 uint32_t arm_uart_get_baudrate(struct arm_uart_dev_t* dev)
107 {
108 return dev->data->baudrate;
109 }
110
arm_uart_set_clock(struct arm_uart_dev_t * dev,uint32_t system_clk)111 enum arm_uart_error_t arm_uart_set_clock(struct arm_uart_dev_t* dev,
112 uint32_t system_clk)
113 {
114 struct _arm_uart_reg_map_t* p_uart =
115 (struct _arm_uart_reg_map_t*)dev->cfg->base;
116
117 if(system_clk == 0) {
118 return ARM_UART_ERR_INVALID_ARG;
119 }
120
121 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
122 return ARM_UART_ERR_NOT_INIT;
123 }
124
125 /* Sets system clock */
126 dev->data->system_clk = system_clk;
127
128 /* Updates baudrate divider */
129 p_uart->bauddiv = (dev->data->system_clk / dev->data->baudrate);
130
131 /* Enables receiver and transmitter */
132 return ARM_UART_ERR_NONE;
133 }
134
arm_uart_read(struct arm_uart_dev_t * dev,uint8_t * byte)135 enum arm_uart_error_t arm_uart_read(struct arm_uart_dev_t* dev, uint8_t* byte)
136 {
137 struct _arm_uart_reg_map_t* p_uart =
138 (struct _arm_uart_reg_map_t*)dev->cfg->base;
139
140 if(!(p_uart->state & ARM_UART_RX_BF)) {
141 return ARM_UART_ERR_NOT_READY;
142 }
143
144 /* Reads data */
145 *byte = (uint8_t)p_uart->data;
146
147 return ARM_UART_ERR_NONE;
148 }
149
arm_uart_write(struct arm_uart_dev_t * dev,uint8_t byte)150 enum arm_uart_error_t arm_uart_write(struct arm_uart_dev_t* dev, uint8_t byte)
151 {
152 struct _arm_uart_reg_map_t* p_uart =
153 (struct _arm_uart_reg_map_t*)dev->cfg->base;
154
155 if(p_uart->state & ARM_UART_TX_BF) {
156 return ARM_UART_ERR_NOT_READY;
157 }
158
159 /* Sends data */
160 p_uart->data = byte;
161
162 return ARM_UART_ERR_NONE;
163 }
164
arm_uart_irq_tx_enable(struct arm_uart_dev_t * dev)165 enum arm_uart_error_t arm_uart_irq_tx_enable(struct arm_uart_dev_t* dev)
166 {
167 struct _arm_uart_reg_map_t* p_uart =
168 (struct _arm_uart_reg_map_t*)dev->cfg->base;
169
170 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
171 return ARM_UART_ERR_NOT_INIT;
172 }
173
174 p_uart->ctrl |= ARM_UART_TX_INTR_EN;
175
176 return ARM_UART_ERR_NONE;
177 }
178
arm_uart_irq_tx_disable(struct arm_uart_dev_t * dev)179 void arm_uart_irq_tx_disable(struct arm_uart_dev_t* dev)
180 {
181 struct _arm_uart_reg_map_t* p_uart =
182 (struct _arm_uart_reg_map_t*)dev->cfg->base;
183
184 if(dev->data->state & ARM_UART_INITIALIZED ) {
185 p_uart->ctrl &= ~ARM_UART_TX_INTR_EN;
186 }
187 }
188
arm_uart_tx_ready(struct arm_uart_dev_t * dev)189 uint32_t arm_uart_tx_ready(struct arm_uart_dev_t* dev)
190 {
191 struct _arm_uart_reg_map_t* p_uart =
192 (struct _arm_uart_reg_map_t*)dev->cfg->base;
193
194 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
195 return 0;
196 }
197
198 return !(p_uart->state & ARM_UART_TX_BF);
199 }
200
arm_uart_irq_rx_enable(struct arm_uart_dev_t * dev)201 enum arm_uart_error_t arm_uart_irq_rx_enable(struct arm_uart_dev_t* dev)
202 {
203 struct _arm_uart_reg_map_t* p_uart =
204 (struct _arm_uart_reg_map_t*)dev->cfg->base;
205
206 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
207 return ARM_UART_ERR_NOT_INIT;
208 }
209
210 p_uart->ctrl |= ARM_UART_RX_INTR_EN;
211
212 return ARM_UART_ERR_NONE;
213 }
214
arm_uart_irq_rx_disable(struct arm_uart_dev_t * dev)215 void arm_uart_irq_rx_disable(struct arm_uart_dev_t* dev)
216 {
217 struct _arm_uart_reg_map_t* p_uart =
218 (struct _arm_uart_reg_map_t*)dev->cfg->base;
219
220 if(dev->data->state & ARM_UART_INITIALIZED) {
221 p_uart->ctrl &= ~ARM_UART_RX_INTR_EN;
222 }
223 }
224
arm_uart_rx_ready(struct arm_uart_dev_t * dev)225 uint32_t arm_uart_rx_ready(struct arm_uart_dev_t* dev)
226 {
227 struct _arm_uart_reg_map_t* p_uart =
228 (struct _arm_uart_reg_map_t*)dev->cfg->base;
229
230 if(!(dev->data->state & ARM_UART_INITIALIZED)) {
231 return 0;
232 }
233
234 return (p_uart->state & ARM_UART_RX_BF);
235 }
236
arm_uart_clear_interrupt(struct arm_uart_dev_t * dev,enum arm_uart_irq_t irq)237 void arm_uart_clear_interrupt(struct arm_uart_dev_t* dev,
238 enum arm_uart_irq_t irq)
239 {
240 struct _arm_uart_reg_map_t* p_uart =
241 (struct _arm_uart_reg_map_t*)dev->cfg->base;
242
243 if(dev->data->state & ARM_UART_INITIALIZED) {
244 /* Clears pending interrupts */
245 switch(irq) {
246 case ARM_UART_IRQ_RX:
247 p_uart->intr_reg.intrclear = ARM_UART_RX_INTR;
248 break;
249 case ARM_UART_IRQ_TX:
250 p_uart->intr_reg.intrclear = ARM_UART_TX_INTR;
251 break;
252 case ARM_UART_IRQ_COMBINED:
253 p_uart->intr_reg.intrclear = (ARM_UART_RX_INTR | ARM_UART_TX_INTR);
254 break;
255 /* default: not defined to force all cases to be handled */
256 }
257 }
258 }
259