1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
26
27
28
34
35
37
40
41
44
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
71
72
73
74
79
80
81
82
83
86
87
88
89
90
91
92
93
94
99
100
101
102
107
108
109
110
111
112
113
118
119
120
121
122
123
124
125
126
132
142
143
144
145
146
147
148
149
150
151
152
153
154
155
159
163
167
171
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
200
204
206
207
208
209
210
211
216
217
218
219
220
221
222
223
224
227
231
232
233
234
235
236
237
245
246
247
248
253
254
255
256
257
258
259
263
264
266
267
268
269
270
271
272
273
274
275
276
277
282
283
284
285
286
287
288
289
290
291
292
293
294
295
299
300
305
311
312
319
320
321
326
327
328
340
341
342
357
358
359
380
381
382
383
384
385
386
391
392
394
395
396
397
398
403
404
405
406
407
408
411
412
413
414
415
420
421
422
427
432
433
438
/* ... */
#include "main.h"
Includes
#define APP_RX_DATA_SIZE 2048
#define APP_TX_DATA_SIZE 2048
Private define
USBD_CDC_LineCodingTypeDef LineCoding = {
115200,
0x00,
0x00,
0x08
...};
uint8_t UserRxBuffer[APP_RX_DATA_SIZE];
/* ... */
uint8_t UserTxBuffer[APP_TX_DATA_SIZE];
/* ... */
uint32_t UserTxBufPtrIn = 0;
/* ... */
uint32_t UserTxBufPtrOut = 0;
/* ... */
UART_HandleTypeDef UartHandle;
TIM_HandleTypeDef TimHandle;
extern USBD_HandleTypeDef USBD_Device;
Private variables
static int8_t CDC_Itf_Init(void);
static int8_t CDC_Itf_DeInit(void);
static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t * pbuf, uint16_t length);
static int8_t CDC_Itf_Receive(uint8_t* pbuf, uint32_t *Len);
static int8_t CDC_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
static void Error_Handler(void);
static void ComPort_Config(void);
static void TIM_Config(void);
USBD_CDC_ItfTypeDef USBD_CDC_fops = {
CDC_Itf_Init,
CDC_Itf_DeInit,
CDC_Itf_Control,
CDC_Itf_Receive,
CDC_Itf_TransmitCplt
...};
Private function prototypes
/* ... */
static int8_t CDC_Itf_Init(void)
{
/* ... */
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_UART_Init(&UartHandle) != HAL_OK) { ... }
if (HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1) != HAL_OK)
{
Error_Handler();
}if (HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1) != HAL_OK) { ... }
TIM_Config();
if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK) { ... }
USBD_CDC_SetTxBuffer(&USBD_Device, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&USBD_Device, UserRxBuffer);
return (USBD_OK);
}{ ... }
/* ... */
static int8_t CDC_Itf_DeInit(void)
{
if (HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_UART_DeInit(&UartHandle) != HAL_OK) { ... }
return (USBD_OK);
}{ ... }
/* ... */
static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t * pbuf, uint16_t length)
{
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_SEND_ENCAPSULATED_COMMAND:
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
case CDC_SET_COMM_FEATURE:
break;
case CDC_SET_COMM_FEATURE:
case CDC_GET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
case CDC_CLEAR_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
case CDC_SET_LINE_CODING:
LineCoding.bitrate = (uint32_t) (pbuf[0] | (pbuf[1] << 8) |
(pbuf[2] << 16) | (pbuf[3] << 24));
LineCoding.format = pbuf[4];
LineCoding.paritytype = pbuf[5];
LineCoding.datatype = pbuf[6];
ComPort_Config();
break;
case CDC_SET_LINE_CODING:
case CDC_GET_LINE_CODING:
pbuf[0] = (uint8_t) (LineCoding.bitrate);
pbuf[1] = (uint8_t) (LineCoding.bitrate >> 8);
pbuf[2] = (uint8_t) (LineCoding.bitrate >> 16);
pbuf[3] = (uint8_t) (LineCoding.bitrate >> 24);
pbuf[4] = LineCoding.format;
pbuf[5] = LineCoding.paritytype;
pbuf[6] = LineCoding.datatype;
break;
case CDC_GET_LINE_CODING:
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SET_CONTROL_LINE_STATE:
case CDC_SEND_BREAK:
break;
case CDC_SEND_BREAK:
default:
break;default
}switch (cmd) { ... }
return (USBD_OK);
}{ ... }
/* ... */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)
{
uint32_t buffptr;
uint32_t buffsize;
if (UserTxBufPtrOut != UserTxBufPtrIn)
{
if (UserTxBufPtrOut > UserTxBufPtrIn)
{
buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOut;
...}
else
{
buffsize = UserTxBufPtrIn - UserTxBufPtrOut;
}else { ... }
buffptr = UserTxBufPtrOut;
USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t *) & UserTxBuffer[buffptr],
buffsize);
if (USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK)
{
UserTxBufPtrOut += buffsize;
if (UserTxBufPtrOut == APP_RX_DATA_SIZE)
{
UserTxBufPtrOut = 0;
}if (UserTxBufPtrOut == APP_RX_DATA_SIZE) { ... }
}if (USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK) { ... }
}if (UserTxBufPtrOut != UserTxBufPtrIn) { ... }
}{ ... }
/* ... */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
{
UserTxBufPtrIn++;
if (UserTxBufPtrIn == APP_RX_DATA_SIZE)
{
UserTxBufPtrIn = 0;
}if (UserTxBufPtrIn == APP_RX_DATA_SIZE) { ... }
/* ... */
HAL_UART_Receive_IT(huart, (uint8_t *) (UserTxBuffer + UserTxBufPtrIn), 1);
}{ ... }
/* ... */
static int8_t CDC_Itf_Receive(uint8_t * Buf, uint32_t * Len)
{
HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
return (USBD_OK);
}{ ... }
/* ... */
static int8_t CDC_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
return (0);
}{ ... }
/* ... */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)
{
/* ... */
USBD_CDC_ReceivePacket(&USBD_Device);
}{ ... }
/* ... */
static void ComPort_Config(void)
{
if (HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_UART_DeInit(&UartHandle) != HAL_OK) { ... }
switch (LineCoding.format)
{
case 0:
UartHandle.Init.StopBits = UART_STOPBITS_1;
break;case 0:
case 2:
UartHandle.Init.StopBits = UART_STOPBITS_2;
break;case 2:
default:
UartHandle.Init.StopBits = UART_STOPBITS_1;
break;default
}switch (LineCoding.format) { ... }
switch (LineCoding.paritytype)
{
case 0:
UartHandle.Init.Parity = UART_PARITY_NONE;
break;case 0:
case 1:
UartHandle.Init.Parity = UART_PARITY_ODD;
break;case 1:
case 2:
UartHandle.Init.Parity = UART_PARITY_EVEN;
break;case 2:
default:
UartHandle.Init.Parity = UART_PARITY_NONE;
break;default
}switch (LineCoding.paritytype) { ... }
switch (LineCoding.datatype)
{
case 0x07:
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
break;case 0x07:
case 0x08:
if (UartHandle.Init.Parity == UART_PARITY_NONE)
{
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
}if (UartHandle.Init.Parity == UART_PARITY_NONE) { ... }
else
{
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
}else { ... }
break;case 0x08:
default:
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
break;default
}switch (LineCoding.datatype) { ... }
UartHandle.Init.BaudRate = LineCoding.bitrate;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_UART_Init(&UartHandle) != HAL_OK) { ... }
/* ... */
HAL_UART_Receive_IT(&UartHandle, (uint8_t *) (UserTxBuffer + UserTxBufPtrIn),
1);
}{ ... }
/* ... */
static void TIM_Config(void)
{
TimHandle.Instance = TIMx;
/* ... */
TimHandle.Init.Period = (CDC_POLLING_INTERVAL * 1000) - 1;
TimHandle.Init.Prescaler = 84 - 1;
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
{
Error_Handler();
}if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK) { ... }
}{ ... }
/* ... */
void HAL_UART_ErrorCallback(UART_HandleTypeDef * UartHandle)
{
Error_Handler();
}{ ... }
/* ... */
static void Error_Handler(void)
{
}{ ... }