mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
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>
131 lines
2.7 KiB
C
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;
|
|
}
|