-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuart.c
More file actions
241 lines (229 loc) · 8.6 KB
/
uart.c
File metadata and controls
241 lines (229 loc) · 8.6 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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// U0Rx (VCP receive) connected to PA0
// U0Tx (VCP transmit) connected to PA1
#include "uart.h"
#include "fifo.h"
//#include "timer0.h"
#define GPIO_PORTA_AFSEL_R (*((volatile unsigned long *)0x40004420))
#define GPIO_PORTA_DEN_R (*((volatile unsigned long *)0x4000451C))
#define GPIO_PORTA_AMSEL_R (*((volatile unsigned long *)0x40004528))
#define GPIO_PORTA_PCTL_R (*((volatile unsigned long *)0x4000452C))
#define UART0_DR_R (*((volatile unsigned long *)0x4000C000))
#define UART0_FR_R (*((volatile unsigned long *)0x4000C018))
#define UART0_IBRD_R (*((volatile unsigned long *)0x4000C024))
#define UART0_FBRD_R (*((volatile unsigned long *)0x4000C028))
#define UART0_LCRH_R (*((volatile unsigned long *)0x4000C02C))
#define UART0_CTL_R (*((volatile unsigned long *)0x4000C030))
#define UART0_IFLS_R (*((volatile unsigned long *)0x4000C034))
#define UART0_IM_R (*((volatile unsigned long *)0x4000C038))
#define UART0_RIS_R (*((volatile unsigned long *)0x4000C03C))
#define UART0_ICR_R (*((volatile unsigned long *)0x4000C044))
#define UARTIM (*((volatile unsigned long *)0x4000C038))
#define UART_FR_TXFF 0x00000020 // UART Transmit FIFO Full
#define UART_FR_RXFE 0x00000010 // UART Receive FIFO Empty
#define UART_LCRH_WLEN_8 0x00000060 // 8 bit word length
#define UART_IFLS_RX1_8 0x00000000 // RX FIFO >= 1/8 full
#define UART_IFLS_TX1_8 0x00000000 // TX FIFO <= 1/8 full
#define UART_IM_TXIM 0x00000020 // UART Transmit Interrupt Mask
#define UART_IM_RXIM 0x00000010 // UART Receive Interrupt Mask
#define UART_LCRH_FEN 0x00000010 // UART Enable FIFOs
#define UART_CTL_UARTEN 0x00000001 // UART Enable
#define SYSCTL_RCGC1_R (*((volatile unsigned long *)0x400FE104))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
#define SYSCTL_RCGC1_UART0 0x00000001 // UART0 Clock Gating Control
#define SYSCTL_RCGC2_GPIOA 0x00000001 // port A Clock Gating Control
//------------UART_Init------------
// Initialize the UART for 115,200 baud rate (assuming 50 MHz UART clock),
// 8 bit word length, no parity bits, one stop bit, FIFOs enabled
// Input: none
// Output: none
void UART_Init(void){
SYSCTL_RCGC1_R |= SYSCTL_RCGC1_UART0; // activate UART0
SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA; // activate port A
UART0_CTL_R &= ~UART_CTL_UARTEN; // disable UART
UART0_IBRD_R = 43; // IBRD = int(50,000,000 / (16 * 500kbps)) = int(6.25)
UART0_FBRD_R = 26; // FBRD = int(0.25 * 64 + 0.5) = 16.5
// 8 bit word length (no parity bits, one stop bit, FIFOs)
UART0_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
UART0_CTL_R |= UART_CTL_UARTEN; // enable UART
GPIO_PORTA_AFSEL_R |= 0x03; // enable alt funct on PA1-0
GPIO_PORTA_DEN_R |= 0x03; // enable digital I/O on PA1-0
// configure PA1-0 as UART
GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011;
GPIO_PORTA_AMSEL_R &= ~0x03; // disable analog functionality on PA
// EnableInterrupts();
}
/*void static SoftToUart(void){
unsigned short DataToUart;
while(((UART0_FR_R&UART_FR_TXFF) != 0) && (FIFOsizeAc()>0)){
FIFOTXGet(&DataToUart);
UART_OutUDec(DataToUart);
}
}
*/
//------------UART_InChar------------
// Wait for new serial port input
// Input: none
// Output: ASCII code for key typed
unsigned char UART_InChar(void){
while((UART0_FR_R&UART_FR_RXFE) != 0);
return((unsigned char)(UART0_DR_R&0xFF));
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
void UART_OutChar(unsigned char data){
while((UART0_FR_R&UART_FR_TXFF) != 0);
UART0_DR_R = data;
}
//------------UART_OutString------------
// Output String (NULL termination)
// Input: pointer to a NULL-terminated string to be transferred
// Output: none
void UART_OutString(char *pt){
while(*pt){
UART_OutChar(*pt);
pt++;
}
}
//------------UART_InUDec------------
// InUDec accepts ASCII input in unsigned decimal format
// and converts to a 32-bit unsigned number
// valid range is 0 to 4294967295 (2^32-1)
// Input: none
// Output: 32-bit unsigned number
// If you enter a number above 4294967295, it will return an incorrect value
// Backspace will remove last digit typed
unsigned long UART_InUDec(void){
unsigned long number=0, length=0;
char character;
character = UART_InChar();
while(character != CR){ // accepts until <enter> is typed
// The next line checks that the input is a digit, 0-9.
// If the character is not 0-9, it is ignored and not echoed
if((character>='0') && (character<='9')) {
number = 10*number+(character-'0'); // this line overflows if above 4294967295
length++;
UART_OutChar(character);
}
// If the input is a backspace, then the return number is
// changed and a backspace is outputted to the screen
else if((character==BS) && length){
number /= 10;
length--;
UART_OutChar(character);
}
character = UART_InChar();
}
return number;
}
//-----------------------UART_OutUDec-----------------------
// Output a 32-bit number in unsigned decimal format
// Input: 32-bit number to be transferred
// Output: none
// Variable format 1-10 digits with no space before or after
void UART_OutUDec(unsigned long n){
// This function uses recursion to convert decimal number
// of unspecified length as an ASCII string
if(n >= 10){
UART_OutUDec(n/10);
n = n%10;
}
UART_OutChar(n+'0'); /* n is between 0 and 9 */
}
//---------------------UART_InUHex----------------------------------------
// Accepts ASCII input in unsigned hexadecimal (base 16) format
// Input: none
// Output: 32-bit unsigned number
// No '$' or '0x' need be entered, just the 1 to 8 hex digits
// It will convert lower case a-f to uppercase A-F
// and converts to a 16 bit unsigned number
// value range is 0 to FFFFFFFF
// If you enter a number above FFFFFFFF, it will return an incorrect value
// Backspace will remove last digit typed
unsigned long UART_InUHex(void){
unsigned long number=0, digit, length=0;
char character;
character = UART_InChar();
while(character != CR){
digit = 0x10; // assume bad
if((character>='0') && (character<='9')){
digit = character-'0';
}
else if((character>='A') && (character<='F')){
digit = (character-'A')+0xA;
}
else if((character>='a') && (character<='f')){
digit = (character-'a')+0xA;
}
// If the character is not 0-9 or A-F, it is ignored and not echoed
if(digit <= 0xF){
number = number*0x10+digit;
length++;
UART_OutChar(character);
}
// Backspace outputted and return value changed if a backspace is inputted
else if((character==BS) && length){
number /= 0x10;
length--;
UART_OutChar(character);
}
character = UART_InChar();
}
return number;
}
//--------------------------UART_OutUHex----------------------------
// Output a 32-bit number in unsigned hexadecimal format
// Input: 32-bit number to be transferred
// Output: none
// Variable format 1 to 8 digits with no space before or after
void UART_OutUHex(unsigned long number){
// This function uses recursion to convert the number of
// unspecified length as an ASCII string
if(number >= 0x10){
UART_OutUHex(number/0x10);
UART_OutUHex(number%0x10);
}
else{
if(number < 0xA){
UART_OutChar(number+'0');
}
else{
UART_OutChar((number-0x0A)+'A');
}
}
}
//------------UART_InString------------
// Accepts ASCII characters from the serial port
// and adds them to a string until <enter> is typed
// or until max length of the string is reached.
// It echoes each character as it is inputted.
// If a backspace is inputted, the string is modified
// and the backspace is echoed
// terminates the string with a null character
// uses busy-waiting synchronization on RDRF
// Input: pointer to empty buffer, size of buffer
// Output: Null terminated string
// -- Modified by Agustinus Darmawan + Mingjie Qiu --
void UART_InString(char *bufPt, unsigned short max) {
int length=0;
char character;
character = UART_InChar();
while(character != CR){
if(character == BS){
if(length){
bufPt--;
length--;
UART_OutChar(BS);
}
}
else if(length < max){
*bufPt = character;
bufPt++;
length++;
UART_OutChar(character);
}
character = UART_InChar();
}
*bufPt = 0;
}