-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserial.c
More file actions
202 lines (170 loc) · 5.76 KB
/
serial.c
File metadata and controls
202 lines (170 loc) · 5.76 KB
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
/**
* @file serial.c
* @brief Implementazione delle funzioni di I/O tramite UART per STM32.
*
* Questo file contiene l'implementazione delle funzioni necessarie per
* leggere e scrivere dati tramite UART, inclusi la lettura di righe,
* l'invio di stringhe e la gestione del formato di input.
*/
#include "serial.h"
/**
* @brief Stampa una stringa su UART
*
* Questa funzione invia una stringa tramite UART, senza aggiungere newline.
*
* @param message Stringa da stampare
*/
void serial_print(char *message) {
// Utilizza la funzione HAL_UART_Transmit per inviare i caratteri della stringa
// attraverso la UART, considerando la lunghezza calcolata con strlen().
HAL_UART_Transmit(&hlpuart1, (uint8_t*) message, strlen(message),
HAL_MAX_DELAY);
}
/**
* @brief Stampa una nuova riga su UART ("\r\n")
*
* Invia un carattere di ritorno a capo seguito da newline, simile alla
* stampa di una nuova riga in un terminale.
*/
void serial_newline(void) {
// Utilizza la funzione serial_print per inviare i caratteri di ritorno a capo e newline.
serial_print("\r\n");
}
/**
* @brief Stampa una stringa seguita da una nuova riga
*
* Questa funzione invia una stringa tramite UART, seguita automaticamente
* da un ritorno a capo (`\r\n`).
*
* @param message Stringa da stampare
*/
void serial_println(char *message) {
// Stampa la stringa fornita utilizzando serial_print.
serial_print(message);
// Aggiunge una nuova riga alla fine della stringa.
serial_newline();
}
/**
* @brief Stampa una stringa formattata su UART (come printf)
*
* Questa funzione invia una stringa formattata tramite UART, simile
* alla funzione `printf`.
*
* @param format Formato della stringa
* @param ... Argomenti da formattare
* @return Numero di caratteri scritti
*/
int serial_printf(const char *format, ...) {
char buffer[256];
va_list args;
// Inizializza la lista degli argomenti variabili.
va_start(args, format);
// Scrive la stringa formattata nel buffer utilizzando vsnprintf.
int ret = vsnprintf(buffer, sizeof(buffer), format, args);
// Termina la gestione degli argomenti variabili.
va_end(args);
// Trasmette la stringa formattata tramite UART.
serial_print(buffer);
// Restituisce il numero di caratteri scritti.
return ret;
}
/**
* @brief Stampa una stringa formattata seguita da una nuova riga
*
* Questa funzione invia una stringa formattata tramite UART, seguita
* automaticamente da un ritorno a capo (`\r\n`), simile a `printf`.
*
* @param format Formato della stringa
* @param ... Argomenti da formattare
* @return Numero di caratteri scritti
*/
int serial_printfln(const char *format, ...) {
char buffer[256];
va_list args;
// Inizializza la lista degli argomenti variabili.
va_start(args, format);
// Scrive la stringa formattata nel buffer utilizzando vsnprintf.
int ret = vsnprintf(buffer, sizeof(buffer), format, args);
// Termina la gestione degli argomenti variabili.
va_end(args);
// Trasmette la stringa formattata tramite UART.
serial_print(buffer);
// Aggiunge una nuova riga alla fine della stringa trasmessa.
serial_newline();
// Restituisce il numero di caratteri scritti.
return ret;
}
/**
* @brief Legge una riga da UART con supporto a frecce sinistra/destra e backspace
*
* Questa funzione permette la lettura di una riga con un buffer di input,
* supportando la gestione del backspace per rimuovere i caratteri e
* la gestione di un terminale che simula il comportamento di frecce sinistra e destra.
*
* @param buffer Buffer dove salvare la stringa
* @param length Lunghezza massima del buffer (incluso null terminator)
*/
void serial_readline(char *buffer, int length) {
size_t i = 0;
// Itera fino a riempire il buffer o fino a rilevare un carattere di terminazione
while (i < length - 1) {
uint8_t c;
// Riceve un carattere dalla UART con un timeout massimo
if (HAL_UART_Receive(&hlpuart1, &c, 1, HAL_MAX_DELAY) == HAL_OK) {
// Se il carattere ricevuto è '\r' o '\n', termina la stringa
if (c == '\r' || c == '\n') {
buffer[i] = '\0'; // Aggiunge terminatore di stringa
serial_print("\r\n"); // Stampa ritorno a capo
break;
}
// Gestisce il backspace (127 o 8)
else if (c == 127 || c == 8) {
if (i > 0) {
i--; // Rimuove l'ultimo carattere
serial_print("\b \b"); // Emette sequenza per cancellare il carattere
}
}
// Gestisce caratteri normali
else {
buffer[i++] = c; // Aggiunge il carattere al buffer
HAL_UART_Transmit(&hlpuart1, &c, 1, HAL_MAX_DELAY); // Echo del carattere
}
}
}
buffer[i] = '\0'; // Termina la stringa con il carattere nullo
}
/**
* @brief Versione personalizzata di scanf che legge da UART
*
* Questa funzione legge una riga tramite `serial_readline()` e converte
* il formato dell'input con `sscanf()`, simile a come farebbe `scanf()`.
*
* @param format Stringa di formato come in scanf
* @param ... Argomenti variabili da riempire
* @return Numero di elementi letti con successo
*/
int serial_scanf(const char *format, ...) {
char buffer[128];
// Legge una riga di input dalla UART e la salva nel buffer.
serial_readline(buffer, sizeof(buffer));
va_list args;
// Inizializza la lista di argomenti variabili.
va_start(args, format);
// Usa sscanf per convertire il formato dell'input dal buffer in base ai parametri specificati.
int ret = vsscanf(buffer, format, args);
// Termina la gestione degli argomenti variabili.
va_end(args);
// Restituisce il numero di elementi letti con successo.
return ret;
}
/**
* @brief Pulisce lo schermo del terminale
*
* Invia una sequenza di escape per pulire lo schermo del terminale
* tramite UART, se supportato dal terminale stesso.
*/
void serial_clear(void) {
// Invia una sequenza di escape ANSI tramite UART per pulire
// lo schermo e riposizionare il cursore.
serial_print("\033[2J\033[H");
}