-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart.c
179 lines (164 loc) · 4.52 KB
/
uart.c
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
#include <xc.h>
#include <stdio.h>
#include "file.h"
#include "test.h"
#include "uart.h"
/**
* File des caractères reçus.
* La file est peuplée par {@link #uartReception} et
* vidée par {@link #uartGetCh}.
*/
File fileReception;
/**
* File des caractères à transmettre.
* La file est peuplée par {@link #uartPutch} et
* vidée par {@link uartTransmission}.
*/
File fileTransmission;
typedef enum {
UART_TRANSMISSION_EN_REPOS,
UART_TRANSMISSION_EN_COURS
} UartStatus;
/**
* État actuel de la transmission.
*/
UartStatus uartEtat = UART_TRANSMISSION_EN_REPOS;
/**
* Ajoute un caractère à la file de transmission.
* Si la file de transmission est pleine, la méthode attend qu'il
* y ait de la place.
* @param data Le caractère à placer.
*/
void uartPutch(char data) {
if (uartEtat == UART_TRANSMISSION_EN_REPOS) {
uartEtat = UART_TRANSMISSION_EN_COURS;
TXREG1 = data;
PIE1bits.TX1IE = 1;
} else {
while (fileEstPleine(&fileTransmission));
fileEnfile(&fileTransmission, data);
}
}
/**
* Indique qu'il n'y a plus de caractères à transmettre.
* @return 255 si il n'y a plus de caractères à transmettre.
* @see uartTransmission
*/
unsigned char uartCaracteresDisponiblesPourTransmission() {
if (fileEstVide(&fileTransmission)) {
uartEtat = UART_TRANSMISSION_EN_REPOS;
return 0;
} else {
return 255;
}
}
/**
* Récupère un caractère de la file de réception.
* Si la file de réception est vide, la méthode attend qu'un
* caractère soit disponible.
* @return Un caractère de la file de réception
*/
char uartGetch() {
unsigned char n = 0;
while(fileEstVide(&fileReception)) {
n++;
};
return fileDefile(&fileReception);
}
/**
* Fonction à appeler chaque fois que la UART reçoit un caractère.
* Cette fonction est normalement appelée depuis la routine de gestion
* des interruptions, en réponse à une interruption de réception.
* <pre>
* void interrupt interruptions() {
* if (PIR1bits.RC1IF) {
* uartReception();
* }
* }
* </pre>
* @param c Le caractère reçu.
*/
void uartReception() {
fileEnfile(&fileReception, RCREG1);
}
/**
* Fonction à appeler pour récupérer le prochain caractère à transmettre
* à travers la UART.
* Cette fonction est typiquement appelée depuis la routine de transmission
* des interruptions, en réponse à une interruption de transmission.
* <pre>
* void interrupt interruptions() {
* if (IPR1bits.TX1IF) {
* uartTransmission();
* }
* }
* </pre>
* @return Le caractère à envoyer.
*/
void uartTransmission() {
if (uartCaracteresDisponiblesPourTransmission()) {
TXREG1 = fileDefile(&fileTransmission);
} else {
PIE1bits.TX1IE = 0;
}
}
/**
* Réinitialise la UART.
*/
void uartReinitialise() {
fileReinitialise(&fileReception);
fileReinitialise(&fileTransmission);
uartEtat = UART_TRANSMISSION_EN_REPOS;
}
#ifndef TEST
/**
* Implémentation d'une fonction système qui est appelée par <code>printf</code>.
* Cette implémentation ajoute le caractère à la file de transmission.
* @param data Le code ASCII du caractère à afficher.
*/
void putch(char data) {
uartPutch(data);
}
/**
* Implémentation d'une fonction système qui est appelée par <code>scanf</code>,
* <code>getc</code>, <code>getchar</code>, etc.
* Cette implémentation récupère le caractère à la file de réception.
* @param data Le code ASCII du récupéré.
*/
char getche() {
char data = getch();
putch(data);
return data;
}
/**
* Implémentation d'une fonction système qui est appelée par <code>scanf</code>,
* <code>getc</code>, <code>getchar</code>, etc.
* Cette implémentation récupère le caractère à la file de réception.
* @param data Le code ASCII du récupéré.
*/
char getch() {
return uartGetch();
}
#endif
#ifdef TEST
void testUartTransmission() {
uartReinitialise();
uartPutch('A');
uartPutch('T');
testeEgaliteChars ("UPAT00", uartEtat, UART_TRANSMISSION_EN_COURS);
testeEgaliteChars ("UPAT01", dernierCaractereTransmis, 'A');
testeEgaliteChars ("UPAT02", uartTransmission(), 'T');
testeEgaliteEntiers("UPAT03", uartCaracteresDisponiblesPourTransmission(), 0);
}
void testUartReception() {
uartReinitialise();
uartReception('A');
uartReception('T');
testeEgaliteChars("UARC01", uartGetch(), 'A');
testeEgaliteChars("UARC02", uartGetch(), 'T');
}
void testUart() {
testUartTransmission();
testUartReception();
}
#endif