1 /*
2  * Copyright (c) 2014 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 <stdarg.h>
9 #include <lk/reg.h>
10 #include <lk/debug.h>
11 #include <stdio.h>
12 #include <lk/compiler.h>
13 #include <lib/cbuf.h>
14 #include <kernel/thread.h>
15 #include <platform/debug.h>
16 #include <arch/ops.h>
17 #include <arch/arm/cm.h>
18 #include <target/debugconfig.h>
19 
20 #include <platform/lpc.h>
21 
22 static cbuf_t debug_rx_buf;
23 
24 /* this code is only set up to handle UART0 as the debug uart */
25 STATIC_ASSERT(DEBUG_UART == LPC_USART0);
26 
lpc_debug_early_init(void)27 void lpc_debug_early_init(void) {
28     /* Use main clock rate as base for UART baud rate divider */
29     Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false);
30 
31     /* Setup UART */
32     Chip_UART_Init(DEBUG_UART);
33     Chip_UART_ConfigData(DEBUG_UART, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1);
34     Chip_UART_SetBaud(DEBUG_UART, 115200);
35     Chip_UART_Enable(DEBUG_UART);
36     Chip_UART_TXEnable(DEBUG_UART);
37 }
38 
lpc_debug_init(void)39 void lpc_debug_init(void) {
40     cbuf_initialize(&debug_rx_buf, 16);
41 
42     /* enable uart interrupts */
43     Chip_UART_IntEnable(DEBUG_UART, UART_INTEN_RXRDY);
44 
45     NVIC_EnableIRQ(UART0_IRQn);
46 }
47 
lpc_UART0_irq(void)48 void lpc_UART0_irq(void) {
49     arm_cm_irq_entry();
50 
51     /* read the rx buffer until it's empty */
52     while ((Chip_UART_GetStatus(DEBUG_UART) & UART_STAT_RXRDY) != 0) {
53         uint8_t c = Chip_UART_ReadByte(DEBUG_UART);
54         cbuf_write_char(&debug_rx_buf, c, false);
55     }
56 
57     arm_cm_irq_exit(true);
58 }
59 
platform_dputc(char c)60 void platform_dputc(char c) {
61     if (c == '\n') {
62         platform_dputc('\r');
63     }
64 
65     Chip_UART_SendBlocking(DEBUG_UART, &c, 1);
66 }
67 
platform_dgetc(char * c,bool wait)68 int platform_dgetc(char *c, bool wait) {
69 #if 1
70     return cbuf_read_char(&debug_rx_buf, c, wait);
71 #else
72     uint8_t data;
73 
74     if (Chip_UART_Read(DEBUG_UART, &data, 1) == 1) {
75         *c = data;
76         return 1;
77     }
78     return -1;
79 #endif
80 }
81 
82