1 /*
2 * Copyright (c) 2015 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/reg.h>
9 #include <lk/trace.h>
10 #include <lib/cbuf.h>
11 #include <lk/init.h>
12 #include <kernel/thread.h>
13 #include <platform.h>
14 #include <platform/interrupts.h>
15 #include <sys/types.h>
16 #include <target/microblaze-config.h>
17
18 #include "uartlite.h"
19
20 #define LOCAL_TRACE 0
21
22 #define R_RX 0
23 #define R_TX 1
24 #define R_STATUS 2
25 #define R_CTRL 3
26 #define R_MAX 4
27
28 #define STATUS_RXVALID 0x01
29 #define STATUS_RXFULL 0x02
30 #define STATUS_TXEMPTY 0x04
31 #define STATUS_TXFULL 0x08
32 #define STATUS_IE 0x10
33 #define STATUS_OVERRUN 0x20
34 #define STATUS_FRAME 0x40
35 #define STATUS_PARITY 0x80
36
37 #define CONTROL_RST_TX 0x01
38 #define CONTROL_RST_RX 0x02
39 #define CONTROL_IE 0x10
40
41 #define UART_REG(reg) (*REG32(UARTLITE_BASEADDR + (reg) * 4))
42
43 #define RXBUF_SIZE 128
44 static cbuf_t uart_rx_buf;
45
uartlite_putc(char c)46 void uartlite_putc(char c) {
47 while (UART_REG(R_STATUS) & STATUS_TXFULL)
48 ;
49 UART_REG(R_TX) = c;
50 }
51
uartlite_getc(bool wait)52 int uartlite_getc(bool wait) {
53 #if 0
54 char c;
55 if (cbuf_read_char(&uart_rx_buf, &c, wait) == 1)
56 return c;
57 #else
58 do {
59 if (UART_REG(R_STATUS) & STATUS_RXVALID) {
60 char c = UART_REG(R_RX);
61 return c;
62 }
63 } while (wait);
64 #endif
65
66 return -1;
67 }
68
uartlite_irq(void * arg)69 static enum handler_return uartlite_irq(void *arg) {
70 bool resched = false;
71
72 /* while receive fifo not empty, read a char */
73 while (UART_REG(R_STATUS) & STATUS_RXVALID) {
74 char c = UART_REG(R_RX);
75 cbuf_write_char(&uart_rx_buf, c, false);
76
77 resched = true;
78 }
79
80 return resched ? INT_RESCHEDULE : INT_NO_RESCHEDULE;
81 }
82
uartlite_init(uint level)83 static void uartlite_init(uint level) {
84 TRACE;
85
86 //UART_REG(R_CTRL) = CONTROL_RST_TX | CONTROL_RST_RX;
87 // UART_REG(R_CTRL) |= CONTROL_IE;
88
89 cbuf_initialize(&uart_rx_buf, RXBUF_SIZE);
90
91 // register_int_handler(UARTLITE_IRQ, uartlite_irq, NULL);
92 // unmask_interrupt(UARTLITE_IRQ);
93 }
94
95 LK_INIT_HOOK(uartlite, uartlite_init, LK_INIT_LEVEL_PLATFORM);
96
97