1 /*
2 * Copyright (c) 2015 Eric Holland
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 <assert.h>
13 #include <lk/err.h>
14 #include <lib/cbuf.h>
15 #include <arch/arm/cm.h>
16 #include <arch/ops.h>
17 #include <dev/uart.h>
18 #include <dev/gpio.h>
19 #include <kernel/thread.h>
20 #include <platform/debug.h>
21 #include <target/debugconfig.h>
22 #include <target/gpioconfig.h>
23
24 #define RXBUF_SIZE 16
25
26 cbuf_t uart0_rx_buf;
27
28
29
uart_init_early(void)30 void uart_init_early(void) {
31 #ifdef ENABLE_UART0
32
33 #ifdef UART0_TX_PIN
34 gpio_config(UART0_TX_PIN,GPIO_OUTPUT);
35 NRF_UART0->PSELTXD = UART0_TX_PIN;
36 #endif
37 #ifdef UART0_RX_PIN
38 gpio_config(UART0_RX_PIN,GPIO_INPUT);
39 NRF_UART0->PSELRXD = UART0_RX_PIN;
40 #endif
41
42 NRF_UART0->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud115200 << UART_BAUDRATE_BAUDRATE_Pos;
43 NRF_UART0->CONFIG = UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos | \
44 UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos;
45 NVIC_DisableIRQ(UARTE0_UART0_IRQn);
46 NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos;
47 NRF_UART0->TXD = 'L'; //Must prime the tx queue with a character to start operation
48 NRF_UART0->TASKS_STARTTX=1;
49 NRF_UART0->TASKS_STARTRX=1;
50 #endif //ENABLE_UART0
51 }
52
uart_init(void)53 void uart_init(void) {
54 #ifdef ENABLE_UART0
55 cbuf_initialize(&uart0_rx_buf, RXBUF_SIZE);
56 NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos;
57 NRF_UART0->EVENTS_RXDRDY = 0;
58 NVIC_EnableIRQ(UARTE0_UART0_IRQn);
59 char c = NRF_UART0->RXD;
60 (void)c;
61 #endif //ENABLE_UART0
62 }
63
nrf52_UARTE0_UART0_IRQ(void)64 void nrf52_UARTE0_UART0_IRQ(void) {
65 char c;
66 arm_cm_irq_entry();
67
68 bool resched = false;
69 while ( NRF_UART0->EVENTS_RXDRDY > 0 ) {
70 NRF_UART0->EVENTS_RXDRDY = 0;
71 c = NRF_UART0->RXD;
72 if (!cbuf_space_avail(&uart0_rx_buf)) {
73 break;
74 }
75 cbuf_write_char(&uart0_rx_buf, c, false);
76 resched = true;
77 }
78
79 arm_cm_irq_exit(resched);
80 }
81
uart_putc(int port,char c)82 int uart_putc(int port, char c) {
83 while (NRF_UART0->EVENTS_TXDRDY == 0);
84 NRF_UART0->EVENTS_TXDRDY = 0;
85 NRF_UART0->TXD = c;
86 return 1;
87 }
88
uart_getc(int port,bool wait)89 int uart_getc(int port, bool wait) {
90 cbuf_t *rxbuf = &uart0_rx_buf;
91
92 char c;
93 if (cbuf_read_char(rxbuf, &c, wait) == 1)
94 return c;
95
96 return -1;
97 }
98
uart_flush_tx(int port)99 void uart_flush_tx(int port) {}
100
uart_flush_rx(int port)101 void uart_flush_rx(int port) {}
102
uart_init_port(int port,uint baud)103 void uart_init_port(int port, uint baud) {
104 // TODO - later
105 PANIC_UNIMPLEMENTED;
106 }
107