mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
Clean up UART module
And change some direct uart_printf()/uart_puts() output to console output methods instead. Disable unused comxtest debug command. No other functional changes. BUG=chrome-os-partner:15579 BRANCH=none TEST=boot system; should still see debug output with reset flags Change-Id: I57fe6bb781a1ba7884afa6d090b74a92f45a53cc Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/36835
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
/* UART module for Chrome EC */
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "lpc.h"
|
||||
@@ -17,10 +17,8 @@
|
||||
/* Baud rate for UARTs */
|
||||
#define BAUD_RATE 115200
|
||||
|
||||
|
||||
static int init_done;
|
||||
|
||||
|
||||
int uart_init_done(void)
|
||||
{
|
||||
return init_done;
|
||||
@@ -28,10 +26,12 @@ int uart_init_done(void)
|
||||
|
||||
void uart_tx_start(void)
|
||||
{
|
||||
/* Re-enable the transmit interrupt, then forcibly trigger the
|
||||
/*
|
||||
* Re-enable the transmit interrupt, then forcibly trigger the
|
||||
* interrupt. This works around a hardware problem with the
|
||||
* UART where the FIFO only triggers the interrupt when its
|
||||
* threshold is _crossed_, not just met. */
|
||||
* threshold is _crossed_, not just met.
|
||||
*/
|
||||
LM4_UART_IM(0) |= 0x20;
|
||||
task_trigger_irq(LM4_IRQ_UART0);
|
||||
}
|
||||
@@ -94,7 +94,9 @@ void uart_enable_interrupt(void)
|
||||
task_enable_irq(LM4_IRQ_UART0);
|
||||
}
|
||||
|
||||
/* Interrupt handler for UART0 */
|
||||
/**
|
||||
* Interrupt handler for UART0
|
||||
*/
|
||||
static void uart_0_interrupt(void)
|
||||
{
|
||||
/* Clear transmit and receive interrupt status */
|
||||
@@ -106,26 +108,31 @@ static void uart_0_interrupt(void)
|
||||
}
|
||||
DECLARE_IRQ(LM4_IRQ_UART0, uart_0_interrupt, 1);
|
||||
|
||||
|
||||
/* Interrupt handler for UART1 */
|
||||
/**
|
||||
* Interrupt handler for UART1
|
||||
*/
|
||||
static void uart_1_interrupt(void)
|
||||
{
|
||||
/* Clear transmit and receive interrupt status */
|
||||
LM4_UART_ICR(1) = 0x70;
|
||||
|
||||
#ifdef CONFIG_LPC
|
||||
/* If we have space in our FIFO and a character is pending in LPC,
|
||||
* handle that character. */
|
||||
/*
|
||||
* If we have space in our FIFO and a character is pending in LPC,
|
||||
* handle that character.
|
||||
*/
|
||||
if (!(LM4_UART_FR(1) & 0x20) && lpc_comx_has_char()) {
|
||||
/* Copy the next byte then disable transmit interrupt */
|
||||
LM4_UART_DR(1) = lpc_comx_get_char();
|
||||
LM4_UART_IM(1) &= ~0x20;
|
||||
}
|
||||
|
||||
/* Handle received character. There is no flow control on input;
|
||||
/*
|
||||
* Handle received character. There is no flow control on input;
|
||||
* received characters are blindly forwarded to LPC. This is ok
|
||||
* because LPC is much faster than UART, and we don't have flow control
|
||||
* on the UART receive-side either. */
|
||||
* on the UART receive-side either.
|
||||
*/
|
||||
if (!(LM4_UART_FR(1) & 0x10))
|
||||
lpc_comx_put_char(LM4_UART_DR(1));
|
||||
#endif
|
||||
@@ -133,8 +140,9 @@ static void uart_1_interrupt(void)
|
||||
/* Must be same prio as LPC interrupt handler so they don't preempt */
|
||||
DECLARE_IRQ(LM4_IRQ_UART1, uart_1_interrupt, 2);
|
||||
|
||||
|
||||
/* Configure GPIOs for the UART module. */
|
||||
/**
|
||||
* Configure GPIOs for the UART module.
|
||||
*/
|
||||
static void configure_gpio(void)
|
||||
{
|
||||
#ifdef BOARD_link
|
||||
@@ -150,8 +158,7 @@ static void configure_gpio(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uart_init(void)
|
||||
void uart_init(void)
|
||||
{
|
||||
volatile uint32_t scratch __attribute__((unused));
|
||||
int ch;
|
||||
@@ -174,57 +181,53 @@ int uart_init(void)
|
||||
LM4_UART_FBRD(ch) =
|
||||
(((INTERNAL_CLOCK / 16) % BAUD_RATE) * 64
|
||||
+ BAUD_RATE / 2) / BAUD_RATE;
|
||||
/* 8-N-1, FIFO enabled. Must be done after setting
|
||||
* the divisor for the new divisor to take effect. */
|
||||
/*
|
||||
* 8-N-1, FIFO enabled. Must be done after setting
|
||||
* the divisor for the new divisor to take effect.
|
||||
*/
|
||||
LM4_UART_LCRH(ch) = 0x70;
|
||||
/* Interrupt when RX fifo at minimum (>= 1/8 full), and TX fifo
|
||||
* when <= 1/4 full */
|
||||
/*
|
||||
* Interrupt when RX fifo at minimum (>= 1/8 full), and TX fifo
|
||||
* when <= 1/4 full
|
||||
*/
|
||||
LM4_UART_IFLS(ch) = 0x01;
|
||||
/* Unmask receive-FIFO, receive-timeout. We need
|
||||
/*
|
||||
* Unmask receive-FIFO, receive-timeout. We need
|
||||
* receive-timeout because the minimum RX FIFO depth is 1/8 = 2
|
||||
* bytes; without the receive-timeout we'd never be notified
|
||||
* about single received characters. */
|
||||
* about single received characters.
|
||||
*/
|
||||
LM4_UART_IM(ch) = 0x50;
|
||||
/* Enable the port */
|
||||
LM4_UART_CTL(ch) |= 0x0001;
|
||||
}
|
||||
|
||||
/* Enable interrupts for UART0 only. UART1 will have to wait until the
|
||||
/*
|
||||
* Enable interrupts for UART0 only. UART1 will have to wait until the
|
||||
* LPC bus is initialized.
|
||||
*/
|
||||
uart_clear_rx_fifo(0);
|
||||
task_enable_irq(LM4_IRQ_UART0);
|
||||
|
||||
init_done = 1;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* COMx functions */
|
||||
|
||||
/* Write a character to COMx, waiting for space in the output buffer if
|
||||
* necessary. */
|
||||
static void uart_comx_putc_wait(int c)
|
||||
{
|
||||
while (!uart_comx_putc_ok()) {}
|
||||
uart_comx_putc(c);
|
||||
}
|
||||
|
||||
|
||||
void uart_comx_enable(void)
|
||||
{
|
||||
uart_clear_rx_fifo(1);
|
||||
task_enable_irq(LM4_IRQ_UART1);
|
||||
}
|
||||
|
||||
|
||||
int uart_comx_putc_ok(void)
|
||||
{
|
||||
if (LM4_UART_FR(1) & 0x20) {
|
||||
/* FIFO is full, so enable transmit interrupt to let us know
|
||||
* when it empties. */
|
||||
/*
|
||||
* FIFO is full, so enable transmit interrupt to let us know
|
||||
* when it empties.
|
||||
*/
|
||||
LM4_UART_IM(1) |= 0x20;
|
||||
return 0;
|
||||
} else {
|
||||
@@ -232,16 +235,27 @@ int uart_comx_putc_ok(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uart_comx_putc(int c)
|
||||
{
|
||||
LM4_UART_DR(1) = c;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Console commands */
|
||||
|
||||
#ifdef CONFIG_CMD_COMXTEST
|
||||
|
||||
/**
|
||||
* Write a character to COMx, waiting for space in the output buffer if
|
||||
* necessary.
|
||||
*/
|
||||
static void uart_comx_putc_wait(int c)
|
||||
{
|
||||
while (!uart_comx_putc_ok())
|
||||
;
|
||||
uart_comx_putc(c);
|
||||
}
|
||||
|
||||
static int command_comxtest(int argc, char **argv)
|
||||
{
|
||||
/* Put characters to COMX port */
|
||||
@@ -261,3 +275,5 @@ DECLARE_CONSOLE_COMMAND(comxtest, command_comxtest,
|
||||
"[string]",
|
||||
"Write test data to COMx uart",
|
||||
NULL);
|
||||
|
||||
#endif /* CONFIG_COMX_TEST */
|
||||
|
||||
@@ -112,7 +112,7 @@ static void uart_interrupt(void)
|
||||
}
|
||||
DECLARE_IRQ(STM32_IRQ_USART(UARTN), uart_interrupt, 2);
|
||||
|
||||
int uart_init(void)
|
||||
void uart_init(void)
|
||||
{
|
||||
/* Enable USART clock */
|
||||
if (UARTN == 1)
|
||||
@@ -146,6 +146,4 @@ int uart_init(void)
|
||||
task_enable_irq(STM32_IRQ_USART(UARTN));
|
||||
|
||||
init_done = 1;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "clock.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "eeprom.h"
|
||||
#include "eoption.h"
|
||||
@@ -22,6 +23,10 @@
|
||||
#include "uart.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
|
||||
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/*
|
||||
@@ -76,20 +81,19 @@ int main(void)
|
||||
/* Main initialization stage. Modules may enable interrupts here. */
|
||||
cpu_init();
|
||||
|
||||
/* Initialize UART. uart_printf(), etc. may now be used. */
|
||||
/* Initialize UART. Console output functions may now be used. */
|
||||
uart_init();
|
||||
if (system_jumped_to_this_image())
|
||||
uart_printf("[%T UART initialized after sysjump]\n");
|
||||
else {
|
||||
uart_puts("\n\n--- UART initialized after reboot ---\n");
|
||||
uart_puts("[Reset cause: ");
|
||||
system_print_reset_flags();
|
||||
uart_puts("]\n");
|
||||
}
|
||||
uart_printf("[Image: %s, %s]\n",
|
||||
system_get_image_copy_string(),
|
||||
system_get_build_info());
|
||||
|
||||
if (system_jumped_to_this_image()) {
|
||||
CPRINTF("[%T UART initialized after sysjump]\n");
|
||||
} else {
|
||||
CPUTS("\n\n--- UART initialized after reboot ---\n");
|
||||
CPUTS("[Reset cause: ");
|
||||
system_print_reset_flags();
|
||||
CPUTS("]\n");
|
||||
}
|
||||
CPRINTF("[Image: %s, %s]\n",
|
||||
system_get_image_copy_string(), system_get_build_info());
|
||||
|
||||
#ifdef CONFIG_TASK_WATCHDOG
|
||||
/*
|
||||
@@ -129,7 +133,7 @@ int main(void)
|
||||
* into account the time before timer_init(), but it'll at least catch
|
||||
* the majority of the time.
|
||||
*/
|
||||
uart_printf("[%T Inits done]\n");
|
||||
CPRINTF("[%T Inits done]\n");
|
||||
|
||||
/* Launch task scheduling (never returns) */
|
||||
return task_start();
|
||||
|
||||
@@ -137,16 +137,16 @@ void system_print_reset_flags(void)
|
||||
int i;
|
||||
|
||||
if (!reset_flags) {
|
||||
uart_puts("unknown");
|
||||
CPUTS("unknown");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reset_flag_descs); i++) {
|
||||
if (reset_flags & (1 << i)) {
|
||||
if (count++)
|
||||
uart_puts(" ");
|
||||
CPUTS(" ");
|
||||
|
||||
uart_puts(reset_flag_descs[i]);
|
||||
CPUTS(reset_flag_descs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
166
include/uart.h
166
include/uart.h
@@ -11,60 +11,90 @@
|
||||
#include <stdarg.h> /* For va_list */
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Initialize the UART module.
|
||||
*/
|
||||
void uart_init(void);
|
||||
|
||||
/* Initializes the UART module. */
|
||||
int uart_init(void);
|
||||
|
||||
/* Return non-zero if UART init has completed. */
|
||||
/**
|
||||
* Return non-zero if UART init has completed.
|
||||
*/
|
||||
int uart_init_done(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Output functions
|
||||
/*
|
||||
* Output functions
|
||||
*
|
||||
* Output is buffered. If the buffer overflows, subsequent output is
|
||||
* discarded. */
|
||||
|
||||
/* Put a null-terminated string to the UART, like fputs().
|
||||
* discarded.
|
||||
*
|
||||
* Returns error if output was truncated. */
|
||||
* Modules should use the output functions in console.h in preference to these
|
||||
* routines, so that output can be filtered on a module-by-module basis.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Put a null-terminated string to the UART, like fputs().
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if output was truncated.
|
||||
*/
|
||||
int uart_puts(const char *outstr);
|
||||
|
||||
/* Print formatted output to the UART, like printf().
|
||||
/**
|
||||
* Print formatted output to the UART, like printf().
|
||||
*
|
||||
* See printf.h for valid formatting codes. */
|
||||
* See printf.h for valid formatting codes.
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if output was truncated.
|
||||
*/
|
||||
int uart_printf(const char *format, ...);
|
||||
|
||||
/* Print formatted output to the UART, like vprintf().
|
||||
/**
|
||||
* Print formatted output to the UART, like vprintf().
|
||||
*
|
||||
* See printf.h for valid formatting codes. */
|
||||
* See printf.h for valid formatting codes.
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if output was truncated.
|
||||
*/
|
||||
int uart_vprintf(const char *format, va_list args);
|
||||
|
||||
/* Flushes output. Blocks until UART has transmitted all output. */
|
||||
/**
|
||||
* Flush output. Blocks until UART has transmitted all output.
|
||||
*/
|
||||
void uart_flush_output(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Input functions
|
||||
/*
|
||||
* Input functions
|
||||
*
|
||||
* Input is buffered. If the buffer overflows, the oldest input in
|
||||
* the buffer is discarded to make room for the new input.
|
||||
*
|
||||
* Input lines may be terminated by CR ('\r'), LF ('\n'), or CRLF; all
|
||||
* are translated to newline. */
|
||||
* are translated to newline.
|
||||
*/
|
||||
|
||||
/* Flushes input buffer, discarding all input. */
|
||||
/**
|
||||
* Flush input buffer, discarding all input.
|
||||
*/
|
||||
void uart_flush_input(void);
|
||||
|
||||
/* Non-destructively checks for a character in the input buffer.
|
||||
/**
|
||||
* Non-destructively check for a character in the input buffer.
|
||||
*
|
||||
* Returns the offset into the input buffer of character <c>, or -1 if
|
||||
* it is not in the input buffer. */
|
||||
* @param c Character to search for
|
||||
*
|
||||
* @return the offset into the input buffer of the first match, or -1 if no
|
||||
* match found in the input buffer.
|
||||
*/
|
||||
int uart_peek(int c);
|
||||
|
||||
/* Reads a single character of input, similar to fgetc(). Returns the
|
||||
* character, or -1 if no input waiting. */
|
||||
/**
|
||||
* Read a single character of input, similar to fgetc().
|
||||
*
|
||||
* @return the character, or -1 if no input waiting.
|
||||
*/
|
||||
int uart_getc(void);
|
||||
|
||||
/* Reads characters from the UART, similar to fgets().
|
||||
/**
|
||||
* Read characters from the UART, similar to fgets().
|
||||
*
|
||||
* Reads input until one of the following conditions is met:
|
||||
* (1) <size-1> characters have been read.
|
||||
@@ -73,9 +103,9 @@ int uart_getc(void);
|
||||
*
|
||||
* Condition (3) means this call never blocks. This is important
|
||||
* because it prevents a race condition where the caller calls
|
||||
* UartPeek() to see if input is waiting, or is notified by the
|
||||
* uart_peek() to see if input is waiting, or is notified by the
|
||||
* callack that input is waiting, but then the input buffer overflows
|
||||
* or someone else grabs the input before UartGets() is called.
|
||||
* or someone else grabs the input before uart_gets() is called.
|
||||
*
|
||||
* Characters are stored in <dest> and are null-terminated.
|
||||
* Characters include the newline if present, so that the caller can
|
||||
@@ -83,83 +113,105 @@ int uart_getc(void);
|
||||
* input buffer is empty, a null-terminated empty string ("") is
|
||||
* returned.
|
||||
*
|
||||
* Returns the number of characters read (not counting the terminating
|
||||
* null). */
|
||||
* @param dest Destination for input
|
||||
* @param size Size of buffer pointed to by dest
|
||||
*
|
||||
* @return the number of characters read, not counting the terminating null.
|
||||
*/
|
||||
int uart_gets(char *dest, int size);
|
||||
|
||||
/* TODO: getc(), putc() equivalents? */
|
||||
/*
|
||||
* Hardware UART driver functions
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Hardware UART driver functions */
|
||||
|
||||
/* Flushes the transmit FIFO. */
|
||||
/**
|
||||
* Flush the transmit FIFO.
|
||||
*/
|
||||
void uart_tx_flush(void);
|
||||
|
||||
/* Returns true if there is room to transmit a character immediatly. */
|
||||
/**
|
||||
* Return non-zero if there is room to transmit a character immediately.
|
||||
*/
|
||||
int uart_tx_ready(void);
|
||||
|
||||
/* Returns true if the UART has character available. */
|
||||
/**
|
||||
* Return non-zero if the UART has a character available to read.
|
||||
*/
|
||||
int uart_rx_available(void);
|
||||
|
||||
/**
|
||||
* Sends a character to the UART data register.
|
||||
* If the transmit FIFO is full, this function blocks until there is space.
|
||||
* Send a character to the UART data register.
|
||||
*
|
||||
* c : byte to send.
|
||||
* If the transmit FIFO is full, blocks until there is space.
|
||||
*
|
||||
* @param c Character to send.
|
||||
*/
|
||||
void uart_write_char(char c);
|
||||
|
||||
/**
|
||||
* Reads and returns one char from the UART data register.
|
||||
* Read one char from the UART data register.
|
||||
*
|
||||
* Called when uart_rx_available once returns true.
|
||||
* @return The character read.
|
||||
*/
|
||||
int uart_read_char(void);
|
||||
|
||||
/**
|
||||
* Disables all UART related IRQs.
|
||||
* Disable all UART related IRQs.
|
||||
*
|
||||
* To avoid concurrent accesses on UART management variables.
|
||||
* Used to avoid concurrent accesses on UART management variables.
|
||||
*/
|
||||
void uart_disable_interrupt(void);
|
||||
|
||||
/* Re-enables UART IRQs. */
|
||||
/**
|
||||
* Re-enable UART IRQs.
|
||||
*/
|
||||
void uart_enable_interrupt(void);
|
||||
|
||||
/**
|
||||
* Re-enables the UART transmit interrupt.
|
||||
* Re-enable the UART transmit interrupt.
|
||||
*
|
||||
* It also forces triggering an interrupt if the hardware doesn't automatically
|
||||
* trigger it when the transmit buffer was filled beforehand.
|
||||
* This also forces triggering an interrupt if the hardware doesn't
|
||||
* automatically trigger it when the transmit buffer was filled beforehand.
|
||||
*/
|
||||
void uart_tx_start(void);
|
||||
|
||||
/* Disables the UART transmit interrupt. */
|
||||
/**
|
||||
* Disable the UART transmit interrupt.
|
||||
*/
|
||||
void uart_tx_stop(void);
|
||||
|
||||
/* Returns true if the UART transmit interrupt is disabled */
|
||||
/**
|
||||
* Return non-zero if the UART transmit interrupt is disabled.
|
||||
*/
|
||||
int uart_tx_stopped(void);
|
||||
|
||||
/**
|
||||
* Helper for UART processing.
|
||||
* Read the input FIFO until empty, then fill the output FIFO until the transmit
|
||||
* buffer is empty or the FIFO full.
|
||||
*
|
||||
* Reads the input FIFO until empty, then fills the output FIFO until the
|
||||
* transmit buffer is empty or the FIFO full.
|
||||
*
|
||||
* Designed to be called from the driver interrupt handler.
|
||||
*/
|
||||
void uart_process(void);
|
||||
|
||||
/*
|
||||
* COMx functions
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/* COMx functions */
|
||||
|
||||
/* Enables comx interrupts */
|
||||
/**
|
||||
* Enable COMx interrupts
|
||||
*/
|
||||
void uart_comx_enable(void);
|
||||
|
||||
/* Returns non-zero if ok to put a character via uart_comx_putc(). */
|
||||
/**
|
||||
* Return non-zero if ok to put a character via uart_comx_putc().
|
||||
*/
|
||||
int uart_comx_putc_ok(void);
|
||||
|
||||
/* Puts a character to the COMx UART interface. */
|
||||
/**
|
||||
* Write a character to the COMx UART interface.
|
||||
*/
|
||||
void uart_comx_putc(int c);
|
||||
|
||||
#endif /* __CROS_EC_UART_H */
|
||||
|
||||
Reference in New Issue
Block a user