-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUARTints.c
More file actions
167 lines (162 loc) · 5.6 KB
/
Copy pathUARTints.c
File metadata and controls
167 lines (162 loc) · 5.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
/* UARTints.c
* Jonathan Valvano
* November 18, 2022
* Derived from uart_rw_multibyte_fifo_poll_LP_MSPM0G3507_nortos_ticlang
* uart_echo_interrupts_standby_LP_MSPM0G3507_nortos_ticlang
* PA.10 UART0 Tx to XDS Rx
* PA.11 UART0 Rx from XDS Tx
* Insert jumper J25: Connects PA10 to XDS_UART
* Insert jumper J26: Connects PA11 to XDS_UART
*/
#include <ti/devices/msp/msp.h>
#include "../inc/UART.h"
#include "../inc/Clock.h"
#include "../inc/FIFO.h"
#define PA10INDEX 20
#define PA11INDEX 21
// power Domain PD0
// for 32MHz bus clock, bus clock is 32MHz
// for 40MHz bus clock, bus clock is ULPCLK 20MHz
// for 80MHz bus clock, bus clock is ULPCLK 40MHz
// assume 40MHz bus clock, bus clock = 20MHz
// initialize UART for 115200 baud rate
// interrupt synchronization
void UART_Init(void){
// RSTCLR to GPIOA and UART0 peripherals
// bits 31-24 unlock key 0xB1
// bit 1 is Clear reset sticky bit
// bit 0 is reset gpio port
// GPIOA->GPRCM.RSTCTL = (uint32_t)0xB1000003; // called previously
UART0->GPRCM.RSTCTL = 0xB1000003;
// Enable power to GPIOA and UART0 peripherals
// PWREN
// bits 31-24 unlock key 0x26
// bit 0 is Enable Power
// GPIOA->GPRCM.PWREN = (uint32_t)0x26000001; // called previously
UART0->GPRCM.PWREN = 0x26000001;
Clock_Delay(24); // time for uart to power up
// configure PA11 PA10 as alternate UART0 function
IOMUX->SECCFG.PINCM[PA10INDEX] = 0x00000082;
//bit 7 PC connected
//bits 5-0=2 for UART0_Tx
IOMUX->SECCFG.PINCM[PA11INDEX] = 0x00040082;
//bit 18 INENA input enable
//bit 7 PC connected
//bits 5-0=2 for UART0_Rx
TxFifo_Init();
RxFifo_Init();
UART0->CLKSEL = 0x08; // bus clock
UART0->CLKDIV = 0x00; // no divide
UART0->CTL0 &= ~0x01; // disable UART0
UART0->CTL0 = 0x00020018;
// bit 17 FEN=1 enable FIFO
// bits 16-15 HSE=00 16x oversampling
// bit 14 CTSEN=0 no CTS hardware
// bit 13 RTSEN=0 no RTS hardware
// bit 12 RTS=0 not RTS
// bits 10-8 MODE=000 normal
// bits 6-4 TXE=001 enable TxD
// bit 3 RXE=1 enable TxD
// bit 2 LBE=0 no loop back
// bit 0 ENABLE 0 is disable, 1 to enable
// 20000000/16 = 1,250,000 Hz
// Baud = 115200
/*
// 1,250,000/115200 = 10.850694
// divider = 10+54/64 = 10.84375
UART0->IBRD = 10;
UART0->FBRD = 54; // baud =1,250,000/10.84375 = 115,274 bps
*/
if(Clock_Freq() == 40000000){
// 20000000/16 = 1,250,000 Hz
// Baud = 115200
// 1,250,000/115200 = 10.850694
// divider = 10+54/64 = 10.84375
UART0->IBRD = 10;
UART0->FBRD = 54; // baud =1,250,000/10.84375 = 115,274
}else if (Clock_Freq() == 32000000){
// 32000000/16 = 2,000,000
// Baud = 115200
// 2,000,000/115200 = 17.361
// divider = 17+23/64 = 17.359
UART0->IBRD = 17;
UART0->FBRD = 23;
}else if (Clock_Freq() == 80000000){
// 40000000/16 = 2,500,000 Hz
// Baud = 115200
// 2,500,000/115200 = 21.701388
// divider = 21+45/64 = 21.703125
UART0->IBRD = 21;
UART0->FBRD = 45; // baud =2,500,000/21.703125 = 115,191
}else return;
UART0->LCRH = 0x00000030;
// bits 5-4 WLEN=11 8 bits
// bit 3 STP2=0 1 stop
// bit 2 EPS=0 parity select
// bit 1 PEN=0 no parity
// bit 0 BRK=0 no break
UART0->CPU_INT.IMASK = 0x0C01;
// bit 11 TXINT
// bit 10 RXINT
// bit 0 Receive timeout
UART0->IFLS = 0x0422;
// bits 11-8 RXTOSEL receiver timeout select 4 (0xF highest)
// bits 6-4 RXIFLSEL 2 is greater than or equal to half
// bits 2-0 TXIFLSEL 2 is less than or equal to half
NVIC->ICPR[0] = 1<<15; // UART0 is IRQ 15
NVIC->ISER[0] = 1<<15;
NVIC->IP[3] = (NVIC->IP[3]&(~0xFF000000))|(2<<30); // set priority (bits 31,30) IRQ 15
UART0->CTL0 |= 0x01; // enable UART0
}
// copy from hardware RX FIFO to software RX FIFO
// stop when hardware RX FIFO is empty or software RX FIFO is full
void static copyHardwareToSoftware(void){
char letter;
while(((UART0->STAT&0x04) == 0) && (RxFifo_Size() < (RXFIFOSIZE - 1))){
letter = UART0->RXDATA;
RxFifo_Put(letter);
}
}
//------------UART_InChar------------
// Wait for new serial port input
// Input: none
// Output: ASCII code for key typed
char UART_InChar(void){
char letter;
do{
letter = RxFifo_Get();
}while(letter==0);
return(letter);
}
// copy from software TX FIFO to hardware TX FIFO
// stop when software TX FIFO is empty or hardware TX FIFO is full
void static copySoftwareToHardware(void){
char letter;
while(((UART0->STAT&0x80) == 0) && (TxFifo_Size() > 0)){
letter = TxFifo_Get();
UART0->TXDATA = letter;
}
}
//------------UART_OutChar------------
// Output 8-bit to serial port
// Input: letter is an 8-bit ASCII character to be transferred
// Output: none
void UART_OutChar(char data){
while(TxFifo_Put(data) == 0){};
UART0->CPU_INT.IMASK &= ~0x0800; // disarm TX FIFO interrupt
copySoftwareToHardware();
UART0->CPU_INT.IMASK |= 0x0800; // rearm TX FIFO interrupt
}
void UART0_IRQHandler(void){ uint32_t status;
status = UART0->CPU_INT.IIDX; // reading clears bit in RIS
if(status == 0x01){ // 0x01 receive timeout
copyHardwareToSoftware();
}else if(status == 0x0B){ // 0x0B receive
copyHardwareToSoftware();
}else if(status == 0x0C){ // 0x0C transmit
copySoftwareToHardware();
if(TxFifo_Size() == 0){ // software TX FIFO is empty
UART0->CPU_INT.IMASK &= ~0x0800; // disable TX FIFO interrupt
}
}
}