Files
OpenCellular/chip/nrf51/uart.c
Louis Yung-Chieh Lo f93f1cfe77 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>
2014-07-29 02:21:22 +00:00

131 lines
2.7 KiB
C

/* 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;
}