-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuart.c
144 lines (122 loc) · 4.7 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
#include "uart.h"
xQueueHandle qUART0;
xSemaphoreHandle sUART0;
xSemaphoreHandle mutexTx0;
xSemaphoreHandle mutexRx0;
QueueHandle_t qUART0Tx;
extern void UART_IRQHandler(void *param){
(void)param;
uint32_t ui32Status = MAP_UARTIntStatus(UART0_BASE, true);
char uartchar;
signed portBASE_TYPE pxHigherPriorityTaskWokenTX = pdFALSE;
signed portBASE_TYPE pxHigherPriorityTaskWokenRX = pdFALSE;
UARTIntClear(UART0_BASE, ui32Status);
if(UART_INT_RX & ui32Status){
while(MAP_UARTCharsAvail(UART0_BASE)){
uartchar = (char)MAP_UARTCharGetNonBlocking(UART0_BASE);
xQueueSendToBackFromISR(qUART0,&uartchar,&pxHigherPriorityTaskWokenRX);
}
}
if(UART_INT_TX & ui32Status){
MAP_UARTIntDisable(UART0_BASE, UART_INT_TX);
xSemaphoreGiveFromISR(sUART0,&pxHigherPriorityTaskWokenTX);
}
if((pxHigherPriorityTaskWokenTX == pdTRUE)||(pxHigherPriorityTaskWokenRX == pdTRUE)){
portYIELD();
}
}
void vUartInit(void *param){
(void)param;
sUART0 = xSemaphoreCreateBinary();
if( sUART0 == NULL ){
/* There was insufficient FreeRTOS heap available for the semaphore to
be created successfully. */
vTaskSuspend(NULL);
}
else
{
mutexTx0 = xSemaphoreCreateMutex();
if( mutexTx0 == NULL ){
/* There was insufficient FreeRTOS heap available for the semaphore to
be created successfully. */
vSemaphoreDelete( sUART0);
vTaskSuspend(NULL);
}else{
qUART0 = xQueueCreate(128, sizeof(char));
if( qUART0 == NULL ){
/* There was insufficient FreeRTOS heap available for the queue to
be created successfully. */
vSemaphoreDelete( sUART0);
vSemaphoreDelete( mutexTx0);
vTaskSuspend(NULL);
}else
{
taskENTER_CRITICAL();
/*#if UART_STRING == UART_QUEUE
qUART0Tx = xQueueCreate(128, sizeof(char));
#endif
*///
// Enable the peripherals used by this example.
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Set GPIO A0 and A1 as UART pins.
MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Configure the UART for 115,200, 8-N-1 operation.
MAP_UARTConfigSetExpClk(UART0_BASE, configCPU_CLOCK_HZ, 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
MAP_UARTFIFODisable(UART0_BASE);
//
// Enable the UART interrupt.
MAP_IntPrioritySet(INT_UART0, 0xC0);
MAP_IntEnable(INT_UART0);
MAP_UARTIntEnable(UART0_BASE, UART_INT_RX);
taskEXIT_CRITICAL();
}
}
}
}
void FreeRTOS_write(uint8_t *pui8Data, uint32_t ui32Size){
// espera indefinidamente pelo recurso
if(xSemaphoreTake(mutexRx0, portMAX_DELAY) == pdTRUE){
while(1){
if(xQueueReceive(qUART0, &pui8Data, portMAX_DELAY) == pdTRUE){
ui32Size--;
}
}
xSemaphoreGive(mutexRx0);
}
}
void UARTIntHandler(void){
unsigned int ui32Status;
portBASE_TYPE pxHigherPriorityTaskWokenRX = pdFALSE;
portBASE_TYPE pxHigherPriorityTaskWokenTX = pdFALSE;
char data;
// le flags de interrupcao
ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
// limpa flags das interrupcoes acionadas
UARTIntClear(UART0_BASE, ui32Status);
// Se for interrupcao de recepcao
if ((ui32Status&UART_INT_RX) == UART_INT_RX){
// le o caractere recebido
//data = UART_DATA_R;
xQueueSendToBackFromISR(qUART0, &data, &pxHigherPriorityTaskWokenRX);
}
// Se for interrupcao de transmissao
if ((ui32Status&UART_INT_TX) == UART_INT_TX){
ROM_UARTIntDisable(UART0_BASE, UART_INT_TX);
/* Informa ao driver que o buffer de transmissao esta vazio
* e pronto para o proximo caractere */
xSemaphoreGiveFromISR(sUART0, &pxHigherPriorityTaskWokenRX);
}
/* Verifica se o semaforo ou a fila acordam uma tarefa de maior
* prioridade que a tarefa sendo executada atualmente*/
if ((pxHigherPriorityTaskWokenRX == pdTRUE) || (pxHigherPriorityTaskWokenTX == pdTRUE)){
// Se acordou, chama interrupcao de software para a troca de contexto
portYIELD();
}
}