diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2014-07-15 10:41:16 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-07-29 02:21:22 +0000 |
commit | f93f1cfe77ed3603ab16047d79a283a781416db4 (patch) | |
tree | d0ec489650265d06c90297b884f02b96b18094c0 /chip/nrf51/uart.c | |
parent | bbb5b0636b5d2b9a9d339e32142bf775717bd929 (diff) | |
download | chrome-ec-f93f1cfe77ed3603ab16047d79a283a781416db4.tar.gz |
hadoken: initial commit.
Board bring up. GPIO / UART / timer / console / task / hook are
working now.
BRANCH=tot
BUG=none
TEST=run on evaluation board and see LED 0/1 are blinking.
Console commands are available to use.
Change-Id: If93a2c94b8abe1c2c931c03a7a12ddd2bed9d9f6
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/209403
Reviewed-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'chip/nrf51/uart.c')
-rw-r--r-- | chip/nrf51/uart.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/chip/nrf51/uart.c b/chip/nrf51/uart.c new file mode 100644 index 0000000000..90c1990541 --- /dev/null +++ b/chip/nrf51/uart.c @@ -0,0 +1,130 @@ +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* USART driver for Chrome EC */ + +#include "clock.h" +#include "console.h" +#include "common.h" +#include "dma.h" +#include "hooks.h" +#include "registers.h" +#include "system.h" +#include "task.h" +#include "uart.h" +#include "util.h" + +#define CPUTS(outstr) cputs(CC_SYSTEM, outstr) +#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args) +#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args) + + +static int ever_sent; /* if we ever sent byte to TXD? */ +static int init_done; /* Initialization done? */ +static int should_stop; /* Last TX control action */ + +int uart_init_done(void) +{ + return init_done; +} + +void uart_tx_start(void) +{ + disable_sleep(SLEEP_MASK_UART); + should_stop = 0; + NRF51_UART_INTENSET = (1 << NRF55_UART_TXDRDY_BIT); + task_trigger_irq(NRF51_PERID_USART); +} + +void uart_tx_stop(void) +{ + NRF51_UART_INTENCLR = (1 << NRF55_UART_TXDRDY_BIT); + should_stop = 1; + enable_sleep(SLEEP_MASK_UART); +} + +int uart_tx_ready(void) +{ + /* + * nRF51 design is NOT tx-empty style. Instead, it is if a byte is + * ever transmitted from TxD. This means NRF51_UART_TXDRDY is always + * 0 after reset. So, we use 'ever_sent' to send the first byte. + */ + return NRF51_UART_TXDRDY || (!ever_sent); +} + +int uart_rx_available(void) +{ + return NRF51_UART_RXDRDY; +} + +void uart_tx_flush(void) +{ + while (!uart_tx_ready()) + ; +} + +void uart_write_char(char c) +{ + ever_sent = 1; + NRF51_UART_TXDRDY = 0; + NRF51_UART_TXD = c; + NRF51_UART_STARTTX = 1; +} + +int uart_read_char(void) +{ + NRF51_UART_RXDRDY = 0; + return NRF51_UART_RXD; +} + +void uart_disable_interrupt(void) +{ + task_disable_irq(NRF51_PERID_USART); +} + +void uart_enable_interrupt(void) +{ + task_enable_irq(NRF51_PERID_USART); +} + + +/* Interrupt handler for console USART */ +void uart_interrupt(void) +{ +#ifndef CONFIG_UART_RX_DMA + /* + * Read input FIFO until empty. DMA-based receive does this from a + * hook in the UART buffering module. + */ + uart_process_input(); +#endif + + /* Fill output FIFO */ + uart_process_output(); + +#ifndef CONFIG_UART_TX_DMA + if (!should_stop) + NRF51_UART_INTENSET = (1 << NRF55_UART_TXDRDY_BIT); +#endif /* CONFIG_UART_TX_DMA */ + +} +DECLARE_IRQ(NRF51_PERID_USART, uart_interrupt, 2); + + +void uart_init(void) +{ + NRF51_UART_PSELTXD = NRF51_UART_TX_PIN; /* GPIO Port for Tx */ + NRF51_UART_PSELRXD = NRF51_UART_RX_PIN; /* GPIO Port for Rx */ + NRF51_UART_CONFIG = 0; /* disable HW flow control, no parity bit */ + NRF51_UART_BAUDRATE = 0x01d7e000; /* 115200 */ + NRF51_UART_ENABLE = 0x4; /* Enable UART */ + + uart_enable_interrupt(); + NRF51_UART_INTENSET = (1 << NRF55_UART_RXDRDY_BIT); + NRF51_UART_STARTRX = 1; + + init_done = 1; +} |