1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <stddef.h> // standard definition
16 #include "uart.h"
17 #include "reg_iomux.h"
18 #include "sysctrl_api.h"
19 #include "reg_ipc_comreg.h"
20
21 #define PERCLK_INDEX (PER_UART0 + UART_INDEX)
22 #define UART_INITED_SET M2STR_P3(ipccomreg_state_uart, UART_INDEX, inited_setb)
23
24 #if (PLF_HW_PXP == 1)
25 #define MAX_BAUD_RATE 1
26 #else
27 #define MAX_BAUD_RATE 0
28 #endif
29
30 /// UART BAUDRATE 921600bps
31 #if (PLF_HW_ASIC == 1)
32 #define UART_BAUDRATE 921600
33 #else
34 #define UART_BAUDRATE 3250000
35 #endif
36
37 /// UART Interrupt ID bits
38 #define UART_MODEM_INT 0x00
39 #define UART_NO_INT 0x01
40 #define UART_TX_INT 0x02
41 #define UART_RX_INT 0x04
42 #define UART_RX_ERROR_INT 0x06
43 #define UART_TIMEOUT_INT 0x0C
44 #define UART_ID_MASK 0x0F
45
46 int stdio_uart_inited = 0;
47 uint32_t stdio_uart_baudrate = 0;
48 stdio_uart_rx_func_t stdio_uart_rx_func = NULL;
49
stdio_uart_init(void)50 void stdio_uart_init(void)
51 {
52 while(!ipc_mutex_get(IPC_MUTEX_UART_OUTPUT)); // lock mutex
53
54 stdio_uart_dbufcfg_pack(0, //tx data buf reset
55 0, //rx data buf reset
56 0); //data buf disable
57
58 stdio_uart_irqctl_pack(0, //
59 0, //
60 0, //Line Status irq disable
61 0, //Tx irq disable
62 0); //Rx irq disable
63
64 stdio_uart_dbufth_pack(0, //tx data buffer trigger threshold
65 1); //rx data buffer trigger threshold
66
67 stdio_uart_clk_p_setf(1); //uart clk 0 = 24M, 1 = 48M
68
69 stdio_uart_format_set(8, 0, 1);
70
71 stdio_uart_baud_set(UART_BAUDRATE);
72
73 #if UART_INDEX == 2
74 /* IOMUX UART2_RX = GPIO22 UART2_TX = GPIO23 */
75 iomux_gpio_config_sel_setf(22, 0x02);
76 iomux_gpio_config_sel_setf(23, 0x02);
77 #endif
78
79 stdio_uart_dbufcfg_pack(1, //tx data buf reset
80 1, //rx data buf reset
81 1); //data buf enable
82
83 stdio_uart_rxirqen_setf(1); //enable rx interrupt
84
85 ipc_mutex_set(IPC_MUTEX_UART_OUTPUT, 1); // unlock mutex
86
87 NVIC_SetPriority(UART_IRQn, __NVIC_PRIO_LOWEST);
88 NVIC_EnableIRQ(UART_IRQn);
89
90 stdio_uart_inited = 1;
91 UART_INITED_SET();
92 }
93
stdio_uart_baud_get(void)94 uint32_t stdio_uart_baud_get(void)
95 {
96 return stdio_uart_baudrate;
97 }
98
stdio_uart_baud_set(uint32_t baud)99 void stdio_uart_baud_set(uint32_t baud)
100 {
101 if (stdio_uart_baudrate != baud) {
102 uint32_t div0, div1, div2;
103 #if (!MAX_BAUD_RATE)
104 uint32_t clk, div;
105 #endif
106 stdio_uart_baudrate = baud;
107 #if (MAX_BAUD_RATE)
108 div0 = 0x01UL;
109 div1 = div2 = 0x00UL;
110 #else //MAX_BAUD_RATE
111 #if (PLF_HW_FPGA == 1)
112 clk = DEF_CLK_FREQUENCY_52M;
113 #else
114 clk = sysctrl_clock_get(PERCLK_INDEX);
115 #endif
116 div = clk / stdio_uart_baudrate;
117 div0 = 0xFFUL & (div >> 4);
118 div1 = 0xFFUL & (div >> 12);
119 div2 = (0x01UL & div) + (0x07UL & (div >> 1)) + (0x70UL & (div << 3));
120 #endif
121 stdio_uart_divae_setf(1); //div reg access enable
122 stdio_uart_div0_set(div0);
123 stdio_uart_div1_set(div1);
124 stdio_uart_div2_set(div2);
125 stdio_uart_divae_setf(0); //div reg access disable
126 }
127 }
128
stdio_uart_format_get(uint32_t * bits,uint32_t * parity,uint32_t * stop)129 void stdio_uart_format_get(uint32_t *bits, uint32_t *parity, uint32_t *stop)
130 {
131 *bits = stdio_uart_dls_getf() + 5;
132 *parity = stdio_uart_eps_getf() | (stdio_uart_pen_getf() << 1);
133 *stop = stdio_uart_stop_getf() + 1;
134 }
135
stdio_uart_format_set(uint32_t bits,uint32_t parity,uint32_t stop)136 void stdio_uart_format_set(uint32_t bits, uint32_t parity, uint32_t stop)
137 {
138 uint8_t data_bits = (uint8_t)(bits - 5);
139 uint8_t even_bit = (uint8_t)(parity & 0x01UL);
140 uint8_t pari_bit = (uint8_t)((parity >> 1) & 0x01UL);
141 uint8_t stop_bit = (uint8_t)(stop - 1);
142 stdio_uart_dfmtcfg_pack(0, //div mode sel
143 0, //divisor register access enable 0 = disable 1 = enable
144 0, //break
145 even_bit, //parity, 1 for even
146 pari_bit, //parity enable
147 stop_bit, //stop bits 0 = 1 bit, 1 = 2 bits
148 data_bits); //data bits 0 = 5 bits, 1 = 6 bits, 2 = 7 bits, 3 = 8 bits
149 }
150
stdio_uart_putc(char ch)151 void stdio_uart_putc(char ch)
152 {
153 while (stdio_uart_tx_dbuf_full_getf());
154 stdio_uart_txdata_setf(ch);
155 }
156
stdio_uart_getc(void)157 char stdio_uart_getc(void)
158 {
159 while (stdio_uart_rx_dbuf_empty_getf());
160 return ((char)stdio_uart_rxdata_getf());
161 }
162
stdio_uart_tstc(void)163 bool stdio_uart_tstc(void)
164 {
165 return stdio_uart_dr_getf();
166 }
167
stdio_uart_get_rx_count(void)168 int stdio_uart_get_rx_count(void)
169 {
170 return (stdio_uart_rx_count_getf());
171 }
172
register_stdio_uart_rx_function(stdio_uart_rx_func_t func)173 void register_stdio_uart_rx_function(stdio_uart_rx_func_t func)
174 {
175 stdio_uart_rx_func = func;
176 }
177
stdio_uart_isr(void)178 void stdio_uart_isr(void)
179 {
180 switch (stdio_uart_irqtyp_getf())
181 {
182 case UART_RX_ERROR_INT://RX Error Interrupt, highest priority
183 stdio_uart_irqsts_get();
184 break;
185 case UART_RX_INT://RX Data Ready Interrupt, second priority
186 if (stdio_uart_rx_func) {
187 stdio_uart_rx_func();
188 } else {
189 stdio_uart_rxdata_getf();
190 }
191 break;
192 case UART_TIMEOUT_INT://Char Timeout Interrupt, second priority
193 stdio_uart_rxdata_getf();
194 break;
195 case UART_TX_INT://TX Empty Interrupt, third priority
196 break;
197 case UART_MODEM_INT://Modem Interrupt, forth priority
198 stdio_uart_mdmsts_get();
199 break;
200 case UART_NO_INT://No Interrupt
201 break;
202 default:
203 break;
204 }
205 }
206 /*chipsea_ohos function console log output*/
__io_putchar(int ch)207 int __io_putchar(int ch)
208 {
209 while (stdio_uart_tx_dbuf_full_getf());
210 stdio_uart_txdata_setf((uint8_t)ch);
211
212 return ch;
213 }
214
uart0_send_byte(uint8_t ch)215 void uart0_send_byte(uint8_t ch)
216 {
217 while (stdio_uart_tx_dbuf_full_getf());
218 stdio_uart_txdata_setf((uint8_t)ch);
219 }
uart0_send_data(uint8_t * data,int len)220 void uart0_send_data(uint8_t *data, int len)
221 {
222 int i;
223 for(i = 0; i < len; i++)
224 {
225 uart0_send_byte(data[i]);
226 }
227 }
228 #if 0
229 int _write(int fd, char *buffer, int size){
230 (void)uart0_send_data((uint8_t *)buffer, size);
231 return size;
232 }
233 #endif
234 /*chipsea_ohos function end*/
235