aboutsummaryrefslogtreecommitdiff
path: root/src/uart.rs
blob: 7c048e018077e55631d341b5fef703897b2df60e (plain)
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
pub unsafe fn uart_init() {
    let UART0_CR = 0x3F201030 as *mut u32;
    let UART0_ICR = 0x3F201044 as *mut u32;
    let UART0_IBRD = 0x3F201024 as *mut u32;
    let UART0_FBRD = 0x3F201028 as *mut u32;
    let UART0_LCRH = 0x3F20102C as *mut u32;
    let UART0_IMSC = 0x3F201038 as *mut u32;
    let GPPUD = 0x3F200094 as *mut u32;
    let GPPUDCLK0 = 0x3F200098 as *mut u32;
    *UART0_CR = 0;
    *GPPUD = 0;
    for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));}
    *GPPUDCLK0 = (1 << 14) | (1 << 15);
    for _ in 0..150 {core::arch::asm!("nop", options(nomem, nostack));}
    *GPPUDCLK0 = 0;
    *UART0_ICR = 0x7FF;
    *UART0_IBRD = 9;
    *UART0_FBRD = 49;
    *UART0_LCRH = (1<<4)|(1<<5)|(1<<6);
    *UART0_IMSC = (1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
    *UART0_CR = (1<<0) | (1<<8) | (1<<9);
}

pub fn write_char(ch: u8) {
    let UART0_DR = 0x3F201000 as *mut u32;
    let UART0_FR = 0x3F201018 as *mut u32;
    unsafe {
        while *UART0_FR & 0x20 != 0 {core::arch::asm!("nop", options(nomem, nostack));}
        *UART0_DR = ch as u32;
    }
}