-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdrvSerial.c
146 lines (112 loc) · 4.71 KB
/
drvSerial.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
// -----------------------------------------------------------------------
// drvSerial.c -> implementação do driver da serial
// Autor: Lucas Carvalho de Sousa
// lucas.c.s at unifei.edu.br
// -----------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// -----------------------------------------------------------------------
#include "drvSerial.h"
// variável utilizada para auto-referência do driver
static driver thisDriver ;
// quantidade de funções neste driver
static ptrFuncDrv this_functions[SERIAL_END] ;
// resposta da chamada de outro driver
static process *callBack ;
// valor armazenado da última transmissão de dados via serial
static unsigned char valueTx ;
// valor armazenado da última recepção de dados via serial
static unsigned char valueRx ;
// indica se o buffer da serial está cheio ou não
static unsigned char bufferFull ;
char startSerialTx(void *parameters) {
// verifica se existe algum dado que ainda não foi escrito na serial
if (bufferFull == 0) {
valueTx = (unsigned char)parameters ;
// indica que existe um dado a ser escrito na serial
bufferFull = 1 ;
// ativa interrupção de transmissão EUSART
BitClr(PIE1, 4) ;
return OK ;
}
return FAIL ;
}
// retorna o valor lido na serial em uma variável passada como parâmetro
char serialRxReturnLastValue(void* parameters) {
(*(unsigned char*)parameters) = valueRx ;
return OK ;
}
// lê o buffer de recepção EUSART
void serialRxISR(void* parameters) {
valueRx = RCREG ;
kernelAddProc(callBack) ;
}
// rotina de tratamento de interrupção da transmissão de dados da serial
void serialTxISR() {
// desativa interrupção de transmissão EUSART
BitClr(PIE1, 4) ;
// escreve no buffer de transmissão EUSART
TXREG = valueTx ;
// indica que não existe dado a ser escrito na serial
bufferFull = 0 ;
}
// habilita recepçsão de dados serial por interrupção
char enableSerialRxInterrupt(void* parameters) {
// configura a função de retorno para interrupção de recepção EUSART
callDriver(DRV_INTERRUPT, INT_SERIAL_RXSET, (void*)serialRxISR) ;
// configura a função de retorno para o programa principal em caso de um tratamento de interrupção
callBack = parameters ;
//ativa interrupção de recepção EUSART
BitSet(PIE1, 5) ;
return OK ;
}
// habilita tranmissão de dados serial por interrupção
char enableSerialTxInterrupt(void* parameters) {
//seta a função de retorno para o driver de serial em caso de uma interrupção
callDriver(DRV_INTERRUPT, INT_SERIAL_TXSET, (void*)serialTxISR) ;
// A interrupção de transmissão EUSART ocorre quando o buffer de transmissão esta preparado para _
// receber um dado (buffer vazio), ou seja, enquanto não enchermos o buffer (operação de escrita) a interrupção ocorrerá, por _
// isso a linha abaixo esta comentada.
//BitSet(PIE1, 4) ;
return OK ;
}
// inicialização do driver
char initSerial(void* parameters) {
thisDriver.drv_id = *((char*) parameters) ;
this_functions[SERIAL_WRITE] = startSerialTx ;
this_functions[SERIAL_INT_RX_EN] = enableSerialRxInterrupt ;
this_functions[SERIAL_INT_TX_EN] = enableSerialTxInterrupt ;
this_functions[SERIAL_LAST_VALUE] = serialRxReturnLastValue ;
// configura a serial:
// transmissão de dados da serial
TXSTA = 0b00101100 ;
// recepção de dados da serial
RCSTA = 0b10010000 ;
// sistema de velocidade da serial
BAUDCON = 0b00001000 ;
// velocidade de transmissão para 57600bps
SPBRGH = 0x00 ;
SPBRG = 0x42 ;
//pino de recepção de dados
BitSet(TRISC,6) ;
// pino de envio de dados
BitClr(TRISC,7) ;
// indica que não há informação no buffer
bufferFull = 0 ;
// inicializa, por padrão, as interrupção geradas pelo driver desativadas
BitClr(PIE1, 5) ;
BitClr(PIE1, 4) ;
return OK ;
}
// função de auto-referência
driver* getSerialDriver(void) {
thisDriver.drv_init = initSerial ;
thisDriver.func_ptr = (ptrFuncDrv*) &this_functions ;
return &thisDriver ;
}