aboutsummaryrefslogtreecommitdiff
path: root/src/arm/PL1/PL1_common/uart.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/PL1/PL1_common/uart.h')
-rw-r--r--src/arm/PL1/PL1_common/uart.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/arm/PL1/PL1_common/uart.h b/src/arm/PL1/PL1_common/uart.h
new file mode 100644
index 0000000..96f3634
--- /dev/null
+++ b/src/arm/PL1/PL1_common/uart.h
@@ -0,0 +1,106 @@
+#ifndef UART_H
+#define UART_H
+
+#include <stdint.h>
+#include "global.h"
+#include "interrupts.h"
+
+// The offsets for reach register.
+
+// Controls actuation of pull up/down to ALL GPIO pins.
+#define GPPUD (GPIO_BASE + 0x94)
+
+// Controls actuation of pull up/down for specific GPIO pin.
+#define GPPUDCLK0 (GPIO_BASE + 0x98)
+
+// The base address for UART.
+#define PL011_UART_BASE (GPIO_BASE + 0x1000)
+
+// The offsets for reach register for the UART.
+#define PL011_UART_DR (PL011_UART_BASE + 0x00)
+#define PL011_UART_RSRECR (PL011_UART_BASE + 0x04)
+#define PL011_UART_FR (PL011_UART_BASE + 0x18)
+#define PL011_UART_ILPR (PL011_UART_BASE + 0x20)
+#define PL011_UART_IBRD (PL011_UART_BASE + 0x24)
+#define PL011_UART_FBRD (PL011_UART_BASE + 0x28)
+#define PL011_UART_LCRH (PL011_UART_BASE + 0x2C)
+#define PL011_UART_CR (PL011_UART_BASE + 0x30)
+#define PL011_UART_IFLS (PL011_UART_BASE + 0x34)
+#define PL011_UART_IMSC (PL011_UART_BASE + 0x38)
+#define PL011_UART_RIS (PL011_UART_BASE + 0x3C)
+#define PL011_UART_MIS (PL011_UART_BASE + 0x40)
+#define PL011_UART_ICR (PL011_UART_BASE + 0x44)
+#define PL011_UART_DMACR (PL011_UART_BASE + 0x48)
+#define PL011_UART_ITCR (PL011_UART_BASE + 0x80)
+#define PL011_UART_ITIP (PL011_UART_BASE + 0x84)
+#define PL011_UART_ITOP (PL011_UART_BASE + 0x88)
+#define PL011_UART_TDR (PL011_UART_BASE + 0x8C)
+
+void uart_init();
+void putchar(char c);
+char getchar(void);
+_Bool putchar_non_blocking(char c);
+int getchar_non_blocking(void);
+
+// TODO experiment to see if this gives us raw uart irq or the uart
+// irq bit or'd with it's enable bit (not crucial for now, sice in our
+// code this function only gets called when this irq is enabled)
+static inline _Bool uart_irq_pending(void)
+{
+ return
+ ((uint32_t) 1 << 25) & rd32(ARM_IRQ_PENDING_2);
+}
+
+static inline void uart_irq_disable(void)
+{
+ // Mask uart in arm peripheral interrupts
+ wr32(ARM_DISABLE_IRQS_2, ((uint32_t) 1) << 25);
+}
+
+static inline void uart_irq_enable(void)
+{
+ // Unmask uart in arm peripheral interrupts
+ wr32(ARM_ENABLE_IRQS_2, ((uint32_t) 1) << 25);
+}
+
+static inline _Bool uart_recv_irq_pending(void)
+{
+ return (1 << 4) & rd32(PL011_UART_MIS);
+}
+
+static inline void uart_recv_irq_disable(void)
+{
+ wr32(PL011_UART_IMSC, rd32(PL011_UART_IMSC) & ~(1 << 4));
+}
+
+static inline void uart_recv_irq_enable(void)
+{
+ wr32(PL011_UART_IMSC, rd32(PL011_UART_IMSC) | (1 << 4));
+}
+
+static inline void uart_clear_recv_irq(void)
+{
+ wr32(PL011_UART_ICR, (1 << 4));
+}
+
+static inline _Bool uart_send_irq_pending(void)
+{
+ return (1 << 5) & rd32(PL011_UART_MIS);
+}
+
+static inline void uart_send_irq_disable(void)
+{
+ wr32(PL011_UART_IMSC, rd32(PL011_UART_IMSC) & ~(1 << 5));
+}
+
+static inline void uart_send_irq_enable(void)
+{
+ wr32(PL011_UART_IMSC, rd32(PL011_UART_IMSC) | (1 << 5));
+}
+
+static inline void uart_clear_send_irq(void)
+{
+ wr32(PL011_UART_ICR, (1 << 5));
+}
+
+#endif // UART_H