aboutsummaryrefslogtreecommitdiff
path: root/uart.c
diff options
context:
space:
mode:
authorWojtek Kosior <kwojtus@protonmail.com>2020-01-03 17:08:06 +0100
committerWojtek Kosior <kwojtus@protonmail.com>2020-01-03 17:08:06 +0100
commit814d4a5357d849c4988422d48afa4aaa5432ce78 (patch)
tree77f4a169332f017873e64dcadbd7ed3467140c3f /uart.c
parent42ad29d6475cc63797be5042b90e8b09fc8d93b9 (diff)
downloadrpi-MMU-example-814d4a5357d849c4988422d48afa4aaa5432ce78.tar.gz
rpi-MMU-example-814d4a5357d849c4988422d48afa4aaa5432ce78.zip
write to peripheral registers like humans
Diffstat (limited to 'uart.c')
-rw-r--r--uart.c52
1 files changed, 19 insertions, 33 deletions
diff --git a/uart.c b/uart.c
index c4ae445..2d4e176 100644
--- a/uart.c
+++ b/uart.c
@@ -3,18 +3,6 @@
#include <uart.h>
#include <global.h>
-// Memory-Mapped I/O output
-static inline void mmio_write(uint32_t reg, uint32_t data)
-{
- *(volatile uint32_t*)reg = data;
-}
-
-// Memory-Mapped I/O input
-static inline uint32_t mmio_read(uint32_t reg)
-{
- return *(volatile uint32_t*)reg;
-}
-
// Loop <delay> times in a way that the compiler won't optimize away
static inline void delay(int32_t count)
{
@@ -25,22 +13,20 @@ static inline void delay(int32_t count)
void uart_init()
{
// Disable PL011_UART.
- mmio_write(PL011_UART_CR, 0x00000000);
+ wr32(PL011_UART_CR, 0);
+
// Setup the GPIO pin 14 && 15.
// Disable pull up/down for all GPIO pins & delay for 150 cycles.
- mmio_write(GPPUD, 0x00000000);
+ wr32(GPPUD, 0);
delay(150);
// Disable pull up/down for pin 14,15 & delay for 150 cycles.
- mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
+ wr32(GPPUDCLK0, (1 << 14) | (1 << 15));
delay(150);
// Write 0 to GPPUDCLK0 to make it take effect.
- mmio_write(GPPUDCLK0, 0x00000000);
-
- // Clear pending interrupts.
- mmio_write(PL011_UART_ICR, 0x7FF);
+ wr32(GPPUDCLK0, 0);
// Set integer & fractional part of baud rate.
// Divider = UART_CLOCK/(16 * Baud)
@@ -48,60 +34,60 @@ void uart_init()
// UART_CLOCK = 3000000; Baud = 115200.
// Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
- mmio_write(PL011_UART_IBRD, 1);
+ wr32(PL011_UART_IBRD, 1);
// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
- mmio_write(PL011_UART_FBRD, 40);
+ wr32(PL011_UART_FBRD, 40);
// Set 8 bit data transmission (1 stop bit, no parity)
// and disable FIFO to be able to receive interrupt every received
// char, not every 2 chars
- mmio_write(PL011_UART_LCRH, (1 << 5) | (1 << 6));
+ wr32(PL011_UART_LCRH, (1 << 5) | (1 << 6));
// set interrupt to come when transmit FIFO becomes ≤ 1/8 full
// or receive FIFO becomes ≥ 1/8 full
// (not really matters, since we disabled FIFOs)
- mmio_write(PL011_UART_IFLS, 0);
+ wr32(PL011_UART_IFLS, 0);
// Enable PL011_UART, receive & transfer part of UART.2
- mmio_write(PL011_UART_CR, (1 << 0) | (1 << 8) | (1 << 9));
+ wr32(PL011_UART_CR, (1 << 0) | (1 << 8) | (1 << 9));
// At first, it's probably safer to disable interrupts :)
uart_irq_disable();
- // That disables the entire uart irq; also disable single sources
- // within it
- *(uint32_t volatile*) PL011_UART_IMSC = 0;
+ // The above disables the entire uart irq;
+ // Also disable single sources within it
+ wr32(PL011_UART_IMSC, 0);
}
inline static _Bool can_transmit(void)
{
- return !(mmio_read(PL011_UART_FR) & (1 << 5));
+ return !(rd32(PL011_UART_FR) & (1 << 5));
}
inline static _Bool can_receive(void)
{
- return !(mmio_read(PL011_UART_FR) & (1 << 4));
+ return !(rd32(PL011_UART_FR) & (1 << 4));
}
void putchar(char c)
{
while (!can_transmit());
- mmio_write(PL011_UART_DR, c);
+ wr32(PL011_UART_DR, c);
}
char getchar(void)
{
while (!can_receive());
- return mmio_read(PL011_UART_DR);
+ return rd32(PL011_UART_DR);
}
_Bool putchar_non_blocking(char c)
{
if (can_transmit())
{
- mmio_write(PL011_UART_DR, c);
+ wr32(PL011_UART_DR, c);
return 0;
}
@@ -111,7 +97,7 @@ _Bool putchar_non_blocking(char c)
int getchar_non_blocking(void)
{
if (can_receive())
- return mmio_read(PL011_UART_DR);
+ return rd32(PL011_UART_DR);
return -1;
}