1 /*
2 * Copyright (c) 2022 Hunan OpenValley Digital Industry Development Co., Ltd.
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
16 #include "iot_errno.h"
17 #include "iot_uart.h"
18
19 #include "driver/gpio.h"
20 #include "driver/uart.h"
21 #include "esp_err.h"
22
23 #ifndef portMAX_DELAY
24 #define portMAX_DELAY (TickType_t)0xffffffffUL
25 #endif
26
27 #define TXD_PIN (GPIO_NUM_4)
28 #define RXD_PIN (GPIO_NUM_5)
29
30 #define UART_ATTR_DEFAULT \
31 { \
32 115200, UART_DATA_8_BITS, UART_PARITY_DISABLE, UART_STOP_BITS_1, \
33 UART_HW_FLOWCTRL_DISABLE, UART_SCLK_APB \
34 }
35
36 typedef enum {
37 ESP_UART_BLOCK_STATE_NONE_BLOCK = 1,
38 ESP_UART_BLOCK_STATE_BLOCK,
39 } uart_block_state_e;
40
41 typedef enum {
42 UART_STATE_NOT_OPENED = 0,
43 UART_STATE_USEABLE
44 } uart_status_e;
45
46 typedef struct {
47 uart_port_t num;
48 uart_status_e uart_state;
49 uart_block_state_e tx_block_state;
50 uart_block_state_e rx_block_state;
51 uart_config_t attr;
52 uint8_t pad;
53 } uart_driver_data_t;
54
55 static uart_driver_data_t g_uart_0 = {
56 .num = UART_NUM_0,
57 .uart_state = UART_STATE_NOT_OPENED,
58 .tx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
59 .rx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
60 .attr = UART_ATTR_DEFAULT,
61 .pad = 0,
62 };
63
64 static uart_driver_data_t g_uart_1 = {
65 .num = UART_NUM_1,
66 .uart_state = UART_STATE_NOT_OPENED,
67 .tx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
68 .rx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
69 .attr = UART_ATTR_DEFAULT,
70 .pad = 0,
71 };
72
73 static uart_driver_data_t g_uart_2 = {
74 .num = UART_NUM_2,
75 .uart_state = UART_STATE_NOT_OPENED,
76 .tx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
77 .rx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK,
78 .attr = UART_ATTR_DEFAULT,
79 .pad = 0,
80 };
81
82 static const int RX_BUF_SIZE = 1024;
83 static uart_driver_data_t *g_uart[UART_NUM_MAX] = {&g_uart_0, &g_uart_1, &g_uart_2};
84
HoDataBitsToESPDataBits(IotUartIdxDataBit DataBits)85 static uart_word_length_t HoDataBitsToESPDataBits(IotUartIdxDataBit DataBits)
86 {
87 switch (DataBits) {
88 case IOT_UART_DATA_BIT_5:
89 return UART_DATA_5_BITS;
90 case IOT_UART_DATA_BIT_6:
91 return UART_DATA_6_BITS;
92 case IOT_UART_DATA_BIT_7:
93 return UART_DATA_7_BITS;
94 case IOT_UART_DATA_BIT_8:
95 return UART_DATA_8_BITS;
96 default:
97 return UART_DATA_BITS_MAX;
98 }
99 }
100
HoParityToESParity(IotUartParity Parity)101 static uart_parity_t HoParityToESParity(IotUartParity Parity)
102 {
103 switch (Parity) {
104 case IOT_UART_PARITY_NONE:
105 return UART_PARITY_DISABLE;
106 case IOT_UART_PARITY_ODD:
107 return UART_PARITY_ODD;
108 case IOT_UART_PARITY_EVEN:
109 return UART_PARITY_EVEN;
110 default:
111 assert(0);
112 }
113
114 return UART_PARITY_DISABLE;
115 }
116
HoStopBitsToESPStopBits(IotUartStopBit StopBits)117 static uart_stop_bits_t HoStopBitsToESPStopBits(IotUartStopBit StopBits)
118 {
119 switch (StopBits) {
120 case IOT_UART_STOP_BIT_1:
121 return UART_STOP_BITS_1;
122 case IOT_UART_STOP_BIT_2:
123 return UART_STOP_BITS_2;
124 default:
125 return UART_STOP_BITS_MAX;
126 }
127 }
128
HoflowCtrlToESPflowCtrl(IotFlowCtrl flowCtrl)129 static uart_hw_flowcontrol_t HoflowCtrlToESPflowCtrl(IotFlowCtrl flowCtrl)
130 {
131 switch (flowCtrl) {
132 case IOT_FLOW_CTRL_NONE:
133 return UART_HW_FLOWCTRL_DISABLE;
134 case IOT_FLOW_CTRL_RTS_CTS:
135 return UART_HW_FLOWCTRL_CTS_RTS;
136 case IOT_FLOW_CTRL_RTS_ONLY:
137 return UART_HW_FLOWCTRL_RTS;
138 case IOT_FLOW_CTRL_CTS_ONLY:
139 return UART_HW_FLOWCTRL_CTS;
140 default:
141 return UART_HW_FLOWCTRL_MAX;
142 }
143 }
144
IoTUartInit(unsigned int id,const IotUartAttribute * param)145 unsigned int IoTUartInit(unsigned int id, const IotUartAttribute *param)
146 {
147 if (id > UART_NUM_MAX || param == NULL) {
148 return IOT_FAILURE;
149 }
150
151 uart_driver_data_t *uart = g_uart[id];
152 if (uart->uart_state == UART_STATE_USEABLE) {
153 return IOT_FAILURE;
154 }
155
156 uart->attr.baud_rate = param->baudRate;
157 uart->attr.data_bits = HoDataBitsToESPDataBits(param->dataBits);
158 assert(uart->attr.data_bits != UART_DATA_BITS_MAX);
159 uart->attr.parity = HoParityToESParity(param->parity);
160 uart->attr.stop_bits = HoStopBitsToESPStopBits(param->stopBits);
161 assert(uart->attr.stop_bits != UART_STOP_BITS_MAX);
162 uart->pad = param->pad;
163
164 if (IOT_UART_BLOCK_STATE_NONE_BLOCK == param->rxBlock) {
165 uart->rx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK;
166 } else {
167 uart->rx_block_state = ESP_UART_BLOCK_STATE_BLOCK;
168 }
169
170 if (IOT_UART_BLOCK_STATE_NONE_BLOCK == param->txBlock) {
171 uart->tx_block_state = ESP_UART_BLOCK_STATE_NONE_BLOCK;
172 } else {
173 uart->tx_block_state = ESP_UART_BLOCK_STATE_BLOCK;
174 }
175
176 int ret = uart_driver_install(uart->num, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
177 ret += uart_param_config(uart->num, &(uart->attr));
178 ret += uart_set_pin(uart->num, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
179 if (ret != ESP_OK) {
180 return IOT_FAILURE;
181 }
182
183 uart->uart_state = UART_STATE_USEABLE;
184 return IOT_SUCCESS;
185 }
186
IoTUartRead(unsigned int id,unsigned char * data,unsigned int dataLen)187 int IoTUartRead(unsigned int id, unsigned char *data, unsigned int dataLen)
188 {
189 if (id > UART_NUM_MAX) {
190 return IOT_FAILURE;
191 }
192
193 uart_driver_data_t *uart = g_uart[id];
194 if (data == NULL || dataLen == 0) {
195 return IOT_FAILURE;
196 }
197
198 if (uart->uart_state == UART_STATE_NOT_OPENED) {
199 return IOT_FAILURE;
200 }
201
202 uint8_t *rd_data = data;
203 int data_received = 0;
204 int data_remaining = dataLen;
205 while (data_remaining) {
206 if (uart->rx_block_state == ESP_UART_BLOCK_STATE_BLOCK) {
207 data_received += uart_read_bytes(uart->num, (void *)(&rd_data[data_received]),
208 data_remaining, (TickType_t)portMAX_DELAY);
209 } else {
210 data_received += uart_read_bytes(uart->num, (void *)(&rd_data[data_received]), data_remaining, 0);
211 }
212
213 if (data_received < 0) {
214 return IOT_FAILURE;
215 }
216
217 data_remaining -= data_received;
218 }
219
220 return IOT_SUCCESS;
221 }
222
IoTUartWrite(unsigned int id,const unsigned char * data,unsigned int dataLen)223 int IoTUartWrite(unsigned int id, const unsigned char *data, unsigned int dataLen)
224 {
225 if (id > UART_NUM_MAX) {
226 return IOT_FAILURE;
227 }
228
229 uart_driver_data_t *uart = g_uart[id];
230 if (uart->uart_state == UART_STATE_NOT_OPENED) {
231 return IOT_FAILURE;
232 }
233
234 int txBytes = uart_write_bytes(uart->num, (const char *)data, dataLen);
235 if (uart->tx_block_state == ESP_UART_BLOCK_STATE_BLOCK) {
236 int ret = uart_wait_tx_done(uart->num, (TickType_t)portMAX_DELAY);
237 if (txBytes != dataLen || ret != ESP_OK) {
238 return IOT_FAILURE;
239 }
240 }
241
242 return IOT_SUCCESS;
243 }
244
IoTUartDeinit(unsigned int id)245 unsigned int IoTUartDeinit(unsigned int id)
246 {
247 if (id > UART_NUM_MAX) {
248 return IOT_FAILURE;
249 }
250
251 uart_driver_data_t *uart = g_uart[id];
252 if (uart->uart_state == UART_STATE_NOT_OPENED) {
253 return IOT_FAILURE;
254 }
255
256 return uart_driver_delete(uart->num);
257 }
258
IoTUartSetFlowCtrl(unsigned int id,IotFlowCtrl flowCtrl)259 unsigned int IoTUartSetFlowCtrl(unsigned int id, IotFlowCtrl flowCtrl)
260 {
261 if (id > UART_NUM_MAX) {
262 return IOT_FAILURE;
263 }
264
265 uart_driver_data_t *uart = g_uart[id];
266 uart->attr.flow_ctrl = HoflowCtrlToESPflowCtrl(flowCtrl);
267 assert(uart->attr.flow_ctrl != UART_HW_FLOWCTRL_MAX);
268 return uart_param_config(uart->num, &(uart->attr));
269 }
270