-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart.c
201 lines (180 loc) · 3.95 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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
* uart.c
*
* Created on: 23/07/2019
* Author: Evandro Teixeira
*/
#include "uart.h"
/**
*
*/
void (*uart_irq)(void);
/**
* @brief
* @param uartch
* @param pins
* @param sysclk
* @param baud
* @return
*/
bool uart_init (UART0_MemMapPtr uartch,uart_pins_t pins, uint32_t sysclk, uint32_t baud)
{
register uint16_t sbr;
uint8_t temp;
bool ret = false;
if(uartch == UART0)
{
SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
// UART0 clock source select
// Selects the clock source for the UART0 transmit and receive clock.
// 00 Clock disabled
// 01 MCGFLLCLK clock
// 10 OSCERCLK clock
// 11 MCGIRCLK clock
SIM_SOPT2 &= ~SIM_SOPT2_UART0SRC_MASK; // Clear SIM_SOPT2
SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1); // 01 MCGFLLCLK clock
switch(pins)
{
case Option_Pins_0:
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; // Turn on clock to B module
PORTB_PCR1 = PORT_PCR_ISF_MASK | PORT_PCR_MUX(3); // Set PTB1 to mux 3 [RX]
PORTB_PCR2 = PORT_PCR_ISF_MASK | PORT_PCR_MUX(3); // Set PTB2 to mux 3 [TX]
break;
case Option_Pins_1:
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; // Turn on clock to B module
PORTB_PCR3 = PORT_PCR_ISF_MASK | PORT_PCR_MUX(3); // Set PTB3 to mux 3 [TX]
PORTB_PCR4 = PORT_PCR_ISF_MASK | PORT_PCR_MUX(3); // Set PTB4 to mux 3 [RX]
default:
break;
}
/* Make sure that the transmitter and receiver are disabled while we change settings.*/
UART0_C2_REG(uartch) &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK );
/* Configure the uart for 8-bit mode, no parity */
UART0_C1_REG(uartch) = 0; /* We need all default settings, so entire register is cleared */
/* Calculate baud settings */
temp = UART0_C4;
temp = (temp & UART0_C4_OSR_MASK) + 1;
sbr = (uint16_t)((sysclk)/(baud * (temp)));
/* Save off the current value of the uartx_BDH except for the SBR field */
temp = UART0_BDH_REG(uartch) & ~(UART0_BDH_SBR(0x1F));
UART0_BDH_REG(uartch) = temp | UART0_BDH_SBR(((sbr & 0x1F00) >> 8));
UART0_BDL_REG(uartch) = (uint8_t)(sbr & UART0_BDL_SBR_MASK);
/* Enable receiver and transmitter */
UART0_C2_REG(uartch) |= (UART0_C2_TE_MASK | UART0_C2_RE_MASK );
ret = true;
}
else
{
ret = false;
}
return ret;
}
/**
* @brief
* @param channel
* @return
*/
char uart_getchar (UART0_MemMapPtr channel)
{
/* Wait until character has been received */
while (!(UART0_S1_REG(channel) & UART0_S1_RDRF_MASK));
/* Return the 8-bit data from the receiver */
return UART0_D_REG(channel);
}
/**
* @brief
* @param channel
* @param ch
*/
void uart_putchar (UART0_MemMapPtr channel, char ch)
{
/* Wait until space is available in the FIFO */
while(!(UART0_S1_REG(channel) & UART0_S1_TDRE_MASK));
/* Send the character */
UART0_D_REG(channel) = (uint8_t)ch;
}
/**
* @brief
* @param channel
* @param *txt
*/
void uart_put_string(UART0_MemMapPtr channel, char *txt)
{
while(*txt)
{
uart_putchar (channel,*txt);
txt++;
}
}
/**
* @brief
* @param channel
*/
bool uart_enable_irq(UART0_MemMapPtr channel)
{
bool ret = false;
if(channel == UART0)
{
UART0_C2_REG(channel) |= UART0_C2_RIE_MASK;
//UART0_C2_REG(channel) |= UART0_C2_TIE_MASK;
UART0_C2_REG(channel) |= UART0_C3_ORIE_MASK;
NVIC_EnableIRQ(UART0_IRQn);
ret = true;
}
return ret;
}
/**
* @brief
* @param channel
* @param *task
*/
bool uart_set_callback_irq(UART0_MemMapPtr channel,void (*task)(void))
{
bool ret = false;
if((channel == UART0) && (task != NULL))
{
uart_irq = task;
ret = true;
}
return ret;
}
/**
* @brief
* @param channel
* @return
*/
bool uart_clear_flag_rx(UART0_MemMapPtr channel)
{
bool ret = false;
if(channel == UART0)
{
channel->C2 |= UART0_C2_RIE_MASK;
ret = true;
}
return ret;
}
/**
* @brief
* @param channel
* @return
*/
bool uart_clear_flag_tx(UART0_MemMapPtr channel)
{
bool ret = false;
if(channel == UART0)
{
channel->C2 |= UART0_C2_TIE_MASK;
ret = true;
}
return ret;
}
/**
*
*/
void UART0_IRQHandler(void)
{
if(uart_irq != NULL)
{
uart_irq();
}
}