• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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