1
1
#include "uart.h"
2
2
#include "../common/utils.h"
3
3
4
- void uart_init ( )
4
+ void uart_init ( void )
5
5
{
6
- mmio_write (UART0_CR , 0x00000000 );
7
-
8
- mmio_write (GPPUD , 0x00000000 );
9
- delay (150 );
10
-
11
- mmio_write (GPPUDCLK0 , (1 << 14 ) | (1 << 15 ));
12
- delay (150 );
13
-
14
- mmio_write (GPPUDCLK0 , 0x00000000 );
15
-
16
- mmio_write (UART0_ICR , 0x7FF );
17
-
18
- mmio_write (UART0_IBRD , 1 );
19
- mmio_write (UART0_FBRD , 40 );
20
-
21
- mmio_write (UART0_LCRH , (1 << 4 ) | (1 << 5 ) | (1 << 6 ));
22
-
23
- mmio_write (UART0_IMSC , (1 << 1 ) | (1 << 4 ) | (1 << 5 ) | (1 << 6 ) |
24
- (1 << 7 ) | (1 << 8 ) | (1 << 9 ) | (1 << 10 ));
25
-
26
- mmio_write (UART0_CR , (1 << 0 ) | (1 << 8 ) | (1 << 9 ));
6
+ unsigned int selector ;
7
+ selector = get32 (GPFSEL1 );
8
+ selector &= ~(7 <<12 ); // clean gpio14
9
+ selector |= 4 <<12 ; // set alt0 for gpio14
10
+ selector &= ~(7 <<15 ); // clean gpio15
11
+ selector |= 4 <<15 ; // set alt0 for gpio 15
12
+ put32 (GPFSEL1 , selector );
13
+
14
+ put32 (GPPUD , 0 );
15
+ delay (150 );
16
+ put32 (GPPUDCLK0 , (1 <<14 ) | (1 <<15 ));
17
+ delay (150 );
18
+ put32 (GPPUDCLK0 , 0 );
19
+
20
+ put32 (UART0_CR , 0 ); // disable UART until configuration is done
21
+ /* baud divisor = UARTCLK / (16 * baud_rate) = 48 * 10^6 / (16 * 115200) = 26.0416666667
22
+ * integer part = 26
23
+ * fractional part = (int) ((0.0416666667 * 64) + 0.5) = 3
24
+ * generated baud rate divisor = 26 + (3 / 64) = 26.046875
25
+ * generated baud rate = (48 * 10^6) / (16 * 26.046875) = 115177
26
+ * error = |(115177 - 115200) / 115200 * 100| = 0.02%
27
+ */
28
+ put32 (UART0_IBRD , 26 ); // baud rate divisor, integer part
29
+ put32 (UART0_FBRD , 3 ); // baud rate divisor, fractional part
30
+ put32 (UART0_LCRH , (1 <<4 ) | (3 <<5 )); // enable FIFOs and 8 bits frames
31
+ put32 (UART0_IMSC , 0 ); // mask interupts
32
+ put32 (UART0_CR , 1 | (1 <<8 ) | (1 <<9 )); // enable UART, receive and transmit
27
33
}
28
34
29
- void uart_putc ( unsigned char c )
35
+ void uart_send ( char c )
30
36
{
31
- while ( mmio_read (UART0_FR ) & (1 << 5 ) ) { }
32
- mmio_write (UART0_DR , c );
37
+ // wait for transmit FIFO to have an available slot
38
+ while (get32 (UART0_FR ) & (1 <<5 )) { }
39
+ put32 (UART0_DR , c );
33
40
}
34
41
35
- unsigned char uart_getc ()
42
+ char uart_recv ()
36
43
{
37
- while ( mmio_read (UART0_FR ) & (1 << 4 ) ) { }
38
- return mmio_read (UART0_DR );
44
+ // wait for receive FIFO to have data to read
45
+ while (get32 (UART0_FR ) & (1 <<4 )) { }
46
+ return (get32 (UART0_DR ) & 0xFF );
39
47
}
40
48
41
- void uart_puts ( const char * str )
49
+ void uart_send_string ( char * str )
42
50
{
43
- for (size_t i = 0 ; str [i ] != '\0' ; i ++ )
44
- uart_putc ((unsigned char )str [i ]);
45
- }
51
+ for (int i = 0 ; str [i ] != '\0' ; i ++ ) {
52
+ uart_send ((char ) str [i ]);
53
+ }
54
+ }
55
+
0 commit comments