1 /*
2  * Copyright (c) 2020-2020, BLUETRUM Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "ab32vg1_hal.h"
8 
9 #ifdef HAL_UART_MODULE_ENABLED
10 
11 enum
12 {
13     UARTxCON = 0x00,
14     UARTxCPND,
15     UARTxBAUD,
16     UARTxDATA,
17 };
18 
19 /**
20  * @brief Set the UART baud rate.
21  *
22  * @param uartx This parameter can be UARTxN where x can be (0.2).
23  * @param baud Baud rate.
24  */
hal_uart_setbaud(hal_sfr_t uartx,uint32_t baud)25 void hal_uart_setbaud(hal_sfr_t uartx, uint32_t baud)
26 {
27     uint32_t baud_cfg;
28 
29     uartx[UARTxCON] |= UART_CLK_SRC1;
30     baud_cfg = (26000000/2)/baud;
31     uartx[UARTxBAUD] = (baud_cfg << 16) | baud_cfg;
32 }
33 
34 /**
35  * @brief Set the UART misc paramter.
36  *
37  * @param uartx This parameter can be UARTxN where x can be (0.2).
38  * @param param uart config paramter pointer.
39  */
hal_uart_setparam(hal_sfr_t uartx,struct uart_init * param)40 void hal_uart_setparam(hal_sfr_t uartx, struct uart_init *param)
41 {
42     switch (param->word_len)
43     {
44     case UART_WORDLENGTH_8B:
45         uartx[UARTxCON] &= ~UART_BIT9_ENABLE;
46         break;
47     case UART_WORDLENGTH_9B:
48         uartx[UARTxCON] |= UART_BIT9_ENABLE;
49         break;
50     default:
51         break;
52     }
53 
54     switch (param->stop_bits)
55     {
56     case UART_STOPBITS_1:
57         uartx[UARTxCON] &= ~UART_SB2_ENABLE;
58         break;
59     case UART_STOPBITS_2:
60         uartx[UARTxCON] |= UART_SB2_ENABLE;
61         break;
62     default:
63         break;
64     }
65 
66     if (param->mode & UART_MODE_1LINE)
67     {
68         uartx[UARTxCON] |= UART_1LINE_ENABLE;
69     }
70     else
71     {
72         uartx[UARTxCON] &= ~UART_1LINE_ENABLE;
73     }
74 }
75 /**
76  * @brief Initialize the UART mode.
77  *
78  * @param huart UART handle.
79  * @return hal_error_t
80  */
hal_uart_init(struct uart_handle * huart)81 hal_error_t hal_uart_init(struct uart_handle *huart)
82 {
83     if (huart == HAL_NULL) {
84         return -HAL_ERROR;
85     }
86 
87     hal_uart_mspinit(huart);
88     uart_config_all(huart);
89 
90     return HAL_EOK;
91 }
92 
93 /**
94  * @brief DeInitialize the UART peripheral.
95  *
96  * @param uartx This parameter can be UARTxN where x can be (0.2).
97  */
hal_uart_deinit(hal_sfr_t uartx)98 void hal_uart_deinit(hal_sfr_t uartx)
99 {
100     uartx[UARTxCON] = 0;
101 }
102 
103 /**
104  * @brief Initialize the UART MSP.
105  *
106  * @param huart UART handle.
107  */
HAL_UART_MspInit(struct uart_handle * huart)108 WEAK void HAL_UART_MspInit(struct uart_handle *huart)
109 {}
110 
111 /**
112  * @brief Control the UART peripheral.
113  *
114  * @param uartx This parameter can be UARTxN where x can be (0.2).
115  * @param cntl
116  *      @arg UART_MODULE_ENABLE
117  *      @arg UART_BIT9_ENABLE
118  *      @arg UART_RXIT_ENABLE
119  *      @arg UART_TXIT_ENABLE
120  *      @arg UART_SB2_ENABLE
121  *      @arg UART_CLK_SRC1
122  *      @arg UART_1LINE_ENABLE
123  *      @arg UART_RX_ENABLE
124  * @param param
125  *      @arg HAL_DISABLE
126  *      @arg HAL_ENABLE
127  */
hal_uart_control(hal_sfr_t uartx,uint32_t cntl,uint32_t param)128 void hal_uart_control(hal_sfr_t uartx, uint32_t cntl, uint32_t param)
129 {
130     if (param == HAL_ENABLE) {
131         uartx[UARTxCON] |= (cntl);
132     } else {
133         uartx[UARTxCON] &= ~(cntl);
134     }
135 }
136 
137 /**
138  * @brief Send a character
139  *
140  * @param uartx This parameter can be UARTxN where x can be (0.2).
141  * @param data The characters that need to be sent
142  */
hal_uart_write(hal_sfr_t uartx,uint8_t data)143 void hal_uart_write(hal_sfr_t uartx, uint8_t data)
144 {
145     uartx[UARTxDATA] = data;
146 }
147 
148 /**
149  * @brief Receive a character.
150  *
151  * @param uartx This parameter can be UARTxN where x can be (0.2).
152  * @return uint8_t Received character.
153  */
hal_uart_read(hal_sfr_t uartx)154 uint8_t hal_uart_read(hal_sfr_t uartx)
155 {
156     return (uartx[UARTxDATA] & 0xff);
157 }
158 
159 /**
160  * @brief Get the UART flag.
161  *
162  * @param uartx This parameter can be UARTxN where x can be (0.2).
163  * @param flag
164  *      @arg UART_FLAG_RXPND
165  *      @arg UART_FLAG_TXPND
166  * @return uint32_t
167  */
hal_uart_getflag(hal_sfr_t uartx,uint32_t flag)168 uint32_t hal_uart_getflag(hal_sfr_t uartx, uint32_t flag)
169 {
170     uint32_t ret = uartx[UARTxCON] & flag;
171     return ret;
172 }
173 
174 /**
175  * @brief Clear the UART flag.
176  *
177  * @param uartx This parameter can be UARTxN where x can be (0.2).
178  * @param flag
179  *      @arg UART_FLAG_RXPND
180  *      @arg UART_FLAG_TXPND
181  */
hal_uart_clrflag(hal_sfr_t uartx,uint32_t flag)182 void hal_uart_clrflag(hal_sfr_t uartx, uint32_t flag)
183 {
184     uartx[UARTxCPND] |= flag;
185 }
186 
187 /**
188  * @brief Configure the UART peripheral.
189  *
190  * @param huart UART handle.
191  */
uart_config_all(struct uart_handle * huart)192 void uart_config_all(struct uart_handle *huart)
193 {
194     hal_uart_control(huart->instance, UART_MODULE_ENABLE, HAL_DISABLE);
195 
196     CLKCON1 |= BIT(14);
197     if (huart->instance == UART0_BASE) {
198         hal_rcu_periph_clk_enable(RCU_UART0);
199     } else if (huart->instance == UART1_BASE) {
200         hal_rcu_periph_clk_enable(RCU_UART1);
201     } else if (huart->instance == UART2_BASE) {
202         hal_rcu_periph_clk_enable(RCU_UART2);
203     } else {
204         return; /* Not support! */
205     }
206 
207     hal_uart_deinit(huart->instance);
208     hal_uart_setbaud(huart->instance, huart->init.baud);
209     hal_uart_setparam(huart->instance, &huart->init);
210 
211     if (huart->init.mode != UART_MODE_TX) {
212         hal_uart_control(huart->instance, UART_RX_ENABLE, HAL_ENABLE);
213     }
214     hal_uart_control(huart->instance, UART_MODULE_ENABLE, HAL_ENABLE);
215 }
216 
217 #endif
218