arm uart: Complete redesign of ARM uart code
* Add nested function wrappers to allow usage of other uart drivers depending on board. We may want to use this on other platforms at some point (haha, maybe)
This commit is contained in:
parent
95aae4ae1e
commit
917e9be1a6
@ -14,11 +14,13 @@
|
||||
#include <arch/arm/omap3.h>
|
||||
|
||||
// UART Settings
|
||||
#define BOARD_UART_8250 1
|
||||
|
||||
#define BOARD_UART1_BASE OMAP_UART1_BASE
|
||||
#define BOARD_UART2_BASE OMAP_UART2_BASE
|
||||
#define BOARD_UART3_BASE OMAP_UART3_BASE
|
||||
|
||||
#define BOARD_DEBUG_UART 2
|
||||
#define BOARD_UART_DEBUG BOARD_UART3_BASE
|
||||
|
||||
#define BOARD_UART_CLOCK 48000000
|
||||
// 48MHz (APLL96/2)
|
||||
|
@ -14,11 +14,13 @@
|
||||
#include <arch/arm/arm920t.h>
|
||||
|
||||
// UART Settings
|
||||
#define BOARD_UART_8250 1
|
||||
|
||||
#define BOARD_UART1_BASE UART0_BASE
|
||||
#define BOARD_UART2_BASE UART1_BASE
|
||||
#define BOARD_UART3_BASE UART2_BASE
|
||||
|
||||
#define BOARD_DEBUG_UART 2
|
||||
#define BOARD_UART_DEBUG BOARD_UART3_BASE
|
||||
|
||||
#define BOARD_UART_CLOCK 48000000
|
||||
// 48MHz (APLL96/2)
|
||||
|
@ -14,11 +14,13 @@
|
||||
#include <arch/arm/omap3.h>
|
||||
|
||||
// UART Settings
|
||||
#define BOARD_UART_8250 1
|
||||
|
||||
#define BOARD_UART1_BASE OMAP_UART1_BASE
|
||||
#define BOARD_UART2_BASE OMAP_UART2_BASE
|
||||
#define BOARD_UART3_BASE OMAP_UART3_BASE
|
||||
|
||||
#define BOARD_DEBUG_UART 2
|
||||
#define BOARD_UART_DEBUG BOARD_UART3_BASE
|
||||
|
||||
#define BOARD_UART_CLOCK 48000000
|
||||
// 48MHz (APLL96/2)
|
||||
|
@ -16,11 +16,13 @@
|
||||
#include <arch/arm/bcm2708.h>
|
||||
|
||||
// UART Settings
|
||||
#define BOARD_UART_8250 1
|
||||
|
||||
#define BOARD_UART1_BASE UART0_BASE
|
||||
#define BOARD_UART2_BASE UART1_BASE
|
||||
#define BOARD_UART3_BASE 0
|
||||
|
||||
#define BOARD_DEBUG_UART 0
|
||||
#define BOARD_UART_DEBUG BOARD_UART2_BASE
|
||||
|
||||
#define BOARD_UART_CLOCK 125000000
|
||||
/* 125Mhz, strange */
|
||||
|
@ -14,11 +14,13 @@
|
||||
#include <arch/arm/pxa270.h>
|
||||
|
||||
// UART Settings
|
||||
#define BOARD_UART_8250 1
|
||||
|
||||
#define BOARD_UART1_BASE FFUART_BASE
|
||||
#define BOARD_UART2_BASE BTUART_BASE
|
||||
#define BOARD_UART3_BASE STUART_BASE
|
||||
|
||||
#define BOARD_DEBUG_UART 0
|
||||
#define BOARD_UART_DEBUG BOARD_UART1_BASE
|
||||
|
||||
#define BOARD_UART_CLOCK 48000000
|
||||
// 48MHz (APLL96/2)
|
||||
|
@ -1,47 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Travis Geiselbrecht
|
||||
* Copyright 2011-2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* Authors:
|
||||
* Alexander von Gluck, kallisti5@unixzen.com
|
||||
*/
|
||||
#ifndef __DEV_UART_H
|
||||
#define __DEV_UART_H
|
||||
|
||||
//#include <sys/types.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "uart_8250.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void uart_init(void);
|
||||
void uart_init_early(void);
|
||||
int uart_debug_port(void);
|
||||
struct uart_info {
|
||||
addr_t base;
|
||||
|
||||
// Pointers to functions based on port type
|
||||
void (*init)(addr_t base);
|
||||
void (*init_early)(void);
|
||||
void (*init_port)(addr_t base, uint baud);
|
||||
int (*putc)(addr_t base, char c);
|
||||
int (*getc)(addr_t base, bool wait);
|
||||
void (*flush_tx)(addr_t base);
|
||||
void (*flush_rx)(addr_t base);
|
||||
};
|
||||
|
||||
|
||||
uart_info* uart_create(void);
|
||||
void uart_destroy();
|
||||
addr_t uart_base_port(int port);
|
||||
addr_t uart_debug_port(void);
|
||||
|
||||
int uart_putc(int port, char c);
|
||||
int uart_getc(int port, bool wait);
|
||||
void uart_flush_tx(int port);
|
||||
void uart_flush_rx(int port);
|
||||
void uart_init_port(int port, uint baud);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
47
headers/private/kernel/arch/arm/uart_8250.h
Normal file
47
headers/private/kernel/arch/arm/uart_8250.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Travis Geiselbrecht
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef __DEV_UART_8250_H
|
||||
#define __DEV_UART_8250_H
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void uart_8250_init_port(addr_t base, uint baud);
|
||||
void uart_8250_init_early(void);
|
||||
void uart_8250_init(addr_t base);
|
||||
int uart_8250_putc(addr_t base, char c);
|
||||
int uart_8250_getc(addr_t base, bool wait);
|
||||
void uart_8250_flush_tx(addr_t base);
|
||||
void uart_8250_flush_rx(addr_t base);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -17,6 +17,8 @@ local kernelLibArchObjects =
|
||||
|
||||
KernelMergeObject boot_arch_$(TARGET_ARCH).o :
|
||||
uart.cpp
|
||||
uart_8250.cpp
|
||||
# uart_amba101.cpp
|
||||
arch_elf.cpp
|
||||
arch_video.cpp
|
||||
arch_video_920.cpp
|
||||
@ -28,7 +30,7 @@ KernelMergeObject boot_arch_$(TARGET_ARCH).o :
|
||||
$(kernelLibArchObjects)
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles arch_elf.cpp uart.cpp ]
|
||||
SEARCH on [ FGristFiles arch_elf.cpp uart.cpp uart_8250.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_ARCH) ] ;
|
||||
|
||||
SEARCH on [ FGristFiles $(librootArchObjects) ]
|
||||
|
@ -17,8 +17,9 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static int32 sSerialEnabled = 0;
|
||||
struct uart_info* gUARTInfo;
|
||||
|
||||
static int32 sSerialEnabled = 0;
|
||||
static char sBuffer[16384];
|
||||
static uint32 sBufferPosition;
|
||||
|
||||
@ -26,7 +27,8 @@ static uint32 sBufferPosition;
|
||||
static void
|
||||
serial_putc(char c)
|
||||
{
|
||||
uart_putc(uart_debug_port(), c);
|
||||
if (gUARTInfo != NULL)
|
||||
gUARTInfo->putc(gUARTInfo->base, c);
|
||||
}
|
||||
|
||||
|
||||
@ -65,8 +67,6 @@ serial_disable(void)
|
||||
extern "C" void
|
||||
serial_enable(void)
|
||||
{
|
||||
uart_init_early();
|
||||
uart_init();
|
||||
sSerialEnabled++;
|
||||
}
|
||||
|
||||
@ -81,6 +81,16 @@ serial_cleanup(void)
|
||||
extern "C" void
|
||||
serial_init(void)
|
||||
{
|
||||
gUARTInfo = uart_create();
|
||||
|
||||
if (gUARTInfo == NULL) {
|
||||
// TODO: Notify user somehow.
|
||||
return;
|
||||
}
|
||||
|
||||
gUARTInfo->init_early();
|
||||
gUARTInfo->init(gUARTInfo->base);
|
||||
|
||||
serial_enable();
|
||||
|
||||
serial_putc('S');
|
||||
|
@ -1,6 +1,9 @@
|
||||
/*
|
||||
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2012, Alexander von Gluck, kallisti5@unixzen.com
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
@ -12,12 +15,10 @@
|
||||
#include <boot/stage2.h>
|
||||
#include <string.h>
|
||||
|
||||
// serial output should always be enabled on u-boot platforms..
|
||||
#define ENABLE_SERIAL
|
||||
|
||||
struct uart_info* gUARTInfo;
|
||||
|
||||
static int32 sSerialEnabled = 0;
|
||||
|
||||
static char sBuffer[16384];
|
||||
static uint32 sBufferPosition;
|
||||
|
||||
@ -25,7 +26,7 @@ static uint32 sBufferPosition;
|
||||
static void
|
||||
serial_putc(char c)
|
||||
{
|
||||
uart_putc(uart_debug_port(),c);
|
||||
gUARTInfo->putc(gUARTInfo->base, c);
|
||||
}
|
||||
|
||||
|
||||
@ -54,25 +55,21 @@ serial_puts(const char* string, size_t size)
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
extern "C" void
|
||||
serial_disable(void)
|
||||
{
|
||||
#ifdef ENABLE_SERIAL
|
||||
sSerialEnabled = 0;
|
||||
#else
|
||||
sSerialEnabled--;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
extern "C" void
|
||||
serial_enable(void)
|
||||
{
|
||||
/* should already be initialized by U-Boot */
|
||||
/*
|
||||
uart_init_early();
|
||||
uart_init();//todo
|
||||
uart_init_port(uart_debug_port(),9600);
|
||||
gUARTInfo->init_early();
|
||||
gUARTInfo->init(gUARTInfo->base);
|
||||
gUARTInfo->init_port(gUARTInfo->base, 9600);
|
||||
*/
|
||||
sSerialEnabled++;
|
||||
}
|
||||
@ -95,8 +92,13 @@ serial_cleanup(void)
|
||||
extern "C" void
|
||||
serial_init(void)
|
||||
{
|
||||
#ifdef ENABLE_SERIAL
|
||||
serial_enable();
|
||||
#endif
|
||||
}
|
||||
// Setup information on uart
|
||||
gUARTInfo = uart_create();
|
||||
|
||||
if (gUARTInfo == NULL) {
|
||||
// TODO: Notify user somehow.
|
||||
return;
|
||||
}
|
||||
|
||||
serial_enable();
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ KernelMergeObject kernel_arch_arm.o :
|
||||
arch_vm_translation_map.cpp
|
||||
arch_asm.S
|
||||
uart.cpp
|
||||
uart_8250.cpp
|
||||
|
||||
# paging
|
||||
arm_physical_page_mapper.cpp
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
struct uart_info* gUART;
|
||||
|
||||
|
||||
void
|
||||
arch_debug_remove_interrupt_handler(uint32 line)
|
||||
{
|
||||
@ -57,14 +60,18 @@ arch_debug_serial_try_getchar(void)
|
||||
char
|
||||
arch_debug_serial_getchar(void)
|
||||
{
|
||||
return uart_getc(uart_debug_port(), FALSE);
|
||||
if (gUART->getc != NULL)
|
||||
return gUART->getc(gUART->base, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_debug_serial_putchar(const char c)
|
||||
{
|
||||
uart_putc(uart_debug_port(), c);
|
||||
if (gUART->putc != NULL)
|
||||
gUART->putc(gUART->base, c);
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +96,12 @@ arch_debug_serial_early_boot_message(const char *string)
|
||||
status_t
|
||||
arch_debug_console_init(kernel_args *args)
|
||||
{
|
||||
uart_init_early();
|
||||
gUART = uart_create();
|
||||
|
||||
if (gUART == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
gUART->init_early();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1,193 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Travis Geiselbrecht
|
||||
* Copyright 2011-2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* Authors:
|
||||
* Alexander von Gluck, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
#include <arch/arm/reg.h>
|
||||
#include <arch/arm/uart.h>
|
||||
#include <board_config.h>
|
||||
#include <debug.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//#include <target/debugconfig.h>
|
||||
|
||||
|
||||
#define DEBUG_UART BOARD_DEBUG_UART
|
||||
#define DEBUG_UART BOARD_UART_DEBUG
|
||||
|
||||
|
||||
struct uart_stat {
|
||||
addr_t base;
|
||||
uint shift;
|
||||
};
|
||||
|
||||
|
||||
static struct uart_stat uart[3] = {
|
||||
{ BOARD_UART1_BASE, 2 },
|
||||
{ BOARD_UART2_BASE, 2 },
|
||||
{ BOARD_UART3_BASE, 2 },
|
||||
};
|
||||
|
||||
|
||||
static inline void write_uart_reg(int port, uint reg, unsigned char data)
|
||||
{
|
||||
*(volatile unsigned char *)(uart[port].base + (reg << uart[port].shift))
|
||||
= data;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned char read_uart_reg(int port, uint reg)
|
||||
{
|
||||
return *(volatile unsigned char *)(uart[port].base
|
||||
+ (reg << uart[port].shift));
|
||||
}
|
||||
|
||||
|
||||
#define LCR_8N1 0x03
|
||||
|
||||
#define FCR_FIFO_EN 0x01 /* Fifo enable */
|
||||
#define FCR_RXSR 0x02 /* Receiver soft reset */
|
||||
#define FCR_TXSR 0x04 /* Transmitter soft reset */
|
||||
|
||||
#define MCR_DTR 0x01
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_DMA_EN 0x04
|
||||
#define MCR_TX_DFR 0x08
|
||||
|
||||
#define LCR_WLS_MSK 0x03 /* character length select mask */
|
||||
#define LCR_WLS_5 0x00 /* 5 bit character length */
|
||||
#define LCR_WLS_6 0x01 /* 6 bit character length */
|
||||
#define LCR_WLS_7 0x02 /* 7 bit character length */
|
||||
#define LCR_WLS_8 0x03 /* 8 bit character length */
|
||||
#define LCR_STB 0x04 /* Number of stop Bits, off = 1, on = 1.5 or 2) */
|
||||
#define LCR_PEN 0x08 /* Parity eneble */
|
||||
#define LCR_EPS 0x10 /* Even Parity Select */
|
||||
#define LCR_STKP 0x20 /* Stick Parity */
|
||||
#define LCR_SBRK 0x40 /* Set Break */
|
||||
#define LCR_BKSE 0x80 /* Bank select enable */
|
||||
|
||||
#define LSR_DR 0x01 /* Data ready */
|
||||
#define LSR_OE 0x02 /* Overrun */
|
||||
#define LSR_PE 0x04 /* Parity error */
|
||||
#define LSR_FE 0x08 /* Framing error */
|
||||
#define LSR_BI 0x10 /* Break */
|
||||
#define LSR_THRE 0x20 /* Xmit holding register empty */
|
||||
#define LSR_TEMT 0x40 /* Xmitter empty */
|
||||
#define LSR_ERR 0x80 /* Error */
|
||||
|
||||
|
||||
int uart_debug_port(void)
|
||||
addr_t
|
||||
uart_base_debug(void)
|
||||
{
|
||||
return DEBUG_UART;
|
||||
}
|
||||
|
||||
|
||||
void uart_init_port(int port, uint baud)
|
||||
addr_t
|
||||
uart_base_port(int port)
|
||||
{
|
||||
uint16 baudDivisor = BOARD_UART_CLOCK / (16 * baud);
|
||||
switch (port) {
|
||||
case 1:
|
||||
return BOARD_UART1_BASE;
|
||||
case 2:
|
||||
return BOARD_UART2_BASE;
|
||||
case 3:
|
||||
return BOARD_UART3_BASE;
|
||||
}
|
||||
|
||||
// Write standard uart settings
|
||||
write_uart_reg(port, UART_LCR, LCR_8N1);
|
||||
// 8N1
|
||||
write_uart_reg(port, UART_IER, 0);
|
||||
// Disable interrupt
|
||||
write_uart_reg(port, UART_FCR, 0);
|
||||
// Disable FIFO
|
||||
write_uart_reg(port, UART_MCR, MCR_DTR | MCR_RTS);
|
||||
// DTR / RTS
|
||||
|
||||
// Gain access to, and program baud divisor
|
||||
unsigned char buffer = read_uart_reg(port, UART_LCR);
|
||||
write_uart_reg(port, UART_LCR, buffer | LCR_BKSE);
|
||||
write_uart_reg(port, UART_DLL, baudDivisor & 0xff);
|
||||
write_uart_reg(port, UART_DLH, (baudDivisor >> 8) & 0xff);
|
||||
write_uart_reg(port, UART_LCR, buffer & ~LCR_BKSE);
|
||||
|
||||
// write_uart_reg(port, UART_MDR1, 0); // UART 16x mode
|
||||
// write_uart_reg(port, UART_LCR, 0xBF); // config mode B
|
||||
// write_uart_reg(port, UART_EFR, (1<<7)|(1<<6)); // hw flow control
|
||||
// write_uart_reg(port, UART_LCR, LCR_8N1); // operational mode
|
||||
return uart_base_debug();
|
||||
}
|
||||
|
||||
|
||||
void uart_init_early(void)
|
||||
uart_info*
|
||||
uart_create(void)
|
||||
{
|
||||
// Perform special hardware UART configuration
|
||||
struct uart_info* uart;
|
||||
|
||||
#if BOARD_CPU_OMAP3
|
||||
/* UART1 */
|
||||
RMWREG32(CM_FCLKEN1_CORE, 13, 1, 1);
|
||||
RMWREG32(CM_ICLKEN1_CORE, 13, 1, 1);
|
||||
uart = (uart_info*)malloc(sizeof(uart_info));
|
||||
uart->base = uart_base_debug();
|
||||
|
||||
/* UART2 */
|
||||
RMWREG32(CM_FCLKEN1_CORE, 14, 1, 1);
|
||||
RMWREG32(CM_ICLKEN1_CORE, 14, 1, 1);
|
||||
|
||||
/* UART3 */
|
||||
RMWREG32(CM_FCLKEN_PER, 11, 1, 1);
|
||||
RMWREG32(CM_ICLKEN_PER, 11, 1, 1);
|
||||
#if defined(BOARD_UART_8250)
|
||||
uart->init = uart_8250_init;
|
||||
uart->init_early = uart_8250_init_early;
|
||||
uart->init_port = uart_8250_init_port;
|
||||
uart->putc = uart_8250_putc;
|
||||
uart->getc = uart_8250_getc;
|
||||
uart->flush_tx = uart_8250_flush_tx;
|
||||
uart->flush_rx = uart_8250_flush_rx;
|
||||
#elif defined(BOARD_UART_AMBA)
|
||||
#error BOARD_UART_AMBA is Incomplete!
|
||||
uart->init = uart_amba_init;
|
||||
uart->init_early = uart_amba_init_early;
|
||||
uart->init_port = uart_amba_init_port;
|
||||
uart->putc = uart_amba_putc;
|
||||
uart->getc = uart_amba_getc;
|
||||
uart->flush_tx = uart_amba_flush_tx;
|
||||
uart->flush_rx = uart_amba_flush_rx;
|
||||
#else
|
||||
#warning INTITIALIZE UART!!!!!
|
||||
#error Unknown UART Type (or no UART provided)
|
||||
#endif
|
||||
|
||||
return uart;
|
||||
}
|
||||
|
||||
|
||||
void uart_init(void)
|
||||
void
|
||||
uart_destroy(uart_info* uart)
|
||||
{
|
||||
uart_init_port(uart_debug_port(), 115200);
|
||||
}
|
||||
|
||||
|
||||
int uart_putc(int port, char c )
|
||||
{
|
||||
while (!(read_uart_reg(port, UART_LSR) & (1<<6)));
|
||||
// wait for the last char to get out
|
||||
write_uart_reg(port, UART_THR, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uart_getc(int port, bool wait) /* returns -1 if no data available */
|
||||
{
|
||||
if (wait) {
|
||||
while (!(read_uart_reg(port, UART_LSR) & (1<<0)));
|
||||
// wait for data to show up in the rx fifo
|
||||
} else {
|
||||
if (!(read_uart_reg(port, UART_LSR) & (1<<0)))
|
||||
return -1;
|
||||
}
|
||||
return read_uart_reg(port, UART_RHR);
|
||||
}
|
||||
|
||||
|
||||
void uart_flush_tx(int port)
|
||||
{
|
||||
while (!(read_uart_reg(port, UART_LSR) & (1<<6)));
|
||||
// wait for the last char to get out
|
||||
}
|
||||
|
||||
|
||||
void uart_flush_rx(int port)
|
||||
{
|
||||
// empty the rx fifo
|
||||
while (read_uart_reg(port, UART_LSR) & (1<<0)) {
|
||||
volatile char c = read_uart_reg(port, UART_RHR);
|
||||
(void)c;
|
||||
}
|
||||
free(uart);
|
||||
}
|
||||
|
181
src/system/kernel/arch/arm/uart_8250.cpp
Normal file
181
src/system/kernel/arch/arm/uart_8250.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Travis Geiselbrecht
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
#include <arch/arm/reg.h>
|
||||
#include <arch/arm/uart.h>
|
||||
#include <board_config.h>
|
||||
//#include <target/debugconfig.h>
|
||||
|
||||
|
||||
#define UART_SHIFT 2
|
||||
|
||||
|
||||
static inline void write_8250(addr_t base, uint reg, unsigned char data)
|
||||
{
|
||||
*(volatile unsigned char *)(base + (reg << UART_SHIFT))
|
||||
= data;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned char read_8250(addr_t base, uint reg)
|
||||
{
|
||||
return *(volatile unsigned char *)(base + (reg << UART_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
#define LCR_8N1 0x03
|
||||
|
||||
#define FCR_FIFO_EN 0x01 /* Fifo enable */
|
||||
#define FCR_RXSR 0x02 /* Receiver soft reset */
|
||||
#define FCR_TXSR 0x04 /* Transmitter soft reset */
|
||||
|
||||
#define MCR_DTR 0x01
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_DMA_EN 0x04
|
||||
#define MCR_TX_DFR 0x08
|
||||
|
||||
#define LCR_WLS_MSK 0x03 /* character length select mask */
|
||||
#define LCR_WLS_5 0x00 /* 5 bit character length */
|
||||
#define LCR_WLS_6 0x01 /* 6 bit character length */
|
||||
#define LCR_WLS_7 0x02 /* 7 bit character length */
|
||||
#define LCR_WLS_8 0x03 /* 8 bit character length */
|
||||
#define LCR_STB 0x04 /* Number of stop Bits, off = 1, on = 1.5 or 2) */
|
||||
#define LCR_PEN 0x08 /* Parity eneble */
|
||||
#define LCR_EPS 0x10 /* Even Parity Select */
|
||||
#define LCR_STKP 0x20 /* Stick Parity */
|
||||
#define LCR_SBRK 0x40 /* Set Break */
|
||||
#define LCR_BKSE 0x80 /* Bank select enable */
|
||||
|
||||
#define LSR_DR 0x01 /* Data ready */
|
||||
#define LSR_OE 0x02 /* Overrun */
|
||||
#define LSR_PE 0x04 /* Parity error */
|
||||
#define LSR_FE 0x08 /* Framing error */
|
||||
#define LSR_BI 0x10 /* Break */
|
||||
#define LSR_THRE 0x20 /* Xmit holding register empty */
|
||||
#define LSR_TEMT 0x40 /* Xmitter empty */
|
||||
#define LSR_ERR 0x80 /* Error */
|
||||
|
||||
|
||||
void
|
||||
uart_8250_init_port(addr_t base, uint baud)
|
||||
{
|
||||
uint16 baudDivisor = BOARD_UART_CLOCK / (16 * baud);
|
||||
|
||||
// Write standard uart settings
|
||||
write_8250(base, UART_LCR, LCR_8N1);
|
||||
// 8N1
|
||||
write_8250(base, UART_IER, 0);
|
||||
// Disable interrupt
|
||||
write_8250(base, UART_FCR, 0);
|
||||
// Disable FIFO
|
||||
write_8250(base, UART_MCR, MCR_DTR | MCR_RTS);
|
||||
// DTR / RTS
|
||||
|
||||
// Gain access to, and program baud divisor
|
||||
unsigned char buffer = read_8250(base, UART_LCR);
|
||||
write_8250(base, UART_LCR, buffer | LCR_BKSE);
|
||||
write_8250(base, UART_DLL, baudDivisor & 0xff);
|
||||
write_8250(base, UART_DLH, (baudDivisor >> 8) & 0xff);
|
||||
write_8250(base, UART_LCR, buffer & ~LCR_BKSE);
|
||||
|
||||
// write_8250(base, UART_MDR1, 0); // UART 16x mode
|
||||
// write_8250(base, UART_LCR, 0xBF); // config mode B
|
||||
// write_8250(base, UART_EFR, (1<<7)|(1<<6)); // hw flow control
|
||||
// write_8250(base, UART_LCR, LCR_8N1); // operational mode
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uart_8250_init_early(void)
|
||||
{
|
||||
// Perform special hardware UART configuration
|
||||
|
||||
#if BOARD_CPU_OMAP3
|
||||
/* UART1 */
|
||||
RMWREG32(CM_FCLKEN1_CORE, 13, 1, 1);
|
||||
RMWREG32(CM_ICLKEN1_CORE, 13, 1, 1);
|
||||
|
||||
/* UART2 */
|
||||
RMWREG32(CM_FCLKEN1_CORE, 14, 1, 1);
|
||||
RMWREG32(CM_ICLKEN1_CORE, 14, 1, 1);
|
||||
|
||||
/* UART3 */
|
||||
RMWREG32(CM_FCLKEN_PER, 11, 1, 1);
|
||||
RMWREG32(CM_ICLKEN_PER, 11, 1, 1);
|
||||
#else
|
||||
#warning INTITIALIZE UART!!!!!
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uart_8250_init(addr_t base)
|
||||
{
|
||||
uart_8250_init_port(base, 115200);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
uart_8250_putc(addr_t base, char c )
|
||||
{
|
||||
while (!(read_8250(base, UART_LSR) & (1<<6)));
|
||||
// wait for the last char to get out
|
||||
write_8250(base, UART_THR, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* returns -1 if no data available */
|
||||
int
|
||||
uart_8250_getc(addr_t base, bool wait)
|
||||
{
|
||||
if (wait) {
|
||||
while (!(read_8250(base, UART_LSR) & (1<<0)));
|
||||
// wait for data to show up in the rx fifo
|
||||
} else {
|
||||
if (!(read_8250(base, UART_LSR) & (1<<0)))
|
||||
return -1;
|
||||
}
|
||||
return read_8250(base, UART_RHR);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uart_8250_flush_tx(addr_t base)
|
||||
{
|
||||
while (!(read_8250(base, UART_LSR) & (1<<6)));
|
||||
// wait for the last char to get out
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uart_8250_flush_rx(addr_t base)
|
||||
{
|
||||
// empty the rx fifo
|
||||
while (read_8250(base, UART_LSR) & (1<<0)) {
|
||||
volatile char c = read_8250(base, UART_RHR);
|
||||
(void)c;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user