凌云物联网实验室ISKBoard(IoT Starter Kits Board)开发板项目源码
guowenxue
2023-04-07 6ddecc5e53def103eec427a61f2de308552735f5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/**********************************************************************
*   Copyright: (C)2023 LingYun IoT System Studio
*      Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292
* Description: ISKBoard RS232/TTL/RS485 Hardware Abstract Layer driver
*
*   ChangeLog:
*        Version    Date       Author            Description
*        V1.0.0  2023.04.3    GuoWenxue      Release initial version
***********************************************************************/
 
#include "comport.h"
#include "miscdev.h"
 
//#define CONFIG_COMPORT_DEBUG
 
#ifdef  CONFIG_COMPORT_DEBUG
#define com_print(format,args...) printf(format, ##args)
#else
#define com_print(format,args...) do{} while(0)
#endif
 
#define ARRAY_SIZE(x)   sizeof(x)/sizeof(x[0])
 
comport_t  comports[] = {
        {.fd=-1, .devname="Debug", .huart=&huart1   }, // Debug console
        {.fd=-1, .devname="WiFi",  .huart=&huart2   }, // ESP8266(WiFi)/ESP32(WiFi/BLE)
        {.fd=-1, .devname="RS232", .huart=&huart3   }, // RS232/TTL/MikroBUS
        {.fd=-1, .devname="RS485", .huart=&hlpuart1 }, // RS485
};
 
 
static inline comport_t *comport_find(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
    int                     i;
 
    for(i=0; i<ARRAY_SIZE(comports); i++)
    {
        if( huart==comports[i].huart )
        {
            comport = &comports[i];
        }
    }
 
    return comport;
}
 
comport_t *comport_init(UART_HandleTypeDef *huart, uint8_t *rxch, uint8_t *rxbuf, size_t size)
{
    comport_t              *comport = NULL;
 
    if( !huart )
        return NULL;
 
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( !comport )
        return NULL;
 
    comport->fd = 1;
    comport->huart = huart;
    comport->rxch = rxch;
    rb_init(&comport->rb, rxbuf, size);
 
    return comport;
}
 
 
/* +----------------------------------------+
 * | printf and interrupt receive functions |
 * +----------------------------------------+*/
 
/* printf() callback function on USART1 */
int __io_putchar(int ch)
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}
 
/* scanf() callback function on USART1 */
int __io_getchar(FILE *f)
{
    uint8_t ch = 0;
 
    HAL_UART_Receive(&huart1,(uint8_t *)&ch, 1, 0xFFFF);
 
    if (ch == '\r')
    {
        __io_putchar('\r');
        ch = '\n';
    }
 
    return __io_putchar(ch);
}
 
/* USART interrupt receive callback funciton */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
    uint8_t                 byte;
 
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( !comport )
    {
        goto cleanup;
    }
 
    /* Check comport receive ring buffer */
    if( comport->fd<0 || !comport->rb.buffer || ! rb_free_size(&comport->rb) )
    {
        goto cleanup;
    }
 
    /* Receive and put the byte into receive ring buffer */
    HAL_UART_Receive_IT(comport->huart, comport->rxch, 1);
    rb_write(&comport->rb, comport->rxch, 1);
 
    return ;
 
cleanup:
    HAL_UART_Receive_IT(huart, &byte, 1);
    return ;
}
 
/* +------------------------+
 * | UART/TTL API functions |
 * +------------------------+*/
 
comport_t *comport_open(UART_HandleTypeDef *huart)
{
    comport_t              *comport = NULL;
 
    if( !huart )
        return NULL;
 
    /* Find the corresponding comport in the array */
    comport = comport_find(huart);
    if( comport )
        comport->fd = 1;
 
    return comport;
}
 
void comport_flush(comport_t *comport)
{
    if( !comport || !comport->huart)
        return;
 
    if( comport->rb.buffer )
    {
        rb_clear( &comport->rb );
    }
 
    return;
}
 
void comport_term(comport_t *comport)
{
    if( !comport || !comport->huart)
        return;
 
    comport->fd = -1;
 
    if( comport->rb.buffer )
    {
        rb_clear( &comport->rb );
    }
 
    return;
}
 
int comport_send(comport_t *comport, char *data, int bytes)
{
    if( !comport || !data || bytes<=0 )
        return -1;
 
    com_print("Send %d bytes data: %s\r\n", bytes, data);
    HAL_UART_Transmit(comport->huart, (uint8_t *)data, bytes, 0xFFFF);
 
    return bytes;
}
 
int comport_recv(comport_t *comport, char *buf, int size, uint32_t timeout)
{
    uint32_t          tickstart = 0;
    size_t            bytes = 0; 
 
    if( !comport || !buf || size<=0 )
        return -1;
 
    if( !comport->rb.buffer )
        return -2;
 
    tickstart = HAL_GetTick();
 
    while((HAL_GetTick() - tickstart) < timeout)
    {
        bytes = rb_data_size(&comport->rb);
 
        HAL_Delay( 10 );
 
        /* comport received data before but not receive in 10ms now, maybe data receive over */
        if( bytes>0 && rb_data_size(&comport->rb)==bytes )
        {
            break;
        }
    }
 
    bytes = rb_data_size(&comport->rb);
    if( !bytes )
    {
        return 0;
    }
 
    bytes = bytes>size ? size : bytes;
    rb_read(&comport->rb, (uint8_t *)buf, bytes);
    com_print("Receive %d bytes data: %s\r\n", bytes, buf);
 
    return bytes;
}
 
 
/* +------------------------+
 * |   RS485 API functions  |
 * +------------------------+*/
 
/* Direction Pin set to be high level will be send mode, and low level will be receive mode */
#define rs485_set_dirTx()   HAL_GPIO_WritePin(RS485_Dir_GPIO_Port, RS485_Dir_Pin, GPIO_PIN_SET)
#define rs485_set_dirRx()   HAL_GPIO_WritePin(RS485_Dir_GPIO_Port, RS485_Dir_Pin, GPIO_PIN_RESET)
 
comport_t *rs485_open(UART_HandleTypeDef *huart)
{
    return comport_find(huart);
}
 
void rs485_term(comport_t *comport)
{
    return comport_term(comport);
}
 
int rs485_send(comport_t *comport, char *data, int bytes)
{
    int             rv;
 
    rs485_set_dirTx();
    rv = comport_send(comport, data, bytes);
 
    rs485_set_dirRx();
    return rv;
}
 
int rs485_recv(comport_t *comport, char *buf, int size, uint32_t timeout)
{
    rs485_set_dirRx();
 
    return comport_recv(comport, buf, size, timeout);
}