-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathuart.c
122 lines (106 loc) · 2.43 KB
/
uart.c
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
#include <stddef.h>
#include <stdint.h>
#include "ccu.h"
#include "interrupts.h"
#include "ports.h"
#include "uart.h"
#include "util.h"
// Set up a UART (serial port)
void uart_init(int n)
{
if (n == 0) {
// Configure port
set_pin_mode(PORTA, 4, 2);
}
// Enable clock
if (n < 4) {
#ifdef AWBM_PLATFORM_h3
BUS_CLK_GATING3 |= BIT(16 + n);
BUS_SOFT_RST4 |= BIT(16 + n);
#elif defined(AWBM_PLATFORM_h616)
UART_BGR_REG |= BIT(16 + n) | BIT(n);
#else
#error unknown platform
#endif
} else {
// XXX: S_UART?
}
// Configure baud rate
UART_LCR(n) = (1 << 7) | 3;
UART_DLL(n) = 13;
UART_LCR(n) = 3;
// Enable FIFO
UART_FCR(n) = 0x00000001;
#if defined(GDBSTUB) && !defined(JAILHOUSE)
if (n == 0) {
// signal UART0 interrupt as FIQ for the GDB stub
irq_enable_fiq(32);
UART_IER(n) |= BIT(0);
}
#endif
}
// These functions are used when the stack protector has been triggered
// already.
#pragma GCC push_options
#pragma GCC optimize "-fno-stack-protector"
// UART is ready to receive data to transmit?
unsigned char uart_tx_ready(int n)
{
return (UART_USR(n) & 2);
}
// UART has received data?
unsigned char uart_rx_ready(int n)
{
return (UART_LSR(n) & 1);
}
// Push one byte to the UART port (blocking until ready to transmit)
void uart_write_byte(int n, char byte)
{
// Wait for UART transmit FIFO to be not full.
while (!uart_tx_ready(n))
;
UART_THR(n) = byte;
}
void uart_putc(char byte)
{
uart_write_byte(0, byte);
}
char uart_read_byte(int n)
{
while (!uart_rx_ready(n))
;
return UART_RBR(n);
}
char uart_getc(void)
{
return uart_read_byte(0);
}
// Write a zero terminated string to the UART
void uart_print(const char *str)
{
while (*str) {
uart_putc(*str);
str++;
}
}
// Print a char to the UART as ASCII HEX
void uart_print_uint8(unsigned char number)
{
unsigned char chars[] = "0123456789ABCDEF";
uart_putc(chars[(number >> 4) & 0xF]);
uart_putc(chars[(number >> 0) & 0xF]);
}
// Print a uint32 to the UART as ASCII HEX
void uart_print_uint32(uint32_t number)
{
unsigned char chars[] = "0123456789ABCDEF";
uart_putc(chars[(number >> 28) & 0xF]);
uart_putc(chars[(number >> 24) & 0xF]);
uart_putc(chars[(number >> 20) & 0xF]);
uart_putc(chars[(number >> 16) & 0xF]);
uart_putc(chars[(number >> 12) & 0xF]);
uart_putc(chars[(number >> 8) & 0xF]);
uart_putc(chars[(number >> 4) & 0xF]);
uart_putc(chars[(number >> 0) & 0xF]);
}
#pragma GCC pop_options