forked from Imagelibrary/rtems
bsps: Move console drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -106,9 +106,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/altera-cyclone-v/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/alt_clock_manager.h>
|
||||
#include <bsp/console-termios.h>
|
||||
#include <bsp/socal/alt_rstmgr.h>
|
||||
#include <bsp/socal/socal.h>
|
||||
#include <bsp/socal/alt_uart.h>
|
||||
#include <bsp/socal/hps.h>
|
||||
|
||||
#ifdef BSP_USE_UART_INTERRUPTS
|
||||
#define DEVICE_FNS &ns16550_handler_interrupt
|
||||
#else
|
||||
#define DEVICE_FNS &ns16550_handler_polled
|
||||
#endif
|
||||
|
||||
static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
return (uint8_t) reg [i];
|
||||
}
|
||||
|
||||
static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
reg [i] = val;
|
||||
}
|
||||
|
||||
static bool altera_cyclone_v_uart_probe(
|
||||
rtems_termios_device_context *base,
|
||||
uint32_t uart_set_mask
|
||||
)
|
||||
{
|
||||
ns16550_context *ctx = (ns16550_context *) base;
|
||||
bool ret = true;
|
||||
uint32_t ucr;
|
||||
ALT_STATUS_CODE sc;
|
||||
void* location = (void *) ctx->port;
|
||||
|
||||
/* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs.
|
||||
* Check that it's enabled. */
|
||||
if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if ( ret ) {
|
||||
sc = alt_clk_freq_get(ALT_CLK_L4_SP, &ctx->clock);
|
||||
if ( sc != ALT_E_SUCCESS ) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ret ) {
|
||||
// Bring UART out of reset.
|
||||
alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, uart_set_mask);
|
||||
|
||||
// Verify the UCR (UART Component Version)
|
||||
ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) );
|
||||
if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ret ) {
|
||||
// Write SRR::UR (Shadow Reset Register :: UART Reset)
|
||||
alt_write_word( ALT_UART_SRR_ADDR( location ), ALT_UART_SRR_UR_SET_MSK );
|
||||
|
||||
// Read the MSR to work around case:119085.
|
||||
(void)alt_read_word( ALT_UART_MSR_ADDR( location ) );
|
||||
|
||||
ret = ns16550_probe( base );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CYCLONE_V_CONFIG_CONSOLE
|
||||
static bool altera_cyclone_v_uart_probe_0(rtems_termios_device_context *base)
|
||||
{
|
||||
return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
|
||||
}
|
||||
|
||||
static ns16550_context altera_cyclone_v_uart_context_0 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||
.get_reg = altera_cyclone_v_uart_get_register,
|
||||
.set_reg = altera_cyclone_v_uart_set_register,
|
||||
.port = (uintptr_t) ALT_UART0_ADDR,
|
||||
.irq = ALT_INT_INTERRUPT_UART0,
|
||||
.initial_baud = CYCLONE_V_UART_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CYCLONE_V_CONFIG_UART_1
|
||||
static bool altera_cyclone_v_uart_probe_1(rtems_termios_device_context *base)
|
||||
{
|
||||
return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART1_SET_MSK);
|
||||
}
|
||||
|
||||
static ns16550_context altera_cyclone_v_uart_context_1 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||
.get_reg = altera_cyclone_v_uart_get_register,
|
||||
.set_reg = altera_cyclone_v_uart_set_register,
|
||||
.port = (uintptr_t) ALT_UART1_ADDR,
|
||||
.irq = ALT_INT_INTERRUPT_UART1,
|
||||
.initial_baud = CYCLONE_V_UART_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
const console_device console_device_table[] = {
|
||||
#ifdef CYCLONE_V_CONFIG_CONSOLE
|
||||
{
|
||||
.device_file = "/dev/ttyS0",
|
||||
.probe = altera_cyclone_v_uart_probe_0,
|
||||
.handler = DEVICE_FNS,
|
||||
.context = &altera_cyclone_v_uart_context_0.base
|
||||
},
|
||||
#endif
|
||||
#ifdef CYCLONE_V_CONFIG_UART_1
|
||||
{
|
||||
.device_file = "/dev/ttyS1",
|
||||
.probe = altera_cyclone_v_uart_probe_1,
|
||||
.handler = DEVICE_FNS,
|
||||
.context = &altera_cyclone_v_uart_context_1.base
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||
|
||||
static void output_char(char c)
|
||||
{
|
||||
rtems_termios_device_context *ctx = console_device_table[0].context;
|
||||
|
||||
ns16550_polled_putchar( ctx, c );
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = output_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
@@ -113,9 +113,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq.c
|
||||
librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console.c
|
||||
librtemsbsp_a_SOURCES += console/debug-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/atsam/console/debug-console.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c
|
||||
|
||||
@@ -1,526 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
|
||||
#include <chip.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct {
|
||||
rtems_termios_device_context base;
|
||||
Usart *regs;
|
||||
rtems_vector_number irq;
|
||||
uint32_t id;
|
||||
bool console;
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
bool transmitting;
|
||||
#endif
|
||||
} atsam_usart_context;
|
||||
|
||||
static atsam_usart_context atsam_usart_instances[] = {
|
||||
{
|
||||
.regs = USART0,
|
||||
.irq = USART0_IRQn,
|
||||
.id = ID_USART0
|
||||
}
|
||||
#ifdef USART1
|
||||
, {
|
||||
.regs = USART1,
|
||||
.irq = USART1_IRQn,
|
||||
.id = ID_USART1
|
||||
}
|
||||
#endif
|
||||
#ifdef USART2
|
||||
, {
|
||||
.regs = USART2,
|
||||
.irq = USART2_IRQn,
|
||||
.id = ID_USART2
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
static void atsam_usart_interrupt(void *arg)
|
||||
{
|
||||
rtems_termios_tty *tty = arg;
|
||||
atsam_usart_context *ctx = rtems_termios_get_device_context(tty);
|
||||
Usart *regs = ctx->regs;
|
||||
uint32_t csr = regs->US_CSR;
|
||||
|
||||
while ((csr & US_CSR_RXRDY) != 0) {
|
||||
char c = (char) regs->US_RHR;
|
||||
|
||||
rtems_termios_enqueue_raw_characters(tty, &c, 1);
|
||||
|
||||
csr = regs->US_CSR;
|
||||
}
|
||||
|
||||
if (ctx->transmitting && (csr & US_CSR_TXEMPTY) != 0) {
|
||||
rtems_termios_dequeue_characters(tty, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool atsam_usart_set_attributes(
|
||||
rtems_termios_device_context *base,
|
||||
const struct termios *term
|
||||
)
|
||||
{
|
||||
atsam_usart_context *ctx = (atsam_usart_context *) base;
|
||||
Usart *regs = ctx->regs;
|
||||
rtems_termios_baud_t baud;
|
||||
uint32_t mr;
|
||||
|
||||
baud = rtems_termios_baud_to_number(term->c_ospeed);
|
||||
regs->US_BRGR = (BOARD_MCK / baud) / 16;
|
||||
|
||||
if ((term->c_cflag & CREAD) != 0) {
|
||||
regs->US_CR = US_CR_RXEN | US_CR_TXEN;
|
||||
} else {
|
||||
regs->US_CR = US_CR_TXEN;
|
||||
}
|
||||
|
||||
mr = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK;
|
||||
|
||||
switch (term->c_cflag & CSIZE) {
|
||||
case CS5:
|
||||
mr |= US_MR_CHRL_5_BIT;
|
||||
break;
|
||||
case CS6:
|
||||
mr |= US_MR_CHRL_6_BIT;
|
||||
break;
|
||||
case CS7:
|
||||
mr |= US_MR_CHRL_7_BIT;
|
||||
break;
|
||||
default:
|
||||
mr |= US_MR_CHRL_8_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((term->c_cflag & PARENB) != 0) {
|
||||
if ((term->c_cflag & PARODD) != 0) {
|
||||
mr |= US_MR_PAR_ODD;
|
||||
} else {
|
||||
mr |= US_MR_PAR_EVEN;
|
||||
}
|
||||
} else {
|
||||
mr |= US_MR_PAR_NO;
|
||||
}
|
||||
|
||||
if ((term->c_cflag & CSTOPB) != 0) {
|
||||
mr |= US_MR_NBSTOP_2_BIT;
|
||||
} else {
|
||||
mr |= US_MR_NBSTOP_1_BIT;
|
||||
}
|
||||
|
||||
regs->US_MR = mr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool atsam_usart_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
atsam_usart_context *ctx = (atsam_usart_context *) base;
|
||||
Usart *regs = ctx->regs;
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
rtems_status_code sc;
|
||||
#endif
|
||||
|
||||
regs->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
|
||||
regs->US_IDR = 0xffffffff;
|
||||
|
||||
PMC_EnablePeripheral(ctx->id);
|
||||
|
||||
rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD);
|
||||
atsam_usart_set_attributes(base, term);
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
regs->US_IER = US_IDR_RXRDY;
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ctx->irq,
|
||||
"USART",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
atsam_usart_interrupt,
|
||||
tty
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void atsam_usart_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
atsam_usart_context *ctx = (atsam_usart_context *) base;
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
rtems_interrupt_handler_remove(ctx->irq, atsam_usart_interrupt, tty);
|
||||
#endif
|
||||
|
||||
if (!ctx->console) {
|
||||
PMC_DisablePeripheral(ctx->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void atsam_usart_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
atsam_usart_context *ctx = (atsam_usart_context *) base;
|
||||
Usart *regs = ctx->regs;
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
if (len > 0) {
|
||||
ctx->transmitting = true;
|
||||
regs->US_THR = buf[0];
|
||||
regs->US_IER = US_IDR_TXEMPTY;
|
||||
} else {
|
||||
ctx->transmitting = false;
|
||||
regs->US_IDR = US_IDR_TXEMPTY;
|
||||
}
|
||||
#else
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
while ((regs->US_CSR & US_CSR_TXEMPTY) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
regs->US_THR = buf[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
static int atsam_usart_read(rtems_termios_device_context *base)
|
||||
{
|
||||
atsam_usart_context *ctx = (atsam_usart_context *) base;
|
||||
Usart *regs = ctx->regs;
|
||||
|
||||
if ((regs->US_CSR & US_CSR_RXRDY) != 0) {
|
||||
return (char) regs->US_RHR;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const rtems_termios_device_handler atsam_usart_handler = {
|
||||
.first_open = atsam_usart_first_open,
|
||||
.last_close = atsam_usart_last_close,
|
||||
.write = atsam_usart_write,
|
||||
.set_attributes = atsam_usart_set_attributes,
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
#else
|
||||
.poll_read = atsam_usart_read,
|
||||
.mode = TERMIOS_POLLED
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
rtems_termios_device_context base;
|
||||
Uart *regs;
|
||||
rtems_vector_number irq;
|
||||
uint32_t id;
|
||||
bool console;
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
bool transmitting;
|
||||
#endif
|
||||
} atsam_uart_context;
|
||||
|
||||
static atsam_uart_context atsam_uart_instances[] = {
|
||||
{
|
||||
.regs = UART0,
|
||||
.irq = UART0_IRQn,
|
||||
.id = ID_UART0
|
||||
}
|
||||
#ifdef UART1
|
||||
, {
|
||||
.regs = UART1,
|
||||
.irq = UART1_IRQn,
|
||||
.id = ID_UART1
|
||||
}
|
||||
#endif
|
||||
#ifdef UART2
|
||||
, {
|
||||
.regs = UART2,
|
||||
.irq = UART2_IRQn,
|
||||
.id = ID_UART2
|
||||
}
|
||||
#endif
|
||||
#ifdef UART3
|
||||
, {
|
||||
.regs = UART3,
|
||||
.irq = UART3_IRQn,
|
||||
.id = ID_UART3
|
||||
}
|
||||
#endif
|
||||
#ifdef UART4
|
||||
, {
|
||||
.regs = UART4,
|
||||
.irq = UART4_IRQn,
|
||||
.id = ID_UART4
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
static void atsam_uart_interrupt(void *arg)
|
||||
{
|
||||
rtems_termios_tty *tty = arg;
|
||||
atsam_uart_context *ctx = rtems_termios_get_device_context(tty);
|
||||
Uart *regs = ctx->regs;
|
||||
uint32_t sr = regs->UART_SR;
|
||||
|
||||
while ((sr & UART_SR_RXRDY) != 0) {
|
||||
char c = (char) regs->UART_RHR;
|
||||
|
||||
rtems_termios_enqueue_raw_characters(tty, &c, 1);
|
||||
|
||||
sr = regs->UART_SR;
|
||||
}
|
||||
|
||||
if (ctx->transmitting && (sr & UART_SR_TXEMPTY) != 0) {
|
||||
rtems_termios_dequeue_characters(tty, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool atsam_uart_set_attributes(
|
||||
rtems_termios_device_context *base,
|
||||
const struct termios *term
|
||||
)
|
||||
{
|
||||
atsam_uart_context *ctx = (atsam_uart_context *) base;
|
||||
Uart *regs = ctx->regs;
|
||||
rtems_termios_baud_t baud;
|
||||
uint32_t mr;
|
||||
|
||||
baud = rtems_termios_baud_to_number(term->c_ospeed);
|
||||
regs->UART_BRGR = (BOARD_MCK / baud) / 16;
|
||||
|
||||
if ((term->c_cflag & CREAD) != 0) {
|
||||
regs->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
||||
} else {
|
||||
regs->UART_CR = UART_CR_TXEN;
|
||||
}
|
||||
|
||||
mr = UART_MR_FILTER_DISABLED | UART_MR_BRSRCCK_PERIPH_CLK;
|
||||
|
||||
if ((term->c_cflag & CSIZE) != CS8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((term->c_cflag & PARENB) != 0) {
|
||||
if ((term->c_cflag & PARODD) != 0) {
|
||||
mr |= UART_MR_PAR_ODD;
|
||||
} else {
|
||||
mr |= UART_MR_PAR_EVEN;
|
||||
}
|
||||
} else {
|
||||
mr |= UART_MR_PAR_NO;
|
||||
}
|
||||
|
||||
if ((term->c_cflag & CSTOPB) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
regs->UART_MR = mr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool atsam_uart_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
atsam_uart_context *ctx = (atsam_uart_context *) base;
|
||||
Uart *regs = ctx->regs;
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
rtems_status_code sc;
|
||||
#endif
|
||||
|
||||
regs->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
|
||||
regs->UART_IDR = 0xffffffff;
|
||||
|
||||
PMC_EnablePeripheral(ctx->id);
|
||||
|
||||
rtems_termios_set_initial_baud(tty, ATSAM_CONSOLE_BAUD);
|
||||
atsam_uart_set_attributes(base, term);
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
regs->UART_IER = UART_IDR_RXRDY;
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ctx->irq,
|
||||
"UART",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
atsam_uart_interrupt,
|
||||
tty
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void atsam_uart_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
atsam_uart_context *ctx = (atsam_uart_context *) base;
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
rtems_interrupt_handler_remove(ctx->irq, atsam_uart_interrupt, tty);
|
||||
#endif
|
||||
|
||||
if (!ctx->console) {
|
||||
PMC_DisablePeripheral(ctx->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void atsam_uart_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
atsam_uart_context *ctx = (atsam_uart_context *) base;
|
||||
Uart *regs = ctx->regs;
|
||||
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
if (len > 0) {
|
||||
ctx->transmitting = true;
|
||||
regs->UART_THR = buf[0];
|
||||
regs->UART_IER = UART_IDR_TXEMPTY;
|
||||
} else {
|
||||
ctx->transmitting = false;
|
||||
regs->UART_IDR = UART_IDR_TXEMPTY;
|
||||
}
|
||||
#else
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
while ((regs->UART_SR & UART_SR_TXEMPTY) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
regs->UART_THR = buf[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
static int atsam_uart_read(rtems_termios_device_context *base)
|
||||
{
|
||||
atsam_uart_context *ctx = (atsam_uart_context *) base;
|
||||
Uart *regs = ctx->regs;
|
||||
|
||||
if ((regs->UART_SR & UART_SR_RXRDY) != 0) {
|
||||
return (char) regs->UART_RHR;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const rtems_termios_device_handler atsam_uart_handler = {
|
||||
.first_open = atsam_uart_first_open,
|
||||
.last_close = atsam_uart_last_close,
|
||||
.write = atsam_uart_write,
|
||||
.set_attributes = atsam_uart_set_attributes,
|
||||
#ifdef ATSAM_CONSOLE_USE_INTERRUPTS
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
#else
|
||||
.poll_read = atsam_uart_read,
|
||||
.mode = TERMIOS_POLLED
|
||||
#endif
|
||||
};
|
||||
|
||||
rtems_status_code console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_usart_instances); ++i) {
|
||||
char usart[] = "/dev/ttyUSARTX";
|
||||
|
||||
usart[sizeof(usart) - 2] = (char) ('0' + i);
|
||||
rtems_termios_device_install(
|
||||
&usart[0],
|
||||
&atsam_usart_handler,
|
||||
NULL,
|
||||
&atsam_usart_instances[i].base
|
||||
);
|
||||
|
||||
#if ATSAM_CONSOLE_DEVICE_TYPE == 0
|
||||
if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
|
||||
atsam_usart_instances[i].console = true;
|
||||
link(&usart[0], CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) {
|
||||
char uart[] = "/dev/ttyUARTX";
|
||||
|
||||
uart[sizeof(uart) - 2] = (char) ('0' + i);
|
||||
rtems_termios_device_install(
|
||||
&uart[0],
|
||||
&atsam_uart_handler,
|
||||
NULL,
|
||||
&atsam_uart_instances[i].base
|
||||
);
|
||||
|
||||
#if ATSAM_CONSOLE_DEVICE_TYPE == 1
|
||||
if (i == ATSAM_CONSOLE_DEVICE_INDEX) {
|
||||
atsam_uart_instances[i].console = true;
|
||||
link(&uart[0], CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/sysinit.h>
|
||||
|
||||
#include <bsp/atsam-clock-config.h>
|
||||
#include <chip.h>
|
||||
#include <include/dbg_console.h>
|
||||
|
||||
static void atsam_debug_console_out(char c)
|
||||
{
|
||||
DBG_PutChar((uint8_t) c);
|
||||
}
|
||||
|
||||
static void atsam_debug_console_init(void)
|
||||
{
|
||||
DBG_Configure(115200, BOARD_MCK);
|
||||
BSP_output_char = atsam_debug_console_out;
|
||||
}
|
||||
|
||||
static void atsam_debug_console_early_init(char c)
|
||||
{
|
||||
atsam_debug_console_init();
|
||||
atsam_debug_console_out(c);
|
||||
}
|
||||
|
||||
static int atsam_debug_console_in(void)
|
||||
{
|
||||
return (int) DBG_GetChar();
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = atsam_debug_console_early_init;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = atsam_debug_console_in;
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
atsam_debug_console_init,
|
||||
RTEMS_SYSINIT_BSP_START,
|
||||
RTEMS_SYSINIT_ORDER_LAST
|
||||
);
|
||||
@@ -65,7 +65,7 @@ librtemsbsp_a_SOURCES += irq.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/console/console-config.c
|
||||
|
||||
# I2C
|
||||
librtemsbsp_a_SOURCES += i2c/bbb-i2c.c
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup arm_beagle
|
||||
*
|
||||
* @brief Console configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Claas Ziemke. All rights reserved.
|
||||
*
|
||||
* Claas Ziemke
|
||||
* Kernerstrasse 11
|
||||
* 70182 Stuttgart
|
||||
* Germany
|
||||
* <claas.ziemke@gmx.net>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Modified by Ben Gras <beng@shrike-systems.com> to make
|
||||
* interrupt-driven uart i/o work for beagleboards; beaglebone support added.
|
||||
*/
|
||||
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/uart-output-char.h>
|
||||
|
||||
#define CONSOLE_UART_THR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE)
|
||||
#define CONSOLE_UART_RHR (*(volatile unsigned int *)BSP_CONSOLE_UART_BASE)
|
||||
#define CONSOLE_UART_LSR (*(volatile unsigned int *)(BSP_CONSOLE_UART_BASE+0x14))
|
||||
#define CONSOLE_SYSC (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x54))
|
||||
#define CONSOLE_SYSS (*(volatile uint32_t *) (BSP_CONSOLE_UART_BASE + 0x58))
|
||||
|
||||
#define TX_FIFO_E (1<<5)
|
||||
#define RX_FIFO_E (1<<0)
|
||||
|
||||
static uint8_t beagle_uart_get_register(uintptr_t addr, uint8_t i)
|
||||
{
|
||||
uint8_t v;
|
||||
volatile uint32_t *reg_r = (volatile uint32_t *) addr + i;
|
||||
|
||||
if(reg_r == (uint32_t*) BSP_CONSOLE_UART_BASE /* reading RHR */ ) {
|
||||
/* check there should be anything in the RHR before accessing it */
|
||||
if(!(CONSOLE_UART_LSR & 0x01)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
v = (uint8_t) *reg_r;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void beagle_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
reg [i] = val;
|
||||
}
|
||||
|
||||
console_tbl Console_Configuration_Ports [] = {
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS0",
|
||||
.deviceType = SERIAL_NS16550,
|
||||
#if CONSOLE_POLLED /* option to facilitate running the tests */
|
||||
.pDeviceFns = &ns16550_fns_polled,
|
||||
#else
|
||||
.pDeviceFns = &ns16550_fns,
|
||||
#endif
|
||||
.ulMargin = 16,
|
||||
.ulHysteresis = 8,
|
||||
.pDeviceParams = (void *) CONSOLE_BAUD,
|
||||
.ulCtrlPort1 = BSP_CONSOLE_UART_BASE,
|
||||
.ulDataPort = BSP_CONSOLE_UART_BASE,
|
||||
.ulIntVector = BSP_CONSOLE_UART_IRQ,
|
||||
.getRegister = beagle_uart_get_register,
|
||||
.setRegister = beagle_uart_set_register,
|
||||
.ulClock = UART_CLOCK, /* 48MHz base clock */
|
||||
},
|
||||
};
|
||||
|
||||
unsigned long Console_Configuration_Count = 1;
|
||||
|
||||
static int init_needed = 1; // don't rely on bss being 0
|
||||
|
||||
static void beagle_console_init(void)
|
||||
{
|
||||
if(init_needed) {
|
||||
const uint32_t div = UART_CLOCK / 16 / CONSOLE_BAUD;
|
||||
CONSOLE_SYSC = 2;
|
||||
while ((CONSOLE_SYSS & 1) == 0)
|
||||
;
|
||||
if ((CONSOLE_LSR & (CONSOLE_LSR_THRE | CONSOLE_LSR_TEMT)) == CONSOLE_LSR_THRE) {
|
||||
CONSOLE_LCR = 0x83;
|
||||
CONSOLE_DLL = div;
|
||||
CONSOLE_DLM = (div >> 8) & 0xff;
|
||||
CONSOLE_LCR = 0x03;
|
||||
CONSOLE_ACR = 0x00;
|
||||
}
|
||||
|
||||
while ((CONSOLE_LSR & CONSOLE_LSR_TEMT) == 0)
|
||||
;
|
||||
|
||||
CONSOLE_LCR = 0x80 | 0x03;
|
||||
CONSOLE_DLL = 0x00;
|
||||
CONSOLE_DLM = 0x00;
|
||||
CONSOLE_LCR = 0x03;
|
||||
CONSOLE_MCR = 0x03;
|
||||
CONSOLE_FCR = 0x07;
|
||||
CONSOLE_LCR = 0x83;
|
||||
CONSOLE_DLL = div;
|
||||
CONSOLE_DLM = (div >> 8) & 0xff;
|
||||
CONSOLE_LCR = 0x03;
|
||||
CONSOLE_ACR = 0x00;
|
||||
init_needed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define CONSOLE_THR8 (*(volatile uint8_t *) (BSP_CONSOLE_UART_BASE + 0x00))
|
||||
|
||||
static void uart_write_polled( char c )
|
||||
{
|
||||
if(init_needed) beagle_console_init();
|
||||
|
||||
while( ( CONSOLE_LSR & TX_FIFO_E ) == 0 )
|
||||
;
|
||||
CONSOLE_THR8 = c;
|
||||
}
|
||||
|
||||
static void _BSP_put_char( char c ) {
|
||||
uart_write_polled( c );
|
||||
}
|
||||
|
||||
static int _BSP_get_char(void)
|
||||
{
|
||||
if ((CONSOLE_LSR & CONSOLE_LSR_RDR) != 0) {
|
||||
return CONSOLE_RBR;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
|
||||
@@ -30,7 +30,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounter
|
||||
librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/csb336/clock/clockdrv.c
|
||||
librtemsbsp_a_SOURCES += timer/timer.c
|
||||
# console
|
||||
librtemsbsp_a_SOURCES += console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb336/console/uart.c
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
@@ -1,476 +0,0 @@
|
||||
/*
|
||||
* Console driver for MC9328XML UARTs.
|
||||
*
|
||||
* Written Jay Monkman <jtm@lopingdog.com>
|
||||
* Copyright (c) 2005 by Loping Dog Embedded Systems
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license
|
||||
*/
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <libchip/sersupp.h>
|
||||
#include <rtems/error.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <assert.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/irq.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <mc9328mxl.h>
|
||||
#include <rtems/console.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* Define this to use interrupt driver UART driver */
|
||||
#define USE_INTERRUPTS 1
|
||||
|
||||
/* How many serial ports? */
|
||||
#define NUM_DEVS 2
|
||||
#define poll_write(c) imx_uart_poll_write_char(0, c)
|
||||
#define poll_read() imx_uart_poll_read_char(0)
|
||||
|
||||
static int imx_uart_first_open(int, int, void *);
|
||||
static int imx_uart_last_close(int, int, void *);
|
||||
static int imx_uart_poll_read(int);
|
||||
static int imx_uart_set_attrs(int, const struct termios *);
|
||||
static void imx_uart_init(int minor);
|
||||
static void imx_uart_set_baud(int, int);
|
||||
static ssize_t imx_uart_poll_write(int, const char *, size_t);
|
||||
static int imx_uart_poll_read_char(int minor);
|
||||
static void imx_uart_poll_write_char(int minor, char c);
|
||||
static void _BSP_output_char(char c);
|
||||
static int _BSP_poll_char(void);
|
||||
|
||||
#if USE_INTERRUPTS
|
||||
static void imx_uart_tx_isr(void *);
|
||||
static void imx_uart_rx_isr(void *);
|
||||
static void imx_uart_isr_on(rtems_vector_number);
|
||||
static void imx_uart_isr_off(rtems_vector_number);
|
||||
static ssize_t imx_uart_intr_write(int, const char *, size_t);
|
||||
static rtems_vector_number imx_uart_name_transmit(int minor);
|
||||
static rtems_vector_number imx_uart_name_receive(int minor);
|
||||
#endif
|
||||
|
||||
/* TERMIOS callbacks */
|
||||
#if USE_INTERRUPTS
|
||||
rtems_termios_callbacks imx_uart_cbacks = {
|
||||
.firstOpen = imx_uart_first_open,
|
||||
.lastClose = imx_uart_last_close,
|
||||
.pollRead = NULL,
|
||||
.write = imx_uart_intr_write,
|
||||
.setAttributes = imx_uart_set_attrs,
|
||||
.stopRemoteTx = NULL,
|
||||
.startRemoteTx = NULL,
|
||||
.outputUsesInterrupts = 1,
|
||||
};
|
||||
#else
|
||||
rtems_termios_callbacks imx_uart_cbacks = {
|
||||
.firstOpen = imx_uart_first_open,
|
||||
.lastClose = imx_uart_last_close,
|
||||
.pollRead = imx_uart_poll_read,
|
||||
.write = imx_uart_poll_write,
|
||||
.setAttributes = imx_uart_set_attrs,
|
||||
.stopRemoteTx = NULL,
|
||||
.startRemoteTx = NULL,
|
||||
.outputUsesInterrupts = 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int minor;
|
||||
mc9328mxl_uart_regs_t * regs;
|
||||
volatile const char *buf;
|
||||
volatile int len;
|
||||
volatile int idx;
|
||||
void *tty;
|
||||
} imx_uart_data_t;
|
||||
|
||||
static imx_uart_data_t imx_uart_data[NUM_DEVS];
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_DEVS; i++) {
|
||||
imx_uart_init(i);
|
||||
}
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
/* /dev/console and /dev/tty0 are the same */
|
||||
status = rtems_io_register_name("/dev/console", major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("%s:%d Error registering /dev/console :: %d\n",
|
||||
__FUNCTION__, __LINE__, status);
|
||||
}
|
||||
|
||||
status = rtems_io_register_name("/dev/tty0", major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n",
|
||||
__FUNCTION__, __LINE__, status);
|
||||
}
|
||||
|
||||
status = rtems_io_register_name("/dev/tty1", major, 1);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n",
|
||||
__FUNCTION__, __LINE__, status);
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
|
||||
if (minor > (NUM_DEVS - 1)) {
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
}
|
||||
|
||||
rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_close(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_read(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_write(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return rtems_termios_ioctl(arg);
|
||||
}
|
||||
|
||||
static void imx_uart_init(int minor)
|
||||
{
|
||||
imx_uart_data[minor].minor = minor;
|
||||
imx_uart_data[minor].buf = NULL;
|
||||
imx_uart_data[minor].len = 0;
|
||||
imx_uart_data[minor].idx = 0;
|
||||
|
||||
if (minor == 0) {
|
||||
imx_uart_data[minor].regs =
|
||||
(mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE;
|
||||
} else if (minor == 1) {
|
||||
imx_uart_data[minor].regs =
|
||||
(mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE;
|
||||
} else {
|
||||
rtems_panic("%s:%d Unknown UART minor number %d\n",
|
||||
__FUNCTION__, __LINE__, minor);
|
||||
}
|
||||
|
||||
imx_uart_data[minor].regs->cr1 = (
|
||||
MC9328MXL_UART_CR1_UARTCLKEN |
|
||||
MC9328MXL_UART_CR1_UARTEN);
|
||||
|
||||
imx_uart_data[minor].regs->cr2 = (
|
||||
MC9328MXL_UART_CR2_IRTS |
|
||||
MC9328MXL_UART_CR2_WS |
|
||||
MC9328MXL_UART_CR2_TXEN |
|
||||
MC9328MXL_UART_CR2_RXEN |
|
||||
MC9328MXL_UART_CR2_SRST);
|
||||
|
||||
imx_uart_data[minor].regs->cr3 = 0;
|
||||
|
||||
imx_uart_data[minor].regs->cr4 = 0;
|
||||
|
||||
imx_uart_data[minor].regs->fcr = (
|
||||
MC9328MXL_UART_FCR_TXTL(32) |
|
||||
MC9328MXL_UART_FCR_RFDIV_1 |
|
||||
MC9328MXL_UART_FCR_RXTL(1));
|
||||
|
||||
imx_uart_set_baud(minor, 38400);
|
||||
|
||||
}
|
||||
|
||||
static int imx_uart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
rtems_libio_open_close_args_t *args = arg;
|
||||
rtems_status_code status = RTEMS_SUCCESSFUL;
|
||||
|
||||
imx_uart_data[minor].tty = args->iop->data1;
|
||||
|
||||
#if USE_INTERRUPTS
|
||||
status = rtems_interrupt_handler_install(
|
||||
imx_uart_name_transmit(minor),
|
||||
"UART",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
imx_uart_tx_isr,
|
||||
&imx_uart_data[minor]
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
imx_uart_isr_on(imx_uart_name_transmit(minor));
|
||||
|
||||
status = rtems_interrupt_handler_install(
|
||||
imx_uart_name_receive(minor),
|
||||
"UART",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
imx_uart_rx_isr,
|
||||
&imx_uart_data[minor]
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
imx_uart_isr_on(imx_uart_name_receive(minor));
|
||||
|
||||
imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_uart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
#if USE_INTERRUPTS
|
||||
rtems_status_code status = RTEMS_SUCCESSFUL;
|
||||
|
||||
imx_uart_isr_off(imx_uart_name_transmit(minor));
|
||||
status = rtems_interrupt_handler_remove(
|
||||
imx_uart_name_transmit(minor),
|
||||
imx_uart_tx_isr,
|
||||
&imx_uart_data[minor]
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
|
||||
imx_uart_isr_off(imx_uart_name_receive(minor));
|
||||
status = rtems_interrupt_handler_remove(
|
||||
imx_uart_name_receive(minor),
|
||||
imx_uart_rx_isr,
|
||||
&imx_uart_data[minor]
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_uart_poll_read(int minor)
|
||||
{
|
||||
if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) {
|
||||
return imx_uart_data[minor].regs->rxd & 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ssize_t imx_uart_poll_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Wait for there to be room in the fifo */
|
||||
while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
imx_uart_data[minor].regs->txd = buf[i];
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
#if USE_INTERRUPTS
|
||||
static ssize_t imx_uart_intr_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
imx_uart_data[minor].buf = buf;
|
||||
imx_uart_data[minor].len = len;
|
||||
imx_uart_data[minor].idx = 0;
|
||||
|
||||
imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int imx_uart_set_attrs(int minor, const struct termios *t)
|
||||
{
|
||||
int baud;
|
||||
|
||||
baud = rtems_termios_baud_to_number(t->c_ospeed);
|
||||
imx_uart_set_baud(minor, baud);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if USE_INTERRUPTS
|
||||
static void imx_uart_isr_on(rtems_vector_number name)
|
||||
{
|
||||
MC9328MXL_AITC_INTENNUM = name;
|
||||
}
|
||||
static void imx_uart_isr_off(rtems_vector_number name)
|
||||
{
|
||||
MC9328MXL_AITC_INTDISNUM = name;
|
||||
}
|
||||
|
||||
static void imx_uart_rx_isr(void * param)
|
||||
{
|
||||
imx_uart_data_t *uart_data = param;
|
||||
char buf[32];
|
||||
int i=0;
|
||||
|
||||
while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) {
|
||||
buf[i] = uart_data->regs->rxd & 0xff;
|
||||
i++;
|
||||
}
|
||||
|
||||
rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i);
|
||||
}
|
||||
|
||||
static void imx_uart_tx_isr(void * param)
|
||||
{
|
||||
imx_uart_data_t *uart_data = param;
|
||||
int len;
|
||||
int minor = uart_data->minor;
|
||||
|
||||
|
||||
if (uart_data->idx < uart_data->len) {
|
||||
while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) &&
|
||||
(uart_data->idx < uart_data->len)) {
|
||||
uart_data->regs->txd = uart_data->buf[uart_data->idx];
|
||||
uart_data->idx++;
|
||||
}
|
||||
} else {
|
||||
len = uart_data->len;
|
||||
uart_data->len = 0;
|
||||
imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN;
|
||||
rtems_termios_dequeue_characters(uart_data->tty, len);
|
||||
}
|
||||
}
|
||||
|
||||
static rtems_vector_number imx_uart_name_transmit(int minor)
|
||||
{
|
||||
if (minor == 0) {
|
||||
return BSP_INT_UART1_TX;
|
||||
} else if (minor == 1) {
|
||||
return BSP_INT_UART2_TX;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static rtems_vector_number imx_uart_name_receive(int minor)
|
||||
{
|
||||
if (minor == 0) {
|
||||
return BSP_INT_UART1_RX;
|
||||
} else if (minor == 1) {
|
||||
return BSP_INT_UART2_RX;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the UART's baud rate. The calculation is:
|
||||
* (baud * 16) / ref_freq = num/demom
|
||||
*
|
||||
* ref_freq = perclk1 / RFDIV[2:0]
|
||||
* BIR = num - 1
|
||||
* BMR = demom - 1
|
||||
*
|
||||
* Setting 'num' to 16 yields this equation:
|
||||
* demom = ref_freq / baud
|
||||
*/
|
||||
static void imx_uart_set_baud(int minor, int baud)
|
||||
{
|
||||
unsigned int perclk1;
|
||||
unsigned int denom;
|
||||
unsigned int ref_freq = 0;
|
||||
uint32_t fcr;
|
||||
|
||||
perclk1 = get_perclk1_freq();
|
||||
fcr = imx_uart_data[minor].regs->fcr;
|
||||
|
||||
switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) {
|
||||
case MC9328MXL_UART_FCR_RFDIV_1: ref_freq = perclk1/1; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_2: ref_freq = perclk1/2; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_3: ref_freq = perclk1/3; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_4: ref_freq = perclk1/4; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_5: ref_freq = perclk1/5; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_6: ref_freq = perclk1/6; break;
|
||||
case MC9328MXL_UART_FCR_RFDIV_7: ref_freq = perclk1/7; break;
|
||||
default:
|
||||
rtems_panic("%s:%d Unknown RFDIV: 0x%" PRIx32,
|
||||
__FUNCTION__, __LINE__,
|
||||
fcr & MC9328MXL_UART_FCR_RFDIV_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
denom = ref_freq / baud;
|
||||
|
||||
imx_uart_data[minor].regs->bir = 0xf;
|
||||
imx_uart_data[minor].regs->bmr = denom;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Polled, non-blocking read from UART
|
||||
*/
|
||||
static int imx_uart_poll_read_char(int minor)
|
||||
{
|
||||
return imx_uart_poll_read(minor);
|
||||
}
|
||||
|
||||
/*
|
||||
* Polled, blocking write from UART
|
||||
*/
|
||||
static void imx_uart_poll_write_char(int minor, char c)
|
||||
{
|
||||
imx_uart_poll_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for printk() and friends.
|
||||
*/
|
||||
static void _BSP_output_char(char c)
|
||||
{
|
||||
poll_write(c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_output_char;
|
||||
|
||||
static int _BSP_poll_char(void)
|
||||
{
|
||||
return poll_read();
|
||||
}
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ librtemsbsp_a_SOURCES += timer/timer.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/uarts.c
|
||||
librtemsbsp_a_SOURCES += console/dbgu.c
|
||||
librtemsbsp_a_SOURCES += console/usart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/uarts.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/dbgu.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/usart.c
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
if ENABLE_LCD
|
||||
librtemsbsp_a_SOURCES += console/sed1356.c
|
||||
librtemsbsp_a_SOURCES += console/fbcons.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/sed1356.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/csb337/console/fbcons.c
|
||||
endif
|
||||
# umon
|
||||
if ENABLE_UMON
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Console driver for AT91RM9200 DBGU port
|
||||
*
|
||||
* This driver uses the shared console driver in
|
||||
* ...../libbsp/shared/console.c
|
||||
*
|
||||
* Copyright (c) 2003 by Cogent Computer Systems
|
||||
* Written by Mike Kelly <mike@cogcomp.com>
|
||||
* and Jay Monkman <jtm@lopingdog.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <at91rm9200.h>
|
||||
#include <at91rm9200_dbgu.h>
|
||||
#include <at91rm9200_pmc.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
volatile int dbg_dly;
|
||||
|
||||
/* static function prototypes */
|
||||
static int dbgu_first_open(int major, int minor, void *arg);
|
||||
static int dbgu_last_close(int major, int minor, void *arg);
|
||||
static int dbgu_read(int minor);
|
||||
static ssize_t dbgu_write(int minor, const char *buf, size_t len);
|
||||
static void dbgu_init(int minor);
|
||||
static void dbgu_write_polled(int minor, char c);
|
||||
static int dbgu_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns dbgu_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
dbgu_first_open,
|
||||
dbgu_last_close,
|
||||
dbgu_read,
|
||||
dbgu_write,
|
||||
dbgu_init,
|
||||
dbgu_write_polled, /* not used in this driver */
|
||||
dbgu_set_attributes,
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
/*********************************************************************/
|
||||
/* Functions called via callbacks (i.e. the ones in uart_fns */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd enable interrupts here.
|
||||
*/
|
||||
static int dbgu_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd disable interrupts here.
|
||||
*/
|
||||
static int dbgu_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int dbgu_read(int minor)
|
||||
{
|
||||
char c;
|
||||
console_tbl *console_entry;
|
||||
at91rm9200_dbgu_regs_t *dbgu;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
|
||||
|
||||
if (!(dbgu->sr & DBGU_INT_RXRDY)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = dbgu->rhr & 0xff;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write buffer to UART
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t dbgu_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
int i, x;
|
||||
char c;
|
||||
console_tbl *console_entry;
|
||||
at91rm9200_dbgu_regs_t *dbgu;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Wait for fifo to have room */
|
||||
while(1) {
|
||||
if (dbgu->sr & DBGU_INT_TXRDY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = (char) buf[i];
|
||||
dbgu->thr = c;
|
||||
|
||||
/* the TXRDY flag does not seem to update right away (is this true?) */
|
||||
/* so we wait a bit before continuing */
|
||||
for (x = 0; x < 100; x++) {
|
||||
dbg_dly++; /* using a global so this doesn't get optimized out */
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the UART. */
|
||||
static void dbgu_init(int minor)
|
||||
{
|
||||
console_tbl *console_entry;
|
||||
at91rm9200_dbgu_regs_t *dbgu;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
|
||||
|
||||
/* Clear error bits, and reset */
|
||||
dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX);
|
||||
|
||||
/* Clear pending interrupts */
|
||||
dbgu->idr = DBGU_INT_ALL;
|
||||
dbgu->imr = 0;
|
||||
|
||||
/* Set port to no parity, no loopback */
|
||||
dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM;
|
||||
|
||||
/* Set the baud rate */
|
||||
dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud();
|
||||
|
||||
/* Enable the DBGU */
|
||||
dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN);
|
||||
}
|
||||
|
||||
/* This is used for getchark support */
|
||||
static void dbgu_write_polled(int minor, char c)
|
||||
{
|
||||
dbgu_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int dbgu_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* The following functions are not used by TERMIOS, but other RTEMS
|
||||
* functions use them instead.
|
||||
*/
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Read from UART. This is used in the exit code, and can't
|
||||
* rely on interrupts.
|
||||
*/
|
||||
static int dbgu_poll_read(int minor)
|
||||
{
|
||||
return dbgu_read(minor);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a character to the console. This is used by printk() and
|
||||
* maybe other low level functions. It should not use interrupts or any
|
||||
* RTEMS system calls. It needs to be very simple
|
||||
*/
|
||||
static void _BSP_put_char( char c ) {
|
||||
dbgu_write_polled(0, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
||||
|
||||
static int _BSP_poll_char(void)
|
||||
{
|
||||
return dbgu_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* LCD Console Output Driver for CSBx37
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
* from NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
#include "sed1356.h"
|
||||
|
||||
/* static function prototypes */
|
||||
static int fbcons_first_open(int major, int minor, void *arg);
|
||||
static int fbcons_last_close(int major, int minor, void *arg);
|
||||
static int fbcons_read(int minor);
|
||||
static ssize_t fbcons_write(int minor, const char *buf, size_t len);
|
||||
static void fbcons_init(int minor);
|
||||
static void fbcons_write_polled(int minor, char c);
|
||||
static int fbcons_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns fbcons_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
fbcons_first_open,
|
||||
fbcons_last_close,
|
||||
fbcons_read,
|
||||
fbcons_write,
|
||||
fbcons_init,
|
||||
fbcons_write_polled, /* not used in this driver */
|
||||
fbcons_set_attributes,
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
/*********************************************************************/
|
||||
/* Functions called via callbacks (i.e. the ones in uart_fns */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd enable interrupts here.
|
||||
*/
|
||||
static int fbcons_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
/* printk( "Frame buffer -- first open\n" ); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd disable interrupts here.
|
||||
*/
|
||||
static int fbcons_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
/* printk( "Frame buffer -- last close\n" ); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int fbcons_read(int minor)
|
||||
{
|
||||
/* printk( "Frame buffer -- read\n" ); */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write buffer to LCD
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t fbcons_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* printk( "Frame buffer -- write\n" ); */
|
||||
for ( i=0 ; i<len ; i++ )
|
||||
sed_putchar( buf[i] );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the LCD controller. */
|
||||
static void fbcons_init(int minor)
|
||||
{
|
||||
/* printk( "Initializing frame buffer\n" ); */
|
||||
sed_init();
|
||||
}
|
||||
|
||||
/* This is used for putchark support */
|
||||
static void fbcons_write_polled(int minor, char c)
|
||||
{
|
||||
/* printk( "frame buffer -- write polled\n" ); */
|
||||
sed_putchar( c );
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int fbcons_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
/* printk( "frame buffer -- set attributes\n" ); */
|
||||
return 0;
|
||||
}
|
||||
@@ -1,461 +0,0 @@
|
||||
/*
|
||||
* SED1356 Support for KIT637_V6 (CSB637)
|
||||
*
|
||||
* Based upon code from MicroMonitor 1.17 from http://www.umonfw.com/
|
||||
* which includes this notice:
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* General notice:
|
||||
* This code is part of a boot-monitor package developed as a generic base
|
||||
* platform for embedded system designs. As such, it is likely to be
|
||||
* distributed to various projects beyond the control of the original
|
||||
* author. Please notify the author of any enhancements made or bugs found
|
||||
* so that all may benefit from the changes. In addition, notification back
|
||||
* to the author will allow the new user to pick up changes that may have
|
||||
* been made by other users after this version of the code was distributed.
|
||||
*
|
||||
* Note1: the majority of this code was edited with 4-space tabs.
|
||||
* Note2: as more and more contributions are accepted, the term "author"
|
||||
* is becoming a mis-representation of credit.
|
||||
*
|
||||
* Original author: Ed Sutter
|
||||
* Email: esutter@alcatel-lucent.com
|
||||
* Phone: 908-582-2351
|
||||
**************************************************************************
|
||||
*
|
||||
* Ed Sutter has been informed that this code is being used in RTEMS.
|
||||
*
|
||||
* This code was reformatted by Joel Sherrill from OAR Corporation and
|
||||
* Fernando Nicodemos <fgnicodemos@terra.com.br> from NCB - Sistemas
|
||||
* Embarcados Ltda. (Brazil) to be more compliant with RTEMS coding
|
||||
* standards and to eliminate C++ style comments.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "sed1356.h"
|
||||
#include "font8x16.h"
|
||||
|
||||
int mode900lq;
|
||||
long PIXELS_PER_ROW;
|
||||
long PIXELS_PER_COL;
|
||||
long COLS_PER_SCREEN;
|
||||
long ROWS_PER_SCREEN;
|
||||
long SED_HOR_PULSE_WIDTH_LCD;
|
||||
long SED_VER_PULSE_START_LCD;
|
||||
long SED_HOR_PULSE_START_LCD;
|
||||
long SED_HOR_NONDISP_LCD;
|
||||
long SED_VER_NONDISP_LCD;
|
||||
long SED_VER_PULSE_WIDTH_LCD;
|
||||
|
||||
/* globals to keep track of foreground, background colors and x,y position */
|
||||
int sed_color_depth; /* 4, 8 or 16 */
|
||||
int sed_fg_color; /* 0 to 15, used as lookup into VGA color table */
|
||||
int sed_bg_color; /* 0 to 15, used as lookup into VGA color table */
|
||||
int sed_col; /* current column, 0 to COLS_PER_SCREEN - 1 */
|
||||
int sed_row; /* current row, 0 to (ROWS_PER_SCREEN * 2) - 1 */
|
||||
int sed_disp_mode_crt; /* CRT=1, LCD=0 */
|
||||
int sed135x_ok;
|
||||
int sed135x_tst;
|
||||
uint32_t sed_fb_offset; /* current offset into frame buffer for sed_putchar */
|
||||
|
||||
void sed_writechar(uint8_t c);
|
||||
void sed_scroll(void);
|
||||
|
||||
#define SED_REG_BASE 0x30000000 /* *CS2 */
|
||||
#define SED_MEM_BASE (SED_REG_BASE + 0x00200000)
|
||||
#define SED_STEP 1 /* 16-bit port on 16-bit boundry */
|
||||
|
||||
#define SED_REG16(_x_) *(volatile uint16_t *)((uint32_t)SED_REG_BASE + (((uint32_t)_x_ * SED_STEP) ^ 0)) /* Control/Status Registers, 16-bit mode */
|
||||
#define RD_FB16(_reg_,_val_) ((_val_) = *((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))))
|
||||
#define WR_FB16(_reg_,_val_) (*((volatile uint16_t *)(((uint32_t)SED_MEM_BASE + ((uint32_t)(_reg_ * SED_STEP) ^ 0)))) = (_val_))
|
||||
|
||||
#if 0
|
||||
#define SED1356_REG_LCD_HOR_DISP SED_REG16(0x32)
|
||||
#define SED1356_REG_LCD_HOR_NONDISP_and_START SED_REG16(0x34)
|
||||
#define SED1356_REG_LCD_HOR_PULSE SED_REG16(0x36)
|
||||
#define SED1356_REG_LCD_VER_DISP_HT_LO_and_HI SED_REG16(0x38)
|
||||
#define SED1356_REG_LCD_VER_NONDISP_and_START SED_REG16(0x3a)
|
||||
#define SED1356_REG_LCD_VER_PULSE SED_REG16(0x3c)
|
||||
#define SED1356_REG_LCD_DISP_MODE_and_MISC SED_REG16(0x40)
|
||||
#define SED1356_REG_LCD_DISP_START_LO_and_MID SED_REG16(0x42)
|
||||
#define SED1356_REG_LCD_DISP_START_HI SED_REG16(0x44)
|
||||
#define SED1356_REG_LCD_ADD_OFFSET_LO_and_HI SED_REG16(0x46)
|
||||
#define SED1356_REG_LCD_PIXEL_PAN SED_REG16(0x48)
|
||||
#define SED1356_REG_LCD_FIFO_THRESH_LO_and_HI SED_REG16(0x4a)
|
||||
#endif
|
||||
|
||||
|
||||
#define H2SED(_x_) (_x_)
|
||||
|
||||
#define FB_SIZE (640 * 480)
|
||||
#define SED_ROW_SIZE(_depth_) ((PIXELS_PER_ROW * _depth_) / 8)
|
||||
#define SED_FB_SIZE(_depth_) (((PIXELS_PER_COL * PIXELS_PER_ROW) * _depth_) / 8)
|
||||
|
||||
#define FONT_WIDTH 8
|
||||
#define FONT_HEIGHT 16
|
||||
|
||||
#define SED_GET_ADD(_row_, _col_, _depth_) \
|
||||
(((((_row_ * PIXELS_PER_ROW) * FONT_HEIGHT) \
|
||||
+ (_col_ * FONT_WIDTH)) \
|
||||
* _depth_) / 8)
|
||||
|
||||
|
||||
#define SED_GET_PHYS_ADD(_reg_) \
|
||||
(volatile unsigned long)(SED_MEM_BASE + ((_reg_ * SED_STEP) ^ 0))
|
||||
|
||||
|
||||
#include "sed1356_16bit.h"
|
||||
|
||||
/* #define SED_DBG */
|
||||
int sed135x_tst = 0;
|
||||
|
||||
void sed_write_frame_buffer(
|
||||
uint32_t i,
|
||||
uint16_t wr16
|
||||
)
|
||||
{
|
||||
WR_FB16(i, wr16);
|
||||
}
|
||||
|
||||
int sed_frame_buffer_size(void)
|
||||
{
|
||||
return SED_FB_SIZE(sed_color_depth);
|
||||
}
|
||||
|
||||
void sed_clr_row(int char_row)
|
||||
{
|
||||
unsigned long sed_mem_add;
|
||||
int i;
|
||||
uint16_t wr16;
|
||||
|
||||
/* clear the desired row */
|
||||
sed_mem_add = SED_GET_ADD(char_row, 0, sed_color_depth);
|
||||
|
||||
#ifdef SED_DBG
|
||||
sed135x_tst = 1;
|
||||
printf("SED Clear Row %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", char_row, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
|
||||
sed135x_tst = 0;
|
||||
#endif
|
||||
|
||||
switch (sed_color_depth)
|
||||
{
|
||||
case 4:
|
||||
wr16 = ((sed_bg_color << 12) | (sed_bg_color << 8) | (sed_bg_color << 4) | (sed_bg_color << 0));
|
||||
#ifdef SED_DBG
|
||||
sed135x_tst = 1;
|
||||
printf("SED Clear Row %d, FB Add 0x%08lx to 0x%08lx.\n ", char_row, sed_mem_add, sed_mem_add + ((PIXELS_PER_ROW * FONT_HEIGHT) / 2));
|
||||
sed135x_tst = 0;
|
||||
#endif
|
||||
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) / 2); i += 2){
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
sed_mem_add += 2;
|
||||
} /* for font_row */
|
||||
break;
|
||||
case 8:
|
||||
wr16 = ((sed_bg_color << 8) | (sed_bg_color << 0));
|
||||
for (i = 0; i < (PIXELS_PER_ROW * FONT_HEIGHT); i += 2){
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
sed_mem_add += 2;
|
||||
} /* for font_row */
|
||||
break;
|
||||
case 16:
|
||||
wr16 = ((vga_lookup[sed_bg_color]));
|
||||
for (i = 0; i < ((PIXELS_PER_ROW * FONT_HEIGHT) * 2); i += 2){
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
sed_mem_add += 2;
|
||||
} /* for font_row */
|
||||
break;
|
||||
} /* switch sed_color_depth */
|
||||
} /* sed_clr_row */
|
||||
|
||||
void sed_init(void)
|
||||
{
|
||||
mode900lq = 0;
|
||||
PIXELS_PER_ROW = 640;
|
||||
PIXELS_PER_COL = 480;
|
||||
COLS_PER_SCREEN = 80;
|
||||
ROWS_PER_SCREEN = 30;
|
||||
SED_HOR_PULSE_WIDTH_LCD = 0x0b;
|
||||
SED_HOR_NONDISP_LCD = 0x13;
|
||||
SED_VER_PULSE_WIDTH_LCD = 0x01;
|
||||
SED_VER_PULSE_START_LCD = 0x09;
|
||||
SED_VER_NONDISP_LCD = 0x2c;
|
||||
|
||||
sed_color_depth = 16; /* 16 => vga lookup */
|
||||
sed_fg_color = 14; /* Bright Yellow */
|
||||
sed_bg_color = 1; /* Blue */
|
||||
sed_disp_mode_crt = 0; /* default to LCD */
|
||||
sed_fb_offset = 0x00;
|
||||
sed_row = 0;
|
||||
sed_col = 0;
|
||||
|
||||
sed135x_ok = 1;
|
||||
sed135x_tst = 0;
|
||||
sed_clearscreen();
|
||||
}
|
||||
|
||||
/*
|
||||
* sed_putchar()
|
||||
*
|
||||
* This routine parses the character and calls sed_writechar if it is a
|
||||
* printable character
|
||||
*/
|
||||
void sed_putchar(char c)
|
||||
{
|
||||
|
||||
if ((sed135x_ok == 0) || (sed135x_tst == 1)) return;
|
||||
|
||||
/* First parse the character to see if it printable or an
|
||||
* acceptable control character.
|
||||
*/
|
||||
switch (c) {
|
||||
case '\r':
|
||||
sed_col = 0;
|
||||
return;
|
||||
case '\n':
|
||||
sed_col = 0;
|
||||
sed_scroll();
|
||||
return;
|
||||
case '\b':
|
||||
sed_col--;
|
||||
if (sed_col < 0) {
|
||||
sed_row--;
|
||||
if (sed_row < 0)
|
||||
sed_row = 0;
|
||||
sed_col = COLS_PER_SCREEN - 1;
|
||||
}
|
||||
c = 0; /* erase the character */
|
||||
sed_writechar(c);
|
||||
break;
|
||||
default:
|
||||
if (((uint8_t)c < FIRST_CHAR) || ((uint8_t)c > LAST_CHAR))
|
||||
return; /* drop anything we can't print */
|
||||
c -= FIRST_CHAR; /* get aligned to the first printable character */
|
||||
sed_writechar(c);
|
||||
/* advance to next column */
|
||||
sed_col++;
|
||||
if (sed_col == COLS_PER_SCREEN) {
|
||||
sed_col = 0;
|
||||
sed_scroll();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} /* sed_putchar() */
|
||||
|
||||
/*
|
||||
* sed_writechar()
|
||||
*
|
||||
* This routine writes the character to the screen at the current cursor
|
||||
* location.
|
||||
*/
|
||||
void sed_writechar(uint8_t c)
|
||||
{
|
||||
uint32_t sed_mem_add;
|
||||
int font_row, font_col;
|
||||
uint8_t font_data8;
|
||||
uint16_t wr16;
|
||||
|
||||
/* Convert the current row,col and color depth values
|
||||
* into an address
|
||||
*/
|
||||
sed_mem_add = SED_GET_ADD(sed_row, sed_col, sed_color_depth);
|
||||
|
||||
#ifdef SED_DBG
|
||||
sed135x_tst = 1;
|
||||
printf("SED writechar at row %d, col %d, FB Add 0x%08lx, CPU Add 0x%08lx.\n ", sed_row, sed_col, sed_mem_add, SED_GET_PHYS_ADD(sed_mem_add));
|
||||
sed135x_tst = 0;
|
||||
#endif
|
||||
|
||||
if (FONT_WIDTH == 8) {
|
||||
switch (sed_color_depth) {
|
||||
case 4:
|
||||
/* Now render the font by painting one font row at a time */
|
||||
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
|
||||
/* get the font row of data */
|
||||
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
|
||||
|
||||
|
||||
for (font_col = 0; font_col < 8; font_col += 4)
|
||||
{
|
||||
/* get a words worth of pixels */
|
||||
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 12 : sed_bg_color << 12)
|
||||
| ((font_data8 & 0x40) ? sed_fg_color << 8 : sed_bg_color << 8)
|
||||
| ((font_data8 & 0x20) ? sed_fg_color << 4 : sed_bg_color << 4)
|
||||
| ((font_data8 & 0x10) ? sed_fg_color << 0 : sed_bg_color << 0));
|
||||
font_data8 = font_data8 << 4;
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
/* if we are in the 2nd frame buffer, write to the 1st
|
||||
* frame buffer also
|
||||
*/
|
||||
if (sed_row > (ROWS_PER_SCREEN - 1)) {
|
||||
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
|
||||
}
|
||||
sed_mem_add += 2;
|
||||
} /* for font_col */
|
||||
/* go to the next pixel row */
|
||||
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
|
||||
} /* for font_row */
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* Now render the font by painting one font row at a time */
|
||||
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
|
||||
/* get the font row of data */
|
||||
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
|
||||
for (font_col = 0; font_col < 8; font_col += 2)
|
||||
{
|
||||
/* get a words worth of pixels */
|
||||
wr16 = (((font_data8 & 0x80) ? sed_fg_color << 8 : sed_bg_color << 8)
|
||||
| ((font_data8 & 0x40) ? sed_fg_color << 0 : sed_bg_color << 0));
|
||||
font_data8 = font_data8 << 2;
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
/* if we are in the 2nd frame buffer, write to the 1st
|
||||
* frame buffer also
|
||||
*/
|
||||
if (sed_row > (ROWS_PER_SCREEN - 1)) {
|
||||
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
|
||||
}
|
||||
sed_mem_add += 2;
|
||||
} /* for font_col */
|
||||
/* go to the next pixel row */
|
||||
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
|
||||
} /* for font_row */
|
||||
break;
|
||||
|
||||
case 16:
|
||||
/* Now render the font by painting one font row at a time */
|
||||
for (font_row = 0; font_row < FONT_HEIGHT; font_row++) {
|
||||
/* get the font row of data */
|
||||
font_data8 = font8x16[(c * FONT_HEIGHT) + font_row];
|
||||
for (font_col = 0; font_col < 8; font_col++)
|
||||
{
|
||||
/* get a words worth of pixels */
|
||||
wr16 = ((font_data8 & 0x80) ?
|
||||
vga_lookup[sed_fg_color] : vga_lookup[sed_bg_color]);
|
||||
font_data8 = font_data8 << 1;
|
||||
WR_FB16(sed_mem_add, wr16);
|
||||
/* if we are in the 2nd frame buffer, write to the 1st
|
||||
* frame buffer also.
|
||||
*/
|
||||
if (sed_row > (ROWS_PER_SCREEN - 1)) {
|
||||
WR_FB16((sed_mem_add - SED_FB_SIZE(sed_color_depth)), wr16);
|
||||
}
|
||||
sed_mem_add += 2;
|
||||
} /* for font_col */
|
||||
/* go to the next pixel row */
|
||||
sed_mem_add += (SED_ROW_SIZE(sed_color_depth) - ((FONT_WIDTH * sed_color_depth) / 8));
|
||||
} /* for font_row */
|
||||
break;
|
||||
|
||||
} /* switch sed_color depth */
|
||||
} /* FONT_WIDTH == 8 */
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
} /* sed_writechar() */
|
||||
|
||||
static void sed_update_fb_offset(void)
|
||||
{
|
||||
/* write the new sed_fb_offset value */
|
||||
if (sed_disp_mode_crt) {
|
||||
/* before we change the address offset, wait for the display to
|
||||
* go from active to non-active, unless the display is not enabled
|
||||
*/
|
||||
if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_CRT)) { /* CRT is on */
|
||||
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {}
|
||||
while ((SED1356_REG_CRT_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {}
|
||||
}
|
||||
SED1356_REG_CRT_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0));
|
||||
SED1356_REG_CRT_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16));
|
||||
}
|
||||
else /* LCD */
|
||||
{
|
||||
if (SED1356_REG_DISP_MODE & H2SED(SED1356_DISP_MODE_LCD)) { /* LCD is on */
|
||||
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 0) {}
|
||||
while ((SED1356_REG_LCD_VER_NONDISP_and_START & H2SED(SED1356_VER_NONDISP)) == 1) {}
|
||||
}
|
||||
SED1356_REG_LCD_DISP_START_LO_and_MID = H2SED(((sed_fb_offset & 0x00ffff) >> 0));
|
||||
SED1356_REG_LCD_DISP_START_HI = H2SED(((sed_fb_offset & 0x070000) >> 16));
|
||||
}
|
||||
}
|
||||
|
||||
/* sed_scroll()
|
||||
*
|
||||
* Because we are most likely running out of FLASH and probably also with
|
||||
* cache disabled, a brute force memcpy of the whole screen would be very
|
||||
* slow, even with reduced color depths. Instead, we define a frame buffer
|
||||
* that is twice the size of our actual display. This does limit us to a
|
||||
* 1Mbyte active display size, but 640 x 480 @ 16-bits/pixel = 614K so it
|
||||
* works just fine. 800 x 600 can be had by reducing the color depth to
|
||||
* 8-bits/pixel and using the look up tables.
|
||||
*
|
||||
* With the double buffering, we always write to the first buffer, even
|
||||
* when the second buffer is active. This allows us to scroll by adjusting
|
||||
* the starting and ending addresses in the SED135x by one row. When we
|
||||
* reach the end of our virtual buffer, we reset the starting and ending
|
||||
* addresses to the first buffer. Note that we can not adjust the SED135x
|
||||
* registers until it is in vertical retrace. That means we have to wait
|
||||
* until it is in active display, then goes to non-display, unless the
|
||||
* screen is blanked, in which case we can update immediately.
|
||||
*/
|
||||
void sed_scroll(void)
|
||||
{
|
||||
sed_row++;
|
||||
|
||||
/* clear the new row(s) */
|
||||
sed_clr_row(sed_row);
|
||||
if (sed_row > (ROWS_PER_SCREEN - 1)) {
|
||||
sed_clr_row(sed_row - ROWS_PER_SCREEN);
|
||||
}
|
||||
/* when sed_y_pos is greater than ROWS_PER_SCREEN we just adjust the
|
||||
* start and end addresses in the SED135x. If it is equal to 2 *
|
||||
* ROWS_PER_SCREEN, we reset the start and end addresses to SED_MEM_BASE.
|
||||
*/
|
||||
if (sed_row > (ROWS_PER_SCREEN - 1)) {
|
||||
if (sed_row > ((ROWS_PER_SCREEN * 2) - 1)) {
|
||||
sed_fb_offset = 0x00;
|
||||
sed_row = 0;
|
||||
sed_clearscreen();
|
||||
} else {
|
||||
/* calculate the new offset address of the frame buffer in words */
|
||||
sed_fb_offset += (SED_GET_ADD(1, 0, sed_color_depth) / 2);
|
||||
}
|
||||
sed_update_fb_offset();
|
||||
} /* if (sed_row > (ROWS_PER_SCREEN - 1)) */
|
||||
}
|
||||
|
||||
void sed_putstring(char *s)
|
||||
{
|
||||
char *p = s;
|
||||
while (*p)
|
||||
sed_putchar(*p++);
|
||||
}
|
||||
|
||||
void sed_clearscreen(void)
|
||||
{
|
||||
int i;
|
||||
uint16_t wr16;
|
||||
int bg = sed_bg_color;
|
||||
int fbsize = sed_frame_buffer_size();
|
||||
|
||||
/* we double buffer so clear ALL of memory */
|
||||
fbsize *= 2;
|
||||
|
||||
/* fill the frame buffer with incrementing color values */
|
||||
switch (sed_color_depth){
|
||||
case 4: wr16 = bg | bg << 4 | bg << 8 | bg << 12; break;
|
||||
case 8: wr16 = bg | bg << 8; break;
|
||||
/* 16-bits bypasses the lookup table */
|
||||
default: wr16 = vga_lookup[bg]; break;
|
||||
}
|
||||
for (i = 0; i < fbsize; i += 2){
|
||||
sed_write_frame_buffer(i, wr16);
|
||||
}
|
||||
}
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Console driver for for KIT637_V6 (CSB637)
|
||||
*
|
||||
* This driver uses the shared console driver in
|
||||
* ...../libbsp/shared/console.c
|
||||
*
|
||||
* Copyright (c) 2003 by Cogent Computer Systems
|
||||
* Written by Jay Monkman <jtm@lopingdog.com>
|
||||
*
|
||||
* Modified by Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
* from NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Modified and FrameBuffer Console Device Support added by
|
||||
* Joel Sherrill, 2009.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <at91rm9200.h>
|
||||
#include <at91rm9200_dbgu.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
#include <bspopts.h>
|
||||
|
||||
extern const console_fns dbgu_fns;
|
||||
|
||||
#if ENABLE_LCD
|
||||
extern const console_fns fbcons_fns;
|
||||
#define LCD_DEV 1
|
||||
#else
|
||||
#define LCD_DEV 0
|
||||
#endif
|
||||
|
||||
#if (ENABLE_UMON && ENABLE_UMON_CONSOLE)
|
||||
extern const console_fns umoncons_fns;
|
||||
#define UMON_CONS_DEV 1
|
||||
#else
|
||||
#define UMON_CONS_DEV 0
|
||||
#endif
|
||||
|
||||
#if ENABLE_USART0 || ENABLE_USART1 || ENABLE_USART2 || ENABLE_USART3
|
||||
extern const console_fns usart_polling_fns;
|
||||
#endif
|
||||
|
||||
#if ENABLE_USART0
|
||||
#define USART0_DEV 1
|
||||
#else
|
||||
#define USART0_DEV 0
|
||||
#endif
|
||||
|
||||
#if ENABLE_USART1
|
||||
#define USART1_DEV 1
|
||||
#else
|
||||
#define USART1_DEV 0
|
||||
#endif
|
||||
|
||||
#if ENABLE_USART2
|
||||
#define USART2_DEV 1
|
||||
#else
|
||||
#define USART2_DEV 0
|
||||
#endif
|
||||
|
||||
#if ENABLE_USART3
|
||||
#define USART3_DEV 1
|
||||
#else
|
||||
#define USART3_DEV 0
|
||||
#endif
|
||||
|
||||
#define NUM_DEVS \
|
||||
(1 + LCD_DEV + UMON_CONS_DEV + \
|
||||
USART0_DEV + USART1_DEV + USART2_DEV + USART3_DEV)
|
||||
|
||||
/* These are used by code in console.c */
|
||||
unsigned long Console_Configuration_Count = NUM_DEVS;
|
||||
|
||||
/*
|
||||
* There's one item in array for each UART.
|
||||
*
|
||||
* Some of these fields are marked "NOT USED". They are not used
|
||||
* by console.c, but may be used by drivers in libchip
|
||||
*
|
||||
* when we add other types of UARTS we will need to move this
|
||||
* structure to a generic uart.c file with only this in it
|
||||
*/
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
{
|
||||
"/dev/com0", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&dbgu_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
DBGU_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#if ENABLE_LCD
|
||||
{
|
||||
"/dev/fbcons", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&fbcons_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
0, /* ulCtrlPort1 - Pointer to DBGU regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#endif
|
||||
#if (ENABLE_UMON && ENABLE_UMON_CONSOLE)
|
||||
{
|
||||
"/dev/umon", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&umoncons_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
0, /* ulCtrlPort1 - Pointer to UMON regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#endif
|
||||
#if ENABLE_USART0
|
||||
{
|
||||
"/dev/com1", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&usart_polling_fns,/* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
USART0_BASE, /* ulCtrlPort1 - Pointer to USART 0 regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#endif
|
||||
#if ENABLE_USART1
|
||||
{
|
||||
"/dev/com2", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&usart_polling_fns,/* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
USART1_BASE, /* ulCtrlPort1 - Pointer to USART 1 regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#endif
|
||||
#if ENABLE_USART2
|
||||
{
|
||||
"/dev/com3", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&usart_polling_fns,/* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
USART2_BASE, /* ulCtrlPort1 - Pointer to USART 2 regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
},
|
||||
#endif
|
||||
#if ENABLE_USART3
|
||||
{
|
||||
"/dev/com4", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&usart_polling_fns,/* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
USART3_BASE, /* ulCtrlPort1 - Pointer to USART 3 regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
console_tbl *BSP_get_uart_from_minor(int minor)
|
||||
{
|
||||
return Console_Port_Tbl[minor];
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Driver for AT91RM9200 USART ports
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 2006-2009.
|
||||
* NCB - Sistemas Embarcados Ltda. (Brazil)
|
||||
* Fernando Nicodemos <fgnicodemos@terra.com.br>
|
||||
*
|
||||
* and
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <at91rm9200.h>
|
||||
#include <at91rm9200_usart.h>
|
||||
#include <at91rm9200_pmc.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
/* static function prototypes */
|
||||
static int usart_first_open(int major, int minor, void *arg);
|
||||
static int usart_last_close(int major, int minor, void *arg);
|
||||
static int usart_read_polled(int minor);
|
||||
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
|
||||
static void usart_init(int minor);
|
||||
static void usart_write_polled(int minor, char c);
|
||||
static int usart_set_attributes(int minor, const struct termios *t);
|
||||
at91rm9200_usart_regs_t *usart_get_base(int minor);
|
||||
|
||||
/* Pointers to functions for handling the UART polled. */
|
||||
const console_fns usart_polling_fns = {
|
||||
libchip_serial_default_probe, /* deviceProbe */
|
||||
usart_first_open, /* deviceFirstOpen */
|
||||
usart_last_close, /* deviceLastClose */
|
||||
usart_read_polled, /* deviceRead */
|
||||
usart_write_polled_support, /* deviceWrite */
|
||||
usart_init, /* deviceInitialize */
|
||||
usart_write_polled, /* deviceWritePolled */
|
||||
usart_set_attributes, /* deviceSetAttributes */
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
|
||||
at91rm9200_usart_regs_t *usart_get_base(int minor)
|
||||
{
|
||||
console_tbl *console_entry;
|
||||
at91rm9200_usart_regs_t *port;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL)
|
||||
return 0;
|
||||
|
||||
port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
|
||||
//printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port );
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions called via callbacks (i.e. the ones in uart_fns
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd enable interrupts here.
|
||||
*/
|
||||
static int usart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return -1;
|
||||
|
||||
/* XXX port isn't being initialized or enabled */
|
||||
|
||||
/* XXX I hope this is enough */
|
||||
usart->cr = (US_CR_RXEN | US_CR_TXEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd disable interrupts here.
|
||||
*/
|
||||
static int usart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int usart_read_polled(int minor)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return -1;
|
||||
|
||||
/* if nothing ready return -1 */
|
||||
if ( (usart->sr & US_IER_RXRDY) == 0 )
|
||||
return -1;
|
||||
|
||||
return usart->rhr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write character out
|
||||
*/
|
||||
static void usart_write_polled(int minor, char c)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return;
|
||||
|
||||
/* delay until TX empty */
|
||||
while ( (usart->sr & US_IER_TXEMPTY) == 0 )
|
||||
;
|
||||
|
||||
usart->thr = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write buffer to UART
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
int nwrite=0;
|
||||
|
||||
/*
|
||||
* Verify the minor number
|
||||
*/
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* poll each byte in the string out of the port.
|
||||
*/
|
||||
while (nwrite < len) {
|
||||
usart_write_polled(minor, *buf++);
|
||||
nwrite++;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the number of bytes written.
|
||||
*/
|
||||
return nwrite;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the UART. */
|
||||
static void usart_init(int minor)
|
||||
{
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int usart_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
uint32_t brgr;
|
||||
uint32_t mode, baud, baud_requested;
|
||||
at91rm9200_usart_regs_t *usart;
|
||||
|
||||
usart = usart_get_base(minor);
|
||||
if ( !usart )
|
||||
return -1;
|
||||
|
||||
/* Get current mode register */
|
||||
mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
|
||||
| US_MR_PAR | US_MR_NBSTOP);
|
||||
|
||||
/* Byte size */
|
||||
switch (t->c_cflag & CSIZE){
|
||||
case CS5:
|
||||
mode |= US_MR_CHRL_5;
|
||||
break;
|
||||
case CS6:
|
||||
mode |= US_MR_CHRL_6;
|
||||
break;
|
||||
case CS7:
|
||||
mode |= US_MR_CHRL_7;
|
||||
break;
|
||||
default:
|
||||
mode |= US_MR_CHRL_8;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stop bits */
|
||||
if (t->c_cflag & CSTOPB){
|
||||
mode |= US_MR_NBSTOP_2; /* 2 stop bits */
|
||||
} else
|
||||
mode |= US_MR_NBSTOP_1; /* 1 stop bits */
|
||||
|
||||
/* Parity */
|
||||
if (t->c_cflag & PARENB){
|
||||
/* Mark or Space parity */
|
||||
if (t->c_cflag & PARODD){
|
||||
mode |= US_MR_PAR_ODD;
|
||||
} else
|
||||
mode |= US_MR_PAR_EVEN;
|
||||
} else
|
||||
mode |= US_MR_PAR_NONE;
|
||||
|
||||
baud_requested = t->c_ospeed;
|
||||
|
||||
/* If not, set the dbgu console baud as USART baud default */
|
||||
if (!baud_requested)
|
||||
baud_requested = BSP_get_baud();
|
||||
|
||||
baud = rtems_termios_baud_to_number(baud_requested);
|
||||
|
||||
brgr = (at91rm9200_get_mck() / 16) / baud;
|
||||
|
||||
if (brgr > 65535){ /* BRGR is 16-bit, so switch to slower clock */
|
||||
brgr /= 8;
|
||||
mode |= US_MR_USCLKS_MCK_DIV8;
|
||||
}
|
||||
|
||||
usart->mr = mode;
|
||||
usart->brgr = brgr;
|
||||
return 0;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/edb7312/clock/clockdrv.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/edb7312/console/uart.c
|
||||
# timer
|
||||
librtemsbsp_a_SOURCES += timer/timer.c
|
||||
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Cirrus EP7312 Console Driver
|
||||
*
|
||||
* Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h> /* Must be before libio.h */
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <ep7312.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
#define NUM_DEVS 1
|
||||
int uart_poll_read(int minor);
|
||||
|
||||
static int uart_first_open(int major, int minor, void *arg);
|
||||
static int uart_last_close(int major, int minor, void *arg);
|
||||
static int uart_read(int minor);
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len);
|
||||
static void uart_init(int minor);
|
||||
static void uart_write_polled(int minor, char c);
|
||||
static int uart_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
unsigned long Console_Configuration_Count = NUM_DEVS;
|
||||
|
||||
const console_fns uart_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
uart_first_open,
|
||||
uart_last_close,
|
||||
uart_read,
|
||||
uart_write,
|
||||
uart_init,
|
||||
uart_write_polled,
|
||||
uart_set_attributes,
|
||||
FALSE
|
||||
};
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
{
|
||||
"/dev/com0", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&uart_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
NULL, /* pDeviceParams */
|
||||
(uint32_t)EP7312_UARTCR1, /* ulCtrlPort1 */
|
||||
(uint32_t)EP7312_SYSFLG1, /* ulCtrlPort2 */
|
||||
(uint32_t)EP7312_UARTDR1, /* ulDataPort */
|
||||
0, /* getRegister */
|
||||
0, /* setRegister */
|
||||
0, /* getData */
|
||||
0, /* setData */
|
||||
0, /* ulClock */
|
||||
0 /* ulIntVector */
|
||||
}};
|
||||
|
||||
static int uart_first_open(int major, int minor, void *arg) {return 0;}
|
||||
static int uart_last_close(int major, int minor, void *arg) {return 0;}
|
||||
static int uart_read(int minor)
|
||||
{
|
||||
return uart_poll_read(minor);
|
||||
}
|
||||
|
||||
static void uart_write_polled(int minor, char c)
|
||||
{
|
||||
uart_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
static int uart_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uart_poll_read(int minor)
|
||||
{
|
||||
volatile uint32_t *data_reg;
|
||||
volatile uint32_t *ctrl_reg2;
|
||||
char c;
|
||||
int err;
|
||||
|
||||
data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort;
|
||||
ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2;
|
||||
|
||||
if ((*ctrl_reg2 & EP7312_UART_URXFE1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = *data_reg;
|
||||
c = err & 0xff;
|
||||
err &= (EP7312_UART_FRMERR | EP7312_UART_PARERR | EP7312_UART_OVERR);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static ssize_t uart_do_write(
|
||||
volatile uint32_t *uartdr,
|
||||
const char *buf,
|
||||
size_t len,
|
||||
volatile uint32_t *sysflg
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Wait for fifo to have room */
|
||||
while ((*sysflg & EP7312_UART_UTXFF1) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*uartdr = buf[i];
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
volatile uint32_t *data_reg;
|
||||
volatile uint32_t *ctrl_reg2;
|
||||
|
||||
data_reg = (uint32_t *)Console_Port_Tbl[minor]->ulDataPort;
|
||||
ctrl_reg2 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort2;
|
||||
|
||||
return uart_do_write(data_reg, buf, len, ctrl_reg2);
|
||||
}
|
||||
|
||||
static void uart_init(int minor)
|
||||
{
|
||||
volatile uint32_t *ctrl_reg1;
|
||||
|
||||
ctrl_reg1 = (uint32_t *)Console_Port_Tbl[minor]->ulCtrlPort1;
|
||||
|
||||
/* *ctrl_reg = (BSP_UART_DATA8 |
|
||||
BSP_UART_STOP1 |
|
||||
BSP_UART_PARITY_NONE |
|
||||
EP7312_UART_FIFOEN |
|
||||
BSP_UART_BAUD_9600);
|
||||
*/
|
||||
*ctrl_reg1 = (EP7312_UART_WRDLEN8 |
|
||||
EP7312_UART_FIFOEN |
|
||||
0x17); /* 9600 baud */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Debug IO support
|
||||
*/
|
||||
static void _BSP_null_char(char c)
|
||||
{
|
||||
uart_do_write(EP7312_UARTDR1, &c, 1, EP7312_SYSFLG1);
|
||||
}
|
||||
|
||||
static int _BSP_get_char(void)
|
||||
{
|
||||
return uart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_null_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
|
||||
@@ -28,8 +28,8 @@ librtemsbsp_a_SOURCES += startup/syscalls.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterread.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterdiff.c
|
||||
# console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-polled.c
|
||||
librtemsbsp_a_SOURCES += console/console-io.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gdbarmsim/console/console-io.c
|
||||
# clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c
|
||||
# timer
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2009.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/console-polled.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* console_initialize_hardware
|
||||
*
|
||||
* This routine initializes the console hardware.
|
||||
*
|
||||
*/
|
||||
void console_initialize_hardware(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* console_outbyte_polled
|
||||
*
|
||||
* This routine transmits a character using polling.
|
||||
*/
|
||||
void console_outbyte_polled(
|
||||
int port,
|
||||
char ch
|
||||
)
|
||||
{
|
||||
gdbarmsim_writec(ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* console_inbyte_nonblocking
|
||||
*
|
||||
* This routine polls for a character.
|
||||
*/
|
||||
|
||||
int console_inbyte_nonblocking(
|
||||
int port
|
||||
)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
static void MyBSP_output_char(char c) { console_outbyte_polled( 0, c ); }
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = MyBSP_output_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
@@ -33,8 +33,8 @@ librtemsbsp_a_SOURCES += timer/timer.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/uarts.c
|
||||
librtemsbsp_a_SOURCES += console/ffuart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/uarts.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/gumstix/console/ffuart.c
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Console driver for pxa255 full function port by Yang Xi <hiyangxi@gmail.com>
|
||||
* Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <pxa255.h>
|
||||
#include <ffuart.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
volatile int dbg_dly;
|
||||
|
||||
/* static function prototypes */
|
||||
static int ffuart_first_open(int major, int minor, void *arg);
|
||||
static int ffuart_last_close(int major, int minor, void *arg);
|
||||
static int ffuart_read(int minor);
|
||||
static ssize_t ffuart_write(int minor, const char *buf, size_t len);
|
||||
static void ffuart_init(int minor);
|
||||
static void ffuart_write_polled(int minor, char c);
|
||||
static int ffuart_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns ffuart_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
ffuart_first_open,
|
||||
ffuart_last_close,
|
||||
ffuart_read,
|
||||
ffuart_write,
|
||||
ffuart_init,
|
||||
ffuart_write_polled, /* not used in this driver */
|
||||
ffuart_set_attributes,
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd enable interrupts here.
|
||||
*/
|
||||
static int ffuart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. Since
|
||||
* the driver is polled, we don't have to do anything. If the driver
|
||||
* were interrupt driven, we'd disable interrupts here.
|
||||
*/
|
||||
static int ffuart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int ffuart_read(int minor)
|
||||
{
|
||||
char c;
|
||||
console_tbl *console_entry;
|
||||
ffuart_reg_t *ffuart;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
|
||||
|
||||
if (!(ffuart->lsr & FULL_RECEIVE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = ffuart->rbr & 0xff;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write buffer to UART
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t ffuart_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
size_t i, x;
|
||||
char c;
|
||||
console_tbl *console_entry;
|
||||
ffuart_reg_t *ffuart;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
while(1) {
|
||||
if (ffuart->lsr & SEND_EMPTY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = (char) buf[i];
|
||||
#if ON_SKYEYE != 1
|
||||
if(c=='\n'){
|
||||
ffuart->rbr = '\r';
|
||||
for (x = 0; x < 100; x++) {
|
||||
dbg_dly++; /* using a global so this doesn't get optimized out */
|
||||
}
|
||||
while(1){
|
||||
if(ffuart->lsr & SEND_EMPTY){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ffuart->rbr = c;
|
||||
|
||||
/* the TXRDY flag does not seem to update right away (is this true?) */
|
||||
/* so we wait a bit before continuing */
|
||||
for (x = 0; x < 100; x++) {
|
||||
dbg_dly++; /* using a global so this doesn't get optimized out */
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void ffuart_init(int minor)
|
||||
{
|
||||
|
||||
|
||||
console_tbl *console_entry;
|
||||
ffuart_reg_t *ffuart;
|
||||
unsigned int divisor;
|
||||
|
||||
console_entry = BSP_get_uart_from_minor(minor);
|
||||
|
||||
|
||||
|
||||
if (console_entry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
|
||||
ffuart->lcr |= DLAB;
|
||||
/*Set the Bound*/
|
||||
ffuart->lcr |= DLAB;
|
||||
divisor = FREQUENCY_UART / (115200*16);
|
||||
ffuart->rbr = divisor & 0xff;
|
||||
ffuart->ier = (divisor >> 8)&0xff;
|
||||
/*Disable FIFO*/
|
||||
ffuart->iir = 0;
|
||||
ffuart->lcr &=~DLAB;
|
||||
/*Enable UART*/
|
||||
ffuart->ier = 0x40;
|
||||
ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT;
|
||||
|
||||
}
|
||||
|
||||
/* I'm not sure this is needed for the shared console driver. */
|
||||
static void ffuart_write_polled(int minor, char c)
|
||||
{
|
||||
ffuart_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int ffuart_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* The following functions are not used by TERMIOS, but other RTEMS
|
||||
* functions use them instead.
|
||||
*/
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Read from UART. This is used in the exit code, and can't
|
||||
* rely on interrupts.
|
||||
*/
|
||||
static int ffuart_poll_read(int minor)
|
||||
{
|
||||
return ffuart_read(minor);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a character to the console. This is used by printk() and
|
||||
* maybe other low level functions. It should not use interrupts or any
|
||||
* RTEMS system calls. It needs to be very simple
|
||||
*/
|
||||
static void _BSP_put_char( char c ) {
|
||||
ffuart_write_polled(0, c);
|
||||
}
|
||||
|
||||
static int _BSP_poll_char(void) {
|
||||
return ffuart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Console driver for GUMSTIX by Yang Xi <hiyangxi@gmail.com>
|
||||
*
|
||||
* This driver uses the shared console driver in
|
||||
* ...../libbsp/shared/console.c
|
||||
*
|
||||
* Copyright (c) 2003 by Cogent Computer Systems
|
||||
* Written by Jay Monkman <jtm@lopingdog.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <pxa255.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
/* How many serial ports? */
|
||||
#define NUM_DEVS 1
|
||||
|
||||
/* These are used by code in console.c */
|
||||
unsigned long Console_Configuration_Count = NUM_DEVS;
|
||||
|
||||
extern const console_fns ffuart_fns;
|
||||
|
||||
/*
|
||||
* There's one item in array for each UART.
|
||||
*
|
||||
* Some of these fields are marked "NOT USED". They are not used
|
||||
* by console.c, but may be used by drivers in libchip
|
||||
*
|
||||
* when we add other types of UARTS we will need to move this
|
||||
* structure to a generic uart.c file with only this in it
|
||||
*/
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
{
|
||||
"/dev/com0", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&ffuart_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
FFUART_BASE, /* ulCtrlPort1 - Pointer to DBGU regs */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
}};
|
||||
|
||||
|
||||
console_tbl *BSP_get_uart_from_minor(int minor)
|
||||
{
|
||||
return Console_Port_Tbl[minor];
|
||||
}
|
||||
@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/imx/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-generic-timer-clock-config.c
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fdt.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <arm/freescale/imx/imx_ccmvar.h>
|
||||
#include <arm/freescale/imx/imx_uartreg.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#define IMX_UART_TX_FIFO_LEVEL 16
|
||||
|
||||
typedef struct {
|
||||
rtems_termios_device_context base;
|
||||
volatile imx_uart *regs;
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
rtems_vector_number irq;
|
||||
int tx_in_progress;
|
||||
#endif
|
||||
} imx_uart_context;
|
||||
|
||||
static imx_uart_context imx_uart_instances[7];
|
||||
|
||||
static imx_uart_context *imx_uart_console = &imx_uart_instances[0];
|
||||
|
||||
static volatile imx_uart *imx_uart_get_regs(rtems_termios_device_context *base)
|
||||
{
|
||||
imx_uart_context *ctx;
|
||||
|
||||
ctx = (imx_uart_context *) base;
|
||||
return ctx->regs;
|
||||
}
|
||||
|
||||
static void imx_uart_write_polled(rtems_termios_device_context *base, char c)
|
||||
{
|
||||
volatile imx_uart *regs;
|
||||
|
||||
regs = imx_uart_get_regs(base);
|
||||
|
||||
while ((regs->usr1 & IMX_UART_USR1_TRDY) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
regs->utxd = IMX_UART_UTXD_TX_DATA(c);
|
||||
}
|
||||
|
||||
void imx_uart_console_drain(void)
|
||||
{
|
||||
volatile imx_uart *regs;
|
||||
|
||||
regs = imx_uart_get_regs(&imx_uart_console->base);
|
||||
|
||||
if (regs != NULL) {
|
||||
while ((regs->usr2 & IMX_UART_USR2_TXFE) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_output_char(char c)
|
||||
{
|
||||
imx_uart_write_polled(&imx_uart_console->base, c);
|
||||
}
|
||||
|
||||
static void imx_uart_init_context(
|
||||
imx_uart_context *ctx,
|
||||
const char *fdt,
|
||||
const char *serial
|
||||
)
|
||||
{
|
||||
int node;
|
||||
|
||||
rtems_termios_device_context_initialize(&ctx->base, "UART");
|
||||
node = fdt_path_offset(fdt, serial);
|
||||
ctx->regs = imx_get_reg_of_node(fdt, node);
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
ctx->irq = imx_get_irq_of_node(fdt, node, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void imx_uart_probe(void)
|
||||
{
|
||||
const void *fdt;
|
||||
int node;
|
||||
int offset;
|
||||
const char *console;
|
||||
size_t i;
|
||||
|
||||
fdt = bsp_fdt_get();
|
||||
node = fdt_path_offset(fdt, "/chosen");
|
||||
|
||||
console = fdt_getprop(fdt, node, "stdout-path", NULL);
|
||||
if (console == NULL) {
|
||||
console = "";
|
||||
}
|
||||
|
||||
node = fdt_path_offset(fdt, "/aliases");
|
||||
offset = fdt_first_property_offset(fdt, node);
|
||||
i = 0;
|
||||
|
||||
while (offset >= 0 && i < RTEMS_ARRAY_SIZE(imx_uart_instances)) {
|
||||
const struct fdt_property *prop;
|
||||
|
||||
prop = fdt_get_property_by_offset(fdt, offset, NULL);
|
||||
|
||||
if (prop != NULL) {
|
||||
const char *name;
|
||||
|
||||
name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
|
||||
if (strstr(name, "serial") != NULL) {
|
||||
imx_uart_context *ctx;
|
||||
const char *serial;
|
||||
|
||||
ctx = &imx_uart_instances[i];
|
||||
serial = prop->data;
|
||||
|
||||
if (strcmp(serial, console) == 0) {
|
||||
imx_uart_console = ctx;
|
||||
}
|
||||
|
||||
imx_uart_init_context(ctx, fdt, serial);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
offset = fdt_next_property_offset(fdt, offset);
|
||||
}
|
||||
|
||||
BSP_output_char = imx_output_char;
|
||||
}
|
||||
|
||||
static void imx_output_char_init(char c)
|
||||
{
|
||||
imx_uart_probe();
|
||||
imx_output_char(c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = imx_output_char_init;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
static void imx_uart_interrupt(void *arg)
|
||||
{
|
||||
rtems_termios_tty *tty;
|
||||
imx_uart_context *ctx;
|
||||
volatile imx_uart *regs;
|
||||
uint32_t usr2;
|
||||
|
||||
tty = arg;
|
||||
ctx = rtems_termios_get_device_context(tty);
|
||||
regs = ctx->regs;
|
||||
usr2 = regs->usr2;
|
||||
|
||||
regs->usr1 = IMX_UART_USR1_AGTIM;
|
||||
|
||||
while ((usr2 & IMX_UART_USR2_RDR) != 0) {
|
||||
char c;
|
||||
|
||||
c = IMX_UART_URXD_RX_DATA_GET(regs->urxd);
|
||||
rtems_termios_enqueue_raw_characters(tty, &c, 1);
|
||||
usr2 = regs->usr2;
|
||||
}
|
||||
|
||||
if (ctx->tx_in_progress > 0 && (regs->usr1 & IMX_UART_USR1_TRDY) != 0) {
|
||||
rtems_termios_dequeue_characters(tty, ctx->tx_in_progress);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool imx_uart_set_attributes(
|
||||
rtems_termios_device_context *base,
|
||||
const struct termios *term
|
||||
)
|
||||
{
|
||||
imx_uart_context *ctx;
|
||||
volatile imx_uart *regs;
|
||||
uint32_t ufcr;
|
||||
uint32_t baud;
|
||||
|
||||
ctx = (imx_uart_context *) base;
|
||||
regs = imx_uart_get_regs(&ctx->base);
|
||||
|
||||
baud = rtems_termios_baud_to_number(term->c_ospeed);
|
||||
|
||||
if (baud != 0) {
|
||||
ufcr = regs->ufcr;
|
||||
ufcr = IMX_UART_UFCR_RFDIV_SET(ufcr, 0x5);
|
||||
regs->ufcr = ufcr;
|
||||
regs->ubir = 15;
|
||||
regs->ubmr = imx_ccm_uart_hz() / baud - 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool imx_uart_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
imx_uart_context *ctx;
|
||||
volatile imx_uart *regs;
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
rtems_status_code sc;
|
||||
uint32_t ufcr;
|
||||
#endif
|
||||
|
||||
ctx = (imx_uart_context *) base;
|
||||
regs = imx_uart_get_regs(&ctx->base);
|
||||
|
||||
regs->ucr1 = IMX_UART_UCR1_UARTEN;
|
||||
regs->ucr2 = IMX_UART_UCR2_IRTS | IMX_UART_UCR2_WS | IMX_UART_UCR2_RXEN
|
||||
| IMX_UART_UCR2_TXEN | IMX_UART_UCR2_SRST;
|
||||
|
||||
rtems_termios_set_initial_baud(tty, 115200);
|
||||
imx_uart_set_attributes(base, term);
|
||||
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
ufcr = regs->ufcr;
|
||||
ufcr = IMX_UART_UFCR_RXTL_SET(ufcr, 16);
|
||||
ufcr = IMX_UART_UFCR_TXTL_SET(ufcr, IMX_UART_TX_FIFO_LEVEL);
|
||||
regs->ufcr = ufcr;
|
||||
regs->ucr1 |= IMX_UART_UCR1_RRDYEN;
|
||||
regs->ucr2 |= IMX_UART_UCR2_ATEN;
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ctx->irq,
|
||||
"UART",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
imx_uart_interrupt,
|
||||
tty
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void imx_uart_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
imx_uart_context *ctx;
|
||||
|
||||
ctx = (imx_uart_context *) base;
|
||||
rtems_interrupt_handler_remove(ctx->irq, imx_uart_interrupt, tty);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void imx_uart_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
imx_uart_context *ctx;
|
||||
volatile imx_uart *regs;
|
||||
int n;
|
||||
uint32_t ucr1;
|
||||
|
||||
ctx = (imx_uart_context *) base;
|
||||
regs = imx_uart_get_regs(&ctx->base);
|
||||
ucr1 = regs->ucr1;
|
||||
|
||||
if (len > 0) {
|
||||
int i;
|
||||
|
||||
n = (int) MIN(len, IMX_UART_TX_FIFO_LEVEL);
|
||||
ucr1 |= IMX_UART_UCR1_TRDYEN;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
regs->utxd = IMX_UART_UTXD_TX_DATA(buf[i]);
|
||||
}
|
||||
} else {
|
||||
n = 0;
|
||||
ucr1 &= ~IMX_UART_UCR1_TRDYEN;
|
||||
}
|
||||
|
||||
regs->ucr1 = ucr1;
|
||||
ctx->tx_in_progress = n;
|
||||
#else
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
imx_uart_write_polled(base, buf[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONSOLE_USE_INTERRUPTS
|
||||
static int imx_uart_read(rtems_termios_device_context *base)
|
||||
{
|
||||
volatile imx_uart *regs;
|
||||
|
||||
regs = imx_uart_get_regs(base);
|
||||
|
||||
if ((regs->usr2 & IMX_UART_USR2_RDR) != 0) {
|
||||
return IMX_UART_URXD_RX_DATA_GET(regs->urxd);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const rtems_termios_device_handler imx_uart_handler = {
|
||||
.first_open = imx_uart_first_open,
|
||||
.last_close = imx_uart_last_close,
|
||||
.write = imx_uart_write,
|
||||
.set_attributes = imx_uart_set_attributes,
|
||||
#ifdef CONSOLE_USE_INTERRUPTS
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
#else
|
||||
.poll_read = imx_uart_read,
|
||||
.mode = TERMIOS_POLLED
|
||||
#endif
|
||||
};
|
||||
|
||||
rtems_status_code console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
char path[] = "/dev/ttyS?";
|
||||
size_t i;
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
for (i = 0; i < RTEMS_ARRAY_SIZE(imx_uart_instances); ++i) {
|
||||
imx_uart_context *ctx;
|
||||
|
||||
ctx = &imx_uart_instances[i];
|
||||
path[sizeof(path) - 2] = (char) ('0' + i);
|
||||
|
||||
rtems_termios_device_install(
|
||||
path,
|
||||
&imx_uart_handler,
|
||||
NULL,
|
||||
&ctx->base
|
||||
);
|
||||
|
||||
if (ctx == imx_uart_console) {
|
||||
link(path, CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
imx_uart_probe,
|
||||
RTEMS_SYSINIT_BSP_START,
|
||||
RTEMS_SYSINIT_ORDER_LAST
|
||||
);
|
||||
@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lm3s69xx/console/uart.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-armv7m.c
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright <20> 2013 Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
*
|
||||
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/uart.h>
|
||||
#include <bsp/lm3s69xx.h>
|
||||
|
||||
console_tbl Console_Configuration_Ports [] = {
|
||||
#ifdef LM3S69XX_ENABLE_UART_0
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS0",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &lm3s69xx_uart_fns,
|
||||
.ulCtrlPort1 = LM3S69XX_UART_0_BASE,
|
||||
.ulClock = LM3S69XX_UART_BAUD,
|
||||
.ulIntVector = LM3S69XX_IRQ_UART_0,
|
||||
.pDeviceParams = (void *)0
|
||||
},
|
||||
#endif
|
||||
#ifdef LM3S69XX_ENABLE_UART_1
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS1",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &lm3s69xx_uart_fns,
|
||||
.ulCtrlPort1 = LM3S69XX_UART_1_BASE,
|
||||
.ulClock = LM3S69XX_UART_BAUD,
|
||||
.ulIntVector = LM3S69XX_IRQ_UART_1,
|
||||
.pDeviceParams = (void *)1
|
||||
},
|
||||
#endif
|
||||
#ifdef LM3S69XX_ENABLE_UART_2
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS2",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &lm3s69xx_uart_fns,
|
||||
.ulCtrlPort1 = LM3S69XX_UART_2_BASE,
|
||||
.ulClock = LM3S69XX_UART_BAUD,
|
||||
.ulIntVector = LM3S69XX_IRQ_UART_2,
|
||||
.pDeviceParams = (void *)2
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define PORT_COUNT \
|
||||
(sizeof(Console_Configuration_Ports) \
|
||||
/ sizeof(Console_Configuration_Ports [0]))
|
||||
|
||||
unsigned long Console_Configuration_Count = PORT_COUNT;
|
||||
|
||||
static void output_char(char c)
|
||||
{
|
||||
const console_fns *con =
|
||||
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
|
||||
|
||||
con->deviceWritePolled((int) Console_Port_Minor, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = output_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright <20> 2013 Eugeniy Meshcheryakov <eugen@debian.org>
|
||||
*
|
||||
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/uart.h>
|
||||
#include <libchip/sersupp.h>
|
||||
#include <bsp/syscon.h>
|
||||
#include <bsp/lm3s69xx.h>
|
||||
#include <rtems/irq-extension.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define LM3S69XX_UART_FIFO_DEPTH 16
|
||||
|
||||
static volatile lm3s69xx_uart *get_uart_regs(int minor)
|
||||
{
|
||||
console_tbl *ct = Console_Port_Tbl [minor];
|
||||
|
||||
return (lm3s69xx_uart *) ct->ulCtrlPort1;
|
||||
}
|
||||
|
||||
static unsigned int get_uart_number(int minor)
|
||||
{
|
||||
console_tbl *ct = Console_Port_Tbl [minor];
|
||||
|
||||
return (unsigned int)ct->pDeviceParams;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns both integer and fractional parts as one number.
|
||||
*/
|
||||
static uint32_t get_baud_div(uint32_t baud)
|
||||
{
|
||||
uint32_t clock4 = LM3S69XX_SYSTEM_CLOCK * 4;
|
||||
return (clock4 + baud - 1) / baud;
|
||||
}
|
||||
|
||||
static void irq_handler(void *arg)
|
||||
{
|
||||
int minor = (int)arg;
|
||||
console_data *cd = &Console_Port_Data [minor];
|
||||
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
|
||||
|
||||
do {
|
||||
char buf[LM3S69XX_UART_FIFO_DEPTH];
|
||||
int i = 0;
|
||||
uint32_t status = uart->fr;
|
||||
|
||||
while (((status & UARTFR_RXFE) == 0) && (i < LM3S69XX_UART_FIFO_DEPTH)) {
|
||||
uint32_t d = uart->dr;
|
||||
|
||||
if ((d & UARTDR_ERROR_MSK) == 0) {
|
||||
buf[i] = UARTDR_DATA_GET(d);
|
||||
i++;
|
||||
}
|
||||
|
||||
status = uart->fr;
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
|
||||
} while (uart->mis != 0);
|
||||
}
|
||||
|
||||
static void initialize(int minor)
|
||||
{
|
||||
const console_tbl *ct = Console_Port_Tbl[minor];
|
||||
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
|
||||
unsigned int num = get_uart_number(minor);
|
||||
|
||||
lm3s69xx_syscon_enable_uart_clock(num, true);
|
||||
|
||||
uart->ctl = 0;
|
||||
|
||||
uint32_t brd = get_baud_div(LM3S69XX_UART_BAUD);
|
||||
uart->ibrd = brd / 64;
|
||||
uart->fbrd = brd % 64;
|
||||
|
||||
uart->lcrh = UARTLCRH_WLEN(0x3) | UARTLCRH_FEN;
|
||||
uart->ctl = UARTCTL_RXE | UARTCTL_TXE | UARTCTL_UARTEN;
|
||||
|
||||
int rv = rtems_interrupt_handler_install(ct->ulIntVector, "UART",
|
||||
RTEMS_INTERRUPT_UNIQUE, irq_handler, (void *)minor);
|
||||
assert(rv == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
static int first_open(int major, int minor, void *arg)
|
||||
{
|
||||
rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
|
||||
struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
|
||||
console_data *cd = &Console_Port_Data [minor];
|
||||
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
|
||||
|
||||
cd->termios_data = tty;
|
||||
rtems_termios_set_initial_baud(tty, LM3S69XX_UART_BAUD);
|
||||
|
||||
/* Drain the RX FIFO. */
|
||||
while ((uart->fr & UARTFR_RXFE) == 0)
|
||||
(void)uart->dr;
|
||||
|
||||
uart->im = UARTI_RX | UARTI_RT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int last_close(int major, int minor, void *arg)
|
||||
{
|
||||
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
|
||||
uart->im = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_polled(int minor, char c)
|
||||
{
|
||||
volatile lm3s69xx_uart *uart = get_uart_regs(minor);
|
||||
|
||||
while ((uart->fr & UARTFR_TXFF) != 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
uart->dr = UARTDR_DATA(c);
|
||||
}
|
||||
|
||||
static ssize_t write_support_polled(
|
||||
int minor,
|
||||
const char *s,
|
||||
size_t n
|
||||
)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
write_polled(minor, s [i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int set_attribues(int minor, const struct termios *term)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
const console_fns lm3s69xx_uart_fns = {
|
||||
.deviceProbe = libchip_serial_default_probe,
|
||||
.deviceFirstOpen = first_open,
|
||||
.deviceLastClose = last_close,
|
||||
.deviceRead = NULL,
|
||||
.deviceWrite = write_support_polled,
|
||||
.deviceInitialize = initialize,
|
||||
.deviceWritePolled = write_polled,
|
||||
.deviceSetAttributes = set_attribues,
|
||||
.deviceOutputUsesInterrupts = false
|
||||
};
|
||||
@@ -59,9 +59,9 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc176x/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc176x
|
||||
*
|
||||
* @brief Console configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/console-termios.h>
|
||||
|
||||
/**
|
||||
* @brief Gets the uart register according to the current address.
|
||||
*
|
||||
* @param addr Register address.
|
||||
* @param i Index register.
|
||||
* @return Uart register.
|
||||
*/
|
||||
static inline uint8_t lpc176x_uart_get_register(
|
||||
const uintptr_t addr,
|
||||
const uint8_t i
|
||||
)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
return (uint8_t) reg[ i ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the uart register address according to the value passed.
|
||||
*
|
||||
* @param addr Register address.
|
||||
* @param i Index register.
|
||||
* @param val Value to set.
|
||||
*/
|
||||
static inline void lpc176x_uart_set_register(
|
||||
const uintptr_t addr,
|
||||
const uint8_t i,
|
||||
const uint8_t val
|
||||
)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
reg[ i ] = val;
|
||||
}
|
||||
|
||||
static bool lpc176x_uart1_probe(rtems_termios_device_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
|
||||
lpc176x_module_enable( LPC176X_MODULE_UART_1, LPC176X_MODULE_PCLK_DEFAULT );
|
||||
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_1_TXD, LPC176X_PIN_FUNCTION_01 );
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_1_RXD, LPC176X_PIN_FUNCTION_01 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef LPC176X_CONFIG_UART_2
|
||||
static bool lpc176x_uart2_probe(rtems_termios_device_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
|
||||
lpc176x_module_enable( LPC176X_MODULE_UART_2, LPC176X_MODULE_PCLK_DEFAULT );
|
||||
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_2_TXD, LPC176X_PIN_FUNCTION_01 );
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_2_RXD, LPC176X_PIN_FUNCTION_01 );
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPC176X_CONFIG_UART_3
|
||||
static bool lpc176x_uart3_probe(rtems_termios_device_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
|
||||
lpc176x_module_enable( LPC176X_MODULE_UART_3, LPC176X_MODULE_PCLK_DEFAULT );
|
||||
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_3_TXD, LPC176X_PIN_FUNCTION_10 );
|
||||
lpc176x_pin_select( LPC176X_PIN_UART_3_RXD, LPC176X_PIN_FUNCTION_10 );
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPC176X_CONFIG_CONSOLE
|
||||
static ns16550_context lpc176x_uart_context_0 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||
.get_reg = lpc176x_uart_get_register,
|
||||
.set_reg = lpc176x_uart_set_register,
|
||||
.port = UART0_BASE_ADDR,
|
||||
.irq = LPC176X_IRQ_UART_0,
|
||||
.clock = LPC176X_PCLK,
|
||||
.initial_baud = LPC176X_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC176X_CONFIG_UART_1
|
||||
static ns16550_context lpc176x_uart_context_1 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||
.get_reg = lpc176x_uart_get_register,
|
||||
.set_reg = lpc176x_uart_set_register,
|
||||
.port = UART1_BASE_ADDR,
|
||||
.irq = LPC176X_IRQ_UART_1,
|
||||
.clock = LPC176X_PCLK,
|
||||
.initial_baud = LPC176X_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC176X_CONFIG_UART_2
|
||||
static ns16550_context lpc176x_uart_context_2 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
|
||||
.get_reg = lpc176x_uart_get_register,
|
||||
.set_reg = lpc176x_uart_set_register,
|
||||
.port = UART2_BASE_ADDR,
|
||||
.irq = LPC176X_IRQ_UART_2,
|
||||
.clock = LPC176X_PCLK,
|
||||
.initial_baud = LPC176X_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC176X_CONFIG_UART_3
|
||||
static ns16550_context lpc176x_uart_context_3 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
|
||||
.get_reg = lpc176x_uart_get_register,
|
||||
.set_reg = lpc176x_uart_set_register,
|
||||
.port = UART3_BASE_ADDR,
|
||||
.irq = LPC176X_IRQ_UART_3,
|
||||
.clock = LPC176X_PCLK,
|
||||
.initial_baud = LPC176X_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
const console_device console_device_table[] = {
|
||||
#ifdef LPC176X_CONFIG_CONSOLE
|
||||
{
|
||||
.device_file = "/dev/ttyS0",
|
||||
.probe = console_device_probe_default,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc176x_uart_context_0.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC176X_CONFIG_UART_1
|
||||
{
|
||||
.device_file = "/dev/ttyS1",
|
||||
.probe = lpc176x_uart1_probe,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc176x_uart_context_1.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC176X_CONFIG_UART_2
|
||||
{
|
||||
.device_file = "/dev/ttyS2",
|
||||
.probe = lpc176x_uart2_probe,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc176x_uart_context_2.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC176X_CONFIG_UART_3
|
||||
{
|
||||
.device_file = "/dev/ttyS3",
|
||||
.probe = lpc176x_uart3_probe,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc176x_uart_context_3.base
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||
@@ -71,12 +71,12 @@ librtemsbsp_a_SOURCES += irq/irq.c
|
||||
librtemsbsp_a_SOURCES += irq/irq-dispatch.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/uart-probe-1.c
|
||||
librtemsbsp_a_SOURCES += console/uart-probe-2.c
|
||||
librtemsbsp_a_SOURCES += console/uart-probe-3.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-1.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-2.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/console/uart-probe-3.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc24xx
|
||||
*
|
||||
* @brief Console configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/lpc24xx.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/console-termios.h>
|
||||
|
||||
static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
return (uint8_t) reg [i];
|
||||
}
|
||||
|
||||
static void lpc24xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
reg [i] = val;
|
||||
}
|
||||
|
||||
#ifdef LPC24XX_CONFIG_CONSOLE
|
||||
static ns16550_context lpc24xx_uart_context_0 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||
.get_reg = lpc24xx_uart_get_register,
|
||||
.set_reg = lpc24xx_uart_set_register,
|
||||
.port = UART0_BASE_ADDR,
|
||||
.irq = LPC24XX_IRQ_UART_0,
|
||||
.clock = LPC24XX_PCLK,
|
||||
.initial_baud = LPC24XX_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC24XX_CONFIG_UART_1
|
||||
static ns16550_context lpc24xx_uart_context_1 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||
.get_reg = lpc24xx_uart_get_register,
|
||||
.set_reg = lpc24xx_uart_set_register,
|
||||
.port = UART1_BASE_ADDR,
|
||||
.irq = LPC24XX_IRQ_UART_1,
|
||||
.clock = LPC24XX_PCLK,
|
||||
.initial_baud = LPC24XX_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC24XX_CONFIG_UART_2
|
||||
static ns16550_context lpc24xx_uart_context_2 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
|
||||
.get_reg = lpc24xx_uart_get_register,
|
||||
.set_reg = lpc24xx_uart_set_register,
|
||||
.port = UART2_BASE_ADDR,
|
||||
.irq = LPC24XX_IRQ_UART_2,
|
||||
.clock = LPC24XX_PCLK,
|
||||
.initial_baud = LPC24XX_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC24XX_CONFIG_UART_3
|
||||
static ns16550_context lpc24xx_uart_context_3 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
|
||||
.get_reg = lpc24xx_uart_get_register,
|
||||
.set_reg = lpc24xx_uart_set_register,
|
||||
.port = UART3_BASE_ADDR,
|
||||
.irq = LPC24XX_IRQ_UART_3,
|
||||
.clock = LPC24XX_PCLK,
|
||||
.initial_baud = LPC24XX_UART_BAUD,
|
||||
.has_fractional_divider_register = true
|
||||
};
|
||||
#endif
|
||||
|
||||
const console_device console_device_table[] = {
|
||||
#ifdef LPC24XX_CONFIG_CONSOLE
|
||||
{
|
||||
.device_file = "/dev/ttyS0",
|
||||
.probe = console_device_probe_default,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc24xx_uart_context_0.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC24XX_CONFIG_UART_1
|
||||
{
|
||||
.device_file = "/dev/ttyS1",
|
||||
.probe = lpc24xx_uart_probe_1,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc24xx_uart_context_1.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC24XX_CONFIG_UART_2
|
||||
{
|
||||
.device_file = "/dev/ttyS2",
|
||||
.probe = lpc24xx_uart_probe_2,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc24xx_uart_context_2.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC24XX_CONFIG_UART_3
|
||||
{
|
||||
.device_file = "/dev/ttyS3",
|
||||
.probe = lpc24xx_uart_probe_3,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc24xx_uart_context_3.base
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc24xx
|
||||
*
|
||||
* @brief UART 1 probe.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
bool lpc24xx_uart_probe_1(rtems_termios_device_context *context)
|
||||
{
|
||||
static const lpc24xx_pin_range pins [] = {
|
||||
LPC24XX_PIN_UART_1_TXD_P0_15,
|
||||
LPC24XX_PIN_UART_1_RXD_P0_16,
|
||||
LPC24XX_PIN_TERMINAL
|
||||
};
|
||||
|
||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc24xx
|
||||
*
|
||||
* @brief UART 2 probe.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
bool lpc24xx_uart_probe_2(rtems_termios_device_context *context)
|
||||
{
|
||||
static const lpc24xx_pin_range pins [] = {
|
||||
LPC24XX_PIN_UART_2_TXD_P0_10,
|
||||
LPC24XX_PIN_UART_2_RXD_P0_11,
|
||||
LPC24XX_PIN_TERMINAL
|
||||
};
|
||||
|
||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc24xx
|
||||
*
|
||||
* @brief UART 3 probe.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
bool lpc24xx_uart_probe_3(rtems_termios_device_context *context)
|
||||
{
|
||||
static const lpc24xx_pin_range pins [] = {
|
||||
LPC24XX_PIN_UART_3_TXD_P0_0,
|
||||
LPC24XX_PIN_UART_3_RXD_P0_1,
|
||||
LPC24XX_PIN_TERMINAL
|
||||
};
|
||||
|
||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
@@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/hsu.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc32xx/console/hsu.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/clock/clock-nxp-lpc.c
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup arm_lpc32xx
|
||||
*
|
||||
* @brief Console configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/lpc32xx.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/hsu.h>
|
||||
#include <bsp/console-termios.h>
|
||||
|
||||
static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
return (uint8_t) reg [i];
|
||||
}
|
||||
|
||||
static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||
|
||||
reg [i] = val;
|
||||
}
|
||||
|
||||
#ifdef LPC32XX_UART_3_BAUD
|
||||
static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context)
|
||||
{
|
||||
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0);
|
||||
LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
|
||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_4_BAUD
|
||||
static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context)
|
||||
{
|
||||
volatile lpc32xx_gpio *gpio = &lpc32xx.gpio;
|
||||
|
||||
/*
|
||||
* Set GPO_21/U4_TX/LCDVD[3] to U4_TX. This works only if LCD module is
|
||||
* disabled.
|
||||
*/
|
||||
gpio->p2_mux_set = BSP_BIT32(2);
|
||||
|
||||
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(1);
|
||||
LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
|
||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_6_BAUD
|
||||
static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context)
|
||||
{
|
||||
/* Bypass the IrDA modulator/demodulator */
|
||||
LPC32XX_UART_CTRL |= BSP_BIT32(5);
|
||||
|
||||
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(3);
|
||||
LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
|
||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11);
|
||||
|
||||
return ns16550_probe(context);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME: Console selection */
|
||||
|
||||
#ifdef LPC32XX_UART_5_BAUD
|
||||
static ns16550_context lpc32xx_uart_context_5 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 5"),
|
||||
.get_reg = lpc32xx_uart_get_register,
|
||||
.set_reg = lpc32xx_uart_set_register,
|
||||
.port = LPC32XX_BASE_UART_5,
|
||||
.irq = LPC32XX_IRQ_UART_5,
|
||||
.clock = 16 * LPC32XX_UART_5_BAUD,
|
||||
.initial_baud = LPC32XX_UART_5_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_3_BAUD
|
||||
static ns16550_context lpc32xx_uart_context_3 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 3"),
|
||||
.get_reg = lpc32xx_uart_get_register,
|
||||
.set_reg = lpc32xx_uart_set_register,
|
||||
.port = LPC32XX_BASE_UART_3,
|
||||
.irq = LPC32XX_IRQ_UART_3,
|
||||
.clock = 16 * LPC32XX_UART_3_BAUD,
|
||||
.initial_baud = LPC32XX_UART_3_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_4_BAUD
|
||||
static ns16550_context lpc32xx_uart_context_4 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 4"),
|
||||
.get_reg = lpc32xx_uart_get_register,
|
||||
.set_reg = lpc32xx_uart_set_register,
|
||||
.port = LPC32XX_BASE_UART_4,
|
||||
.irq = LPC32XX_IRQ_UART_4,
|
||||
.clock = 16 * LPC32XX_UART_4_BAUD,
|
||||
.initial_baud = LPC32XX_UART_4_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_6_BAUD
|
||||
static ns16550_context lpc32xx_uart_context_6 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 6"),
|
||||
.get_reg = lpc32xx_uart_get_register,
|
||||
.set_reg = lpc32xx_uart_set_register,
|
||||
.port = LPC32XX_BASE_UART_6,
|
||||
.irq = LPC32XX_IRQ_UART_6,
|
||||
.clock = 16 * LPC32XX_UART_6_BAUD,
|
||||
.initial_baud = LPC32XX_UART_6_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_1_BAUD
|
||||
static lpc32xx_hsu_context lpc32xx_uart_context_1 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_1,
|
||||
.irq = LPC32XX_IRQ_UART_1,
|
||||
.initial_baud = LPC32XX_UART_1_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_2_BAUD
|
||||
static lpc32xx_hsu_context lpc32xx_uart_context_2 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 2"),
|
||||
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_2,
|
||||
.irq = LPC32XX_IRQ_UART_2,
|
||||
.initial_baud = LPC32XX_UART_2_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef LPC32XX_UART_7_BAUD
|
||||
static lpc32xx_hsu_context lpc32xx_uart_context_7 = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 7"),
|
||||
.hsu = (volatile lpc32xx_hsu *) LPC32XX_BASE_UART_7,
|
||||
.irq = LPC32XX_IRQ_UART_7,
|
||||
.initial_baud = LPC32XX_UART_7_BAUD
|
||||
};
|
||||
#endif
|
||||
|
||||
const console_device console_device_table[] = {
|
||||
#ifdef LPC32XX_UART_5_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS5",
|
||||
.probe = console_device_probe_default,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc32xx_uart_context_5.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_3_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS3",
|
||||
.probe = lpc32xx_uart_probe_3,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc32xx_uart_context_3.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_4_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS4",
|
||||
.probe = lpc32xx_uart_probe_4,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc32xx_uart_context_4.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_6_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS6",
|
||||
.probe = lpc32xx_uart_probe_6,
|
||||
.handler = &ns16550_handler_interrupt,
|
||||
.context = &lpc32xx_uart_context_6.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_1_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS1",
|
||||
.probe = lpc32xx_hsu_probe,
|
||||
.handler = &lpc32xx_hsu_fns,
|
||||
.context = &lpc32xx_uart_context_1.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_2_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS2",
|
||||
.probe = lpc32xx_hsu_probe,
|
||||
.handler = &lpc32xx_hsu_fns,
|
||||
.context = &lpc32xx_uart_context_2.base
|
||||
},
|
||||
#endif
|
||||
#ifdef LPC32XX_UART_7_BAUD
|
||||
{
|
||||
.device_file = "/dev/ttyS7",
|
||||
.probe = lpc32xx_hsu_probe,
|
||||
.handler = &lpc32xx_hsu_fns,
|
||||
.context = &lpc32xx_uart_context_7.base
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||
@@ -1,208 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup arm_lpc32xx
|
||||
*
|
||||
* @brief High speed UART driver (14-clock).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/lpc32xx.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/hsu.h>
|
||||
|
||||
#define HSU_FIFO_SIZE 64
|
||||
|
||||
#define HSU_LEVEL_RX_MASK 0xffU
|
||||
#define HSU_LEVEL_TX_MASK 0xff00U
|
||||
#define HSU_LEVEL_TX_SHIFT 8
|
||||
|
||||
#define HSU_RX_DATA_MASK 0xffU
|
||||
#define HSU_RX_EMPTY (1U << 8)
|
||||
#define HSU_RX_ERROR (1U << 9)
|
||||
#define HSU_RX_BREAK (1U << 10)
|
||||
|
||||
#define HSU_IIR_TX (1U << 0)
|
||||
#define HSU_IIR_RX_TRIG (1U << 1)
|
||||
#define HSU_IIR_RX_TIMEOUT (1U << 2)
|
||||
|
||||
#define HSU_CTRL_INTR_DISABLED 0x1280fU
|
||||
#define HSU_CTRL_RX_INTR_ENABLED 0x1284fU
|
||||
#define HSU_CTRL_RX_AND_TX_INTR_ENABLED 0x1286fU
|
||||
|
||||
/* We are interested in RX timeout, RX trigger and TX trigger interrupts */
|
||||
#define HSU_IIR_MASK 0x7U
|
||||
|
||||
bool lpc32xx_hsu_probe(rtems_termios_device_context *base)
|
||||
{
|
||||
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
|
||||
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
|
||||
|
||||
/* Drain FIFOs */
|
||||
while (hsu->level != 0) {
|
||||
hsu->fifo;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void lpc32xx_hsu_interrupt_handler(void *arg)
|
||||
{
|
||||
rtems_termios_tty *tty = arg;
|
||||
lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty);
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
|
||||
/* Iterate until no more interrupts are pending */
|
||||
do {
|
||||
int rv = 0;
|
||||
int i = 0;
|
||||
char buf [HSU_FIFO_SIZE];
|
||||
|
||||
/* Enqueue received characters */
|
||||
while (i < HSU_FIFO_SIZE) {
|
||||
uint32_t in = hsu->fifo;
|
||||
|
||||
if ((in & HSU_RX_EMPTY) == 0) {
|
||||
if ((in & HSU_RX_BREAK) == 0) {
|
||||
buf [i] = in & HSU_RX_DATA_MASK;
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtems_termios_enqueue_raw_characters(tty, buf, i);
|
||||
|
||||
/* Dequeue transmitted characters */
|
||||
rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission);
|
||||
if (rv == 0) {
|
||||
/* Nothing to transmit */
|
||||
}
|
||||
} while ((hsu->iir & HSU_IIR_MASK) != 0);
|
||||
}
|
||||
|
||||
static bool lpc32xx_hsu_first_open(
|
||||
struct rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
rtems_status_code sc;
|
||||
bool ok;
|
||||
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ctx->irq,
|
||||
"HSU",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
lpc32xx_hsu_interrupt_handler,
|
||||
tty
|
||||
);
|
||||
ok = sc == RTEMS_SUCCESSFUL;
|
||||
|
||||
if (ok) {
|
||||
rtems_termios_set_initial_baud(tty, ctx->initial_baud);
|
||||
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void lpc32xx_hsu_last_close(
|
||||
struct rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
|
||||
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
|
||||
|
||||
rtems_interrupt_handler_remove(
|
||||
ctx->irq,
|
||||
lpc32xx_hsu_interrupt_handler,
|
||||
tty
|
||||
);
|
||||
}
|
||||
|
||||
static void lpc32xx_hsu_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
size_t tx_level = (hsu->level & HSU_LEVEL_TX_MASK) >> HSU_LEVEL_TX_SHIFT;
|
||||
size_t tx_free = HSU_FIFO_SIZE - tx_level;
|
||||
size_t i = 0;
|
||||
size_t out = len > tx_free ? tx_free : len;
|
||||
|
||||
for (i = 0; i < out; ++i) {
|
||||
hsu->fifo = buf [i];
|
||||
}
|
||||
|
||||
ctx->chars_in_transmission = out;
|
||||
|
||||
if (len > 0) {
|
||||
hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED;
|
||||
} else {
|
||||
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
|
||||
hsu->iir = HSU_IIR_TX;
|
||||
}
|
||||
}
|
||||
|
||||
static bool lpc32xx_hsu_set_attributes(
|
||||
rtems_termios_device_context *base,
|
||||
const struct termios *term
|
||||
)
|
||||
{
|
||||
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||
int baud_flags = term->c_ospeed;
|
||||
|
||||
if (baud_flags != 0) {
|
||||
int32_t baud = rtems_termios_baud_to_number(baud_flags);
|
||||
|
||||
if (baud > 0) {
|
||||
uint32_t baud_divisor = 14 * (uint32_t) baud;
|
||||
uint32_t rate = LPC32XX_PERIPH_CLK / baud_divisor;
|
||||
uint32_t remainder = LPC32XX_PERIPH_CLK - rate * baud_divisor;
|
||||
|
||||
if (2 * remainder >= baud_divisor) {
|
||||
++rate;
|
||||
}
|
||||
|
||||
hsu->rate = rate - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const rtems_termios_device_handler lpc32xx_hsu_fns = {
|
||||
.first_open = lpc32xx_hsu_first_open,
|
||||
.last_close = lpc32xx_hsu_last_close,
|
||||
.write = lpc32xx_hsu_write,
|
||||
.set_attributes = lpc32xx_hsu_set_attributes,
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
};
|
||||
@@ -16,7 +16,7 @@ dist_project_lib_DATA = startup/bsp_specs
|
||||
# Header #
|
||||
###############################################################################
|
||||
|
||||
noinst_HEADERS = console/font_data.h
|
||||
noinst_HEADERS = ../../../../../../bsps/arm/raspberrypi/console/font_data.h
|
||||
|
||||
###############################################################################
|
||||
# Data #
|
||||
@@ -68,12 +68,12 @@ librtemsbsp_a_SOURCES += irq/irq.c
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/console_select.c
|
||||
librtemsbsp_a_SOURCES += console/usart.c
|
||||
librtemsbsp_a_SOURCES += console/fb.c
|
||||
librtemsbsp_a_SOURCES += console/fbcons.c
|
||||
librtemsbsp_a_SOURCES += console/outch.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/console_select.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/usart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fb.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/fbcons.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/raspberrypi/console/outch.c
|
||||
|
||||
# Mailbox
|
||||
librtemsbsp_a_SOURCES += misc/mailbox.c
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi_usart
|
||||
*
|
||||
* @brief Console Configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Yang Qiao
|
||||
* based on work by:
|
||||
* Copyright (c) 2013 Alan Cudmore
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
*
|
||||
* http://www.rtems.org/license/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/usart.h>
|
||||
#include <bsp/raspberrypi.h>
|
||||
#include <bsp/fbcons.h>
|
||||
|
||||
console_tbl Console_Configuration_Ports [] = {
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS0",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &bcm2835_usart_fns,
|
||||
.deviceProbe = NULL,
|
||||
.pDeviceFlow = NULL,
|
||||
.ulCtrlPort1 = BCM2835_UART0_BASE,
|
||||
.ulCtrlPort2 = 0,
|
||||
.ulClock = USART0_DEFAULT_BAUD,
|
||||
.ulIntVector = BCM2835_IRQ_ID_UART
|
||||
},
|
||||
{
|
||||
.sDeviceName ="/dev/fbcons",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &fbcons_fns,
|
||||
.deviceProbe = fbcons_probe,
|
||||
.pDeviceFlow = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
#define PORT_COUNT \
|
||||
(sizeof(Console_Configuration_Ports) \
|
||||
/ sizeof(Console_Configuration_Ports [0]))
|
||||
|
||||
unsigned long Console_Configuration_Count = PORT_COUNT;
|
||||
|
||||
static void output_char(char c)
|
||||
{
|
||||
const console_fns *con =
|
||||
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
|
||||
|
||||
con->deviceWritePolled((int) Console_Port_Minor, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = output_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
@@ -1,114 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi_console
|
||||
*
|
||||
* @brief console select
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Yang Qiao
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
*
|
||||
* http://www.rtems.org/license/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <libchip/serial.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
#include <bsp/rpi-fb.h>
|
||||
|
||||
rtems_device_minor_number BSPPrintkPort = 0;
|
||||
|
||||
/*
|
||||
* Method to return true if the device associated with the
|
||||
* minor number probs available.
|
||||
*/
|
||||
static bool bsp_Is_Available( rtems_device_minor_number minor )
|
||||
{
|
||||
console_tbl *cptr = Console_Port_Tbl[ minor ];
|
||||
|
||||
/*
|
||||
* First perform the configuration dependent probe, then the
|
||||
* device dependent probe
|
||||
*/
|
||||
if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) &&
|
||||
cptr->pDeviceFns->deviceProbe( minor ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to return the first available device.
|
||||
*/
|
||||
static rtems_device_minor_number bsp_First_Available_Device( void )
|
||||
{
|
||||
rtems_device_minor_number minor;
|
||||
|
||||
for ( minor = 0; minor < Console_Port_Count; minor++ ) {
|
||||
console_tbl *cptr = Console_Port_Tbl[ minor ];
|
||||
|
||||
/*
|
||||
* First perform the configuration dependent probe, then the
|
||||
* device dependent probe
|
||||
*/
|
||||
|
||||
if ( ( !cptr->deviceProbe || cptr->deviceProbe( minor ) ) &&
|
||||
cptr->pDeviceFns->deviceProbe( minor ) ) {
|
||||
return minor;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error No devices were found. We will want to bail here.
|
||||
*/
|
||||
bsp_fatal( BSP_FATAL_CONSOLE_NO_DEV );
|
||||
}
|
||||
|
||||
void bsp_console_select( void )
|
||||
{
|
||||
/*
|
||||
* Reset Console_Port_Minor and
|
||||
* BSPPrintkPort here if desired.
|
||||
*
|
||||
* This default version allows the bsp to set these
|
||||
* values at creation and will not touch them again
|
||||
* unless the selected port number is not available.
|
||||
*/
|
||||
const char *opt;
|
||||
|
||||
Console_Port_Minor = BSP_CONSOLE_UART0;
|
||||
BSPPrintkPort = BSP_CONSOLE_UART0;
|
||||
|
||||
opt = rpi_cmdline_get_arg( "--console=" );
|
||||
|
||||
if ( opt ) {
|
||||
if ( strncmp( opt, "fbcons", sizeof( "fbcons" ) - 1 ) == 0 ) {
|
||||
if ( rpi_video_is_initialized() > 0 ) {
|
||||
Console_Port_Minor = BSP_CONSOLE_FB;
|
||||
BSPPrintkPort = BSP_CONSOLE_FB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device that was selected isn't available then
|
||||
* let the user know and select the first available device.
|
||||
*/
|
||||
if ( !bsp_Is_Available( Console_Port_Minor ) ) {
|
||||
Console_Port_Minor = bsp_First_Available_Device();
|
||||
}
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi
|
||||
*
|
||||
* @brief framebuffer support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Yang Qiao
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
*
|
||||
* http://www.rtems.org/license/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/raspberrypi.h>
|
||||
#include <bsp/mailbox.h>
|
||||
#include <bsp/vc.h>
|
||||
#include <bsp/rpi-fb.h>
|
||||
|
||||
#include <libcpu/arm-cp15.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/fb.h>
|
||||
#include <rtems/framebuffer.h>
|
||||
#include <rtems/score/atomic.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#define SCREEN_WIDTH 1024
|
||||
#define SCREEN_HEIGHT 768
|
||||
#define BPP 32
|
||||
|
||||
/* flag to limit driver to protect against multiple opens */
|
||||
static Atomic_Flag driver_mutex;
|
||||
|
||||
/*
|
||||
* screen information for the driver (fb0).
|
||||
*/
|
||||
|
||||
static struct fb_var_screeninfo fb_var_info = {
|
||||
.xres = SCREEN_WIDTH,
|
||||
.yres = SCREEN_HEIGHT,
|
||||
.bits_per_pixel = BPP
|
||||
};
|
||||
|
||||
static struct fb_fix_screeninfo fb_fix_info = {
|
||||
.smem_start = (void *) NULL,
|
||||
.smem_len = 0,
|
||||
.type = FB_TYPE_PACKED_PIXELS,
|
||||
.visual = FB_VISUAL_TRUECOLOR,
|
||||
.line_length = 0
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NO_SUITABLE_MODE = -1,
|
||||
BAD_FORMAT = -2,
|
||||
AUTO_SELECT = -3,
|
||||
DONT_INIT = -4,
|
||||
NO_MODE_REQ = -5,
|
||||
} mode_err_ret_val;
|
||||
|
||||
int rpi_get_fix_screen_info( struct fb_fix_screeninfo *info )
|
||||
{
|
||||
*info = fb_fix_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpi_get_var_screen_info( struct fb_var_screeninfo *info )
|
||||
{
|
||||
*info = fb_var_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find mode given in string format.
|
||||
*
|
||||
* expected format
|
||||
* <resX>x<resY>[-<bpp>]
|
||||
* numbers <resX>, <resY> and <bpp> are decadic
|
||||
*
|
||||
* @param[out] fb_var_ptr pointer to variable mode part filled by function
|
||||
* @param[in] video_string string to be parsed
|
||||
* @retval video mode number to be set
|
||||
* @retval -1 no suitable mode found
|
||||
* @retval -2 bad format of the video_string
|
||||
* @retval -3 automatic mode selection requested
|
||||
* @retval -4 request to not initialize graphics
|
||||
* @retval -5 no mode requested/empty video string
|
||||
*/
|
||||
|
||||
static int parse_mode_from_string(
|
||||
struct fb_var_screeninfo *fb_var_ptr,
|
||||
const char *video_string
|
||||
)
|
||||
{
|
||||
const char *opt;
|
||||
char *endptr;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t bpp = 0;
|
||||
|
||||
opt = video_string;
|
||||
|
||||
if ( opt == NULL )
|
||||
return NO_MODE_REQ;
|
||||
|
||||
if ( strncmp( opt, "auto", 4 ) == 0 )
|
||||
return AUTO_SELECT;
|
||||
|
||||
if ( strncmp( opt, "none", 4 ) == 0 ||
|
||||
strncmp( opt, "off", 3 ) == 0 )
|
||||
return DONT_INIT;
|
||||
|
||||
width = strtol( opt, &endptr, 10 );
|
||||
|
||||
if ( *endptr != 'x' ) {
|
||||
return BAD_FORMAT;
|
||||
}
|
||||
|
||||
opt = endptr + 1;
|
||||
height = strtol( opt, &endptr, 10 );
|
||||
|
||||
switch ( *endptr ) {
|
||||
case '-':
|
||||
opt = endptr + 1;
|
||||
endptr = NULL;
|
||||
bpp = strtol( opt, &endptr, 10 );
|
||||
|
||||
if ( ( endptr == opt ) || ( endptr == NULL ) )
|
||||
return BAD_FORMAT;
|
||||
|
||||
if ( *endptr && ( *endptr != ' ' ) )
|
||||
return BAD_FORMAT;
|
||||
|
||||
break;
|
||||
case ' ':
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return BAD_FORMAT;
|
||||
}
|
||||
|
||||
fb_var_ptr->xres = width;
|
||||
fb_var_ptr->yres = height;
|
||||
|
||||
if ( bpp != 0 )
|
||||
fb_var_ptr->bits_per_pixel = bpp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_mode_from_vc( void )
|
||||
{
|
||||
int res;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
bcm2835_get_display_size_entries entries;
|
||||
|
||||
res = bcm2835_mailbox_get_display_size( &entries );
|
||||
|
||||
width = entries.width;
|
||||
height = entries.height;
|
||||
|
||||
if ( width == 0 || height == 0 ) {
|
||||
fb_var_info.xres = SCREEN_WIDTH;
|
||||
fb_var_info.yres = SCREEN_HEIGHT;
|
||||
} else {
|
||||
fb_var_info.xres = width;
|
||||
fb_var_info.yres = height;
|
||||
}
|
||||
printk("find_mode_from_vc %u x %u, res %d\n", width, height, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool rpi_fb_hdmi_is_present( void )
|
||||
{
|
||||
bcm2835_get_display_size_entries entries;
|
||||
|
||||
memset( &entries, 0, sizeof( entries ) );
|
||||
bcm2835_mailbox_get_display_size( &entries );
|
||||
|
||||
/* Impossible display dimension */
|
||||
if ( ( entries.width < 10 ) || ( entries.height < 10 ) )
|
||||
return false;
|
||||
|
||||
/* Know default values reported when monitor is not present */
|
||||
if ( ( entries.width == 0x290 ) && ( entries.height == 0x1A0 ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int rpi_fb_init( void )
|
||||
{
|
||||
int res;
|
||||
int mode_from_cmdline;
|
||||
bcm2835_init_frame_buffer_entries init_frame_buffer_entries;
|
||||
|
||||
if ( fb_fix_info.smem_start != NULL ) {
|
||||
return RPI_FB_INIT_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
if ( rpi_fb_hdmi_is_present() == false ) {
|
||||
return RPI_FB_INIT_NO_DISPLAY;
|
||||
}
|
||||
|
||||
mode_from_cmdline = parse_mode_from_string( &fb_var_info,
|
||||
rpi_cmdline_get_arg( "--video=" ) );
|
||||
|
||||
switch ( mode_from_cmdline ) {
|
||||
case BAD_FORMAT:
|
||||
return RPI_FB_INIT_CMDLINE_BAD_FORMAT;
|
||||
case AUTO_SELECT:
|
||||
break;
|
||||
case DONT_INIT:
|
||||
return RPI_FB_INIT_CMDLINE_DONT_INIT;
|
||||
case NO_MODE_REQ:
|
||||
return RPI_FB_INIT_CMDLINE_NO_MODE_REQ;
|
||||
}
|
||||
|
||||
if ( mode_from_cmdline ) {
|
||||
if ( find_mode_from_vc() )
|
||||
return RPI_FB_INIT_MODE_PROBE_ERROR;
|
||||
}
|
||||
|
||||
memset( &init_frame_buffer_entries, 0, sizeof( init_frame_buffer_entries ) );
|
||||
init_frame_buffer_entries.xres = fb_var_info.xres;
|
||||
init_frame_buffer_entries.yres = fb_var_info.yres;
|
||||
init_frame_buffer_entries.xvirt = fb_var_info.xres;
|
||||
init_frame_buffer_entries.yvirt = fb_var_info.yres;
|
||||
init_frame_buffer_entries.depth = fb_var_info.bits_per_pixel;
|
||||
init_frame_buffer_entries.pixel_order = bcm2835_mailbox_pixel_order_rgb;
|
||||
init_frame_buffer_entries.alpha_mode = bcm2835_mailbox_alpha_mode_0_opaque;
|
||||
init_frame_buffer_entries.voffset_x = 0;
|
||||
init_frame_buffer_entries.voffset_y = 0;
|
||||
init_frame_buffer_entries.overscan_left = 0;
|
||||
init_frame_buffer_entries.overscan_right = 0;
|
||||
init_frame_buffer_entries.overscan_top = 0;
|
||||
init_frame_buffer_entries.overscan_bottom = 0;
|
||||
printk("bcm2835_mailbox_init_frame_buffer ...\n");
|
||||
res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries );
|
||||
printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res);
|
||||
if (res != 0) {
|
||||
printk("bcm2835_mailbox_init_frame_buffer retry ...\n");
|
||||
res = bcm2835_mailbox_init_frame_buffer( &init_frame_buffer_entries );
|
||||
printk("bcm2835_mailbox_init_frame_buffer returned %d\n", res);
|
||||
if (res != 0)
|
||||
return RPI_FB_INIT_SETUP_FAILED;
|
||||
}
|
||||
|
||||
bcm2835_get_pitch_entries get_pitch_entries;
|
||||
bcm2835_mailbox_get_pitch( &get_pitch_entries );
|
||||
|
||||
fb_var_info.xres = init_frame_buffer_entries.xres;
|
||||
fb_var_info.yres = init_frame_buffer_entries.yres;
|
||||
fb_var_info.bits_per_pixel = init_frame_buffer_entries.depth;
|
||||
fb_fix_info.smem_start = (void *) init_frame_buffer_entries.base;
|
||||
fb_fix_info.smem_len = init_frame_buffer_entries.size;
|
||||
fb_fix_info.line_length = get_pitch_entries.pitch;
|
||||
|
||||
if ( fb_fix_info.smem_start == NULL )
|
||||
return RPI_FB_INIT_START_ADDR_UNKNOWN;
|
||||
|
||||
printk("fb_fix_info.smem_start %p\n", fb_fix_info.smem_start);
|
||||
|
||||
arm_cp15_set_translation_table_entries( (void *) fb_fix_info.smem_start,
|
||||
(void *) fb_fix_info.smem_start +
|
||||
fb_fix_info.smem_len,
|
||||
ARMV7_MMU_DATA_READ_WRITE_CACHED );
|
||||
|
||||
return RPI_FB_INIT_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbds device driver initialize entry point.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
/* register the devices */
|
||||
status = rtems_io_register_name( FRAMEBUFFER_DEVICE_0_NAME, major, 0 );
|
||||
|
||||
if ( status != RTEMS_SUCCESSFUL ) {
|
||||
printk( "[!] error registering framebuffer\n" );
|
||||
rtems_fatal_error_occurred( status );
|
||||
}
|
||||
|
||||
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbds device driver open operation.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
if ( _Atomic_Flag_test_and_set( &driver_mutex,
|
||||
ATOMIC_ORDER_ACQUIRE ) != 0 ) {
|
||||
printk( "RaspberryPi framebuffer could not lock driver_mutex\n" );
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
if ( fb_fix_info.smem_start == NULL ) {
|
||||
int res;
|
||||
res = rpi_fb_init();
|
||||
if ( (res < RPI_FB_INIT_OK) || (fb_fix_info.smem_start == NULL) ) {
|
||||
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
|
||||
printk( "RaspberryPi framebuffer initialization failed\n" );
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
}
|
||||
|
||||
memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbds device driver close operation.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
/* restore previous state. for VGA this means return to text mode.
|
||||
* leave out if graphics hardware has been initialized in
|
||||
* frame_buffer_initialize() */
|
||||
memset( (void *) fb_fix_info.smem_start, 0, fb_fix_info.smem_len );
|
||||
_Atomic_Flag_clear( &driver_mutex, ATOMIC_ORDER_RELEASE );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbds device driver read operation.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
|
||||
rw_args->bytes_moved =
|
||||
( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ?
|
||||
( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count;
|
||||
memcpy( rw_args->buffer,
|
||||
(const void *) ( fb_fix_info.smem_start + rw_args->offset ),
|
||||
rw_args->bytes_moved );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbds device driver write operation.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
|
||||
rw_args->bytes_moved =
|
||||
( ( rw_args->offset + rw_args->count ) > fb_fix_info.smem_len ) ?
|
||||
( fb_fix_info.smem_len - rw_args->offset ) : rw_args->count;
|
||||
memcpy( (void *) ( fb_fix_info.smem_start + rw_args->offset ),
|
||||
rw_args->buffer,
|
||||
rw_args->bytes_moved );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ioctl entry point.
|
||||
*/
|
||||
|
||||
rtems_device_driver frame_buffer_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = arg;
|
||||
|
||||
/* XXX check minor */
|
||||
|
||||
switch ( args->command ) {
|
||||
case FBIOGET_VSCREENINFO:
|
||||
memcpy( args->buffer, &fb_var_info, sizeof( fb_var_info ) );
|
||||
args->ioctl_return = 0;
|
||||
break;
|
||||
case FBIOGET_FSCREENINFO:
|
||||
memcpy( args->buffer, &fb_fix_info, sizeof( fb_fix_info ) );
|
||||
args->ioctl_return = 0;
|
||||
break;
|
||||
case FBIOGETCMAP:
|
||||
/* no palette - truecolor mode */
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
case FBIOPUTCMAP:
|
||||
/* no palette - truecolor mode */
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
default:
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi_console
|
||||
*
|
||||
* @brief framebuffer graphic console support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Yang Qiao
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
*
|
||||
* http://www.rtems.org/license/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fbcons.h>
|
||||
#include <bsp/vc.h>
|
||||
#include <bsp/rpi-fb.h>
|
||||
|
||||
/*
|
||||
* fbcons_init
|
||||
*
|
||||
* This function initializes the fb console to a quiecsent state.
|
||||
*/
|
||||
static void fbcons_init( int minor )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_open
|
||||
*
|
||||
* This function opens a port for communication.
|
||||
*
|
||||
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
|
||||
*/
|
||||
static int fbcons_open(
|
||||
int major,
|
||||
int minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_close
|
||||
*
|
||||
* This function shuts down the requested port.
|
||||
*/
|
||||
static int fbcons_close(
|
||||
int major,
|
||||
int minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return ( RTEMS_SUCCESSFUL );
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_write_polled
|
||||
*
|
||||
* This routine polls out the requested character.
|
||||
*/
|
||||
static void fbcons_write_polled(
|
||||
int minor,
|
||||
char c
|
||||
)
|
||||
{
|
||||
rpi_fb_outch( c );
|
||||
|
||||
if ( c == '\n' )
|
||||
rpi_fb_outch( '\r' ); /* LF = LF + CR */
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_write_support_polled
|
||||
*
|
||||
* Console Termios output entry point when using polled output.
|
||||
*
|
||||
*/
|
||||
static ssize_t fbcons_write_support_polled(
|
||||
int minor,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
int nwrite = 0;
|
||||
|
||||
/*
|
||||
* poll each byte in the string out of the port.
|
||||
*/
|
||||
while ( nwrite < len ) {
|
||||
fbcons_write_polled( minor, *buf++ );
|
||||
nwrite++;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the number of bytes written.
|
||||
*/
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_inbyte_nonblocking_polled
|
||||
*
|
||||
* Console Termios polling input entry point.
|
||||
*/
|
||||
static int fbcons_inbyte_nonblocking_polled( int minor )
|
||||
{
|
||||
// if( rtems_kbpoll() ) {
|
||||
// int c = getch();
|
||||
// return c;
|
||||
// }
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbcons_set_attributes
|
||||
*
|
||||
* This function sets the UART channel to reflect the requested termios
|
||||
* port settings.
|
||||
*/
|
||||
static int fbcons_set_attributes(
|
||||
int minor,
|
||||
const struct termios *t
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fbcons_probe( int minor )
|
||||
{
|
||||
// rtems_status_code status;
|
||||
static bool firstTime = true;
|
||||
static bool ret = false;
|
||||
|
||||
/*
|
||||
* keyboard interrupt should be registered when the keyboard is available
|
||||
*/
|
||||
if ( firstTime ) {
|
||||
if ( !rpi_fb_hdmi_is_present() ) {
|
||||
ret = false;
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const console_fns fbcons_fns =
|
||||
{
|
||||
.deviceProbe = libchip_serial_default_probe, /* deviceProbe */
|
||||
.deviceFirstOpen = fbcons_open, /* deviceFirstOpen */
|
||||
.deviceLastClose = fbcons_close, /* deviceLastClose */
|
||||
.deviceRead = fbcons_inbyte_nonblocking_polled, /* deviceRead */
|
||||
.deviceWrite = fbcons_write_support_polled, /* deviceWrite */
|
||||
.deviceInitialize = fbcons_init, /* deviceInitialize */
|
||||
.deviceWritePolled = fbcons_write_polled, /* deviceWritePolled */
|
||||
.deviceSetAttributes = fbcons_set_attributes, /* deviceSetAttributes */
|
||||
.deviceOutputUsesInterrupts = FALSE, /* deviceOutputUsesInterrupts*/
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,463 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi
|
||||
*
|
||||
* @brief displaying characters on the console
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2015 Yang Qiao
|
||||
* based on work by:
|
||||
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
|
||||
* Canon Centre Recherche France.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Till Straumann <strauman@slac.stanford.edu>, 2003/9:
|
||||
* - added handling of basic escape sequences (cursor movement
|
||||
* and erasing; just enough for the line editor 'libtecla' to
|
||||
* work...)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/vc.h>
|
||||
#include <bsp/rpi-fb.h>
|
||||
#include <rtems/fb.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "font_data.h"
|
||||
|
||||
static void wr_cursor(
|
||||
int r,
|
||||
int c
|
||||
)
|
||||
{
|
||||
/* dummy function for now */
|
||||
}
|
||||
|
||||
#define TAB_SPACE 4
|
||||
#define CONSOLE_BG_COL 0x00
|
||||
#define CONSOLE_FG_COL 0xa0
|
||||
|
||||
static void *fb_mem = NULL;
|
||||
static unsigned short maxCol;
|
||||
static unsigned short maxRow;
|
||||
static unsigned short bytes_per_pixel;
|
||||
static unsigned int bytes_per_line;
|
||||
static unsigned int bytes_per_char_line;
|
||||
static unsigned char row;
|
||||
static unsigned char column;
|
||||
static unsigned int nLines;
|
||||
static uint32_t fgx, bgx, eorx;
|
||||
static int rpi_video_initialized;
|
||||
|
||||
static const int video_font_draw_table32[ 16 ][ 4 ] = {
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
|
||||
{ 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
|
||||
{ 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
|
||||
{ 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
|
||||
{ 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
|
||||
{ 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
|
||||
{ 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
|
||||
{ 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
|
||||
{ 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
|
||||
{ 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
|
||||
{ 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
|
||||
{ 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
|
||||
{ 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
|
||||
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
|
||||
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff }
|
||||
};
|
||||
|
||||
static void scroll( void )
|
||||
{
|
||||
int i, j; /* Counters */
|
||||
uint8_t *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */
|
||||
|
||||
pt_bitmap = fb_mem;
|
||||
j = 0;
|
||||
pt_bitmap = pt_bitmap + j;
|
||||
pt_scroll = pt_bitmap + bytes_per_char_line;
|
||||
|
||||
for ( i = j; i < maxRow - 1; i++ ) {
|
||||
memcpy( pt_bitmap, pt_scroll, bytes_per_char_line );
|
||||
pt_bitmap = pt_bitmap + bytes_per_char_line;
|
||||
pt_scroll = pt_bitmap + bytes_per_char_line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Blank characters are displayed on the last line.
|
||||
*/
|
||||
memset( pt_bitmap, 0, bytes_per_char_line );
|
||||
}
|
||||
|
||||
static void doCRNL(
|
||||
int cr,
|
||||
int nl
|
||||
)
|
||||
{
|
||||
if ( nl ) {
|
||||
if ( ++row == maxRow ) {
|
||||
scroll(); /* Scroll the screen now */
|
||||
row = maxRow - 1;
|
||||
}
|
||||
|
||||
nLines++;
|
||||
}
|
||||
|
||||
if ( cr )
|
||||
column = 0;
|
||||
|
||||
/* Move cursor on the next location */
|
||||
if ( cr || nl ) {
|
||||
wr_cursor( row, column );
|
||||
}
|
||||
}
|
||||
|
||||
static void advanceCursor( void )
|
||||
{
|
||||
if ( ++column == maxCol )
|
||||
doCRNL( 1, 1 );
|
||||
else
|
||||
wr_cursor( row, column );
|
||||
}
|
||||
|
||||
static void gotorc(
|
||||
int r,
|
||||
int c
|
||||
)
|
||||
{
|
||||
column = c;
|
||||
row = r;
|
||||
wr_cursor( row, column );
|
||||
}
|
||||
|
||||
static void video_drawchars(
|
||||
int r,
|
||||
int c,
|
||||
unsigned char ch
|
||||
)
|
||||
{
|
||||
if ( fb_mem == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *cdat, *dest, *dest0;
|
||||
int rows, offset;
|
||||
|
||||
offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH;
|
||||
dest0 = fb_mem + offset;
|
||||
|
||||
/*
|
||||
* only 32-bit per pixel format is supported for now
|
||||
*/
|
||||
cdat = rpi_font + ch * RPI_FONT_HEIGHT;
|
||||
|
||||
for ( rows = RPI_FONT_HEIGHT, dest = dest0;
|
||||
rows--; dest += bytes_per_line ) {
|
||||
uint8_t bits = *cdat++;
|
||||
|
||||
( (uint32_t *) dest )[ 0 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits >> 4 ][ 0 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 1 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits >> 4 ][ 1 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 2 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits >> 4 ][ 2 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 3 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits >> 4 ][ 3 ] & eorx ) ^ bgx;
|
||||
|
||||
( (uint32_t *) dest )[ 4 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits & 15 ][ 0 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 5 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits & 15 ][ 1 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 6 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits & 15 ][ 2 ] & eorx ) ^ bgx;
|
||||
( (uint32_t *) dest )[ 7 ] =
|
||||
( video_font_draw_table32
|
||||
[ bits & 15 ][ 3 ] & eorx ) ^ bgx;
|
||||
}
|
||||
}
|
||||
|
||||
#define ESC ( (char) 27 )
|
||||
/* erase current location without moving the cursor */
|
||||
#define BLANK ( (char) 0x7f )
|
||||
|
||||
static void videoPutChar( char ch )
|
||||
{
|
||||
switch ( ch ) {
|
||||
case '\b': {
|
||||
if ( column )
|
||||
column--;
|
||||
|
||||
/* Move cursor on the previous location */
|
||||
wr_cursor( row, column );
|
||||
return;
|
||||
}
|
||||
case '\t': {
|
||||
int i;
|
||||
|
||||
i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) );
|
||||
|
||||
while ( i-- ) {
|
||||
|
||||
video_drawchars( row, column, ' ' );
|
||||
column += 1;
|
||||
|
||||
if ( column >= maxCol ) {
|
||||
doCRNL( 1, 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wr_cursor( row, column );
|
||||
|
||||
return;
|
||||
}
|
||||
case '\n': {
|
||||
doCRNL( 0, 1 );
|
||||
return;
|
||||
}
|
||||
case 7: { /* Bell code must be inserted here */
|
||||
return;
|
||||
}
|
||||
case '\r': {
|
||||
doCRNL( 1, 0 );
|
||||
return;
|
||||
}
|
||||
case BLANK: {
|
||||
video_drawchars( row, column, ' ' );
|
||||
|
||||
wr_cursor( row, column );
|
||||
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
// *pt_bitmap = (unsigned char)ch | attribute;
|
||||
video_drawchars( row, column, ch );
|
||||
advanceCursor();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* trivial state machine to handle escape sequences:
|
||||
*
|
||||
* ---------------------------------
|
||||
* | |
|
||||
* | |
|
||||
* KEY: esc V [ DCABHKJ esc |
|
||||
* STATE: 0 -----> 27 -----> '[' ----------> -1 -----
|
||||
* ^\ \ \ \
|
||||
* KEY: | \other \ other \ other \ other
|
||||
* <-------------------------------------
|
||||
*
|
||||
* in state '-1', the DCABHKJ cases are handled
|
||||
*
|
||||
* (cursor motion and screen clearing)
|
||||
*/
|
||||
|
||||
#define DONE ( -1 )
|
||||
|
||||
static int handleEscape(
|
||||
int oldState,
|
||||
char ch
|
||||
)
|
||||
{
|
||||
int rval = 0;
|
||||
int ro, co;
|
||||
|
||||
switch ( oldState ) {
|
||||
case DONE: /* means the previous char terminated an ESC sequence... */
|
||||
case 0:
|
||||
|
||||
if ( 27 == ch ) {
|
||||
rval = 27; /* START of an ESC sequence */
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 27:
|
||||
|
||||
if ( '[' == ch ) {
|
||||
rval = ch; /* received ESC '[', so far */
|
||||
} else {
|
||||
/* dump suppressed 'ESC'; outch will append the char */
|
||||
videoPutChar( ESC );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '[':
|
||||
/* handle 'ESC' '[' sequences here */
|
||||
ro = row;
|
||||
co = column;
|
||||
rval = DONE; /* done */
|
||||
|
||||
switch ( ch ) {
|
||||
case 'D': /* left */
|
||||
|
||||
if ( co > 0 )
|
||||
co--;
|
||||
|
||||
break;
|
||||
case 'C': /* right */
|
||||
|
||||
if ( co < maxCol )
|
||||
co++;
|
||||
|
||||
break;
|
||||
case 'A': /* up */
|
||||
|
||||
if ( ro > 0 )
|
||||
ro--;
|
||||
|
||||
break;
|
||||
case 'B': /* down */
|
||||
|
||||
if ( ro < maxRow )
|
||||
ro++;
|
||||
|
||||
break;
|
||||
case 'H': /* home */
|
||||
ro = co = 0;
|
||||
break;
|
||||
case 'K': /* clear to end of line */
|
||||
|
||||
while ( column < maxCol - 1 )
|
||||
videoPutChar( ' ' );
|
||||
|
||||
videoPutChar( BLANK );
|
||||
break;
|
||||
case 'J': /* clear to end of screen */
|
||||
|
||||
while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) )
|
||||
videoPutChar( ' ' );
|
||||
|
||||
videoPutChar( BLANK );
|
||||
break;
|
||||
default:
|
||||
videoPutChar( ESC );
|
||||
videoPutChar( '[' );
|
||||
/* DONT move the cursor */
|
||||
ro = -1;
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// /* reset cursor */
|
||||
if ( ro >= 0 )
|
||||
gotorc( ro, co );
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void clear_screen( void )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for ( j = 0; j < maxRow; j++ ) {
|
||||
for ( i = 0; i < maxCol; i++ ) {
|
||||
videoPutChar( ' ' );
|
||||
}
|
||||
}
|
||||
|
||||
column = 0;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
void rpi_fb_outch( char c )
|
||||
{
|
||||
static int escaped = 0;
|
||||
|
||||
if ( !( escaped = handleEscape( escaped, c ) ) ) {
|
||||
if ( '\n' == c )
|
||||
videoPutChar( '\r' );
|
||||
|
||||
videoPutChar( c );
|
||||
}
|
||||
}
|
||||
|
||||
void rpi_video_init( void )
|
||||
{
|
||||
int ret = rpi_fb_init();
|
||||
|
||||
if ( ( ret != RPI_FB_INIT_OK ) &&
|
||||
( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) {
|
||||
rpi_video_initialized = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
struct fb_var_screeninfo fb_var_info;
|
||||
struct fb_fix_screeninfo fb_fix_info;
|
||||
rpi_get_var_screen_info( &fb_var_info );
|
||||
rpi_get_fix_screen_info( &fb_fix_info );
|
||||
maxCol = fb_var_info.xres / RPI_FONT_WIDTH;
|
||||
maxRow = fb_var_info.yres / RPI_FONT_HEIGHT;
|
||||
bytes_per_pixel = fb_var_info.bits_per_pixel / 8;
|
||||
bytes_per_line = bytes_per_pixel * fb_var_info.xres;
|
||||
bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line;
|
||||
fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start );
|
||||
column = 0;
|
||||
row = 0;
|
||||
nLines = 0;
|
||||
fgx = ( CONSOLE_FG_COL << 24 ) |
|
||||
( CONSOLE_FG_COL << 16 ) |
|
||||
( CONSOLE_FG_COL << 8 ) |
|
||||
CONSOLE_FG_COL;
|
||||
bgx = ( CONSOLE_BG_COL << 24 ) |
|
||||
( CONSOLE_BG_COL << 16 ) |
|
||||
( CONSOLE_BG_COL << 8 ) |
|
||||
CONSOLE_BG_COL;
|
||||
eorx = fgx ^ bgx;
|
||||
clear_screen();
|
||||
rpi_video_initialized = 1;
|
||||
}
|
||||
|
||||
int rpi_video_is_initialized( void )
|
||||
{
|
||||
return rpi_video_initialized;
|
||||
}
|
||||
|
||||
/* for old DOS compatibility n-curses type of applications */
|
||||
void gotoxy(
|
||||
int x,
|
||||
int y
|
||||
);
|
||||
int whereX( void );
|
||||
int whereY( void );
|
||||
|
||||
void gotoxy(
|
||||
int x,
|
||||
int y
|
||||
)
|
||||
{
|
||||
gotorc( y, x );
|
||||
}
|
||||
|
||||
int whereX( void )
|
||||
{
|
||||
return row;
|
||||
}
|
||||
|
||||
int whereY( void )
|
||||
{
|
||||
return column;
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup raspberrypi_usart
|
||||
*
|
||||
* @brief USART support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Alan Cudmore
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
*
|
||||
* http://www.rtems.org/license/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/usart.h>
|
||||
#include <bsp/raspberrypi.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
static void usart_delay(uint32_t n)
|
||||
{
|
||||
volatile uint32_t i = 0;
|
||||
|
||||
for(i = 0; i < n; i++)
|
||||
;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* These will be useful when the driver supports interrupt driven IO.
|
||||
*/
|
||||
static rtems_vector_number usart_get_irq_number(const console_tbl *ct)
|
||||
{
|
||||
return ct->ulIntVector;
|
||||
}
|
||||
|
||||
static uint32_t usart_get_baud(const console_tbl *ct)
|
||||
{
|
||||
return ct->ulClock;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void usart_set_baud(int minor, int baud)
|
||||
{
|
||||
/*
|
||||
* Nothing for now
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
static void usart_initialize(int minor)
|
||||
{
|
||||
unsigned int gpio_reg;
|
||||
|
||||
/*
|
||||
** Program GPIO pins for UART 0
|
||||
*/
|
||||
gpio_reg = BCM2835_REG(BCM2835_GPIO_GPFSEL1);
|
||||
gpio_reg &= ~(7<<12); /* gpio14 */
|
||||
gpio_reg |= (4<<12); /* alt0 */
|
||||
gpio_reg &= ~(7<<15); /* gpio15 */
|
||||
gpio_reg |= (4<<15); /* alt0 */
|
||||
BCM2835_REG(BCM2835_GPIO_GPFSEL1) = gpio_reg;
|
||||
|
||||
BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
|
||||
usart_delay(150);
|
||||
BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1<<14)|(1<<15);
|
||||
usart_delay(150);
|
||||
BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0;
|
||||
|
||||
/*
|
||||
** Init the PL011 UART
|
||||
*/
|
||||
BCM2835_REG(BCM2835_UART0_CR) = 0;
|
||||
BCM2835_REG(BCM2835_UART0_ICR) = 0x7FF;
|
||||
BCM2835_REG(BCM2835_UART0_IMSC) = 0;
|
||||
BCM2835_REG(BCM2835_UART0_IBRD) = 1;
|
||||
BCM2835_REG(BCM2835_UART0_FBRD) = 40;
|
||||
BCM2835_REG(BCM2835_UART0_LCRH) = 0x70;
|
||||
BCM2835_REG(BCM2835_UART0_RSRECR) = 0;
|
||||
|
||||
BCM2835_REG(BCM2835_UART0_CR) = 0x301;
|
||||
|
||||
BCM2835_REG(BCM2835_UART0_IMSC) = BCM2835_UART0_IMSC_RX;
|
||||
|
||||
usart_set_baud(minor, 115000);
|
||||
}
|
||||
|
||||
static int usart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
|
||||
struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
|
||||
const console_tbl *ct = Console_Port_Tbl [minor];
|
||||
console_data *cd = &Console_Port_Data [minor];
|
||||
|
||||
cd->termios_data = tty;
|
||||
rtems_termios_set_initial_baud(tty, ct->ulClock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usart_read_polled(int minor)
|
||||
{
|
||||
if (minor == 0) {
|
||||
if (((BCM2835_REG(BCM2835_UART0_FR)) & BCM2835_UART0_FR_RXFE) == 0) {
|
||||
return((BCM2835_REG(BCM2835_UART0_DR)) & 0xFF );
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printk("Unknown console minor number: %d\n", minor);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void usart_write_polled(int minor, char c)
|
||||
{
|
||||
while (1) {
|
||||
if ((BCM2835_REG(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF) == 0)
|
||||
break;
|
||||
}
|
||||
BCM2835_REG(BCM2835_UART0_DR) = c;
|
||||
}
|
||||
|
||||
static ssize_t usart_write_support_polled(
|
||||
int minor,
|
||||
const char *s,
|
||||
size_t n
|
||||
)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
usart_write_polled(minor, s [i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int usart_set_attributes(int minor, const struct termios *term)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
const console_fns bcm2835_usart_fns = {
|
||||
.deviceProbe = libchip_serial_default_probe,
|
||||
.deviceFirstOpen = usart_first_open,
|
||||
.deviceLastClose = usart_last_close,
|
||||
.deviceRead = usart_read_polled,
|
||||
.deviceWrite = usart_write_support_polled,
|
||||
.deviceInitialize = usart_initialize,
|
||||
.deviceWritePolled = usart_write_polled,
|
||||
.deviceSetAttributes = usart_set_attributes,
|
||||
.deviceOutputUsesInterrupts = false
|
||||
};
|
||||
@@ -61,12 +61,12 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../shared/get-serial-mouse-ps2.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios-init.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/getserialmouseps2.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-pl011.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-pl050.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/console/console-config.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/serial_mouse.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/arm-pl011.h>
|
||||
#include <bsp/arm-pl050.h>
|
||||
#include <bsp/console-termios.h>
|
||||
|
||||
static arm_pl011_context pl011_context = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL011"),
|
||||
.regs = (volatile pl011 *) 0x10009000,
|
||||
.irq = RVPBXA9_IRQ_UART_0,
|
||||
.initial_baud = 115200
|
||||
};
|
||||
|
||||
static arm_pl050_context pl050_context = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL050"),
|
||||
.regs = (volatile pl050 *) 0x10007000,
|
||||
.irq = RVPBXA9_IRQ_KMI1,
|
||||
.initial_baud = 115200
|
||||
};
|
||||
|
||||
static void output_char(char c)
|
||||
{
|
||||
arm_pl011_write_polled(&pl011_context.base, c);
|
||||
}
|
||||
|
||||
static bool pl011_probe(rtems_termios_device_context *base)
|
||||
{
|
||||
BSP_output_char = output_char;
|
||||
|
||||
return arm_pl011_probe(base);
|
||||
}
|
||||
|
||||
static void output_char_init(char c)
|
||||
{
|
||||
pl011_probe(&pl011_context.base);
|
||||
output_char(c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = output_char_init;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
|
||||
const console_device console_device_table[] = {
|
||||
{
|
||||
.device_file = "/dev/ttyS0",
|
||||
.probe = pl011_probe,
|
||||
.handler = &arm_pl011_fns,
|
||||
.context = &pl011_context.base
|
||||
}, {
|
||||
.device_file = SERIAL_MOUSE_DEVICE_PS2,
|
||||
.probe = console_device_probe_default,
|
||||
.handler = &arm_pl050_fns,
|
||||
.context = &pl050_context.base
|
||||
}
|
||||
};
|
||||
|
||||
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||
@@ -33,7 +33,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/rtl22xx/clock/clockdrv.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/rtl22xx/console/uart.c
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* @ingroup rtl22xx_uart
|
||||
* @brief UART support.
|
||||
*/
|
||||
|
||||
#ifndef LPC22XX_UART_H
|
||||
#define LPC22XX_UART_H
|
||||
|
||||
/**
|
||||
* @defgroup rtl22xx_uart UART Support
|
||||
* @ingroup arm_rtl22xx
|
||||
* @brief UART (Universal Asynchronous Reciever/Transmitter) Support
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FIFODEEP 16
|
||||
|
||||
#define BD115200 115200
|
||||
#define BD38400 38400
|
||||
#define BD9600 9600
|
||||
|
||||
/** @brief PINSEL0 Value for UART0 */
|
||||
#define U0_PINSEL (0x00000005)
|
||||
/** @brief PINSEL0 Mask for UART0 */
|
||||
#define U0_PINMASK (0x0000000F)
|
||||
/** @brief PINSEL0 Value for UART1 */
|
||||
#define U1_PINSEL (0x00050000)
|
||||
/** @brief PINSEL0 Mask for UART1 */
|
||||
#define U1_PINMASK (0x000F0000)
|
||||
|
||||
/**
|
||||
* @name Uart line control register bit descriptions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define LCR_WORDLENTH_BIT 0
|
||||
#define LCR_STOPBITSEL_BIT 2
|
||||
#define LCR_PARITYENBALE_BIT 3
|
||||
#define LCR_PARITYSEL_BIT 4
|
||||
#define LCR_BREAKCONTROL_BIT 6
|
||||
#define LCR_DLAB_BIT 7
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Line Control Register bit definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief 5-bit character length */
|
||||
#define ULCR_CHAR_5 (0 << 0)
|
||||
/** @brief 6-bit character length */
|
||||
#define ULCR_CHAR_6 (1 << 0)
|
||||
/** @brief 7-bit character length */
|
||||
#define ULCR_CHAR_7 (2 << 0)
|
||||
/** @brief 8-bit character length */
|
||||
#define ULCR_CHAR_8 (3 << 0)
|
||||
/** @brief no stop bits */
|
||||
#define ULCR_STOP_0 (0 << 2)
|
||||
/** @brief 1 stop bit */
|
||||
#define ULCR_STOP_1 (1 << 2)
|
||||
/** @brief No Parity */
|
||||
#define ULCR_PAR_NO (0 << 3)
|
||||
/** @brief Odd Parity */
|
||||
#define ULCR_PAR_ODD (1 << 3)
|
||||
/** @brief Even Parity */
|
||||
#define ULCR_PAR_EVEN (3 << 3)
|
||||
/** @brief MARK "1" Parity */
|
||||
#define ULCR_PAR_MARK (5 << 3)
|
||||
/** @brief SPACE "0" Paruty */
|
||||
#define ULCR_PAR_SPACE (7 << 3)
|
||||
/** @brief Output BREAK line condition */
|
||||
#define ULCR_BREAK_ENABLE (1 << 6)
|
||||
/** @brief Enable Divisor Latch Access */
|
||||
#define ULCR_DLAB_ENABLE (1 << 7)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Modem Control Register bit definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Data Terminal Ready */
|
||||
#define UMCR_DTR (1 << 0)
|
||||
/** @brief Request To Send */
|
||||
#define UMCR_RTS (1 << 1)
|
||||
/** @brief Loopback */
|
||||
#define UMCR_LB (1 << 4)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Line Status Register bit definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Receive Data Ready */
|
||||
#define ULSR_RDR (1 << 0)
|
||||
/** @brief Overrun Error */
|
||||
#define ULSR_OE (1 << 1)
|
||||
/** @brief Parity Error */
|
||||
#define ULSR_PE (1 << 2)
|
||||
/** @brief Framing Error */
|
||||
#define ULSR_FE (1 << 3)
|
||||
/** @brief Break Interrupt */
|
||||
#define ULSR_BI (1 << 4)
|
||||
/** @brief Transmit Holding Register Empty */
|
||||
#define ULSR_THRE (1 << 5)
|
||||
/** @brief Transmitter Empty */
|
||||
#define ULSR_TEMT (1 << 6)
|
||||
/** @brief Error in Receive FIFO */
|
||||
#define ULSR_RXFE (1 << 7)
|
||||
#define ULSR_ERR_MASK 0x1E
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Modem Status Register bit definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Delta Clear To Send */
|
||||
#define UMSR_DCTS (1 << 0)
|
||||
/** @brief Delta Data Set Ready */
|
||||
#define UMSR_DDSR (1 << 1)
|
||||
/** @brief Trailing Edge Ring Indicator */
|
||||
#define UMSR_TERI (1 << 2)
|
||||
/** @brief Delta Data Carrier Detect */
|
||||
#define UMSR_DDCD (1 << 3)
|
||||
/** @brief Clear To Send */
|
||||
#define UMSR_CTS (1 << 4)
|
||||
/** @brief Data Set Ready */
|
||||
#define UMSR_DSR (1 << 5)
|
||||
/** @brief Ring Indicator */
|
||||
#define UMSR_RI (1 << 6)
|
||||
/** @brief Data Carrier Detect */
|
||||
#define UMSR_DCD (1 << 7)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Uart Interrupt Identification
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IIR_RSL 0x3
|
||||
#define IIR_RDA 0x2
|
||||
#define IIR_CTI 0x6
|
||||
#define IIR_THRE 0x1
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Uart Interrupt Enable Type
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IER_RBR 0x1
|
||||
#define IER_THRE 0x2
|
||||
#define IER_RLS 0x4
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Uart Receiver Errors
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define RC_FIFO_OVERRUN_ERR 0x1
|
||||
#define RC_OVERRUN_ERR 0x2
|
||||
#define RC_PARITY_ERR 0x4
|
||||
#define RC_FRAMING_ERR 0x8
|
||||
#define RC_BREAK_IND 0x10
|
||||
|
||||
/** @} */
|
||||
|
||||
typedef enum {
|
||||
UART0 = 0,
|
||||
UART1
|
||||
} LPC_UartChanel_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* console driver for RTL22xx UARTs
|
||||
*
|
||||
* If you want the driver to be interrupt driven, you
|
||||
* need to write the ISR, and in the ISR insert the
|
||||
* chars into termios's queue.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) By ray <rayx.cn@gmail.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h> /* Must be before libio.h */
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
/* Put the CPU (or UART) specific header file #include here */
|
||||
#include <lpc22xx.h>
|
||||
#include "lpc22xx_uart.h"
|
||||
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
/* How many serial ports? */
|
||||
#define NUM_DEVS 1
|
||||
|
||||
int dbg_dly;
|
||||
|
||||
/* static function prototypes */
|
||||
static int uart_first_open(int major, int minor, void *arg);
|
||||
static int uart_last_close(int major, int minor, void *arg);
|
||||
static int uart_read(int minor);
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len);
|
||||
static void uart_init(int minor);
|
||||
static void uart_write_polled(int minor, char c);
|
||||
static int uart_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* These are used by code in console.c */
|
||||
unsigned long Console_Configuration_Count = NUM_DEVS;
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns uart_fns = {
|
||||
libchip_serial_default_probe,
|
||||
uart_first_open,
|
||||
uart_last_close,
|
||||
uart_read,
|
||||
uart_write,
|
||||
uart_init,
|
||||
uart_write_polled, /* not used in this driver */
|
||||
uart_set_attributes,
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
|
||||
/*
|
||||
* There's one item in array for each UART.
|
||||
*
|
||||
* Some of these fields are marked "NOT USED". They are not used
|
||||
* by console.c, but may be used by drivers in libchip
|
||||
*/
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
{
|
||||
"/dev/com0", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&uart_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
0, /* ulCtrlPort1 - NOT USED */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
"/dev/com1", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&uart_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
0, /* ulCtrlPort1 - NOT USED */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. If the driver
|
||||
* is interrupt driven, you should enable interrupts here. Otherwise,
|
||||
* it's probably safe to do nothing.
|
||||
*
|
||||
* Since micromonitor already set up the UART, we do nothing.
|
||||
*/
|
||||
static int uart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. If the driver
|
||||
* is interrupt driven, you should disable interrupts here. Otherwise,
|
||||
* it's probably safe to do nothing.
|
||||
*/
|
||||
static int uart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* Return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int uart_read(int minor)
|
||||
{
|
||||
char c;
|
||||
|
||||
switch (minor) {
|
||||
case 0:
|
||||
if (U0LSR & ULSR_RDR) {
|
||||
c = U0RBR;
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
case 1:
|
||||
if (U1LSR & ULSR_RDR) {
|
||||
c = U1RBR;
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printk("Unknown console minor number %d\n", minor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write buffer to UART
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
switch (minor) {
|
||||
case 0:
|
||||
for (i = 0; i < len; i++) {
|
||||
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
|
||||
continue; /* also either WDOG() or swap()*/
|
||||
U0THR = (char) buf[i];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (i = 0; i < len; i++) {
|
||||
while (!(U0LSR & ULSR_THRE)) /* wait for TX buffer to empty*/
|
||||
continue; /* also either WDOG() or swap()*/
|
||||
U0THR = (char) buf[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk("Unknown console minor number %d\n", minor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Set up the UART. */
|
||||
static void uart_init(int minor)
|
||||
{
|
||||
#if 0 //init will be done in bspstart.c
|
||||
int baud=6;
|
||||
int mode =0x03;
|
||||
if(minor==0){
|
||||
// set port pins for UART0
|
||||
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
||||
|
||||
U0IER = 0x00; // disable all interrupts
|
||||
|
||||
// set the baudrate
|
||||
U0LCR = 1<<7; // select divisor latches
|
||||
U0DLL = (uint8_t)baud; // set for baud low byte
|
||||
U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
||||
|
||||
// set the number of characters and other
|
||||
// user specified operating parameters
|
||||
U0LCR = (mode & ~ULCR_DLAB_ENABLE);
|
||||
U0FCR = mode>>8; /*fifo mode*/
|
||||
|
||||
// set port pins for UART1
|
||||
PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
|
||||
|
||||
U1IER = 0x00; // disable all interrupts
|
||||
}else if(minor==1){
|
||||
// set the baudrate
|
||||
U1LCR = ULCR_DLAB_ENABLE; // select divisor latches
|
||||
U1DLL = (uint8_t)baud; // set for baud low byte
|
||||
U1DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
||||
|
||||
// set the number of characters and other
|
||||
// user specified operating parameters
|
||||
U1LCR = (mode & ~ULCR_DLAB_ENABLE);
|
||||
U1FCR = mode>>8;/*fifo mode*/
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* I'm not sure this is needed for the shared console driver. */
|
||||
static void uart_write_polled(int minor, char c)
|
||||
{
|
||||
uart_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int uart_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a character to the console. This is used by printk() and
|
||||
* maybe other low level functions. It should not use interrupts or any
|
||||
* RTEMS system calls. It needs to be very simple
|
||||
*/
|
||||
static void _BSP_put_char( char c )
|
||||
{
|
||||
uart_write_polled(0, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
||||
|
||||
static int _BSP_get_char(void)
|
||||
{
|
||||
return uart_read(0);
|
||||
}
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
|
||||
|
||||
/*
|
||||
* init USART 0<><30>8 bit, 1 Stop,No checkout, BPS115200
|
||||
*/
|
||||
void UART0_Ini(void)
|
||||
{
|
||||
long Fdiv;
|
||||
int i;
|
||||
|
||||
PINSEL0 = 0x00000005; // I/O to UART0
|
||||
U0LCR = 0x83; // DLAB = 1
|
||||
Fdiv = (Fpclk >>4) / UART_BPS; // configure BPS
|
||||
U0DLM = Fdiv/256;
|
||||
U0DLL = Fdiv%256;
|
||||
U0LCR = 0x03;
|
||||
|
||||
for(i=0;i<10;i++){
|
||||
U0THR = 67; //send a C to see if is OK
|
||||
while ( (U0LSR&0x40)==0 );
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/smdk2410/clock/support.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/smdk2410/console/uart.c
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* console driver for S3C2400 UARTs
|
||||
*
|
||||
* This driver uses the shared console driver in
|
||||
* ...../libbsp/shared/console.c
|
||||
*
|
||||
* If you want the driver to be interrupt driven, you
|
||||
* need to write the ISR, and in the ISR insert the
|
||||
* chars into termios's queue.
|
||||
*
|
||||
* Copyright (c) 2004 Cogent Computer Systems
|
||||
* Written by Jay Monkman <jtm@lopingdog.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
#include <bsp.h> /* Must be before libio.h */
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
/* Put the CPU (or UART) specific header file #include here */
|
||||
#include <s3c24xx.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
/* How many serial ports? */
|
||||
#define NUM_DEVS 1
|
||||
|
||||
int uart_poll_read(int minor);
|
||||
|
||||
int dbg_dly;
|
||||
|
||||
/* static function prototypes */
|
||||
static int uart_first_open(int major, int minor, void *arg);
|
||||
static int uart_last_close(int major, int minor, void *arg);
|
||||
static int uart_read(int minor);
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len);
|
||||
static void uart_init(int minor);
|
||||
static void uart_write_polled(int minor, char c);
|
||||
static int uart_set_attributes(int minor, const struct termios *t);
|
||||
|
||||
/* These are used by code in console.c */
|
||||
unsigned long Console_Configuration_Count = NUM_DEVS;
|
||||
|
||||
/* Pointers to functions for handling the UART. */
|
||||
const console_fns uart_fns =
|
||||
{
|
||||
libchip_serial_default_probe,
|
||||
uart_first_open,
|
||||
uart_last_close,
|
||||
uart_read,
|
||||
uart_write,
|
||||
uart_init,
|
||||
uart_write_polled, /* not used in this driver */
|
||||
uart_set_attributes,
|
||||
FALSE /* TRUE if interrupt driven, FALSE if not. */
|
||||
};
|
||||
|
||||
/*
|
||||
* There's one item in array for each UART.
|
||||
*
|
||||
* Some of these fields are marked "NOT USED". They are not used
|
||||
* by console.c, but may be used by drivers in libchip
|
||||
*
|
||||
*/
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
{
|
||||
"/dev/com0", /* sDeviceName */
|
||||
SERIAL_CUSTOM, /* deviceType */
|
||||
&uart_fns, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
0, /* ulMargin - NOT USED */
|
||||
0, /* ulHysteresis - NOT USED */
|
||||
NULL, /* pDeviceParams */
|
||||
0, /* ulCtrlPort1 - NOT USED */
|
||||
0, /* ulCtrlPort2 - NOT USED */
|
||||
0, /* ulDataPort - NOT USED */
|
||||
NULL, /* getRegister - NOT USED */
|
||||
NULL, /* setRegister - NOT USED */
|
||||
NULL, /* getData - NOT USED */
|
||||
NULL, /* setData - NOT USED */
|
||||
0, /* ulClock - NOT USED */
|
||||
0 /* ulIntVector - NOT USED */
|
||||
}
|
||||
};
|
||||
|
||||
/*********************************************************************/
|
||||
/* Functions called via termios callbacks (i.e. the ones in uart_fns */
|
||||
/*********************************************************************/
|
||||
|
||||
/*
|
||||
* This is called the first time each device is opened. If the driver
|
||||
* is interrupt driven, you should enable interrupts here. Otherwise,
|
||||
* it's probably safe to do nothing.
|
||||
*
|
||||
* Since micromonitor already set up the UART, we do nothing.
|
||||
*/
|
||||
static int uart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is called the last time each device is closed. If the driver
|
||||
* is interrupt driven, you should disable interrupts here. Otherwise,
|
||||
* it's probably safe to do nothing.
|
||||
*/
|
||||
static int uart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read one character from UART.
|
||||
*
|
||||
* Return -1 if there's no data, otherwise return
|
||||
* the character in lowest 8 bits of returned int.
|
||||
*/
|
||||
static int uart_read(int minor)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (minor == 0) {
|
||||
if (rUTRSTAT0 & 0x1) {
|
||||
c = rURXH0 & 0xff;
|
||||
return c;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printk("Unknown console minor number: %d\n", minor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write buffer to UART
|
||||
*
|
||||
* return 1 on success, -1 on error
|
||||
*/
|
||||
static ssize_t uart_write(int minor, const char *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (minor == 0) {
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Wait for fifo to have room */
|
||||
while(!(rUTRSTAT0 & 0x2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rUTXH0 = (char) buf[i];
|
||||
}
|
||||
} else {
|
||||
printk("Unknown console minor number: %d\n", minor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Set up the UART. */
|
||||
static void uart_init(int minor)
|
||||
{
|
||||
int i;
|
||||
unsigned int reg = 0;
|
||||
|
||||
/* enable UART0 */
|
||||
rCLKCON|=0x100;
|
||||
|
||||
/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
|
||||
reg = get_PCLK() / (16 * 115200) - 1;
|
||||
|
||||
/* FIFO enable, Tx/Rx FIFO clear */
|
||||
rUFCON0 = 0x07;
|
||||
rUMCON0 = 0x0;
|
||||
/* Normal,No parity,1 stop,8 bit */
|
||||
rULCON0 = 0x3;
|
||||
/*
|
||||
* tx=level,rx=edge,disable timeout int.,enable rx error int.,
|
||||
* normal,interrupt or polling
|
||||
*/
|
||||
rUCON0 = 0x245;
|
||||
rUBRDIV0 = reg;
|
||||
|
||||
for (i = 0; i < 100; i++);
|
||||
|
||||
}
|
||||
|
||||
/* I'm not sure this is needed for the shared console driver. */
|
||||
static void uart_write_polled(int minor, char c)
|
||||
{
|
||||
uart_write(minor, &c, 1);
|
||||
}
|
||||
|
||||
/* This is for setting baud rate, bits, etc. */
|
||||
static int uart_set_attributes(int minor, const struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* The following functions are not used by TERMIOS, but other RTEMS
|
||||
* functions use them instead.
|
||||
*/
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Read from UART. This is used in the exit code, and can't
|
||||
* rely on interrupts.
|
||||
*/
|
||||
int uart_poll_read(int minor)
|
||||
{
|
||||
return uart_read(minor);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write a character to the console. This is used by printk() and
|
||||
* maybe other low level functions. It should not use interrupts or any
|
||||
* RTEMS system calls. It needs to be very simple
|
||||
*/
|
||||
static void _BSP_put_char( char c ) {
|
||||
uart_write_polled(0, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
|
||||
|
||||
static int _BSP_get_char(void)
|
||||
{
|
||||
return uart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
|
||||
@@ -56,8 +56,8 @@ librtemsbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console-select.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/usart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/stm32f4/console/usart.c
|
||||
|
||||
# I2C
|
||||
librtemsbsp_a_SOURCES += i2c/i2c.c
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Sebastian Huber. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/usart.h>
|
||||
#include <bsp/stm32f4.h>
|
||||
|
||||
console_tbl Console_Configuration_Ports [] = {
|
||||
#ifdef STM32F4_ENABLE_USART_1
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS0",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_1,
|
||||
.ulCtrlPort2 = 0,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_USART1
|
||||
},
|
||||
#endif
|
||||
#ifdef STM32F4_ENABLE_USART_2
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS1",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_2,
|
||||
.ulCtrlPort2 = 1,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_USART2
|
||||
},
|
||||
#endif
|
||||
#ifdef STM32F4_ENABLE_USART_3
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS2",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_3,
|
||||
.ulCtrlPort2 = 2,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_USART3
|
||||
},
|
||||
#endif
|
||||
#ifdef STM32F4_ENABLE_UART_4
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS3",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_4,
|
||||
.ulCtrlPort2 = 3,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_UART4
|
||||
},
|
||||
#endif
|
||||
#ifdef STM32F4_ENABLE_UART_5
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS4",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_5,
|
||||
.ulCtrlPort2 = 4,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_UART5
|
||||
},
|
||||
#endif
|
||||
#ifdef STM32F4_ENABLE_USART_6
|
||||
{
|
||||
.sDeviceName = "/dev/ttyS5",
|
||||
.deviceType = SERIAL_CUSTOM,
|
||||
.pDeviceFns = &stm32f4_usart_fns,
|
||||
.ulCtrlPort1 = (uint32_t) STM32F4_USART_6,
|
||||
.ulCtrlPort2 = 5,
|
||||
.ulClock = STM32F4_USART_BAUD,
|
||||
.ulIntVector = STM32F4_IRQ_USART6
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define PORT_COUNT \
|
||||
(sizeof(Console_Configuration_Ports) \
|
||||
/ sizeof(Console_Configuration_Ports [0]))
|
||||
|
||||
unsigned long Console_Configuration_Count = PORT_COUNT;
|
||||
|
||||
static void output_char(char c)
|
||||
{
|
||||
const console_fns *con =
|
||||
Console_Configuration_Ports [Console_Port_Minor].pDeviceFns;
|
||||
|
||||
con->deviceWritePolled((int) Console_Port_Minor, c);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = output_char;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = NULL;
|
||||
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Sebastian Huber. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <libchip/sersupp.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/rcc.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/usart.h>
|
||||
#include <bsp/stm32f4.h>
|
||||
|
||||
static volatile stm32f4_usart *usart_get_regs(const console_tbl *ct)
|
||||
{
|
||||
return (stm32f4_usart *) ct->ulCtrlPort1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static rtems_vector_number usart_get_irq_number(const console_tbl *ct)
|
||||
{
|
||||
return ct->ulIntVector;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const stm32f4_rcc_index usart_rcc_index [] = {
|
||||
STM32F4_RCC_USART1,
|
||||
STM32F4_RCC_USART2,
|
||||
STM32F4_RCC_USART3,
|
||||
STM32F4_RCC_UART4,
|
||||
STM32F4_RCC_UART5,
|
||||
#ifdef STM32F4_FAMILY_F4XXXX
|
||||
STM32F4_RCC_USART6
|
||||
#endif /* STM32F4_FAMILY_F4XXXX */
|
||||
};
|
||||
|
||||
static stm32f4_rcc_index usart_get_rcc_index(const console_tbl *ct)
|
||||
{
|
||||
return usart_rcc_index [ct->ulCtrlPort2];
|
||||
}
|
||||
|
||||
static const uint8_t usart_pclk_index [] = { 1, 0, 0, 0, 0, 1 };
|
||||
|
||||
static const uint32_t usart_pclk_by_index [] = {
|
||||
STM32F4_PCLK1,
|
||||
STM32F4_PCLK2
|
||||
};
|
||||
|
||||
static uint32_t usart_get_pclk(const console_tbl *ct)
|
||||
{
|
||||
return usart_pclk_by_index [usart_pclk_index [ct->ulCtrlPort2]];
|
||||
}
|
||||
|
||||
static uint32_t usart_get_baud(const console_tbl *ct)
|
||||
{
|
||||
return ct->ulClock;
|
||||
}
|
||||
|
||||
/*
|
||||
* a = 8 * (2 - CR1[OVER8])
|
||||
*
|
||||
* usartdiv = div_mantissa + div_fraction / a
|
||||
*
|
||||
* baud = pclk / (a * usartdiv)
|
||||
*
|
||||
* usartdiv = pclk / (a * baud)
|
||||
*
|
||||
* Calculation in integer arithmetic:
|
||||
*
|
||||
* 1. div_mantissa = pclk / (a * baud)
|
||||
*
|
||||
* 2. div_fraction = pclk / (baud - a * div_mantissa)
|
||||
*/
|
||||
static uint32_t usart_get_bbr(
|
||||
volatile stm32f4_usart *usart,
|
||||
uint32_t pclk,
|
||||
uint32_t baud
|
||||
)
|
||||
{
|
||||
uint32_t a = 8 * (2 - ((usart->cr1 & STM32F4_USART_CR1_OVER8) != 0));
|
||||
uint32_t div_mantissa_low = pclk / (a * baud);
|
||||
uint32_t div_fraction_low = pclk / (baud - a * div_mantissa_low);
|
||||
uint32_t div_mantissa_high;
|
||||
uint32_t div_fraction_high;
|
||||
uint32_t high_err;
|
||||
uint32_t low_err;
|
||||
uint32_t div_mantissa;
|
||||
uint32_t div_fraction;
|
||||
|
||||
if (div_fraction_low < a - 1) {
|
||||
div_mantissa_high = div_fraction_low;
|
||||
div_fraction_high = div_fraction_low + 1;
|
||||
} else {
|
||||
div_mantissa_high = div_fraction_low + 1;
|
||||
div_fraction_high = 0;
|
||||
}
|
||||
|
||||
high_err = pclk - baud * (a * div_mantissa_high + div_fraction_high);
|
||||
low_err = baud * (a * div_mantissa_low + div_fraction_low) - pclk;
|
||||
|
||||
if (low_err < high_err) {
|
||||
div_mantissa = div_mantissa_low;
|
||||
div_fraction = div_fraction_low;
|
||||
} else {
|
||||
div_mantissa = div_mantissa_high;
|
||||
div_fraction = div_fraction_high;
|
||||
}
|
||||
|
||||
return STM32F4_USART_BBR_DIV_MANTISSA(div_mantissa)
|
||||
| STM32F4_USART_BBR_DIV_FRACTION(div_fraction);
|
||||
}
|
||||
|
||||
static void usart_initialize(int minor)
|
||||
{
|
||||
const console_tbl *ct = Console_Port_Tbl [minor];
|
||||
volatile stm32f4_usart *usart = usart_get_regs(ct);
|
||||
uint32_t pclk = usart_get_pclk(ct);
|
||||
uint32_t baud = usart_get_baud(ct);
|
||||
stm32f4_rcc_index rcc_index = usart_get_rcc_index(ct);
|
||||
|
||||
stm32f4_rcc_set_clock(rcc_index, true);
|
||||
|
||||
usart->cr1 = 0;
|
||||
usart->cr2 = 0;
|
||||
usart->cr3 = 0;
|
||||
usart->bbr = usart_get_bbr(usart, pclk, baud);
|
||||
usart->cr1 = STM32F4_USART_CR1_UE
|
||||
| STM32F4_USART_CR1_TE
|
||||
| STM32F4_USART_CR1_RE;
|
||||
}
|
||||
|
||||
static int usart_first_open(int major, int minor, void *arg)
|
||||
{
|
||||
rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
|
||||
struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
|
||||
const console_tbl *ct = Console_Port_Tbl [minor];
|
||||
console_data *cd = &Console_Port_Data [minor];
|
||||
|
||||
cd->termios_data = tty;
|
||||
rtems_termios_set_initial_baud(tty, ct->ulClock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usart_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usart_read_polled(int minor)
|
||||
{
|
||||
const console_tbl *ct = Console_Port_Tbl [minor];
|
||||
volatile stm32f4_usart *usart = usart_get_regs(ct);
|
||||
|
||||
if ((usart->sr & STM32F4_USART_SR_RXNE) != 0) {
|
||||
return STM32F4_USART_DR_GET(usart->dr);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void usart_write_polled(int minor, char c)
|
||||
{
|
||||
const console_tbl *ct = Console_Port_Tbl [minor];
|
||||
volatile stm32f4_usart *usart = usart_get_regs(ct);
|
||||
|
||||
while ((usart->sr & STM32F4_USART_SR_TXE) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
usart->dr = STM32F4_USART_DR(c);
|
||||
}
|
||||
|
||||
static ssize_t usart_write_support_polled(
|
||||
int minor,
|
||||
const char *s,
|
||||
size_t n
|
||||
)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
usart_write_polled(minor, s [i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int usart_set_attributes(int minor, const struct termios *term)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
const console_fns stm32f4_usart_fns = {
|
||||
.deviceProbe = libchip_serial_default_probe,
|
||||
.deviceFirstOpen = usart_first_open,
|
||||
.deviceLastClose = usart_last_close,
|
||||
.deviceRead = usart_read_polled,
|
||||
.deviceWrite = usart_write_support_polled,
|
||||
.deviceInitialize = usart_initialize,
|
||||
.deviceWritePolled = usart_write_polled,
|
||||
.deviceSetAttributes = usart_set_attributes,
|
||||
.deviceOutputUsesInterrupts = false
|
||||
};
|
||||
@@ -62,9 +62,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += irq/irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/printk-support.c
|
||||
librtemsbsp_a_SOURCES += console/tms570-sci.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/printk-support.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/tms570/console/tms570-sci.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES +=../../../../../../bsps/arm/tms570/clock/clock.c
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/**
|
||||
* @file printk-support.c
|
||||
*
|
||||
* @ingroup tms570
|
||||
*
|
||||
* @brief definitions of serial line for debugging.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
|
||||
*
|
||||
* Google Summer of Code 2014 at
|
||||
* Czech Technical University in Prague
|
||||
* Zikova 1903/4
|
||||
* 166 36 Praha 6
|
||||
* Czech Republic
|
||||
*
|
||||
* Based on LPC24xx and LPC1768 BSP
|
||||
* by embedded brains GmbH and others
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <bsp/tms570-sci.h>
|
||||
#include <bsp/tms570-sci-driver.h>
|
||||
|
||||
#define TMS570_CONSOLE (&driver_context_table[0])
|
||||
|
||||
/**
|
||||
* @brief Puts chars into peripheral
|
||||
*
|
||||
* debug functions always use serial dev 0 peripheral
|
||||
*
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_debug_console_putc(char ch)
|
||||
{
|
||||
tms570_sci_context *ctx = TMS570_CONSOLE;
|
||||
volatile tms570_sci_t *regs = ctx->regs;
|
||||
rtems_interrupt_level level;
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
while ( ( regs->FLR & TMS570_SCI_FLR_TXRDY ) == 0) {
|
||||
rtems_interrupt_flash(level);
|
||||
}
|
||||
regs->TD = ch;
|
||||
while ( ( regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) {
|
||||
rtems_interrupt_flash(level);
|
||||
}
|
||||
rtems_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief debug console output
|
||||
*
|
||||
* debug functions always use serial dev 0 peripheral
|
||||
*
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_debug_console_out(char c)
|
||||
{
|
||||
tms570_debug_console_putc(c);
|
||||
}
|
||||
|
||||
static void tms570_debug_console_init(void)
|
||||
{
|
||||
tms570_sci_context *ctx = TMS570_CONSOLE;
|
||||
struct termios term;
|
||||
|
||||
tms570_sci_initialize(ctx);
|
||||
memset(&term, 0, sizeof(term));
|
||||
term.c_cflag = B115200;
|
||||
tms570_sci_set_attributes(&ctx->base, &term);
|
||||
BSP_output_char = tms570_debug_console_out;
|
||||
}
|
||||
|
||||
static void tms570_debug_console_early_init(char c)
|
||||
{
|
||||
tms570_debug_console_init();
|
||||
tms570_debug_console_out(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief debug console input
|
||||
*
|
||||
* debug functions always use serial dev 0 peripheral
|
||||
*
|
||||
* @retval x Read char
|
||||
* @retval -1 No input character available
|
||||
*/
|
||||
static int tms570_debug_console_in( void )
|
||||
{
|
||||
tms570_sci_context *ctx = TMS570_CONSOLE;
|
||||
volatile tms570_sci_t *regs = ctx->regs;
|
||||
rtems_interrupt_level level;
|
||||
int c;
|
||||
|
||||
rtems_interrupt_disable(level);
|
||||
|
||||
if ( regs->FLR & TMS570_SCI_FLR_RXRDY ) {
|
||||
c = (unsigned char) regs->RD;
|
||||
} else {
|
||||
c = -1;
|
||||
}
|
||||
|
||||
rtems_interrupt_enable(level);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char =
|
||||
tms570_debug_console_early_init;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = tms570_debug_console_in;
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
tms570_debug_console_init,
|
||||
RTEMS_SYSINIT_BSP_START,
|
||||
RTEMS_SYSINIT_ORDER_LAST
|
||||
);
|
||||
@@ -1,642 +0,0 @@
|
||||
/**
|
||||
* @file tms570-sci.c
|
||||
*
|
||||
* @ingroup tms570
|
||||
*
|
||||
* @brief Serial communication interface (SCI) functions definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
|
||||
*
|
||||
* Google Summer of Code 2014 at
|
||||
* Czech Technical University in Prague
|
||||
* Zikova 1903/4
|
||||
* 166 36 Praha 6
|
||||
* Czech Republic
|
||||
*
|
||||
* Based on LPC24xx and LPC1768 BSP
|
||||
* by embedded brains GmbH and others
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bspopts.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <bsp/tms570-sci.h>
|
||||
#include <bsp/tms570-sci-driver.h>
|
||||
#include <rtems/console.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#define TMS570_SCI_BUFFER_SIZE 1
|
||||
|
||||
/**
|
||||
* @brief Table including all serial drivers
|
||||
*
|
||||
* Definitions of all serial drivers
|
||||
*/
|
||||
tms570_sci_context driver_context_table[] = {
|
||||
{
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI1"),
|
||||
.device_name = "/dev/console",
|
||||
/* TMS570 UART peripheral use subset of LIN registers which are equivalent
|
||||
* to SCI ones
|
||||
*/
|
||||
.regs = (volatile tms570_sci_t *) &TMS570_LIN,
|
||||
.irq = TMS570_IRQ_SCI_LEVEL_0,
|
||||
},
|
||||
{
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI2"),
|
||||
.device_name = "/dev/ttyS1",
|
||||
.regs = &TMS570_SCI,
|
||||
.irq = TMS570_IRQ_SCI2_LEVEL_0,
|
||||
}
|
||||
};
|
||||
|
||||
void tms570_sci_initialize(tms570_sci_context *ctx)
|
||||
{
|
||||
uint32_t rx_pin = 1 << 1;
|
||||
uint32_t tx_pin = 1 << 2;
|
||||
|
||||
/* Resec SCI peripheral */
|
||||
ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 0;
|
||||
ctx->regs->GCR0 = TMS570_SCI_GCR0_RESET * 1;
|
||||
|
||||
/* Clear all interrupt sources */
|
||||
ctx->regs->CLEARINT = 0xffffffff;
|
||||
|
||||
/* Map all interrupts to SCI INT0 line */
|
||||
ctx->regs->CLEARINTLVL = 0xffffffff;
|
||||
|
||||
ctx->regs->GCR1 = TMS570_SCI_GCR1_TXENA * 0 |
|
||||
TMS570_SCI_GCR1_RXENA * 0 |
|
||||
TMS570_SCI_GCR1_CONT * 0 | /* continue operation when debugged */
|
||||
TMS570_SCI_GCR1_LOOP_BACK * 0 |
|
||||
TMS570_SCI_GCR1_POWERDOWN * 0 |
|
||||
TMS570_SCI_GCR1_SLEEP * 0 |
|
||||
TMS570_SCI_GCR1_SWnRST * 0 | /* reset state */
|
||||
TMS570_SCI_GCR1_CLOCK * 1 | /* internal clock */
|
||||
TMS570_SCI_GCR1_TIMING_MODE * 1 |
|
||||
TMS570_SCI_GCR1_COMM_MODE * 0;
|
||||
|
||||
/* Setup connection of SCI peripheral Rx and Tx pins */
|
||||
ctx->regs->PIO0 = rx_pin * 1 | tx_pin * 1; /* Rx and Tx pins are not GPIO */
|
||||
ctx->regs->PIO3 = rx_pin * 0 | tx_pin * 0; /* Default output low */
|
||||
ctx->regs->PIO1 = rx_pin * 0 | tx_pin * 0; /* Input when not used by SCI */
|
||||
ctx->regs->PIO6 = rx_pin * 0 | tx_pin * 0; /* No open drain */
|
||||
ctx->regs->PIO7 = rx_pin * 0 | tx_pin * 0; /* Pull-up/down enabled */
|
||||
ctx->regs->PIO8 = rx_pin * 1 | tx_pin * 1; /* Select pull-up */
|
||||
|
||||
/* Bring device out of software reset */
|
||||
ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Serial drivers init function
|
||||
*
|
||||
* Initialize all serial drivers specified in driver_context_table
|
||||
*
|
||||
* @param[in] major
|
||||
* @param[in] minor
|
||||
* @param[in] arg
|
||||
* @retval RTEMS_SUCCESSFUL Initialization completed
|
||||
*/
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
const rtems_termios_device_handler *handler = &tms570_sci_handler_interrupt;
|
||||
#else
|
||||
const rtems_termios_device_handler *handler = &tms570_sci_handler_polled;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the Termios infrastructure. If Termios has already
|
||||
* been initialized by another device driver, then this call will
|
||||
* have no effect.
|
||||
*/
|
||||
rtems_termios_initialize();
|
||||
|
||||
/* Initialize each device */
|
||||
for (
|
||||
minor = 0;
|
||||
minor < RTEMS_ARRAY_SIZE(driver_context_table);
|
||||
++minor
|
||||
) {
|
||||
tms570_sci_context *ctx = &driver_context_table[minor];
|
||||
|
||||
tms570_sci_initialize(ctx);
|
||||
|
||||
/*
|
||||
* Install this device in the file system and Termios. In order
|
||||
* to use the console (i.e. being able to do printf, scanf etc.
|
||||
* on stdin, stdout and stderr), one device must be registered as
|
||||
* "/dev/console" (CONSOLE_DEVICE_NAME).
|
||||
*/
|
||||
sc = rtems_termios_device_install(
|
||||
ctx->device_name,
|
||||
handler,
|
||||
NULL,
|
||||
&ctx->base
|
||||
);
|
||||
if ( sc != RTEMS_SUCCESSFUL ) {
|
||||
bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV);
|
||||
}
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads chars from HW
|
||||
*
|
||||
* Reads chars from HW peripheral specified in driver context.
|
||||
* TMS570 does not have HW buffer for serial line so this function can
|
||||
* return only 0 or 1 char
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @param[out] buf read data buffer
|
||||
* @param[in] N size of buffer
|
||||
* @retval x Number of read chars from peripherals
|
||||
*/
|
||||
static int tms570_sci_read_received_chars(
|
||||
tms570_sci_context * ctx,
|
||||
char * buf,
|
||||
int N)
|
||||
{
|
||||
if ( N < 1 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( ctx->regs->RD != 0 ) {
|
||||
buf[0] = ctx->regs->RD;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables RX interrupt
|
||||
*
|
||||
* Enables RX interrupt source of SCI peripheral
|
||||
* specified in the driver context.
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_sci_enable_interrupts(tms570_sci_context * ctx)
|
||||
{
|
||||
ctx->regs->SETINT = TMS570_SCI_SETINT_SET_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables RX interrupt
|
||||
*
|
||||
* Disables RX interrupt source of SCI peripheral specified in the driver
|
||||
* context.
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_sci_disable_interrupts(tms570_sci_context * ctx)
|
||||
{
|
||||
ctx->regs->CLEARINT = TMS570_SCI_CLEARINT_CLR_RX_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether driver has put char in HW
|
||||
*
|
||||
* Check whether driver has put char in HW.
|
||||
* This information is read from the driver context not from a peripheral.
|
||||
* TMS570 does not have write data buffer asociated with SCI
|
||||
* so the return can be only 0 or 1.
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @retval x
|
||||
*/
|
||||
static int tms570_sci_transmitted_chars(tms570_sci_context * ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ctx->tx_chars_in_hw;
|
||||
if ( ret == 1 ) {
|
||||
ctx->tx_chars_in_hw = 0;
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set attributes of the HW peripheral
|
||||
*
|
||||
* Sets attributes of the HW peripheral (parity, baud rate, etc.)
|
||||
*
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] t termios driver
|
||||
* @retval true peripheral setting is changed
|
||||
*/
|
||||
bool tms570_sci_set_attributes(
|
||||
rtems_termios_device_context *base,
|
||||
const struct termios *t
|
||||
)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
int32_t bauddiv;
|
||||
int32_t baudrate;
|
||||
uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY;
|
||||
/*
|
||||
* Test for TMS570_SCI_FLR_TXRDY is not necessary
|
||||
* because both SCITD and SCITXSHF has to be empty
|
||||
* to TX_EMPTY be asserted. But there is no interrupt
|
||||
* option for TX_EMPTY. Polling is used isntead.
|
||||
*/
|
||||
|
||||
/* Baud rate */
|
||||
baudrate = rtems_termios_baud_to_number(cfgetospeed(t));
|
||||
|
||||
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||
|
||||
while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) &&
|
||||
(ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) {
|
||||
/*
|
||||
* There are pending characters in the hardware,
|
||||
* change in the middle of the character Tx leads
|
||||
* to disturb of the character and SCI engine
|
||||
*/
|
||||
rtems_interval tw;
|
||||
|
||||
rtems_termios_device_lock_release(base, &lock_context);
|
||||
|
||||
tw = rtems_clock_get_ticks_per_second();
|
||||
tw = tw * 5 / baudrate + 1;
|
||||
rtems_task_wake_after( tw );
|
||||
|
||||
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||
}
|
||||
|
||||
ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA |
|
||||
TMS570_SCI_GCR1_RXENA );
|
||||
|
||||
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_STOP; /*one stop bit*/
|
||||
ctx->regs->FORMAT = TMS570_SCI_FORMAT_CHAR(0x7);
|
||||
|
||||
switch ( t->c_cflag & ( PARENB|PARODD ) ) {
|
||||
case ( PARENB|PARODD ):
|
||||
/* Odd parity */
|
||||
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY;
|
||||
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA;
|
||||
break;
|
||||
|
||||
case PARENB:
|
||||
/* Even parity */
|
||||
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY;
|
||||
ctx->regs->GCR1 |= TMS570_SCI_GCR1_PARITY_ENA;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0:
|
||||
case PARODD:
|
||||
/* No Parity */
|
||||
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA;
|
||||
}
|
||||
|
||||
/* Apply baudrate to the hardware */
|
||||
baudrate *= 2 * 16;
|
||||
bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate;
|
||||
ctx->regs->BRS = bauddiv;
|
||||
|
||||
ctx->regs->GCR1 |= TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA |
|
||||
TMS570_SCI_GCR1_RXENA;
|
||||
|
||||
rtems_termios_device_lock_release(base, &lock_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sci interrupt handler
|
||||
*
|
||||
* Handler checks which interrupt occured and provides nessesary maintenance
|
||||
* dequeue characters in termios driver whether character is send succesfully
|
||||
* enqueue characters in termios driver whether character is recieved
|
||||
*
|
||||
* @param[in] arg rtems_termios_tty
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_sci_interrupt_handler(void * arg)
|
||||
{
|
||||
rtems_termios_tty *tty = arg;
|
||||
tms570_sci_context *ctx = rtems_termios_get_device_context(tty);
|
||||
char buf[TMS570_SCI_BUFFER_SIZE];
|
||||
size_t n;
|
||||
|
||||
/*
|
||||
* Check if we have received something.
|
||||
*/
|
||||
if ( (ctx->regs->FLR & TMS570_SCI_FLR_RXRDY ) == TMS570_SCI_FLR_RXRDY ) {
|
||||
n = tms570_sci_read_received_chars(ctx, buf, TMS570_SCI_BUFFER_SIZE);
|
||||
if ( n > 0 ) {
|
||||
/* Hand the data over to the Termios infrastructure */
|
||||
rtems_termios_enqueue_raw_characters(tty, buf, n);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check if we have something transmitted.
|
||||
*/
|
||||
if ( (ctx->regs->FLR & TMS570_SCI_FLR_TXRDY ) == TMS570_SCI_FLR_TXRDY ) {
|
||||
n = tms570_sci_transmitted_chars(ctx);
|
||||
if ( n > 0 ) {
|
||||
/*
|
||||
* Notify Termios that we have transmitted some characters. It
|
||||
* will call now the interrupt write function if more characters
|
||||
* are ready for transmission.
|
||||
*/
|
||||
rtems_termios_dequeue_characters(tty, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sci write function called from interrupt
|
||||
*
|
||||
* Nonblocking write function. Writes characters to HW peripheral
|
||||
* TMS570 does not have write data buffer asociated with SCI
|
||||
* so only one character can be written.
|
||||
*
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] buf buffer of characters pending to send
|
||||
* @param[in] len size of the buffer
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_sci_interrupt_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
|
||||
if ( len > 0 ) {
|
||||
/* start UART TX, this will result in an interrupt when done */
|
||||
ctx->regs->TD = *buf;
|
||||
/* character written - raise count*/
|
||||
ctx->tx_chars_in_hw = 1;
|
||||
/* Enable TX interrupt (interrupt is edge-triggered) */
|
||||
ctx->regs->SETINT = (1<<8);
|
||||
|
||||
} else {
|
||||
/* No more to send, disable TX interrupts */
|
||||
ctx->regs->CLEARINT = (1<<8);
|
||||
/* Tell close that we sent everything */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sci write function
|
||||
*
|
||||
* Blocking write function. Waits until HW peripheral is ready and then writes
|
||||
* character to HW peripheral. Writes all characters in the buffer.
|
||||
*
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] buf buffer of characters pending to send
|
||||
* @param[in] len size of the buffer
|
||||
* @retval Void
|
||||
*/
|
||||
static void tms570_sci_poll_write(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t n
|
||||
)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
size_t i;
|
||||
|
||||
/* Write */
|
||||
|
||||
for ( i = 0; i < n; ++i ) {
|
||||
while ( (ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0) {
|
||||
;
|
||||
}
|
||||
ctx->regs->TD = buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief See if there is recieved charakter to read
|
||||
*
|
||||
* read the RX flag from peripheral specified in context
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @retval 0 No character to read
|
||||
* @retval x Character ready to read
|
||||
*/
|
||||
static int TMS570_sci_can_read_char(
|
||||
tms570_sci_context * ctx
|
||||
)
|
||||
{
|
||||
return ctx->regs->FLR & TMS570_SCI_FLR_RXRDY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reads character from peripheral
|
||||
*
|
||||
* reads the recieved character from peripheral specified in context
|
||||
*
|
||||
* @param[in] ctx context of the driver
|
||||
* @retval x Character
|
||||
*/
|
||||
static char TMS570_sci_read_char(
|
||||
tms570_sci_context * ctx
|
||||
)
|
||||
{
|
||||
return ctx->regs->RD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sci read function
|
||||
*
|
||||
* check if there is recieved character to be read and reads it.
|
||||
*
|
||||
* @param[in] base context of the driver
|
||||
* @retval -1 No character to be read
|
||||
* @retval x Read character
|
||||
*/
|
||||
static int tms570_sci_poll_read(rtems_termios_device_context *base)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
|
||||
/* Check if a character is available */
|
||||
if ( TMS570_sci_can_read_char(ctx) ) {
|
||||
return TMS570_sci_read_char(ctx);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialization of the driver
|
||||
*
|
||||
* initialization of the HW peripheral specified in contex of the driver.
|
||||
* This function is called only once when opening the driver.
|
||||
*
|
||||
* @param[in] tty Termios control
|
||||
* @param[in] ctx context of the driver
|
||||
* @param[in] term Termios attributes
|
||||
* @param[in] args
|
||||
* @retval false Error occured during initialization
|
||||
* @retval true Driver is open and ready
|
||||
*/
|
||||
static bool tms570_sci_poll_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *ctx,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
rtems_termios_set_best_baud(term, TMS570_SCI_BAUD_RATE);
|
||||
ok = tms570_sci_set_attributes(ctx, term);
|
||||
if ( !ok ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialization of the interrupt driven driver
|
||||
*
|
||||
* calls tms570_sci_poll_first_open function.
|
||||
* install and enables interrupts.
|
||||
*
|
||||
* @param[in] tty Termios control
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] args
|
||||
* @retval false Error occured during initialization
|
||||
* @retval true Driver is open and ready
|
||||
*/
|
||||
static bool tms570_sci_interrupt_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
rtems_status_code sc;
|
||||
bool ret;
|
||||
|
||||
ret = tms570_sci_poll_first_open(tty, base, term, args);
|
||||
if ( ret == false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Register Interrupt handler */
|
||||
sc = rtems_interrupt_handler_install(ctx->irq,
|
||||
ctx->device_name,
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
tms570_sci_interrupt_handler,
|
||||
tty
|
||||
);
|
||||
if ( sc != RTEMS_SUCCESSFUL ) {
|
||||
return false;
|
||||
}
|
||||
tms570_sci_enable_interrupts(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief closes sci peripheral
|
||||
*
|
||||
* @param[in] tty Termios control
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] args
|
||||
* @retval false Error occured during initialization
|
||||
* @retval true Driver is open and ready
|
||||
*/
|
||||
static void tms570_sci_poll_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief closes sci peripheral of interrupt driven driver
|
||||
*
|
||||
* calls tms570_sci_poll_last_close and disables interrupts
|
||||
*
|
||||
* @param[in] tty Termios control
|
||||
* @param[in] base context of the driver
|
||||
* @param[in] args
|
||||
* @retval false Error occured during initialization
|
||||
* @retval true Driver is open and ready
|
||||
*/
|
||||
static void tms570_sci_interrupt_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
tms570_sci_context *ctx = (tms570_sci_context *) base;
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
rtems_interval tw;
|
||||
int32_t baudrate;
|
||||
|
||||
/* Turn off RX interrupts */
|
||||
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||
tms570_sci_disable_interrupts(ctx);
|
||||
rtems_termios_device_lock_release(base, &lock_context);
|
||||
|
||||
tw = rtems_clock_get_ticks_per_second();
|
||||
baudrate = rtems_termios_baud_to_number(cfgetospeed(&tty->termios));
|
||||
tw = tw * 10 / baudrate + 1;
|
||||
while ( ( ctx->regs->FLR & TMS570_SCI_FLR_TX_EMPTY ) == 0 ) {
|
||||
rtems_task_wake_after(tw);
|
||||
}
|
||||
|
||||
/* uninstall ISR */
|
||||
rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty);
|
||||
|
||||
tms570_sci_poll_last_close(tty, base, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Struct containing definitions of polled driver functions.
|
||||
*
|
||||
* Encapsulates polled driver functions.
|
||||
* Use of this table is determited by not defining TMS570_USE_INTERRUPTS
|
||||
*/
|
||||
const rtems_termios_device_handler tms570_sci_handler_polled = {
|
||||
.first_open = tms570_sci_poll_first_open,
|
||||
.last_close = tms570_sci_poll_last_close,
|
||||
.poll_read = tms570_sci_poll_read,
|
||||
.write = tms570_sci_poll_write,
|
||||
.set_attributes = tms570_sci_set_attributes,
|
||||
.mode = TERMIOS_POLLED
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct containing definitions of interrupt driven driver functions.
|
||||
*
|
||||
* Encapsulates interrupt driven driver functions.
|
||||
* Use of this table is determited by defining TMS570_USE_INTERRUPTS
|
||||
*/
|
||||
const rtems_termios_device_handler tms570_sci_handler_interrupt = {
|
||||
.first_open = tms570_sci_interrupt_first_open,
|
||||
.last_close = tms570_sci_interrupt_last_close,
|
||||
.poll_read = NULL,
|
||||
.write = tms570_sci_interrupt_write,
|
||||
.set_attributes = tms570_sci_set_attributes,
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
};
|
||||
@@ -59,10 +59,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-gic-irq.c
|
||||
|
||||
# Console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-termios.c
|
||||
librtemsbsp_a_SOURCES += console/console-config.c
|
||||
librtemsbsp_a_SOURCES += console/debug-console.c
|
||||
librtemsbsp_a_SOURCES += console/zynq-uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/console-config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/debug-console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/console/zynq-uart.c
|
||||
|
||||
# Clock
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-a9mpcore-clock-config.c
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/zynq-uart.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
zynq_uart_context zynq_uart_instances[2] = {
|
||||
{
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ),
|
||||
.regs = (volatile struct zynq_uart *) 0xe0000000,
|
||||
.irq = ZYNQ_IRQ_UART_0
|
||||
}, {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ),
|
||||
.regs = (volatile struct zynq_uart *) 0xe0001000,
|
||||
.irq = ZYNQ_IRQ_UART_1
|
||||
}
|
||||
};
|
||||
|
||||
rtems_status_code console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) {
|
||||
char uart[] = "/dev/ttySX";
|
||||
|
||||
uart[sizeof(uart) - 2] = (char) ('0' + i);
|
||||
rtems_termios_device_install(
|
||||
&uart[0],
|
||||
&zynq_uart_handler,
|
||||
NULL,
|
||||
&zynq_uart_instances[i].base
|
||||
);
|
||||
|
||||
if (i == BSP_CONSOLE_MINOR) {
|
||||
link(&uart[0], CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/sysinit.h>
|
||||
|
||||
#include <bsp/zynq-uart.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
static void zynq_debug_console_out(char c)
|
||||
{
|
||||
rtems_termios_device_context *base =
|
||||
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
|
||||
|
||||
zynq_uart_write_polled(base, c);
|
||||
}
|
||||
|
||||
static void zynq_debug_console_init(void)
|
||||
{
|
||||
rtems_termios_device_context *base =
|
||||
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
|
||||
|
||||
zynq_uart_initialize(base);
|
||||
BSP_output_char = zynq_debug_console_out;
|
||||
}
|
||||
|
||||
static void zynq_debug_console_early_init(char c)
|
||||
{
|
||||
rtems_termios_device_context *base =
|
||||
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
|
||||
|
||||
zynq_uart_initialize(base);
|
||||
zynq_debug_console_out(c);
|
||||
}
|
||||
|
||||
static int zynq_debug_console_in(void)
|
||||
{
|
||||
rtems_termios_device_context *base =
|
||||
&zynq_uart_instances[BSP_CONSOLE_MINOR].base;
|
||||
|
||||
return zynq_uart_read_polled(base);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init;
|
||||
|
||||
BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in;
|
||||
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
zynq_debug_console_init,
|
||||
RTEMS_SYSINIT_BSP_START,
|
||||
RTEMS_SYSINIT_ORDER_LAST
|
||||
);
|
||||
@@ -1,315 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp/zynq-uart.h>
|
||||
#include <bsp/zynq-uart-regs.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
/*
|
||||
* Make weak and let the user override.
|
||||
*/
|
||||
uint32_t zynq_uart_input_clock(void) __attribute__ ((weak));
|
||||
|
||||
uint32_t zynq_uart_input_clock(void)
|
||||
{
|
||||
return ZYNQ_CLOCK_UART;
|
||||
}
|
||||
|
||||
static int zynq_cal_baud_rate(uint32_t baudrate,
|
||||
uint32_t* brgr,
|
||||
uint32_t* bauddiv,
|
||||
uint32_t modereg)
|
||||
{
|
||||
uint32_t brgr_value; /* Calculated value for baud rate generator */
|
||||
uint32_t calcbaudrate; /* Calculated baud rate */
|
||||
uint32_t bauderror; /* Diff between calculated and requested baud rate */
|
||||
uint32_t best_error = 0xFFFFFFFF;
|
||||
uint32_t percenterror;
|
||||
uint32_t bdiv;
|
||||
uint32_t inputclk = zynq_uart_input_clock();
|
||||
|
||||
/*
|
||||
* Make sure the baud rate is not impossilby large.
|
||||
* Fastest possible baud rate is Input Clock / 2.
|
||||
*/
|
||||
if ((baudrate * 2) > inputclk) {
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Check whether the input clock is divided by 8
|
||||
*/
|
||||
if(modereg & ZYNQ_UART_MODE_CLKS) {
|
||||
inputclk = inputclk / 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the Baud divider. It can be 4to 254.
|
||||
* Loop through all possible combinations
|
||||
*/
|
||||
for (bdiv = 4; bdiv < 255; bdiv++) {
|
||||
|
||||
/*
|
||||
* Calculate the value for BRGR register
|
||||
*/
|
||||
brgr_value = inputclk / (baudrate * (bdiv + 1));
|
||||
|
||||
/*
|
||||
* Calculate the baud rate from the BRGR value
|
||||
*/
|
||||
calcbaudrate = inputclk/ (brgr_value * (bdiv + 1));
|
||||
|
||||
/*
|
||||
* Avoid unsigned integer underflow
|
||||
*/
|
||||
if (baudrate > calcbaudrate) {
|
||||
bauderror = baudrate - calcbaudrate;
|
||||
}
|
||||
else {
|
||||
bauderror = calcbaudrate - baudrate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the calculated baud rate closest to requested baud rate.
|
||||
*/
|
||||
if (best_error > bauderror) {
|
||||
*brgr = brgr_value;
|
||||
*bauddiv = bdiv;
|
||||
best_error = bauderror;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the best error is not too large.
|
||||
*/
|
||||
percenterror = (best_error * 100) / baudrate;
|
||||
#define XUARTPS_MAX_BAUD_ERROR_RATE 3 /* max % error allowed */
|
||||
if (XUARTPS_MAX_BAUD_ERROR_RATE < percenterror) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zynq_uart_initialize(rtems_termios_device_context *base)
|
||||
{
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
uint32_t brgr = 0x3e;
|
||||
uint32_t bauddiv = 0x6;
|
||||
|
||||
zynq_cal_baud_rate(ZYNQ_UART_DEFAULT_BAUD, &brgr, &bauddiv, regs->mode);
|
||||
|
||||
regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
|
||||
regs->control = ZYNQ_UART_CONTROL_RXDIS
|
||||
| ZYNQ_UART_CONTROL_TXDIS
|
||||
| ZYNQ_UART_CONTROL_RXRES
|
||||
| ZYNQ_UART_CONTROL_TXRES;
|
||||
regs->mode = ZYNQ_UART_MODE_CHMODE(ZYNQ_UART_MODE_CHMODE_NORMAL)
|
||||
| ZYNQ_UART_MODE_PAR(ZYNQ_UART_MODE_PAR_NONE)
|
||||
| ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8);
|
||||
regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr);
|
||||
regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv);
|
||||
regs->rx_fifo_trg_lvl = ZYNQ_UART_RX_FIFO_TRG_LVL_RTRIG(0);
|
||||
regs->rx_timeout = ZYNQ_UART_RX_TIMEOUT_RTO(0);
|
||||
regs->control = ZYNQ_UART_CONTROL_RXEN
|
||||
| ZYNQ_UART_CONTROL_TXEN
|
||||
| ZYNQ_UART_CONTROL_RSTTO;
|
||||
}
|
||||
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
static void zynq_uart_interrupt(void *arg)
|
||||
{
|
||||
rtems_termios_tty *tty = arg;
|
||||
zynq_uart_context *ctx = rtems_termios_get_device_context(tty);
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
uint32_t channel_sts;
|
||||
|
||||
if ((regs->irq_sts & (ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG)) != 0) {
|
||||
regs->irq_sts = ZYNQ_UART_TIMEOUT | ZYNQ_UART_RTRIG;
|
||||
|
||||
do {
|
||||
char c = (char) ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo);
|
||||
|
||||
rtems_termios_enqueue_raw_characters(tty, &c, 1);
|
||||
|
||||
channel_sts = regs->channel_sts;
|
||||
} while ((channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) == 0);
|
||||
} else {
|
||||
channel_sts = regs->channel_sts;
|
||||
}
|
||||
|
||||
if (ctx->transmitting && (channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) != 0) {
|
||||
rtems_termios_dequeue_characters(tty, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool zynq_uart_first_open(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
struct termios *term,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
rtems_status_code sc;
|
||||
#endif
|
||||
|
||||
rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD);
|
||||
zynq_uart_initialize(base);
|
||||
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
regs->rx_timeout = 32;
|
||||
regs->rx_fifo_trg_lvl = ZYNQ_UART_FIFO_DEPTH / 2;
|
||||
regs->irq_dis = 0xffffffff;
|
||||
regs->irq_sts = 0xffffffff;
|
||||
regs->irq_en = ZYNQ_UART_RTRIG | ZYNQ_UART_TIMEOUT;
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ctx->irq,
|
||||
"UART",
|
||||
RTEMS_INTERRUPT_SHARED,
|
||||
zynq_uart_interrupt,
|
||||
tty
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
static void zynq_uart_last_close(
|
||||
rtems_termios_tty *tty,
|
||||
rtems_termios_device_context *base,
|
||||
rtems_libio_open_close_args_t *args
|
||||
)
|
||||
{
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
|
||||
rtems_interrupt_handler_remove(ctx->irq, zynq_uart_interrupt, tty);
|
||||
}
|
||||
#endif
|
||||
|
||||
int zynq_uart_read_polled(rtems_termios_device_context *base)
|
||||
{
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
|
||||
if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return ZYNQ_UART_TX_RX_FIFO_FIFO_GET(regs->tx_rx_fifo);
|
||||
}
|
||||
}
|
||||
|
||||
void zynq_uart_write_polled(
|
||||
rtems_termios_device_context *base,
|
||||
char c
|
||||
)
|
||||
{
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
|
||||
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TFUL) != 0) {
|
||||
/* Wait */
|
||||
}
|
||||
|
||||
regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c);
|
||||
}
|
||||
|
||||
static void zynq_uart_write_support(
|
||||
rtems_termios_device_context *base,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
zynq_uart_context *ctx = (zynq_uart_context *) base;
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
|
||||
if (len > 0) {
|
||||
ctx->transmitting = true;
|
||||
regs->irq_sts = ZYNQ_UART_TEMPTY;
|
||||
regs->irq_en = ZYNQ_UART_TEMPTY;
|
||||
regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(buf[0]);
|
||||
} else {
|
||||
ctx->transmitting = false;
|
||||
regs->irq_dis = ZYNQ_UART_TEMPTY;
|
||||
}
|
||||
#else
|
||||
ssize_t i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
zynq_uart_write_polled(base, buf[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool zynq_uart_set_attributes(
|
||||
rtems_termios_device_context *context,
|
||||
const struct termios *term
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
volatile zynq_uart *regs = zynq_uart_get_regs(minor);
|
||||
uint32_t brgr = 0;
|
||||
uint32_t bauddiv = 0;
|
||||
int rc;
|
||||
|
||||
rc = zynq_cal_baud_rate(115200, &brgr, &bauddiv, regs->mode);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
regs->control &= ~(ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN);
|
||||
regs->baud_rate_gen = ZYNQ_UART_BAUD_RATE_GEN_CD(brgr);
|
||||
regs->baud_rate_div = ZYNQ_UART_BAUD_RATE_DIV_BDIV(bauddiv);
|
||||
regs->control |= ZYNQ_UART_CONTROL_RXEN | ZYNQ_UART_CONTROL_TXEN;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const rtems_termios_device_handler zynq_uart_handler = {
|
||||
.first_open = zynq_uart_first_open,
|
||||
.set_attributes = zynq_uart_set_attributes,
|
||||
.write = zynq_uart_write_support,
|
||||
#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS
|
||||
.last_close = zynq_uart_last_close,
|
||||
.mode = TERMIOS_IRQ_DRIVEN
|
||||
#else
|
||||
.poll_read = zynq_uart_read_polled,
|
||||
.mode = TERMIOS_POLLED
|
||||
#endif
|
||||
};
|
||||
|
||||
void zynq_uart_reset_tx_flush(zynq_uart_context *ctx)
|
||||
{
|
||||
volatile zynq_uart *regs = ctx->regs;
|
||||
int c = 4;
|
||||
|
||||
while (c-- > 0)
|
||||
zynq_uart_write_polled(&ctx->base, '\r');
|
||||
|
||||
while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0) {
|
||||
/* Wait */
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
|
||||
|
||||
librtemsbsp_a_SOURCES += console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/TLL6527M/start/interrupt.c
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/**
|
||||
*@file console.c
|
||||
*
|
||||
*@brief
|
||||
* - This file implements uart console for TLL6527M. TLL6527M has BF527 with
|
||||
* second uart (uart-1) connected to the console.
|
||||
*
|
||||
* Target: TLL6527v1-0
|
||||
* Compiler:
|
||||
*
|
||||
* COPYRIGHT (c) 2010 by ECE Northeastern University.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license
|
||||
*
|
||||
* @author Rohan Kangralkar, ECE, Northeastern University
|
||||
* (kangralkar.r@husky.neu.edu)
|
||||
*
|
||||
* LastChange:
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <bsp/interrupt.h>
|
||||
#include <libcpu/uart.h>
|
||||
|
||||
/***************************************************
|
||||
LOCAL DEFINES
|
||||
***************************************************/
|
||||
|
||||
|
||||
/***************************************************
|
||||
STATIC GLOBALS
|
||||
***************************************************/
|
||||
/**
|
||||
* Declaration of UART
|
||||
*/
|
||||
static bfin_uart_channel_t channels[] = {
|
||||
{"/dev/console",
|
||||
UART1_BASE_ADDRESS,
|
||||
DMA10_BASE_ADDRESS,
|
||||
DMA11_BASE_ADDRESS,
|
||||
CONSOLE_USE_INTERRUPTS,
|
||||
UART_USE_DMA,
|
||||
CONSOLE_BAUDRATE,
|
||||
NULL,
|
||||
0,
|
||||
0}
|
||||
};
|
||||
|
||||
/**
|
||||
* Over all configuration
|
||||
*/
|
||||
static bfin_uart_config_t config = {
|
||||
SCLK,
|
||||
sizeof(channels) / sizeof(channels[0]),
|
||||
channels
|
||||
};
|
||||
|
||||
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
/**
|
||||
* The Rx and Tx isr will get the same argument
|
||||
* The isr will have to find if it was the rx that caused the interrupt or
|
||||
* the tx
|
||||
*/
|
||||
static bfin_isr_t bfinUARTISRs[] = {
|
||||
#if UART_USE_DMA
|
||||
/* For First uart */
|
||||
{IRQ_DMA10_UART1_RX, bfinUart_rxDmaIsr, (void *)&channels[0], 0},
|
||||
{IRQ_DMA11_UART1_TX, bfinUart_txDmaIsr, (void *)&channels[0], 0},
|
||||
/* For second uart */
|
||||
#else
|
||||
/* For First uart */
|
||||
{IRQ_DMA10_UART1_RX, bfinUart_rxIsr, &channels[0], 0},
|
||||
{IRQ_DMA11_UART1_TX, bfinUart_txIsr, &channels[0], 0},
|
||||
/* For second uart */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void TLL6527_BSP_output_char(char c) {
|
||||
|
||||
bfin_uart_poll_write(0, c);
|
||||
}
|
||||
|
||||
static int TLL6527_BSP_poll_char(void) {
|
||||
|
||||
return bfin_uart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = TLL6527_BSP_output_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = TLL6527_BSP_poll_char;
|
||||
|
||||
|
||||
|
||||
rtems_device_driver console_close(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_close(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_read(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_write(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_ioctl(arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Open entry point
|
||||
*/
|
||||
rtems_device_driver console_open(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return bfin_uart_open(major, minor, arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*
|
||||
* Parameters
|
||||
* @param major major number
|
||||
* @param minor minor number
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
rtems_device_driver console_initialize(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
rtems_status_code status = RTEMS_NOT_DEFINED;
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
status = bfin_uart_initialize(major, &config);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
rtems_fatal_error_occurred(status);
|
||||
}
|
||||
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
|
||||
bfin_interrupt_register(&bfinUARTISRs[i]);
|
||||
#if INTERRUPT_USE_TABLE
|
||||
#else
|
||||
bfin_interrupt_enable(&bfinUARTISRs[i], 1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
|
||||
|
||||
librtemsbsp_a_SOURCES += console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/bf537Stamp/console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/* Console driver for bf537Stamp
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA
|
||||
* written by Allan Hessenflow <allanh@kallisti.com>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <libcpu/bf537.h>
|
||||
#include <libcpu/interrupt.h>
|
||||
#include <libcpu/uart.h>
|
||||
|
||||
/*
|
||||
#undef CONSOLE_USE_INTERRUPTS
|
||||
#define CONSOLE_USE_INTERRUPTS 1
|
||||
*/
|
||||
|
||||
static bfin_uart_channel_t channels[] = {
|
||||
{"/dev/console",
|
||||
UART0_BASE_ADDRESS,
|
||||
0,
|
||||
0,
|
||||
CONSOLE_USE_INTERRUPTS,
|
||||
0,
|
||||
#ifdef CONSOLE_FORCE_BAUD
|
||||
CONSOLE_FORCE_BAUD,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
NULL,
|
||||
0,
|
||||
0}
|
||||
|
||||
#if (!BFIN_ON_SKYEYE)
|
||||
,
|
||||
{"/dev/tty1",
|
||||
UART1_BASE_ADDRESS,
|
||||
CONSOLE_USE_INTERRUPTS,
|
||||
0,
|
||||
NULL,
|
||||
0}
|
||||
#endif
|
||||
};
|
||||
|
||||
static bfin_uart_config_t config = {
|
||||
SCLK,
|
||||
sizeof(channels) / sizeof(channels[0]),
|
||||
channels
|
||||
};
|
||||
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
static bfin_isr_t bfinUARTISRs[] = {
|
||||
{SIC_DMA8_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
|
||||
{SIC_DMA10_UART1_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
|
||||
{SIC_DMA9_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL},
|
||||
{SIC_DMA11_UART1_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void bf537Stamp_BSP_output_char(char c) {
|
||||
|
||||
bfin_uart_poll_write(0, c);
|
||||
}
|
||||
|
||||
static int bf537Stamp_BSP_poll_char(void) {
|
||||
|
||||
return bfin_uart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = bf537Stamp_BSP_output_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = bf537Stamp_BSP_poll_char;
|
||||
|
||||
rtems_device_driver console_initialize(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
rtems_status_code status;
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
int i;
|
||||
#endif
|
||||
|
||||
status = bfin_uart_initialize(major, &config);
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
|
||||
bfin_interrupt_register(&bfinUARTISRs[i]);
|
||||
bfin_interrupt_enable(&bfinUARTISRs[i], TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(status);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_open(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return bfin_uart_open(major, minor, arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_close(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_close(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_read(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_write(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_ioctl(arg);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
|
||||
|
||||
librtemsbsp_a_SOURCES += console/console-io.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/eZKit533/console/console-io.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/cache/cache.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/bfin/shared/interrupt.c
|
||||
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/* console-io.c
|
||||
*
|
||||
* This file contains the hardware specific portions of the TTY driver
|
||||
* for the serial ports for ezkit533.
|
||||
*
|
||||
* Copyright (c) 2006 by Atos Automacao Industrial Ltda.
|
||||
* written by Alain Schaefer <alain.schaefer@easc.ch>
|
||||
* and Antonio Giovanini <antonio@atos.com.br>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <libcpu/bf533.h>
|
||||
#include <libcpu/interrupt.h>
|
||||
#include <libcpu/uart.h>
|
||||
|
||||
static bfin_uart_channel_t channels[] = {
|
||||
{"/dev/console",
|
||||
UART0_BASE_ADDRESS,
|
||||
0,
|
||||
0,
|
||||
CONSOLE_USE_INTERRUPTS,
|
||||
0,
|
||||
#ifdef CONSOLE_FORCE_BAUD
|
||||
CONSOLE_FORCE_BAUD,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
NULL,
|
||||
0,
|
||||
0}
|
||||
};
|
||||
|
||||
static bfin_uart_config_t config = {
|
||||
SCLK,
|
||||
sizeof(channels) / sizeof(channels[0]),
|
||||
channels
|
||||
};
|
||||
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
static bfin_isr_t bfinUARTISRs[] = {
|
||||
{SIC_DMA6_UART0_RX_VECTOR, bfinUart_rxIsr, 0, 0, NULL},
|
||||
{SIC_DMA7_UART0_TX_VECTOR, bfinUart_txIsr, 0, 0, NULL},
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void eZKit533_BSP_output_char(char c) {
|
||||
|
||||
bfin_uart_poll_write(0, c);
|
||||
}
|
||||
|
||||
static int eZKit533_BSP_poll_char(void) {
|
||||
|
||||
return bfin_uart_poll_read(0);
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = eZKit533_BSP_output_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = eZKit533_BSP_poll_char;
|
||||
|
||||
rtems_device_driver console_initialize(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
rtems_status_code status;
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
int i;
|
||||
#endif
|
||||
|
||||
status = bfin_uart_initialize(major, &config);
|
||||
#if CONSOLE_USE_INTERRUPTS
|
||||
for (i = 0; i < sizeof(bfinUARTISRs) / sizeof(bfinUARTISRs[0]); i++) {
|
||||
bfin_interrupt_register(&bfinUARTISRs[i]);
|
||||
bfin_interrupt_enable(&bfinUARTISRs[i], TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(status);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver console_open(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return bfin_uart_open(major, minor, arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_close(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_close(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_read(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_read(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_write(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_write(arg);
|
||||
}
|
||||
|
||||
rtems_device_driver console_control(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg) {
|
||||
|
||||
return rtems_termios_ioctl(arg);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/clock/clock-simidle.c
|
||||
librtemsbsp_a_SOURCES += timer/timer.c
|
||||
|
||||
# console
|
||||
librtemsbsp_a_SOURCES += ../../shared/console-polled.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-polled.c
|
||||
|
||||
# IRQ
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
|
||||
@@ -58,7 +58,7 @@ librtemsbsp_a_SOURCES += irq/irq.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c
|
||||
|
||||
# debugio
|
||||
librtemsbsp_a_SOURCES += console/console-io.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/epiphany/epiphany_sim/console/console-io.c
|
||||
|
||||
|
||||
include $(top_srcdir)/../../../../automake/local.am
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 University of York.
|
||||
* Hesham ALMatary <hmka501@york.ac.uk>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/console-polled.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void outbyte_console( char );
|
||||
static char inbyte_console( void );
|
||||
|
||||
void console_initialize_hardware(void)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
/* Epiphany simulator would handle this system call */
|
||||
static void outbyte_console(char c)
|
||||
{
|
||||
register int chan asm("r0") = STDOUT_FILENO;
|
||||
register void* addr asm("r1") = &c;
|
||||
register int len asm("r2") = 1;
|
||||
|
||||
/* Invoke write system call to be handled by Epiphany simulator */
|
||||
__asm__ __volatile__ ("trap 0" : : "r" (chan), "r" (addr), "r" (len));
|
||||
}
|
||||
|
||||
static char inbyte_console(void)
|
||||
{
|
||||
char c;
|
||||
register int chan asm("r0") = STDIN_FILENO;
|
||||
register void* addr asm("r1") = &c;
|
||||
register int len asm("r2") = 1;
|
||||
|
||||
/* Invoke read system call to be handled by Epiphany simulator */
|
||||
asm ("trap 1" :: "r" (chan), "r" (addr), "r" (len));
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* console_outbyte_polled
|
||||
*
|
||||
* This routine transmits a character using polling.
|
||||
*/
|
||||
void console_outbyte_polled(
|
||||
int port,
|
||||
char ch
|
||||
)
|
||||
{
|
||||
outbyte_console( ch );
|
||||
}
|
||||
|
||||
/*
|
||||
* console_inbyte_nonblocking
|
||||
*
|
||||
* This routine polls for a character.
|
||||
*/
|
||||
|
||||
int console_inbyte_nonblocking(int port)
|
||||
{
|
||||
char c;
|
||||
|
||||
c = inbyte_console();
|
||||
if (!c)
|
||||
return -1;
|
||||
return (int) c;
|
||||
}
|
||||
|
||||
/*
|
||||
* To support printk
|
||||
*/
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
static void Epiphany_output_char(char c) { console_outbyte_polled( 0, c ); }
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = Epiphany_output_char;
|
||||
BSP_polling_getchar_function_type BSP_poll_char =
|
||||
(void *)console_inbyte_nonblocking;
|
||||
@@ -53,42 +53,42 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/i386/pc386/clock/todcfg.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c
|
||||
|
||||
if RTEMS_VGA
|
||||
librtemsbsp_a_SOURCES += console/inch.c
|
||||
librtemsbsp_a_SOURCES += console/outch.c
|
||||
librtemsbsp_a_SOURCES += console/defkeymap.c
|
||||
librtemsbsp_a_SOURCES += console/keyboard.c
|
||||
librtemsbsp_a_SOURCES += console/pc_keyb.c
|
||||
librtemsbsp_a_SOURCES += console/ps2_mouse.c
|
||||
librtemsbsp_a_SOURCES += console/vgainit.c
|
||||
librtemsbsp_a_SOURCES += console/vt.c
|
||||
librtemsbsp_a_SOURCES += console/videoAsm.S
|
||||
librtemsbsp_a_SOURCES += console/kbd_parser.c
|
||||
librtemsbsp_a_SOURCES += console/vgacons.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/inch.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/outch.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/defkeymap.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/keyboard.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/pc_keyb.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/ps2_mouse.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgainit.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vt.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/videoAsm.S
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/kbd_parser.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/vgacons.c
|
||||
if USE_VGA
|
||||
librtemsbsp_a_SOURCES += console/fb_vga.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vga.c
|
||||
endif
|
||||
if USE_CIRRUS_GD5446
|
||||
librtemsbsp_a_SOURCES += console/fb_cirrus.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_cirrus.c
|
||||
endif
|
||||
if USE_VBE_RM
|
||||
librtemsbsp_a_SOURCES += console/fb_vesa_rm.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/fb_vesa_rm.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# console (non-graphics support)
|
||||
librtemsbsp_a_SOURCES += console/serial_mouse_config.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/serial_mouse_config.c
|
||||
librtemsbsp_a_SOURCES += ../shared/comm/uart.c
|
||||
librtemsbsp_a_SOURCES += ../shared/comm/tty_drv.c
|
||||
librtemsbsp_a_SOURCES += ../shared/realmode_int/realmode_int.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/legacy-console.c
|
||||
librtemsbsp_a_SOURCES += console/console_select.c
|
||||
librtemsbsp_a_SOURCES += console/console_control.c
|
||||
librtemsbsp_a_SOURCES += console/conscfg.c
|
||||
librtemsbsp_a_SOURCES += console/printk_support.c
|
||||
librtemsbsp_a_SOURCES += console/exar17d15x.c
|
||||
librtemsbsp_a_SOURCES += console/rtd316.c
|
||||
librtemsbsp_a_SOURCES += console/uart_bus_pci.c
|
||||
librtemsbsp_a_SOURCES += console/gdb_select.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_select.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/console_control.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/conscfg.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/printk_support.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/exar17d15x.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/rtd316.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/uart_bus_pci.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/i386/pc386/console/gdb_select.c
|
||||
|
||||
# gdb
|
||||
librtemsbsp_a_SOURCES += ../shared/comm/i386-stub.c
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* This file contains the libchip configuration information
|
||||
* to instantiate the libchip driver for the VGA console
|
||||
* and serial ports on a PC.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014, 2016.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/bspimpl.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
#if BSP_ENABLE_VGA
|
||||
#include <rtems/vgacons.h>
|
||||
#endif
|
||||
#include <bsp/irq.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
#if BSP_ENABLE_VGA
|
||||
#define VGA_CONSOLE_FUNCTIONS &vgacons_fns
|
||||
#endif
|
||||
|
||||
#if BSP_ENABLE_COM1_COM4
|
||||
#if 0
|
||||
#define COM_CONSOLE_FUNCTIONS &ns16550_fns_polled
|
||||
#else
|
||||
#define COM_CONSOLE_FUNCTIONS &ns16550_fns
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Base IO for UART
|
||||
*/
|
||||
#define COM1_BASE_IO 0x3F8
|
||||
#define COM2_BASE_IO 0x3E8
|
||||
#define COM3_BASE_IO 0x2F8
|
||||
#define COM4_BASE_IO 0x2E8
|
||||
|
||||
#define CLOCK_RATE (115200 * 16)
|
||||
|
||||
static uint8_t com_get_register(uint32_t addr, uint8_t i)
|
||||
{
|
||||
register uint8_t val;
|
||||
|
||||
inport_byte( (addr + i), val );
|
||||
return val;
|
||||
}
|
||||
|
||||
static void com_set_register(uint32_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
outport_byte( (addr + i), val );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default to the PC VGA console if present and configured.
|
||||
*/
|
||||
console_tbl Console_Configuration_Ports[] = {
|
||||
#if BSP_ENABLE_VGA
|
||||
/*
|
||||
* If present the VGA console must always be minor 0.
|
||||
* See console_control.
|
||||
*/
|
||||
{
|
||||
"/dev/vgacons", /* sDeviceName */
|
||||
VGA_CONSOLE, /* deviceType */
|
||||
VGA_CONSOLE_FUNCTIONS, /* pDeviceFns */
|
||||
vgacons_probe, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
(void *) NULL, /* NULL */ /* pDeviceParams */
|
||||
0x00000000, /* ulCtrlPort1 */
|
||||
0x00000000, /* ulCtrlPort2 */
|
||||
0x00000000, /* ulDataPort */
|
||||
NULL, /* getRegister */
|
||||
NULL, /* setRegister */
|
||||
NULL,/* unused */ /* getData */
|
||||
NULL,/* unused */ /* setData */
|
||||
0x0, /* ulClock */
|
||||
0x0 /* ulIntVector -- base for port */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned long Console_Configuration_Count =
|
||||
(sizeof(Console_Configuration_Ports)/sizeof(console_tbl));
|
||||
|
||||
static console_tbl Legacy_Ports[] = {
|
||||
#if BSP_ENABLE_COM1_COM4
|
||||
{
|
||||
"/dev/com1", /* sDeviceName */
|
||||
SERIAL_NS16550, /* deviceType */
|
||||
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
|
||||
COM1_BASE_IO, /* ulCtrlPort1 */
|
||||
0x00000000, /* ulCtrlPort2 */
|
||||
COM1_BASE_IO, /* ulDataPort */
|
||||
com_get_register, /* getRegister */
|
||||
com_set_register, /* setRegister */
|
||||
NULL,/* unused */ /* getData */
|
||||
NULL,/* unused */ /* setData */
|
||||
CLOCK_RATE, /* ulClock */
|
||||
BSP_UART_COM1_IRQ /* ulIntVector -- base for port */
|
||||
},
|
||||
{
|
||||
"/dev/com2", /* sDeviceName */
|
||||
SERIAL_NS16550, /* deviceType */
|
||||
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
|
||||
COM2_BASE_IO, /* ulCtrlPort1 */
|
||||
0x00000000, /* ulCtrlPort2 */
|
||||
COM2_BASE_IO, /* ulDataPort */
|
||||
com_get_register, /* getRegister */
|
||||
com_set_register, /* setRegister */
|
||||
NULL,/* unused */ /* getData */
|
||||
NULL,/* unused */ /* setData */
|
||||
CLOCK_RATE, /* ulClock */
|
||||
BSP_UART_COM2_IRQ /* ulIntVector -- base for port */
|
||||
},
|
||||
{
|
||||
"/dev/com3", /* sDeviceName */
|
||||
SERIAL_NS16550, /* deviceType */
|
||||
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
|
||||
COM3_BASE_IO, /* ulCtrlPort1 */
|
||||
0x00000000, /* ulCtrlPort2 */
|
||||
COM3_BASE_IO, /* ulDataPort */
|
||||
com_get_register, /* getRegister */
|
||||
com_set_register, /* setRegister */
|
||||
NULL,/* unused */ /* getData */
|
||||
NULL,/* unused */ /* setData */
|
||||
CLOCK_RATE, /* ulClock */
|
||||
BSP_UART_COM3_IRQ /* ulIntVector -- base for port */
|
||||
},
|
||||
{
|
||||
"/dev/com4", /* sDeviceName */
|
||||
SERIAL_NS16550, /* deviceType */
|
||||
COM_CONSOLE_FUNCTIONS, /* pDeviceFns */
|
||||
NULL, /* deviceProbe */
|
||||
NULL, /* pDeviceFlow */
|
||||
16, /* ulMargin */
|
||||
8, /* ulHysteresis */
|
||||
(void *) 9600, /* Baud Rate */ /* pDeviceParams */
|
||||
COM4_BASE_IO, /* ulCtrlPort1 */
|
||||
0x00000000, /* ulCtrlPort2 */
|
||||
COM4_BASE_IO, /* ulDataPort */
|
||||
com_get_register, /* getRegister */
|
||||
com_set_register, /* setRegister */
|
||||
NULL,/* unused */ /* getData */
|
||||
NULL,/* unused */ /* setData */
|
||||
CLOCK_RATE, /* ulClock */
|
||||
BSP_UART_COM4_IRQ /* ulIntVector -- base for port */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define Legacy_Port_Count \
|
||||
(sizeof(Legacy_Ports)/sizeof(console_tbl))
|
||||
|
||||
void legacy_uart_probe(void)
|
||||
{
|
||||
#if BSP_ENABLE_COM1_COM4
|
||||
const char *opt;
|
||||
/*
|
||||
* Check the command line to see if com1-com4 are disabled.
|
||||
*/
|
||||
opt = bsp_cmdline_arg("--disable-com1-com4");
|
||||
if ( opt ) {
|
||||
printk( "COM1-COM4: disabled\n" );
|
||||
} else {
|
||||
if (Legacy_Port_Count) {
|
||||
printk("Legacy UART Ports: COM1-COM4\n");
|
||||
console_register_devices( Legacy_Ports, Legacy_Port_Count );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* This file is an extension of the generic console driver
|
||||
* shell used by all console drivers using libchip, it contains
|
||||
* the console_control routine, This bsp needs its own version
|
||||
* of this method to handle the keyboard and mouse as a single
|
||||
* device.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <termios.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <rtems/mouse_parser.h>
|
||||
#if BSP_ENABLE_VGA
|
||||
#include <rtems/keyboard.h>
|
||||
#endif
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
/*
|
||||
* console_control
|
||||
*
|
||||
* this routine uses the termios driver to process io
|
||||
*/
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
#if BSP_ENABLE_VGA
|
||||
if (minor == 0) {
|
||||
rtems_libio_ioctl_args_t *args = arg;
|
||||
|
||||
switch (args->command) {
|
||||
default:
|
||||
if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
|
||||
return rtems_termios_ioctl (arg);
|
||||
break;
|
||||
|
||||
case MW_UID_REGISTER_DEVICE:
|
||||
printk( "SerialMouse: reg=%s\n", (const char*) args->buffer );
|
||||
register_kbd_msg_queue( args->buffer, 0 );
|
||||
break;
|
||||
|
||||
case MW_UID_UNREGISTER_DEVICE:
|
||||
unregister_kbd_msg_queue( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
args->ioctl_return = 0;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
return rtems_termios_ioctl (arg);
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup Console
|
||||
*
|
||||
* @brief pc386 console select
|
||||
*
|
||||
* This file contains a routine to select the console based upon a number
|
||||
* of criteria.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 2011-2012, 2016.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <bsp/bspimpl.h>
|
||||
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
|
||||
#include <crt.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Method to return true if the device associated with the
|
||||
* minor number probs available.
|
||||
*/
|
||||
static bool bsp_Is_Available( rtems_device_minor_number minor )
|
||||
{
|
||||
console_tbl *cptr = Console_Port_Tbl[minor];
|
||||
|
||||
/*
|
||||
* First perform the configuration dependent probe, then the
|
||||
* device dependent probe
|
||||
*/
|
||||
if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
|
||||
cptr->pDeviceFns->deviceProbe(minor)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to return the first available device.
|
||||
*/
|
||||
static rtems_device_minor_number bsp_First_Available_Device( void )
|
||||
{
|
||||
rtems_device_minor_number minor;
|
||||
|
||||
for (minor=0; minor < Console_Port_Count ; minor++) {
|
||||
console_tbl *cptr = Console_Port_Tbl[minor];
|
||||
|
||||
/*
|
||||
* First perform the configuration dependent probe, then the
|
||||
* device dependent probe
|
||||
*/
|
||||
|
||||
if ((!cptr->deviceProbe || cptr->deviceProbe(minor)) &&
|
||||
cptr->pDeviceFns->deviceProbe(minor)) {
|
||||
return minor;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error No devices were found. We will want to bail here.
|
||||
*/
|
||||
rtems_fatal_error_occurred(RTEMS_IO_ERROR);
|
||||
}
|
||||
|
||||
static bool parse_printk_or_console(
|
||||
const char *param,
|
||||
rtems_device_minor_number *minor_out
|
||||
)
|
||||
{
|
||||
static const char *opt;
|
||||
const char *option;
|
||||
const char *comma;
|
||||
size_t length;
|
||||
size_t index;
|
||||
rtems_device_minor_number minor;
|
||||
console_tbl *conscfg;
|
||||
|
||||
/*
|
||||
* Check the command line for the type of mode the console is.
|
||||
*/
|
||||
opt = bsp_cmdline_arg(param);
|
||||
if ( !opt ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fine the length, there can be more command line visible.
|
||||
*/
|
||||
length = 0;
|
||||
while ((opt[length] != ' ') && (opt[length] != '\0')) {
|
||||
++length;
|
||||
if (length > NAME_MAX) {
|
||||
printk("invalid option (%s): too long\n", param);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only match up to a comma or NULL
|
||||
*/
|
||||
index = 0;
|
||||
while ((opt[index] != '=') && (index < length)) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (opt[index] != '=') {
|
||||
printk("invalid option (%s): no equals\n", param);
|
||||
return false;
|
||||
}
|
||||
|
||||
++index;
|
||||
option = &opt[index];
|
||||
|
||||
while ((opt[index] != ',') && (index < length)) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (opt[index] == ',')
|
||||
comma = &opt[index];
|
||||
else
|
||||
comma = NULL;
|
||||
|
||||
length = &opt[index] - option;
|
||||
|
||||
conscfg = console_find_console_entry( option, length, &minor );
|
||||
if ( conscfg == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*minor_out = minor;
|
||||
if (comma) {
|
||||
option = comma + 1;
|
||||
if (strncmp (option, "115200", sizeof ("115200") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)115200;
|
||||
else if (strncmp (option, "57600", sizeof ("57600") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)57600;
|
||||
else if (strncmp (option, "38400", sizeof ("38400") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)38400;
|
||||
else if (strncmp (option, "19200", sizeof ("19200") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)19200;
|
||||
else if (strncmp (option, "9600", sizeof ("9600") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)9600;
|
||||
else if (strncmp (option, "4800", sizeof ("4800") - 1) == 0)
|
||||
conscfg->pDeviceParams = (void *)4800;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper to retrieve device name
|
||||
*/
|
||||
static inline const char *get_name(
|
||||
rtems_device_minor_number minor
|
||||
)
|
||||
{
|
||||
return Console_Port_Tbl[minor]->sDeviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the arguments early so the printk and console ports are
|
||||
* set appropriately.
|
||||
*/
|
||||
void pc386_parse_console_arguments(void)
|
||||
{
|
||||
rtems_device_minor_number minor;
|
||||
rtems_device_minor_number minor_console = 0;
|
||||
rtems_device_minor_number minor_printk = 0;
|
||||
|
||||
/*
|
||||
* Assume that if only --console is specified, that printk() should
|
||||
* follow that selection by default.
|
||||
*/
|
||||
if ( parse_printk_or_console( "--console=", &minor ) ) {
|
||||
minor_console = minor;
|
||||
minor_printk = minor;
|
||||
}
|
||||
|
||||
/*
|
||||
* But if explicitly specified, attempt to honor it.
|
||||
*/
|
||||
if ( parse_printk_or_console( "--printk=", &minor ) ) {
|
||||
minor_printk = minor;
|
||||
}
|
||||
|
||||
printk( "Console: %s printk: %s\n",
|
||||
get_name(minor_console),get_name(minor_printk) );
|
||||
|
||||
/*
|
||||
* Any output after this can cause problems until termios is initialised.
|
||||
*/
|
||||
Console_Port_Minor = minor_console;
|
||||
BSPPrintkPort = minor_printk;
|
||||
}
|
||||
|
||||
/*
|
||||
* This handles the selection of the console after the devices are
|
||||
* initialized.
|
||||
*/
|
||||
void bsp_console_select(void)
|
||||
{
|
||||
#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
|
||||
/*
|
||||
* WARNING: This code is really needed any more and should be removed.
|
||||
* references to COM1 and COM2 like they are wrong.
|
||||
*/
|
||||
if ( BSP_runtime_console_select )
|
||||
BSP_runtime_console_select(&BSPPrintkPort, &Console_Port_Minor);
|
||||
|
||||
/*
|
||||
* If no video card, fall back to serial port console
|
||||
*/
|
||||
if((Console_Port_Minor == BSP_CONSOLE_VGA)
|
||||
&& (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
|
||||
&& (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
|
||||
Console_Port_Minor = BSP_CONSOLE_COM2;
|
||||
BSPPrintkPort = BSP_CONSOLE_COM1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the device that was selected isn't available then
|
||||
* let the user know and select the first available device.
|
||||
*/
|
||||
if ( !bsp_Is_Available( Console_Port_Minor ) ) {
|
||||
printk(
|
||||
"Error finding %s setting console to first available\n",
|
||||
get_name(Console_Port_Minor)
|
||||
);
|
||||
Console_Port_Minor = bsp_First_Available_Device();
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
/* Do not edit this file! It was automatically generated by */
|
||||
/* loadkeys --mktable defkeymap.map > defkeymap.c */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <rtems/keyboard.h>
|
||||
#include <rtems/kd.h>
|
||||
|
||||
u_short plain_map[NR_KEYS] = {
|
||||
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
|
||||
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
|
||||
0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
|
||||
0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
|
||||
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
|
||||
0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
|
||||
0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
|
||||
0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
|
||||
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
|
||||
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
|
||||
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
|
||||
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short shift_map[NR_KEYS] = {
|
||||
0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
|
||||
0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
|
||||
0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
|
||||
0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
|
||||
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
|
||||
0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
|
||||
0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
|
||||
0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
|
||||
0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
|
||||
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
|
||||
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
|
||||
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short altgr_map[NR_KEYS] = {
|
||||
0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
|
||||
0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
|
||||
0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
|
||||
0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
|
||||
0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
|
||||
0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
|
||||
0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
|
||||
0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
|
||||
0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
|
||||
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
|
||||
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
|
||||
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short ctrl_map[NR_KEYS] = {
|
||||
0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
|
||||
0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
|
||||
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
|
||||
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
|
||||
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
|
||||
0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
|
||||
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
|
||||
0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
|
||||
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
|
||||
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
|
||||
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
|
||||
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short shift_ctrl_map[NR_KEYS] = {
|
||||
0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
|
||||
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
|
||||
0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
|
||||
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
|
||||
0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
|
||||
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
|
||||
0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
|
||||
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
|
||||
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short alt_map[NR_KEYS] = {
|
||||
0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
|
||||
0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
|
||||
0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
|
||||
0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
|
||||
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
|
||||
0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
|
||||
0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
|
||||
0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
|
||||
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
|
||||
0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
|
||||
0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
|
||||
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
u_short ctrl_alt_map[NR_KEYS] = {
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
|
||||
0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
|
||||
0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
|
||||
0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
|
||||
0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
|
||||
0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
|
||||
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
|
||||
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
|
||||
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
|
||||
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
|
||||
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
|
||||
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
|
||||
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
|
||||
};
|
||||
|
||||
ushort *key_maps[MAX_NR_KEYMAPS] = {
|
||||
plain_map, shift_map, altgr_map, 0,
|
||||
ctrl_map, shift_ctrl_map, 0, 0,
|
||||
alt_map, 0, 0, 0,
|
||||
ctrl_alt_map, 0
|
||||
};
|
||||
|
||||
unsigned int keymap_count = 7;
|
||||
|
||||
/*
|
||||
* Philosophy: most people do not define more strings, but they who do
|
||||
* often want quite a lot of string space. So, we statically allocate
|
||||
* the default and allocate dynamically in chunks of 512 bytes.
|
||||
*/
|
||||
|
||||
char func_buf[] = {
|
||||
'\033', '[', '[', 'A', 0,
|
||||
'\033', '[', '[', 'B', 0,
|
||||
'\033', '[', '[', 'C', 0,
|
||||
'\033', '[', '[', 'D', 0,
|
||||
'\033', '[', '[', 'E', 0,
|
||||
'\033', '[', '1', '7', '~', 0,
|
||||
'\033', '[', '1', '8', '~', 0,
|
||||
'\033', '[', '1', '9', '~', 0,
|
||||
'\033', '[', '2', '0', '~', 0,
|
||||
'\033', '[', '2', '1', '~', 0,
|
||||
'\033', '[', '2', '3', '~', 0,
|
||||
'\033', '[', '2', '4', '~', 0,
|
||||
'\033', '[', '2', '5', '~', 0,
|
||||
'\033', '[', '2', '6', '~', 0,
|
||||
'\033', '[', '2', '8', '~', 0,
|
||||
'\033', '[', '2', '9', '~', 0,
|
||||
'\033', '[', '3', '1', '~', 0,
|
||||
'\033', '[', '3', '2', '~', 0,
|
||||
'\033', '[', '3', '3', '~', 0,
|
||||
'\033', '[', '3', '4', '~', 0,
|
||||
'\033', '[', '1', '~', 0,
|
||||
'\033', '[', '2', '~', 0,
|
||||
'\033', '[', '3', '~', 0,
|
||||
'\033', '[', '4', '~', 0,
|
||||
'\033', '[', '5', '~', 0,
|
||||
'\033', '[', '6', '~', 0,
|
||||
'\033', '[', 'M', 0,
|
||||
'\033', '[', 'P', 0,
|
||||
};
|
||||
|
||||
char *funcbufptr = func_buf;
|
||||
int funcbufsize = sizeof(func_buf);
|
||||
int funcbufleft = 0; /* space left */
|
||||
|
||||
char *func_table[MAX_NR_FUNC] = {
|
||||
func_buf + 0,
|
||||
func_buf + 5,
|
||||
func_buf + 10,
|
||||
func_buf + 15,
|
||||
func_buf + 20,
|
||||
func_buf + 25,
|
||||
func_buf + 31,
|
||||
func_buf + 37,
|
||||
func_buf + 43,
|
||||
func_buf + 49,
|
||||
func_buf + 55,
|
||||
func_buf + 61,
|
||||
func_buf + 67,
|
||||
func_buf + 73,
|
||||
func_buf + 79,
|
||||
func_buf + 85,
|
||||
func_buf + 91,
|
||||
func_buf + 97,
|
||||
func_buf + 103,
|
||||
func_buf + 109,
|
||||
func_buf + 115,
|
||||
func_buf + 120,
|
||||
func_buf + 125,
|
||||
func_buf + 130,
|
||||
func_buf + 135,
|
||||
func_buf + 140,
|
||||
func_buf + 145,
|
||||
0,
|
||||
0,
|
||||
func_buf + 149,
|
||||
0,
|
||||
};
|
||||
|
||||
struct kbdiacr accent_table[MAX_DIACR] = {
|
||||
{'`', 'A', '\300'}, {'`', 'a', '\340'},
|
||||
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
|
||||
{'^', 'A', '\302'}, {'^', 'a', '\342'},
|
||||
{'~', 'A', '\303'}, {'~', 'a', '\343'},
|
||||
{'"', 'A', '\304'}, {'"', 'a', '\344'},
|
||||
{'O', 'A', '\305'}, {'o', 'a', '\345'},
|
||||
{'0', 'A', '\305'}, {'0', 'a', '\345'},
|
||||
{'A', 'A', '\305'}, {'a', 'a', '\345'},
|
||||
{'A', 'E', '\306'}, {'a', 'e', '\346'},
|
||||
{',', 'C', '\307'}, {',', 'c', '\347'},
|
||||
{'`', 'E', '\310'}, {'`', 'e', '\350'},
|
||||
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
|
||||
{'^', 'E', '\312'}, {'^', 'e', '\352'},
|
||||
{'"', 'E', '\313'}, {'"', 'e', '\353'},
|
||||
{'`', 'I', '\314'}, {'`', 'i', '\354'},
|
||||
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
|
||||
{'^', 'I', '\316'}, {'^', 'i', '\356'},
|
||||
{'"', 'I', '\317'}, {'"', 'i', '\357'},
|
||||
{'-', 'D', '\320'}, {'-', 'd', '\360'},
|
||||
{'~', 'N', '\321'}, {'~', 'n', '\361'},
|
||||
{'`', 'O', '\322'}, {'`', 'o', '\362'},
|
||||
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
|
||||
{'^', 'O', '\324'}, {'^', 'o', '\364'},
|
||||
{'~', 'O', '\325'}, {'~', 'o', '\365'},
|
||||
{'"', 'O', '\326'}, {'"', 'o', '\366'},
|
||||
{'/', 'O', '\330'}, {'/', 'o', '\370'},
|
||||
{'`', 'U', '\331'}, {'`', 'u', '\371'},
|
||||
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
|
||||
{'^', 'U', '\333'}, {'^', 'u', '\373'},
|
||||
{'"', 'U', '\334'}, {'"', 'u', '\374'},
|
||||
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
|
||||
{'T', 'H', '\336'}, {'t', 'h', '\376'},
|
||||
{'s', 's', '\337'}, {'"', 'y', '\377'},
|
||||
{'s', 'z', '\337'}, {'i', 'j', '\377'},
|
||||
};
|
||||
|
||||
unsigned int accent_table_size = 68;
|
||||
@@ -1,224 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Driver for Exar XR17D15x Multiport UARTs
|
||||
*
|
||||
* This driver supports 2, 4 or 8 port Exar parts which are NS16550
|
||||
* compatible.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2012.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/pci.h>
|
||||
#include <bsp/exar17d15x.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
#define MAX_BOARDS 4
|
||||
|
||||
/*
|
||||
* This is the rate for the clock internal to the parts.
|
||||
*/
|
||||
#define EXAR_CLOCK_RATE (921600*16)
|
||||
|
||||
/*
|
||||
* Supported PCI Ids
|
||||
*/
|
||||
#define PCI_VENDOR_ID_EXAR 0x13A8
|
||||
#define PCI_VENDOR_ID_EXAR_XR17D158 0x0158
|
||||
#define PCI_VENDOR_ID_EXAR_XR17D154 0x0154
|
||||
#define PCI_VENDOR_ID_EXAR_XR17D152 0x0152
|
||||
|
||||
/*
|
||||
* Structure to manage each instance found.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t vendor;
|
||||
uint16_t device;
|
||||
uint8_t ports;
|
||||
} exar_parts_t;
|
||||
|
||||
static exar_parts_t Supported[] = {
|
||||
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 },
|
||||
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 },
|
||||
{ PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Information saved from PCI scan
|
||||
*/
|
||||
typedef struct {
|
||||
bool found;
|
||||
uint32_t base;
|
||||
uint8_t irq;
|
||||
uint8_t bus;
|
||||
uint8_t slot;
|
||||
uint8_t ports;
|
||||
} exar17d15x_conf_t;
|
||||
|
||||
/*
|
||||
* Register Access Routines
|
||||
*/
|
||||
static uint8_t xr17d15x_get_register(uint32_t addr, uint8_t i)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
|
||||
|
||||
val = *reg;
|
||||
// printk( "RD %p -> 0x%02x\n", reg, val );
|
||||
return val;
|
||||
}
|
||||
|
||||
static void xr17d15x_set_register(uint32_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
|
||||
|
||||
// printk( "WR %p <- 0x%02x\n", reg, val );
|
||||
*reg = val;
|
||||
}
|
||||
|
||||
rtems_device_driver exar17d15x_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor_arg,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
// int pbus, pdev, pfun;
|
||||
exar17d15x_conf_t conf[MAX_BOARDS];
|
||||
int boards = 0;
|
||||
int b = 0;
|
||||
int p;
|
||||
console_tbl *ports;
|
||||
console_tbl *port_p;
|
||||
int pbus;
|
||||
int pdev;
|
||||
int pfun;
|
||||
int status;
|
||||
int instance;
|
||||
int i;
|
||||
int total_ports = 0;
|
||||
|
||||
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
|
||||
conf[b].found = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan for Serial port boards
|
||||
*
|
||||
* NOTE: There appear to be Exar parts with 2 and 4 ports which would
|
||||
* be easy to support. Just change the hard-coded 8 ports per
|
||||
* board to variable and adjust.
|
||||
*
|
||||
* NOTE: There are likely other board vendors which could be supported
|
||||
* by this.
|
||||
*/
|
||||
for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
|
||||
|
||||
for ( i=0 ; Supported[i].ports != 0 ; i++ ) {
|
||||
status = pci_find_device(
|
||||
Supported[i].vendor,
|
||||
Supported[i].device,
|
||||
instance,
|
||||
&pbus,
|
||||
&pdev,
|
||||
&pfun
|
||||
);
|
||||
if ( status == PCIB_ERR_SUCCESS ) {
|
||||
boards++;
|
||||
conf[instance].found = true;
|
||||
conf[instance].ports = Supported[i].ports;
|
||||
total_ports += conf[instance].ports;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( status != PCIB_ERR_SUCCESS )
|
||||
continue;
|
||||
|
||||
pci_read_config_byte(
|
||||
pbus,
|
||||
pdev,
|
||||
pfun,
|
||||
PCI_INTERRUPT_LINE,
|
||||
&conf[instance].irq
|
||||
);
|
||||
pci_read_config_dword(
|
||||
pbus,
|
||||
pdev,
|
||||
pfun,
|
||||
PCI_BASE_ADDRESS_0,
|
||||
&conf[instance].base
|
||||
);
|
||||
printk(
|
||||
"Found Exar 17D15x %d at 0x%08lx IRQ %d with %d ports\n",
|
||||
instance,
|
||||
conf[instance].base,
|
||||
conf[instance].irq,
|
||||
conf[instance].ports
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate array of device structures and fill them in
|
||||
*/
|
||||
ports = calloc( total_ports, sizeof( console_tbl ) );
|
||||
port_p = ports;
|
||||
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
|
||||
if ( conf[b].found == false )
|
||||
continue;
|
||||
for ( p=0 ; p<conf[b].ports ; p++ ) {
|
||||
char name[32];
|
||||
|
||||
sprintf( name, "/dev/exar17d15x_%d_%d", b, p );
|
||||
//printk("Found %s\n", name );
|
||||
port_p->sDeviceName = strdup( name );
|
||||
port_p->deviceType = SERIAL_NS16550;
|
||||
#if 1
|
||||
port_p->pDeviceFns = &ns16550_fns_polled;
|
||||
#else
|
||||
port_p->pDeviceFns = &ns16550_fns;
|
||||
#endif
|
||||
|
||||
port_p->deviceProbe = NULL;
|
||||
port_p->pDeviceFlow = NULL;
|
||||
port_p->ulMargin = 16;
|
||||
port_p->ulHysteresis = 8;
|
||||
port_p->pDeviceParams = (void *) 9600;
|
||||
port_p->ulCtrlPort1 = conf[b].base + (p * 0x0200);
|
||||
port_p->ulCtrlPort2 = 0; /* NA */
|
||||
port_p->ulDataPort = 0; /* NA */
|
||||
port_p->getRegister = xr17d15x_get_register;
|
||||
port_p->setRegister = xr17d15x_set_register;
|
||||
port_p->getData = NULL; /* NA */
|
||||
port_p->setData = NULL; /* NA */
|
||||
port_p->ulClock = EXAR_CLOCK_RATE;
|
||||
port_p->ulIntVector = conf[b].irq;
|
||||
|
||||
port_p++;
|
||||
} /* end ports */
|
||||
} /* end boards */
|
||||
|
||||
/*
|
||||
* Register the devices
|
||||
*/
|
||||
if ( boards )
|
||||
console_register_devices( ports, total_ports );
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,766 +0,0 @@
|
||||
/*
|
||||
* FB driver for Cirrus GD5446 graphic hardware.
|
||||
* Tested to be compatible with QEMU GD5446 emulation but not on real HW.
|
||||
*
|
||||
* Copyright (c) 2012 - Alexandru-Sever Horin (alex.sever.h@gmail.com).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* The code is based on next information sources:
|
||||
* - CL-GD5446 Technical Reference Manual, 1996, Second Edition
|
||||
* - RTEMS fb_vga.c - Rosimildo da Silva ( rdasilva@connecttel.com )
|
||||
* - Cirrus xf86 driver - used as VGA hardware setup sequence documentation
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/pci.h>
|
||||
|
||||
#include <rtems/fb.h>
|
||||
#include <rtems/framebuffer.h>
|
||||
#include <rtems/score/atomic.h>
|
||||
|
||||
/* flag to limit driver to protect against multiple opens */
|
||||
static Atomic_Flag driver_mutex;
|
||||
|
||||
/* screen information for the VGA driver
|
||||
* standard structures
|
||||
*/
|
||||
static struct fb_var_screeninfo fb_var;
|
||||
static struct fb_fix_screeninfo fb_fix;
|
||||
|
||||
#define CIRRUS_VENDOR_ID 0x1013
|
||||
#define CIRRUS_GD5446_DEVICE_ID 0x00b8
|
||||
|
||||
typedef struct _DisplayModeRec {
|
||||
struct _DisplayModeRec *prev;
|
||||
struct _DisplayModeRec *next;
|
||||
char *name; /* identifier for the mode */
|
||||
int type;
|
||||
|
||||
/* These are the values that the user sees/provides */
|
||||
int Clock; /* pixel clock freq (kHz) */
|
||||
int HDisplay; /* horizontal timing */
|
||||
int HSyncStart;
|
||||
int HSyncEnd;
|
||||
int HTotal;
|
||||
int HSkew;
|
||||
int VDisplay; /* vertical timing */
|
||||
int VSyncStart;
|
||||
int VSyncEnd;
|
||||
int VTotal;
|
||||
int VScan;
|
||||
int Flags;
|
||||
|
||||
/* These are the values the hardware uses */
|
||||
int ClockIndex;
|
||||
int SynthClock; /* Actual clock freq to
|
||||
* be programmed (kHz) */
|
||||
int CrtcHDisplay;
|
||||
int CrtcHBlankStart;
|
||||
int CrtcHSyncStart;
|
||||
int CrtcHSyncEnd;
|
||||
int CrtcHBlankEnd;
|
||||
int CrtcHTotal;
|
||||
int CrtcHSkew;
|
||||
int CrtcVDisplay;
|
||||
int CrtcVBlankStart;
|
||||
int CrtcVSyncStart;
|
||||
int CrtcVSyncEnd;
|
||||
int CrtcVBlankEnd;
|
||||
int CrtcVTotal;
|
||||
int CrtcHAdjusted;
|
||||
int CrtcVAdjusted;
|
||||
int PrivSize;
|
||||
int32_t *Private;
|
||||
int PrivFlags;
|
||||
|
||||
float HSync, VRefresh;
|
||||
} DisplayModeRec, *DisplayModePtr;
|
||||
|
||||
static DisplayModeRec available_modes[] = {
|
||||
{
|
||||
.Clock = 31500 ,
|
||||
.HDisplay = 640 ,
|
||||
.HSyncStart = 664 ,
|
||||
.HSyncEnd = 704 ,
|
||||
.HTotal = 832 ,
|
||||
.HSkew = 0 ,
|
||||
.VDisplay = 480 , /* vertical timing */
|
||||
.VSyncStart = 489 ,
|
||||
.VSyncEnd = 491 ,
|
||||
.VTotal = 520 ,
|
||||
.VScan = 0,
|
||||
.Flags = 0
|
||||
},
|
||||
{
|
||||
.Clock = 40000 ,
|
||||
.HDisplay = 800 ,
|
||||
.HSyncStart = 840 ,
|
||||
.HSyncEnd = 968 ,
|
||||
.HTotal = 1056 ,
|
||||
.HSkew = 0 ,
|
||||
.VDisplay = 600 , /* vertical timing */
|
||||
.VSyncStart = 601 ,
|
||||
.VSyncEnd = 605 ,
|
||||
.VTotal = 628 ,
|
||||
.VScan = 0,
|
||||
.Flags = 0
|
||||
},
|
||||
};
|
||||
static DisplayModePtr active_mode;
|
||||
|
||||
/* The display mode used for the board hardcoded in the following define
|
||||
* Index in above structure
|
||||
*/
|
||||
#define CIRRUS_DISPLAY_MODE 0
|
||||
|
||||
/* The display bytes per pixel used for the board hardcoded in the following define
|
||||
* Index in above structure
|
||||
*/
|
||||
#define CIRRUS_DEFAULT_BPP 24
|
||||
|
||||
/* cirrus board information */
|
||||
struct cirrus_board_str{
|
||||
int pci_bus;
|
||||
int pci_device;
|
||||
int pci_function;
|
||||
void *reg_base;
|
||||
};
|
||||
|
||||
static struct cirrus_board_str cirrus_board_info;
|
||||
|
||||
/*
|
||||
* get information from the board
|
||||
*/
|
||||
static int
|
||||
cirrus_pci_read( struct cirrus_board_str *cirrus_board, uint32_t *mem_base, uint32_t *cirrus_register_base)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = pci_read_config_dword(
|
||||
cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function,
|
||||
PCI_BASE_ADDRESS_0, mem_base);
|
||||
if( r != PCIB_ERR_SUCCESS)
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
r = pci_read_config_dword(
|
||||
cirrus_board->pci_bus, cirrus_board->pci_device, cirrus_board->pci_function,
|
||||
PCI_BASE_ADDRESS_1, cirrus_register_base);
|
||||
if( r != PCIB_ERR_SUCCESS)
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
*mem_base &= PCI_BASE_ADDRESS_MEM_MASK;
|
||||
*cirrus_register_base &= PCI_BASE_ADDRESS_MEM_MASK;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
fb_cirrus_read_config_dword(
|
||||
struct cirrus_board_str *fbst,
|
||||
unsigned char where,
|
||||
uint32_t *pval)
|
||||
{
|
||||
return pci_read_config_dword(
|
||||
fbst->pci_bus, fbst->pci_device, fbst->pci_function,
|
||||
where, pval);
|
||||
}
|
||||
|
||||
static inline int
|
||||
fb_cirrus_write_config_dword(
|
||||
struct cirrus_board_str *fbst,
|
||||
unsigned char where,
|
||||
uint32_t val)
|
||||
{
|
||||
return pci_write_config_dword(
|
||||
fbst->pci_bus, fbst->pci_device, fbst->pci_function,
|
||||
where, val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
fb_cirrus_write_reg8 (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
*(volatile uint8_t*)((char *)fbst->reg_base + reg) = val;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
fb_cirrus_read_reg8 (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg)
|
||||
{
|
||||
return *(volatile uint8_t*)((char *)fbst->reg_base + reg);
|
||||
}
|
||||
|
||||
#define SEQ_INDEX 0x04
|
||||
#define SEQ_DATA 0x05
|
||||
|
||||
static inline void
|
||||
fb_cirrus_write_seq_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg);
|
||||
fb_cirrus_write_reg8(fbst, SEQ_DATA, val);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
fb_cirrus_read_seq_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, SEQ_INDEX, reg);
|
||||
return fb_cirrus_read_reg8(fbst, SEQ_DATA);
|
||||
}
|
||||
|
||||
#define CRT_INDEX 0x14
|
||||
#define CRT_DATA 0x15
|
||||
|
||||
static inline void
|
||||
fb_cirrus_write_crt_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, CRT_INDEX, reg);
|
||||
fb_cirrus_write_reg8(fbst, CRT_DATA, val);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
fb_cirrus_read_crt_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, CRT_INDEX, reg);
|
||||
return fb_cirrus_read_reg8(fbst, CRT_DATA);
|
||||
}
|
||||
|
||||
#define GDC_INDEX 0x0E
|
||||
#define GDC_DATA 0x0F
|
||||
|
||||
static inline void
|
||||
fb_cirrus_write_gdc_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, GDC_INDEX, reg);
|
||||
fb_cirrus_write_reg8(fbst, GDC_DATA, val);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
fb_cirrus_read_gdc_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int reg)
|
||||
{
|
||||
fb_cirrus_write_reg8(fbst, GDC_INDEX, reg);
|
||||
return fb_cirrus_read_reg8(fbst, GDC_DATA);
|
||||
}
|
||||
|
||||
#define VGA_DAC_MASK 0x06
|
||||
|
||||
static inline void
|
||||
fb_cirrus_write_hdr_reg (
|
||||
const struct cirrus_board_str *fbst,
|
||||
unsigned int val)
|
||||
{
|
||||
volatile unsigned int dummy RTEMS_UNUSED;
|
||||
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
|
||||
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
|
||||
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
|
||||
dummy = fb_cirrus_read_reg8(fbst, VGA_DAC_MASK);
|
||||
fb_cirrus_write_reg8(fbst, VGA_DAC_MASK, val);
|
||||
}
|
||||
|
||||
/* Functionality to support multiple VGA frame buffers can be added easily,
|
||||
* but is not supported at this moment because there is no need for two or
|
||||
* more "classic" VGA adapters. Multiple frame buffer drivers may be
|
||||
* implemented and If we had implement it they would be named as "/dev/fb0",
|
||||
* "/dev/fb1", "/dev/fb2" and so on.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fb_cirrus device driver INITIALIZE entry point.
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
int res;
|
||||
|
||||
printk( "FB_CIRRUS -- driver initializing..\n" );
|
||||
|
||||
res = pci_find_device(
|
||||
CIRRUS_VENDOR_ID,
|
||||
CIRRUS_GD5446_DEVICE_ID,
|
||||
minor,
|
||||
&cirrus_board_info.pci_bus,
|
||||
&cirrus_board_info.pci_device,
|
||||
&cirrus_board_info.pci_function
|
||||
);
|
||||
|
||||
if ( res != PCIB_ERR_SUCCESS ) {
|
||||
printk( "FB_CIRRUS initialize -- device not found\n" );
|
||||
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
else{
|
||||
printk( "FB_CIRRUS -- driver initializing..\n" );
|
||||
/*
|
||||
* Register the device
|
||||
*/
|
||||
status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME
|
||||
" FB_CIRRUS framebuffer device!\n");
|
||||
rtems_fatal_error_occurred( status );
|
||||
}
|
||||
|
||||
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to initialize the Start Address - the first
|
||||
* displayed location in the video memory.
|
||||
* Usually mandatory
|
||||
*/
|
||||
static void
|
||||
cirrus_adjust_frame( struct cirrus_board_str *board, int x, int y)
|
||||
{
|
||||
uint32_t Base;
|
||||
uint8_t tmp;
|
||||
|
||||
Base = ((y * fb_var.xres + x) >> 3);
|
||||
if (fb_var.bits_per_pixel != 1)
|
||||
Base *= (fb_var.bits_per_pixel >> 2);
|
||||
|
||||
printk("FB_CIRRUS: cirrus_adjust_frame %d %d >>> %d %x\n", x, y, Base, Base);
|
||||
|
||||
if ((Base & ~0x000FFFFF) != 0) {
|
||||
printk("FB_CIRRUS: Internal error: cirrus_adjust_frame: cannot handle overflow\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fb_cirrus_write_crt_reg( board, 0x0C, (Base >> 8) & 0xff);
|
||||
fb_cirrus_write_crt_reg( board, 0x0D, Base & 0xff);
|
||||
|
||||
tmp = fb_cirrus_read_crt_reg( board, 0x1B);
|
||||
tmp &= 0xF2;
|
||||
tmp |= (Base >> 16) & 0x01;
|
||||
tmp |= (Base >> 15) & 0x0C;
|
||||
fb_cirrus_write_crt_reg( board, 0x1B, tmp);
|
||||
|
||||
tmp = fb_cirrus_read_crt_reg( board, 0x1D);
|
||||
tmp &= 0x7F;
|
||||
tmp |= (Base >> 12) & 0x80;
|
||||
fb_cirrus_write_crt_reg( board, 0x1D, tmp);
|
||||
}
|
||||
|
||||
static int
|
||||
cirrus_set_mode(DisplayModePtr mode)
|
||||
{
|
||||
int depthcode = fb_var.bits_per_pixel;;
|
||||
int width;
|
||||
int HDiv2 = 0, VDiv2 = 0;
|
||||
const struct cirrus_board_str *cirrus_board_ptr = &cirrus_board_info;
|
||||
int temp;
|
||||
int hdr = -1;
|
||||
|
||||
printk("FB_CIRRUS: mode %d bpp, %d Hz %d %d %d %d %d %d %d %d\n",
|
||||
fb_var.bits_per_pixel,
|
||||
mode->Clock,
|
||||
mode->HDisplay,
|
||||
mode->HSyncStart,
|
||||
mode->HSyncEnd,
|
||||
mode->HTotal,
|
||||
mode->VDisplay,
|
||||
mode->VSyncStart,
|
||||
mode->VSyncEnd,
|
||||
mode->VTotal);
|
||||
|
||||
if ( mode->Clock > 85500 ) {
|
||||
/* The actual DAC register value is set later. */
|
||||
/* The CRTC is clocked at VCLK / 2, so we must half the */
|
||||
/* horizontal timings. */
|
||||
if (!mode->CrtcHAdjusted) {
|
||||
mode->HDisplay >>= 1;
|
||||
mode->HSyncStart >>= 1;
|
||||
mode->HTotal >>= 1;
|
||||
mode->HSyncEnd >>= 1;
|
||||
mode->SynthClock >>= 1;
|
||||
mode->CrtcHAdjusted = TRUE;
|
||||
}
|
||||
depthcode += 64;
|
||||
HDiv2 = 1;
|
||||
}
|
||||
if (mode->VTotal >= 1024 ) {
|
||||
/* For non-interlaced vertical timing >= 1024, the vertical timings */
|
||||
/* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
|
||||
if (!mode->CrtcVAdjusted) {
|
||||
mode->VDisplay >>= 1;
|
||||
mode->VSyncStart >>= 1;
|
||||
mode->VSyncEnd >>= 1;
|
||||
mode->VTotal >>= 1;
|
||||
mode->CrtcVAdjusted = TRUE;
|
||||
}
|
||||
VDiv2 = 1;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Sequential registers
|
||||
*/
|
||||
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x00, 0x00);
|
||||
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x01, 0x01);
|
||||
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x02, 0x0F);
|
||||
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x03, 0x00);
|
||||
fb_cirrus_write_seq_reg(cirrus_board_ptr, 0x04, 0x0E);
|
||||
|
||||
/****************************************************
|
||||
* CRTC Controller Registers
|
||||
*/
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x00, (mode->HTotal >> 3) - 5 );
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x01, (mode->HDisplay >> 3) - 1);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x02, (mode->HSyncStart >> 3) - 1);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x03, ((mode->HSyncEnd >> 3) & 0x1F) | 0x80);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x04, (mode->HSyncStart >> 3));
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x05,
|
||||
(((mode->HSyncEnd >> 3) & 0x20 ) << 2 )
|
||||
| (((mode->HSyncEnd >> 3)) & 0x1F));
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x06, (mode->VTotal - 2) & 0xFF);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x07,
|
||||
(((mode->VTotal -2) & 0x100) >> 8 )
|
||||
| (((mode->VDisplay -1) & 0x100) >> 7 )
|
||||
| ((mode->VSyncStart & 0x100) >> 6 )
|
||||
| (((mode->VSyncStart) & 0x100) >> 5 )
|
||||
| 0x10
|
||||
| (((mode->VTotal -2) & 0x200) >> 4 )
|
||||
| (((mode->VDisplay -1) & 0x200) >> 3 )
|
||||
| ((mode->VSyncStart & 0x200) >> 2 ));
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x08, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x09, ((mode->VSyncStart & 0x200) >>4) | 0x40);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0A, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0B, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0C, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0D, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0E, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x0F, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x10, mode->VSyncStart & 0xFF);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x11, (mode->VSyncEnd & 0x0F) | 0x20);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x12, (mode->VDisplay -1) & 0xFF);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, 0x00); /* no interlace */
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x14, 0x00);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x15, mode->VSyncStart & 0xFF);
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x16, (mode->VSyncStart +1) & 0xFF);
|
||||
|
||||
temp = 0xAF;
|
||||
if(VDiv2)
|
||||
temp |= 0x04;
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x17, temp);
|
||||
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x18, 0xFF);
|
||||
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1A ,
|
||||
(((mode->HTotal >> 3) & 0xC0 ) >> 2)
|
||||
| (((mode->VTotal - 2) & 0x300 ) >> 2));
|
||||
|
||||
width = fb_fix.line_length >> 3;
|
||||
if (fb_var.bits_per_pixel == 1)
|
||||
width <<= 2;
|
||||
if(width >= 0xFF)
|
||||
printk("FB_CIRRUS: Warning line size over the limit ... reduce bpp or width resolution");
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x13, width);
|
||||
/* Offset extension (see CR13) */
|
||||
temp = fb_cirrus_read_crt_reg( cirrus_board_ptr, 0x1B);
|
||||
temp &= 0xAF;
|
||||
temp |= (width >> (3+4)) & 0x10;
|
||||
temp |= (width >> (3+3)) & 0x40;
|
||||
temp |= 0x22;
|
||||
fb_cirrus_write_crt_reg( cirrus_board_ptr, 0x1B, temp);
|
||||
|
||||
/****************************************************
|
||||
* Sequential register
|
||||
* Enable linear mode and high-res packed pixel mode
|
||||
*/
|
||||
temp = fb_cirrus_read_seq_reg( cirrus_board_ptr, 0x07);
|
||||
temp &= 0xe0;
|
||||
switch (depthcode) {
|
||||
case 1:
|
||||
case 4:
|
||||
temp |= 0x10;
|
||||
break;
|
||||
case 8:
|
||||
temp |= 0x11;
|
||||
break;
|
||||
case 64+8:
|
||||
temp |= 0x17;
|
||||
break;
|
||||
case 15:
|
||||
temp |= 0x17;
|
||||
hdr = 0xC0; /* 5:5:5 Sierra */
|
||||
break;
|
||||
case 16:
|
||||
temp |= 0x17;
|
||||
hdr = 0xC1; /* 5:6:5 XGA mode */
|
||||
break;
|
||||
case 24:
|
||||
temp |= 0x15;
|
||||
hdr = 0xC5; /* 8:8:8 16M colors */
|
||||
break;
|
||||
case 32:
|
||||
temp |= 0x19;
|
||||
hdr = 0xC5; /* 8:8:8 16M colors */
|
||||
break;
|
||||
default:
|
||||
printk("FB_CIRRUS: Cannot Initialize display to requested mode\n");
|
||||
printk("FB_CIRRUS: returning RTEMS_UNSATISFIED on depthcode %d\n", depthcode);
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
fb_cirrus_write_seq_reg( cirrus_board_ptr, 0x07, temp);
|
||||
/* this just set packed pixel mode with according bpp */
|
||||
|
||||
/****************************************************
|
||||
* HDR Register
|
||||
*/
|
||||
if(hdr > 0)
|
||||
fb_cirrus_write_hdr_reg( cirrus_board_ptr, hdr);
|
||||
|
||||
/****************************************************
|
||||
* Graphic Data Controller Registers
|
||||
*/
|
||||
temp = fb_cirrus_read_gdc_reg( cirrus_board_ptr, 0x12);
|
||||
if (HDiv2)
|
||||
temp |= 0x20;
|
||||
else
|
||||
temp &= ~0x20;
|
||||
fb_cirrus_write_gdc_reg( cirrus_board_ptr, 0x12, temp);
|
||||
|
||||
/* Enable high-color modes */
|
||||
fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x05, 0x40);
|
||||
|
||||
/* VGA graphics mode */
|
||||
fb_cirrus_write_gdc_reg(cirrus_board_ptr, 0x06, 0x01);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cirrus_prepare_mode( void )
|
||||
{
|
||||
|
||||
active_mode = &available_modes[CIRRUS_DISPLAY_MODE];
|
||||
|
||||
fb_var.bits_per_pixel = CIRRUS_DEFAULT_BPP;
|
||||
|
||||
fb_var.xres = active_mode->HDisplay;
|
||||
fb_var.yres = active_mode->VDisplay;
|
||||
|
||||
fb_fix.line_length = (fb_var.xres * fb_var.bits_per_pixel + 7) / 8;
|
||||
|
||||
fb_fix.type = FB_TYPE_PACKED_PIXELS;
|
||||
fb_fix.visual = FB_VISUAL_TRUECOLOR;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* fb_cirrus device driver OPEN entry point
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
int r;
|
||||
uint32_t smem_start, regs_start;
|
||||
|
||||
if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) {
|
||||
printk( "FB_CIRRUS could not lock driver_mutex\n" );
|
||||
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
r = cirrus_pci_read(&cirrus_board_info, &smem_start, ®s_start);
|
||||
if ( r == RTEMS_UNSATISFIED )
|
||||
return RTEMS_UNSATISFIED;
|
||||
|
||||
fb_fix.smem_start = (volatile char *)smem_start;
|
||||
fb_fix.smem_len = 0x1000000;
|
||||
cirrus_board_info.reg_base = (void *)regs_start;
|
||||
|
||||
cirrus_prepare_mode();
|
||||
|
||||
cirrus_set_mode( active_mode );
|
||||
|
||||
cirrus_adjust_frame( &cirrus_board_info, 0, 0);
|
||||
|
||||
if (1) {
|
||||
uint32_t pixmask;
|
||||
int x, y;
|
||||
|
||||
if(fb_var.bits_per_pixel == 32)
|
||||
pixmask = 0xffffff;
|
||||
else
|
||||
pixmask = (1 << fb_var.bits_per_pixel) - 1;
|
||||
|
||||
printk("FB_CIRRUS: mode set, test patter output\n");
|
||||
|
||||
for(y = 0; y < fb_var.yres; y++) {
|
||||
for(x = 0; x < fb_var.xres; x++) {
|
||||
uint32_t color;
|
||||
char *addr = (char *)fb_fix.smem_start;
|
||||
addr += y * fb_fix.line_length;
|
||||
addr += x * fb_var.bits_per_pixel / 8;
|
||||
color = x & 1 ? 0 : y & 1 ? pixmask & 0x000ff00f : pixmask;
|
||||
if(y == fb_var.yres - 1) {
|
||||
if((x > 0) && (x < fb_var.xres-1))
|
||||
color = pixmask & 0x00555555;
|
||||
}
|
||||
switch (fb_var.bits_per_pixel) {
|
||||
case 8: *(volatile uint8_t*) addr = color;
|
||||
break;
|
||||
case 16: *(volatile uint16_t*) addr = color;
|
||||
break;
|
||||
case 24: *(volatile uint32_t*) addr =
|
||||
(*(volatile uint32_t*) addr & 0xff000000) | color;
|
||||
break;
|
||||
case 32: *(volatile uint32_t*) addr = color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* fb_cirrus device driver CLOSE entry point
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
|
||||
|
||||
/* restore previous state. for VGA this means return to text mode.
|
||||
* leave out if graphics hardware has been initialized in
|
||||
* frame_buffer_initialize() */
|
||||
|
||||
/* VGA text mode */
|
||||
fb_cirrus_write_gdc_reg(&cirrus_board_info, 0x06, 0x00);
|
||||
|
||||
printk( "FB_CIRRUS: close called.\n" );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fb_cirrus device driver READ entry point.
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
|
||||
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
|
||||
memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* frame_buffer device driver WRITE entry point.
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
|
||||
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
|
||||
memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int
|
||||
get_fix_screen_info( struct fb_fix_screeninfo *info )
|
||||
{
|
||||
*info = fb_fix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_var_screen_info( struct fb_var_screeninfo *info )
|
||||
{
|
||||
*info = fb_var;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IOCTL entry point -- This method is called to carry
|
||||
* all services of this interface.
|
||||
*/
|
||||
rtems_device_driver
|
||||
frame_buffer_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = arg;
|
||||
|
||||
printk( "FB_CIRRUS ioctl called, cmd=%x\n", args->command );
|
||||
|
||||
switch( args->command ) {
|
||||
case FBIOGET_FSCREENINFO:
|
||||
args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
|
||||
break;
|
||||
case FBIOGET_VSCREENINFO:
|
||||
args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
|
||||
break;
|
||||
case FBIOPUT_VSCREENINFO:
|
||||
/* not implemented yet */
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
case FBIOGETCMAP:
|
||||
/* no palette - truecolor mode */
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
case FBIOPUTCMAP:
|
||||
/* no palette - truecolor mode */
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
default:
|
||||
args->ioctl_return = 0;
|
||||
break;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
|
||||
*
|
||||
* MODULE DESCRIPTION:
|
||||
* This module implements FB driver for "Bare VGA". It uses the
|
||||
* routines for "bare hardware" found in vgainit.c.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <rtems/fb.h>
|
||||
#include <rtems/framebuffer.h>
|
||||
|
||||
#include <rtems/score/atomic.h>
|
||||
|
||||
/* these routines are defined in vgainit.c.*/
|
||||
extern void ega_hwinit( void );
|
||||
extern void ega_hwterm( void );
|
||||
|
||||
/* flag to limit driver to protect against multiple opens */
|
||||
static Atomic_Flag driver_mutex;
|
||||
|
||||
/* screen information for the VGA driver */
|
||||
static struct fb_var_screeninfo fb_var =
|
||||
{
|
||||
.xres = 640,
|
||||
.yres = 480,
|
||||
.bits_per_pixel = 4
|
||||
};
|
||||
|
||||
static struct fb_fix_screeninfo fb_fix =
|
||||
{
|
||||
.smem_start = (volatile char *)0xA0000, /* buffer pointer */
|
||||
.smem_len = 0x10000, /* buffer size */
|
||||
.type = FB_TYPE_VGA_PLANES, /* type of dsplay */
|
||||
.visual = FB_VISUAL_PSEUDOCOLOR, /* color scheme used */
|
||||
.line_length = 80 /* chars per line */
|
||||
};
|
||||
|
||||
|
||||
static uint16_t red16[] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
|
||||
0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
static uint16_t green16[] = {
|
||||
0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
|
||||
0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
|
||||
};
|
||||
static uint16_t blue16[] = {
|
||||
0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
|
||||
0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
|
||||
};
|
||||
|
||||
/* Functionality to support multiple VGA frame buffers can be added easily,
|
||||
* but is not supported at this moment because there is no need for two or
|
||||
* more "classic" VGA adapters. Multiple frame buffer drivers may be
|
||||
* implemented and If we had implement it they would be named as "/dev/fb0",
|
||||
* "/dev/fb1", "/dev/fb2" and so on.
|
||||
*/
|
||||
/*
|
||||
* fbvga device driver INITIALIZE entry point.
|
||||
*/
|
||||
rtems_device_driver frame_buffer_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
printk( "FBVGA -- driver initializing..\n" );
|
||||
|
||||
/*
|
||||
* Register the device
|
||||
*/
|
||||
status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME
|
||||
" FBVGA framebuffer device!\n");
|
||||
rtems_fatal_error_occurred( status );
|
||||
}
|
||||
|
||||
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbvga device driver OPEN entry point
|
||||
*/
|
||||
rtems_device_driver frame_buffer_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) {
|
||||
/* restore previous state. for VGA this means return to text mode.
|
||||
* leave out if graphics hardware has been initialized in
|
||||
* frame_buffer_initialize()
|
||||
*/
|
||||
ega_hwinit();
|
||||
printk( "FBVGA open called.\n" );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbvga device driver CLOSE entry point
|
||||
*/
|
||||
rtems_device_driver frame_buffer_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
_Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
|
||||
/* restore previous state. for VGA this means return to text mode.
|
||||
* leave out if graphics hardware has been initialized in
|
||||
* frame_buffer_initialize() */
|
||||
ega_hwterm();
|
||||
printk( "FBVGA close called.\n" );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
/*
|
||||
* fbvga device driver READ entry point.
|
||||
*/
|
||||
rtems_device_driver frame_buffer_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
|
||||
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
|
||||
memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* frame_buffer device driver WRITE entry point.
|
||||
*/
|
||||
rtems_device_driver frame_buffer_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
|
||||
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
|
||||
memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int get_fix_screen_info( struct fb_fix_screeninfo *info )
|
||||
{
|
||||
*info = fb_fix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_var_screen_info( struct fb_var_screeninfo *info )
|
||||
{
|
||||
*info = fb_var;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_palette( struct fb_cmap *cmap )
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if ( cmap->start + cmap->len >= 16 )
|
||||
return 1;
|
||||
|
||||
for( i = 0; i < cmap->len; i++ ) {
|
||||
cmap->red[ cmap->start + i ] = red16[ cmap->start + i ];
|
||||
cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
|
||||
cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_palette( struct fb_cmap *cmap )
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if ( cmap->start + cmap->len >= 16 )
|
||||
return 1;
|
||||
|
||||
for( i = 0; i < cmap->len; i++ ) {
|
||||
red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
|
||||
green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
|
||||
blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IOCTL entry point -- This method is called to carry
|
||||
* all services of this interface.
|
||||
*/
|
||||
rtems_device_driver frame_buffer_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = arg;
|
||||
|
||||
printk( "FBVGA ioctl called, cmd=%x\n", args->command );
|
||||
|
||||
switch( args->command ) {
|
||||
case FBIOGET_FSCREENINFO:
|
||||
args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
|
||||
break;
|
||||
case FBIOGET_VSCREENINFO:
|
||||
args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
|
||||
break;
|
||||
case FBIOPUT_VSCREENINFO:
|
||||
/* not implemented yet*/
|
||||
args->ioctl_return = -1;
|
||||
return RTEMS_UNSATISFIED;
|
||||
case FBIOGETCMAP:
|
||||
args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer );
|
||||
break;
|
||||
case FBIOPUTCMAP:
|
||||
args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer );
|
||||
break;
|
||||
|
||||
default:
|
||||
args->ioctl_return = 0;
|
||||
break;
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup GDB
|
||||
*
|
||||
* @brief pc386 gdb select
|
||||
*
|
||||
* This file contains a routine to enable and select the UART the gdb stub
|
||||
* connects too. Currently limited to COM1 and COM2. See
|
||||
* shared/comm/i386-stub-glue.c file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 2016.
|
||||
* Chris Johns <chrisj@rtems.org>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
#include <bsp/bspimpl.h>
|
||||
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
/*
|
||||
* Used in the stub to print output.
|
||||
*/
|
||||
int remote_debug;
|
||||
/*
|
||||
* Defined in the stub, used here.
|
||||
*/
|
||||
void set_debug_traps(void);
|
||||
|
||||
/*
|
||||
* Added here to get a valid baudrate. Needs to go once we
|
||||
* move to the standard UART driver.
|
||||
*/
|
||||
int BSPBaseBaud;
|
||||
|
||||
static bool gdb_port_probe(int minor)
|
||||
{
|
||||
/* Return false as GDB has claimed the port */
|
||||
return false;
|
||||
}
|
||||
|
||||
void pc386_parse_gdb_arguments(void)
|
||||
{
|
||||
static const char *opt;
|
||||
|
||||
/*
|
||||
* Check the command line to see if com1-com4 are disabled.
|
||||
*/
|
||||
opt = bsp_cmdline_arg("--gdb=");
|
||||
if ( opt ) {
|
||||
const char *option;
|
||||
const char *comma;
|
||||
size_t length;
|
||||
size_t index;
|
||||
rtems_device_minor_number minor;
|
||||
uint32_t baudrate = 115200;
|
||||
bool halt = false;
|
||||
console_tbl *port;
|
||||
|
||||
/*
|
||||
* Fine the length, there can be more command line visible.
|
||||
*/
|
||||
length = 0;
|
||||
while ((opt[length] != ' ') && (opt[length] != '\0')) {
|
||||
++length;
|
||||
if (length > NAME_MAX) {
|
||||
printk("invalid option (--gdb): too long\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only match up to a comma or NULL
|
||||
*/
|
||||
index = 0;
|
||||
while ((opt[index] != '=') && (index < length)) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (opt[index] != '=') {
|
||||
printk("invalid option (--gdb): no equals\n");
|
||||
return;
|
||||
}
|
||||
|
||||
++index;
|
||||
option = &opt[index];
|
||||
|
||||
while ((opt[index] != ',') && (index < length)) {
|
||||
++index;
|
||||
}
|
||||
|
||||
if (opt[index] == ',')
|
||||
comma = &opt[index];
|
||||
else
|
||||
comma = NULL;
|
||||
|
||||
length = &opt[index] - option;
|
||||
|
||||
port = console_find_console_entry( option, length, &minor );
|
||||
|
||||
if ( port == NULL ) {
|
||||
printk("invalid option (--gdb): port not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (comma) {
|
||||
option = comma + 1;
|
||||
baudrate = strtoul(option, 0, 10);
|
||||
switch (baudrate) {
|
||||
case 115200:
|
||||
case 57600:
|
||||
case 38400:
|
||||
case 19200:
|
||||
case 9600:
|
||||
case 4800:
|
||||
port->pDeviceParams = (void*) baudrate;
|
||||
BSPBaseBaud = baudrate; /* REMOVE ME */
|
||||
break;
|
||||
default:
|
||||
printk("invalid option (--gdb): bad baudrate\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide a probe that fails so the device is not part of termios. All
|
||||
* functions are polling.
|
||||
*/
|
||||
port->deviceProbe = gdb_port_probe;
|
||||
port->pDeviceFns = &ns16550_fns_polled;
|
||||
|
||||
opt = bsp_cmdline_arg("--gdb-remote-debug");
|
||||
if ( opt ) {
|
||||
remote_debug = 1;
|
||||
}
|
||||
|
||||
opt = bsp_cmdline_arg("--gdb-break");
|
||||
if ( opt ) {
|
||||
halt = true;
|
||||
}
|
||||
|
||||
printk("GDB stub: enable %s%s%s\n",
|
||||
port->sDeviceName,
|
||||
remote_debug ? ", remote-debug" : "",
|
||||
halt ? ", halting" : "");
|
||||
|
||||
i386_stub_glue_init(minor);
|
||||
set_debug_traps();
|
||||
i386_stub_glue_init_breakin();
|
||||
|
||||
if ( halt ) {
|
||||
printk("GDB stub: waiting for remote connection..\n");
|
||||
breakpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup i386_pc386
|
||||
*
|
||||
* @brief I386 keyboard definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* linux/include/asm-i386/keyboard.h
|
||||
*
|
||||
* Created 3 Nov 1996 by Geert Uytterhoeven
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the i386 architecture specific keyboard definitions
|
||||
*/
|
||||
|
||||
#ifndef _I386_KEYBOARD_H
|
||||
#define _I386_KEYBOARD_H
|
||||
|
||||
#include <i386_io.h>
|
||||
|
||||
#define KEYBOARD_IRQ 1
|
||||
#define DISABLE_KBD_DURING_INTERRUPTS 0
|
||||
|
||||
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
|
||||
extern int pckbd_getkeycode(unsigned int scancode);
|
||||
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
|
||||
char raw_mode);
|
||||
extern char pckbd_unexpected_up(unsigned char keycode);
|
||||
extern void pckbd_leds(unsigned char leds);
|
||||
extern void pckbd_init_hw(void);
|
||||
extern unsigned char pckbd_sysrq_xlate[128];
|
||||
|
||||
#define kbd_setkeycode pckbd_setkeycode
|
||||
#define kbd_getkeycode pckbd_getkeycode
|
||||
#define kbd_translate pckbd_translate
|
||||
#define kbd_unexpected_up pckbd_unexpected_up
|
||||
#define kbd_leds pckbd_leds
|
||||
#define kbd_init_hw pckbd_init_hw
|
||||
#define kbd_sysrq_xlate pckbd_sysrq_xlate
|
||||
|
||||
#define SYSRQ_KEY 0x54
|
||||
|
||||
/* resource allocation */
|
||||
#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */
|
||||
#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */
|
||||
|
||||
/* How to access the keyboard macros on this platform. */
|
||||
#define kbd_read_input() inb(KBD_DATA_REG)
|
||||
#define kbd_read_status() inb(KBD_STATUS_REG)
|
||||
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
|
||||
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
|
||||
|
||||
/* Some stoneage hardware needs delays after some operations. */
|
||||
#define kbd_pause() do { } while(0)
|
||||
|
||||
/*
|
||||
* Machine specific bits for the PS/2 driver
|
||||
*/
|
||||
|
||||
#define AUX_IRQ 12
|
||||
|
||||
#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */
|
||||
|
||||
#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */
|
||||
|
||||
/*
|
||||
* include/linux/pc_keyb.h
|
||||
*
|
||||
* PC Keyboard And Keyboard Controller
|
||||
*
|
||||
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configuration Switches
|
||||
*/
|
||||
|
||||
#undef KBD_REPORT_ERR /* Report keyboard errors */
|
||||
#define KBD_REPORT_UNKN /* Report unknown scan codes */
|
||||
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
|
||||
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
|
||||
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
|
||||
|
||||
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
|
||||
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
|
||||
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
|
||||
|
||||
/*
|
||||
* Internal variables of the driver
|
||||
*/
|
||||
|
||||
extern unsigned char pckbd_read_mask;
|
||||
extern unsigned char aux_device_present;
|
||||
|
||||
/*
|
||||
* Keyboard Controller Registers on normal PCs.
|
||||
*/
|
||||
|
||||
#define KBD_STATUS_REG 0x64 /* Status register (R) */
|
||||
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
|
||||
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
|
||||
|
||||
/*
|
||||
* Keyboard Controller Commands
|
||||
*/
|
||||
|
||||
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
|
||||
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
|
||||
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
|
||||
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
|
||||
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
|
||||
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
|
||||
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
|
||||
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
|
||||
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
|
||||
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
|
||||
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
|
||||
initiated by the auxiliary device */
|
||||
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
|
||||
|
||||
/*
|
||||
* Keyboard Commands
|
||||
*/
|
||||
|
||||
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
|
||||
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
|
||||
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
|
||||
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
|
||||
#define KBD_CMD_RESET 0xFF /* Reset */
|
||||
|
||||
/*
|
||||
* Keyboard Replies
|
||||
*/
|
||||
|
||||
#define KBD_REPLY_POR 0xAA /* Power on reset */
|
||||
#define KBD_REPLY_ACK 0xFA /* Command ACK */
|
||||
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
|
||||
|
||||
/*
|
||||
* Status Register Bits
|
||||
*/
|
||||
|
||||
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
|
||||
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
|
||||
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
|
||||
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
|
||||
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
|
||||
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
|
||||
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
|
||||
#define KBD_STAT_PERR 0x80 /* Parity error */
|
||||
|
||||
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
|
||||
|
||||
/*
|
||||
* Controller Mode Register Bits
|
||||
*/
|
||||
|
||||
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
|
||||
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
|
||||
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
|
||||
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
|
||||
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
|
||||
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
|
||||
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
|
||||
#define KBD_MODE_RFU 0x80
|
||||
|
||||
/*
|
||||
* Mouse Commands
|
||||
*/
|
||||
|
||||
#define AUX_SET_RES 0xE8 /* Set resolution */
|
||||
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
|
||||
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
|
||||
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
|
||||
#define AUX_SET_STREAM 0xEA /* Set stream mode */
|
||||
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
|
||||
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
|
||||
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
|
||||
#define AUX_RESET 0xFF /* Reset aux device */
|
||||
#define AUX_ACK 0xFA /* Command byte ACK. */
|
||||
|
||||
#define AUX_BUF_SIZE 2048 /* This might be better divisible by
|
||||
three to make overruns stay in sync
|
||||
but then the read function would need
|
||||
a lock etc - ick */
|
||||
|
||||
#define mark_bh(x)
|
||||
|
||||
#endif /* _I386_KEYBOARD_H */
|
||||
@@ -1,300 +0,0 @@
|
||||
/*-------------------------------------------------------------------------+
|
||||
| inch.c v1.1 - PC386 BSP - 1997/08/07
|
||||
+--------------------------------------------------------------------------+
|
||||
| (C) Copyright 1997 -
|
||||
| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
||||
|
|
||||
| http://pandora.ist.utl.pt
|
||||
|
|
||||
| Instituto Superior Tecnico * Lisboa * PORTUGAL
|
||||
+--------------------------------------------------------------------------+
|
||||
| Disclaimer:
|
||||
|
|
||||
| This file is provided "AS IS" without warranty of any kind, either
|
||||
| expressed or implied.
|
||||
+--------------------------------------------------------------------------+
|
||||
| This code is based on:
|
||||
| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP
|
||||
| With the following copyright notice:
|
||||
| With the following copyright notice:
|
||||
| **************************************************************************
|
||||
| * COPYRIGHT (c) 1989-1998.
|
||||
| * On-Line Applications Research Corporation (OAR).
|
||||
| *
|
||||
| * The license and distribution terms for this file may be
|
||||
| * found in the file LICENSE in this distribution or at
|
||||
| * http://www.rtems.org/license/LICENSE.
|
||||
| **************************************************************************
|
||||
+--------------------------------------------------------------------------*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/bootcard.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Constants
|
||||
+--------------------------------------------------------------------------*/
|
||||
#define KBD_CTL 0x61 /* -------------------------------- */
|
||||
#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
|
||||
#define KBD_STATUS 0x64 /* -------------------------------- */
|
||||
|
||||
#define KBD_BUF_SIZE 256
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Global Variables
|
||||
+--------------------------------------------------------------------------*/
|
||||
static char key_map[] =
|
||||
{
|
||||
0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
|
||||
'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
|
||||
'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
|
||||
0134,'z','x','c','v','b','n','m',',','.','/',0x80,
|
||||
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,'0',0177
|
||||
}; /* Keyboard scancode -> character map with no modifiers. */
|
||||
|
||||
static char shift_map[] =
|
||||
{
|
||||
0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
|
||||
'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
|
||||
'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
|
||||
'|','Z','X','C','V','B','N','M','<','>','?',0x80,
|
||||
'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
|
||||
0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
|
||||
'1','2','3','0',177
|
||||
}; /* Keyboard scancode -> character map with SHIFT key modifier. */
|
||||
|
||||
static unsigned short kbd_buffer[KBD_BUF_SIZE];
|
||||
static uint16_t kbd_first = 0;
|
||||
static uint16_t kbd_last = 0;
|
||||
static uint16_t kbd_end = KBD_BUF_SIZE - 1;
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _IBMPC_scankey
|
||||
| Description: This function can be called during a poll for input, or by
|
||||
| an ISR. Basically any time you want to process a keypress.
|
||||
| Global Variables: key_map, shift_map.
|
||||
| Arguments: outChar - character read in case of a valid reading,
|
||||
| otherwise unchanged.
|
||||
| Returns: TRUE in case a valid character has been read,
|
||||
| FALSE otherwise.
|
||||
+--------------------------------------------------------------------------*/
|
||||
static bool
|
||||
_IBMPC_scankey(char *outChar)
|
||||
{
|
||||
unsigned char inChar;
|
||||
static int alt_pressed = 0;
|
||||
static int ctrl_pressed = 0;
|
||||
static int shift_pressed = 0;
|
||||
static int caps_pressed = 0;
|
||||
static int extended = 0;
|
||||
|
||||
*outChar = '\0'; /* default value if we return false */
|
||||
|
||||
/* Read keyboard controller, toggle enable */
|
||||
inport_byte(KBD_CTL, inChar);
|
||||
outport_byte(KBD_CTL, inChar & ~0x80);
|
||||
outport_byte(KBD_CTL, inChar | 0x80);
|
||||
outport_byte(KBD_CTL, inChar & ~0x80);
|
||||
|
||||
/* See if it has data */
|
||||
inport_byte(KBD_STATUS, inChar);
|
||||
if ((inChar & 0x01) == 0)
|
||||
return false;
|
||||
|
||||
/* Read the data. Handle nonsense with shift, control, etc. */
|
||||
inport_byte(KBD_DATA, inChar);
|
||||
|
||||
if (extended)
|
||||
extended--;
|
||||
|
||||
switch (inChar)
|
||||
{
|
||||
case 0xe0:
|
||||
extended = 2;
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0x38:
|
||||
alt_pressed = 1;
|
||||
return false;
|
||||
break;
|
||||
case 0xb8:
|
||||
alt_pressed = 0;
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0x1d:
|
||||
ctrl_pressed = 1;
|
||||
return false;
|
||||
break;
|
||||
case 0x9d:
|
||||
ctrl_pressed = 0;
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0x2a:
|
||||
if (extended)
|
||||
return false;
|
||||
case 0x36:
|
||||
shift_pressed = 1;
|
||||
return false;
|
||||
break;
|
||||
case 0xaa:
|
||||
if (extended)
|
||||
return false;
|
||||
case 0xb6:
|
||||
shift_pressed = 0;
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0x3a:
|
||||
caps_pressed = 1;
|
||||
return false;
|
||||
break;
|
||||
case 0xba:
|
||||
caps_pressed = 0;
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
if (ctrl_pressed && alt_pressed)
|
||||
bsp_reset(); /* ctrl+alt+del -> reboot */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Ignore unrecognized keys--usually arrow and such
|
||||
*/
|
||||
default:
|
||||
if ((inChar & 0x80) || (inChar > 0x39))
|
||||
/* High-bit on means key is being released, not pressed */
|
||||
return false;
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
/* Strip high bit, look up in our map */
|
||||
inChar &= 0x7f;
|
||||
if (ctrl_pressed)
|
||||
{
|
||||
*outChar = key_map[inChar];
|
||||
*outChar &= 037;
|
||||
}
|
||||
else
|
||||
{
|
||||
*outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
|
||||
if (caps_pressed)
|
||||
{
|
||||
if (*outChar >= 'A' && *outChar <= 'Z')
|
||||
*outChar += 'a' - 'A';
|
||||
else if (*outChar >= 'a' && *outChar <= 'z')
|
||||
*outChar -= 'a' - 'A';
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* _IBMPC_scankey */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _IBMPC_chrdy
|
||||
| Description: Check keyboard ISR buffer and return character if not empty.
|
||||
| Global Variables: kbd_buffer, kbd_first, kbd_last.
|
||||
| Arguments: c - character read if keyboard buffer not empty, otherwise
|
||||
| unchanged.
|
||||
| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
|
||||
+--------------------------------------------------------------------------*/
|
||||
static bool
|
||||
_IBMPC_chrdy(char *c)
|
||||
{
|
||||
#if CCJ_REMOVED_NO_IDEA_ABOUT_THIS_CODE_OR_COMMENT
|
||||
/* FIX ME!!! It doesn't work without something like the following line.
|
||||
Find out why! */
|
||||
printk("");
|
||||
#endif
|
||||
|
||||
/* Check buffer our ISR builds */
|
||||
if (kbd_first != kbd_last)
|
||||
{
|
||||
*c = kbd_buffer[kbd_first];
|
||||
|
||||
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
} /* _IBMPC_chrdy */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _IBMPC_inch
|
||||
| Description: Poll keyboard until a character is ready and return it.
|
||||
| Global Variables: None.
|
||||
| Arguments: None.
|
||||
| Returns: character read from keyboard.
|
||||
+--------------------------------------------------------------------------*/
|
||||
char
|
||||
_IBMPC_inch(void)
|
||||
{
|
||||
char c;
|
||||
while (!_IBMPC_chrdy(&c))
|
||||
continue;
|
||||
|
||||
return c;
|
||||
} /* _IBMPC_inch */
|
||||
|
||||
/*
|
||||
* Routine that can be used before interrupt management is initialized.
|
||||
*/
|
||||
int BSP_wait_polled_input(void)
|
||||
{
|
||||
char c;
|
||||
while (!_IBMPC_scankey(&c))
|
||||
continue;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a key has been pressed. This is a non-destructive
|
||||
* call, meaning, it keeps the key in the buffer.
|
||||
*/
|
||||
int rtems_kbpoll( void )
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* The locking or disable of interrupts does not help
|
||||
* there because if interrupts are enabled after leave of this
|
||||
* function the state can change without notice anyway.
|
||||
*/
|
||||
RTEMS_COMPILER_MEMORY_BARRIER();
|
||||
|
||||
rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
|
||||
|
||||
RTEMS_COMPILER_MEMORY_BARRIER();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int getch( void )
|
||||
{
|
||||
int c;
|
||||
|
||||
while( kbd_first == kbd_last )
|
||||
{
|
||||
rtems_task_wake_after( 10 );
|
||||
}
|
||||
c = kbd_buffer[ kbd_first ];
|
||||
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
|
||||
return c;
|
||||
}
|
||||
|
||||
void add_to_queue( unsigned short b )
|
||||
{
|
||||
unsigned int next;
|
||||
kbd_buffer[ kbd_last ] = b;
|
||||
next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
|
||||
if( next != kbd_first )
|
||||
{
|
||||
kbd_last = next;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* The contents of this file were formerly in console.c which
|
||||
* had the following copyright notice:
|
||||
*
|
||||
* (C) Copyright 1997
|
||||
* NavIST Group - Real-Time Distributed Systems and Industrial Automation
|
||||
* http://pandora.ist.utl.pt
|
||||
* Instituto Superior Tecnico * Lisboa * PORTUGAL
|
||||
*
|
||||
* The original code and subsequent modifications are:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/keyboard.h>
|
||||
#include <rtems/mw_uid.h>
|
||||
|
||||
/* adds a kbd message to the queue */
|
||||
static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods )
|
||||
{
|
||||
struct MW_UID_MESSAGE m;
|
||||
struct kbd_struct * kbd = (struct kbd_struct *)ptr;
|
||||
|
||||
m.type = MV_UID_KBD;
|
||||
m.m.kbd.code = keycode;
|
||||
m.m.kbd.modifiers = kbd->ledflagstate;
|
||||
m.m.kbd.mode = kbd->kbdmode;
|
||||
/* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */
|
||||
|
||||
uid_send_message( &m );
|
||||
}
|
||||
|
||||
void register_kbd_msg_queue( char *q_name, int port )
|
||||
{
|
||||
kbd_set_driver_handler( kbd_parser );
|
||||
}
|
||||
|
||||
void unregister_kbd_msg_queue( int port )
|
||||
{
|
||||
kbd_set_driver_handler( NULL );
|
||||
}
|
||||
@@ -1,881 +0,0 @@
|
||||
/*
|
||||
* Rosimildo da Silva: rdasilva@connecttel.com
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <rtems/keyboard.h>
|
||||
#include "i386kbd.h"
|
||||
#include <rtems/kd.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/bootcard.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
#ifndef KBD_DEFMODE
|
||||
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
|
||||
#endif
|
||||
|
||||
#ifndef KBD_DEFLEDS
|
||||
/*
|
||||
* Some laptops take the 789uiojklm,. keys as number pad when NumLock
|
||||
* is on. This seems a good reason to start with NumLock off.
|
||||
*/
|
||||
#define KBD_DEFLEDS 0
|
||||
#endif
|
||||
|
||||
#ifndef KBD_DEFLOCK
|
||||
#define KBD_DEFLOCK 0
|
||||
#endif
|
||||
|
||||
static int kbd_test_and_set_bit(int nr, atomic_uint_least32_t * addr)
|
||||
{
|
||||
uint_least32_t mask;
|
||||
int retval;
|
||||
|
||||
addr += nr >> 5;
|
||||
mask = 1UL << (nr & 0x1f);
|
||||
|
||||
retval = (atomic_fetch_or(addr, mask) & mask) != 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kbd_test_and_clear_bit(int nr, atomic_uint_least32_t * addr)
|
||||
{
|
||||
uint_least32_t mask;
|
||||
int retval;
|
||||
|
||||
addr += nr >> 5;
|
||||
mask = 1UL << (nr & 0x1f);
|
||||
|
||||
retval = (atomic_fetch_and(addr, ~mask) & mask) != 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kbd_test_bit(int nr, atomic_uint_least32_t * addr)
|
||||
{
|
||||
unsigned long mask;
|
||||
|
||||
addr += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
return ((mask & atomic_load(addr)) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* global state includes the following, and various static variables
|
||||
* in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
|
||||
* (last_console is now a global variable)
|
||||
*/
|
||||
#define KBD_BITS_PER_ELEMENT (sizeof(atomic_uint_least32_t)*CHAR_BIT)
|
||||
|
||||
/* shift state counters.. */
|
||||
static unsigned char k_down[NR_SHIFT] = {0, };
|
||||
/* keyboard key bitmap */
|
||||
static atomic_uint_least32_t
|
||||
key_down[(256 + KBD_BITS_PER_ELEMENT - 1) / KBD_BITS_PER_ELEMENT] = { 0, };
|
||||
|
||||
static int dead_key_next = 0;
|
||||
/*
|
||||
* In order to retrieve the shift_state (for the mouse server), either
|
||||
* the variable must be global, or a new procedure must be created to
|
||||
* return the value. I chose the former way.
|
||||
*/
|
||||
int shift_state = 0;
|
||||
static int npadch = -1; /* -1 or number assembled on pad */
|
||||
static unsigned char diacr = 0;
|
||||
static char rep = 0; /* flag telling character repeat */
|
||||
|
||||
/* default console for RTEMS */
|
||||
static int fg_console = 0;
|
||||
|
||||
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
|
||||
static struct kbd_struct * kbd = kbd_table;
|
||||
|
||||
void compute_shiftstate(void);
|
||||
|
||||
typedef void (*k_hand)(unsigned char value, char up_flag);
|
||||
typedef void (k_handfn)(unsigned char value, char up_flag);
|
||||
|
||||
static k_handfn
|
||||
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
|
||||
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
|
||||
do_ignore;
|
||||
|
||||
static k_hand key_handler[16] = {
|
||||
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
|
||||
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
|
||||
do_ignore, do_ignore
|
||||
};
|
||||
|
||||
/* Key types processed even in raw modes */
|
||||
|
||||
#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
|
||||
|
||||
typedef void (*void_fnp)(void);
|
||||
typedef void (void_fn)(void);
|
||||
|
||||
static void show_mem(void)
|
||||
{
|
||||
}
|
||||
static void show_state(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
|
||||
num, hold, scroll_forw, scroll_back, caps_on, compose,
|
||||
SAK, decr_console, incr_console, spawn_console, bare_num;
|
||||
|
||||
static void_fnp spec_fn_table[] = {
|
||||
do_null, enter, show_ptregs, show_mem,
|
||||
show_state, send_intr, lastcons, caps_toggle,
|
||||
num, hold, scroll_forw, scroll_back,
|
||||
bsp_reset, caps_on, compose, SAK,
|
||||
decr_console, incr_console, spawn_console, bare_num
|
||||
};
|
||||
|
||||
#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK))
|
||||
|
||||
/* maximum values each key_handler can handle */
|
||||
const int max_vals[] = {
|
||||
255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
|
||||
NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
|
||||
255, NR_ASCII - 1, NR_LOCK - 1, 255,
|
||||
NR_LOCK - 1, 255
|
||||
};
|
||||
|
||||
const int NR_TYPES = SIZE(max_vals);
|
||||
|
||||
/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
|
||||
static void put_queue(int);
|
||||
static unsigned char handle_diacr(unsigned char);
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
static int sysrq_pressed;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Many other routines do put_queue, but I think either
|
||||
* they produce ASCII, or they produce some user-assigned
|
||||
* string, and in both cases we might assume that it is
|
||||
* in utf-8 already.
|
||||
*/
|
||||
static void to_utf8(ushort c)
|
||||
{
|
||||
if (c < 0x80)
|
||||
put_queue(c); /* 0******* */
|
||||
else if (c < 0x800) {
|
||||
put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */
|
||||
put_queue(0x80 | (c & 0x3f));
|
||||
} else {
|
||||
put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
|
||||
put_queue(0x80 | ((c >> 6) & 0x3f));
|
||||
put_queue(0x80 | (c & 0x3f));
|
||||
}
|
||||
/* UTF-8 is defined for words of up to 31 bits,
|
||||
but we need only 16 bits here */
|
||||
}
|
||||
|
||||
/*
|
||||
* Translation of escaped scancodes to keycodes.
|
||||
* This is now user-settable (for machines were it makes sense).
|
||||
*/
|
||||
|
||||
int setkeycode(unsigned int scancode, unsigned int keycode)
|
||||
{
|
||||
return kbd_setkeycode(scancode, keycode);
|
||||
}
|
||||
|
||||
int getkeycode(unsigned int scancode)
|
||||
{
|
||||
return kbd_getkeycode(scancode);
|
||||
}
|
||||
|
||||
void handle_scancode(unsigned char scancode, int down)
|
||||
{
|
||||
unsigned char keycode;
|
||||
char up_flag = down ? 0 : 0200;
|
||||
char raw_mode;
|
||||
|
||||
mark_bh(CONSOLE_BH);
|
||||
|
||||
#if 0
|
||||
tty = ttytab? ttytab[fg_console]: NULL;
|
||||
if (tty && (!tty->driver_data)) {
|
||||
/*
|
||||
* We touch the tty structure via the the ttytab array
|
||||
* without knowing whether or not tty is open, which
|
||||
* is inherently dangerous. We currently rely on that
|
||||
* fact that console_open sets tty->driver_data when
|
||||
* it opens it, and clears it when it closes it.
|
||||
*/
|
||||
tty = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
kbd = kbd_table + fg_console;
|
||||
if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
|
||||
put_queue(scancode | up_flag);
|
||||
/* we do not return yet, because we want to maintain
|
||||
the key_down array, so that we have the correct
|
||||
values when finishing RAW mode or when changing VT's */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert scancode to keycode
|
||||
*/
|
||||
if (!kbd_translate(scancode, &keycode, raw_mode))
|
||||
return;
|
||||
|
||||
/*
|
||||
* At this point the variable `keycode' contains the keycode.
|
||||
* Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
|
||||
* We keep track of the up/down status of the key, and
|
||||
* return the keycode if in MEDIUMRAW mode.
|
||||
*/
|
||||
|
||||
if (up_flag) {
|
||||
rep = 0;
|
||||
if(!kbd_test_and_clear_bit(keycode, key_down))
|
||||
up_flag = kbd_unexpected_up(keycode);
|
||||
} else
|
||||
rep = kbd_test_and_set_bit(keycode, key_down);
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
|
||||
if (keycode == SYSRQ_KEY) {
|
||||
sysrq_pressed = !up_flag;
|
||||
return;
|
||||
} else if (sysrq_pressed) {
|
||||
if (!up_flag && sysrq_enabled)
|
||||
handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (kbd->kbdmode == VC_MEDIUMRAW) {
|
||||
/* soon keycodes will require more than one byte */
|
||||
put_queue(keycode + up_flag);
|
||||
raw_mode = 1; /* Most key classes will be ignored */
|
||||
}
|
||||
/*
|
||||
* Small change in philosophy: earlier we defined repetition by
|
||||
* rep = keycode == prev_keycode;
|
||||
* prev_keycode = keycode;
|
||||
* but now by the fact that the depressed key was down already.
|
||||
* Does this ever make a difference? Yes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Repeat a key only if the input buffers are empty or the
|
||||
* characters get echoed locally. This makes key repeat usable
|
||||
* with slow applications and under heavy loads.
|
||||
*/
|
||||
if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) {
|
||||
/*
|
||||
|| (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
|
||||
(L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
|
||||
*/
|
||||
u_short keysym;
|
||||
u_char type;
|
||||
|
||||
/* the XOR below used to be an OR */
|
||||
int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
|
||||
ushort *key_map = key_maps[shift_final];
|
||||
|
||||
if (key_map != NULL) {
|
||||
keysym = key_map[keycode];
|
||||
type = KTYP(keysym);
|
||||
|
||||
if (type >= 0xf0) {
|
||||
type -= 0xf0;
|
||||
if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
|
||||
return;
|
||||
if (type == KT_LETTER) {
|
||||
type = KT_LATIN;
|
||||
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
|
||||
key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
|
||||
if (key_map)
|
||||
keysym = key_map[keycode];
|
||||
}
|
||||
}
|
||||
|
||||
(*key_handler[type])(keysym & 0xff, up_flag);
|
||||
|
||||
if (type != KT_SLOCK)
|
||||
kbd->slockstate = 0;
|
||||
|
||||
} else {
|
||||
/* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
|
||||
if (!up_flag && !raw_mode)
|
||||
to_utf8(keysym);
|
||||
}
|
||||
} else {
|
||||
/* maybe beep? */
|
||||
/* we have at least to update shift_state */
|
||||
#if 1 /* how? two almost equivalent choices follow */
|
||||
compute_shiftstate();
|
||||
#else
|
||||
keysym = U(plain_map[keycode]);
|
||||
type = KTYP(keysym);
|
||||
if (type == KT_SHIFT)
|
||||
(*key_handler[type])(keysym & 0xff, up_flag);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0;
|
||||
/*
|
||||
*/
|
||||
void kbd_set_driver_handler(
|
||||
void ( *handler )( void *, unsigned short, unsigned long )
|
||||
)
|
||||
{
|
||||
driver_input_handler_kbd = handler;
|
||||
}
|
||||
|
||||
static void put_queue(int ch)
|
||||
{
|
||||
if ( driver_input_handler_kbd ) {
|
||||
driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 );
|
||||
} else {
|
||||
add_to_queue( ch );
|
||||
}
|
||||
}
|
||||
|
||||
static void puts_queue(char *cp)
|
||||
{
|
||||
while (*cp) {
|
||||
put_queue( *cp );
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void applkey(int key, char mode)
|
||||
{
|
||||
static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
|
||||
|
||||
buf[1] = (mode ? 'O' : '[');
|
||||
buf[2] = key;
|
||||
puts_queue(buf);
|
||||
}
|
||||
|
||||
static void enter(void)
|
||||
{
|
||||
if (diacr) {
|
||||
put_queue(diacr);
|
||||
diacr = 0;
|
||||
}
|
||||
put_queue(13);
|
||||
|
||||
if (vc_kbd_mode(kbd,VC_CRLF))
|
||||
put_queue(10);
|
||||
}
|
||||
|
||||
static void caps_toggle(void)
|
||||
{
|
||||
if (rep)
|
||||
return;
|
||||
chg_vc_kbd_led(kbd, VC_CAPSLOCK);
|
||||
}
|
||||
|
||||
static void caps_on(void)
|
||||
{
|
||||
if (rep)
|
||||
return;
|
||||
set_vc_kbd_led(kbd, VC_CAPSLOCK);
|
||||
}
|
||||
|
||||
static void show_ptregs(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void hold(void)
|
||||
{
|
||||
if (rep )
|
||||
return;
|
||||
chg_vc_kbd_led(kbd, VC_SCROLLOCK );
|
||||
}
|
||||
|
||||
static void num(void)
|
||||
{
|
||||
if (vc_kbd_mode(kbd,VC_APPLIC))
|
||||
applkey('P', 1);
|
||||
else
|
||||
bare_num();
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind this to Shift-NumLock if you work in application keypad mode
|
||||
* but want to be able to change the NumLock flag.
|
||||
* Bind this to NumLock if you prefer that the NumLock key always
|
||||
* changes the NumLock flag.
|
||||
*/
|
||||
static void bare_num(void)
|
||||
{
|
||||
if (!rep)
|
||||
chg_vc_kbd_led(kbd,VC_NUMLOCK);
|
||||
}
|
||||
|
||||
static void lastcons(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void decr_console(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void incr_console(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void send_intr(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void scroll_forw(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void scroll_back(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void compose(void)
|
||||
{
|
||||
dead_key_next = 1;
|
||||
}
|
||||
|
||||
int spawnpid, spawnsig;
|
||||
|
||||
static void spawn_console(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void SAK(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_ignore(unsigned char value, char up_flag)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_null()
|
||||
{
|
||||
compute_shiftstate();
|
||||
}
|
||||
|
||||
static void do_spec(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
if (value >= SIZE(spec_fn_table))
|
||||
return;
|
||||
|
||||
if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
|
||||
!(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
|
||||
return;
|
||||
|
||||
spec_fn_table[value]();
|
||||
}
|
||||
|
||||
static void do_lowercase(unsigned char value, char up_flag)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_self(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return; /* no action, if this is a key release */
|
||||
|
||||
if (diacr)
|
||||
value = handle_diacr(value);
|
||||
|
||||
if (dead_key_next) {
|
||||
dead_key_next = 0;
|
||||
diacr = value;
|
||||
return;
|
||||
}
|
||||
put_queue(value);
|
||||
}
|
||||
|
||||
#define A_GRAVE '`'
|
||||
#define A_ACUTE '\''
|
||||
#define A_CFLEX '^'
|
||||
#define A_TILDE '~'
|
||||
#define A_DIAER '"'
|
||||
#define A_CEDIL ','
|
||||
static unsigned char ret_diacr[NR_DEAD] =
|
||||
{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
|
||||
|
||||
/* Obsolete - for backwards compatibility only */
|
||||
static void do_dead(unsigned char value, char up_flag)
|
||||
{
|
||||
value = ret_diacr[value];
|
||||
printk( " do_dead( %X ) ", value );
|
||||
do_dead2(value,up_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle dead key. Note that we now may have several
|
||||
* dead keys modifying the same character. Very useful
|
||||
* for Vietnamese.
|
||||
*/
|
||||
static void do_dead2(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
diacr = (diacr ? handle_diacr(value) : value);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a combining character DIACR here, followed by the character CH.
|
||||
* If the combination occurs in the table, return the corresponding value.
|
||||
* Otherwise, if CH is a space or equals DIACR, return DIACR.
|
||||
* Otherwise, conclude that DIACR was not combining after all,
|
||||
* queue it and return CH.
|
||||
*/
|
||||
unsigned char handle_diacr(unsigned char ch)
|
||||
{
|
||||
int d = diacr;
|
||||
int i;
|
||||
|
||||
diacr = 0;
|
||||
|
||||
for (i = 0; i < accent_table_size; i++) {
|
||||
if (accent_table[i].diacr == d && accent_table[i].base == ch)
|
||||
return accent_table[i].result;
|
||||
}
|
||||
if (ch == ' ' || ch == d)
|
||||
return d;
|
||||
|
||||
put_queue(d);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void do_cons(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
}
|
||||
|
||||
static void do_fn(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
|
||||
if (value < SIZE(func_table)) {
|
||||
if (func_table[value])
|
||||
puts_queue(func_table[value]);
|
||||
} else
|
||||
printk( "do_fn called with value=%d\n", value);
|
||||
}
|
||||
|
||||
static void do_pad(unsigned char value, char up_flag)
|
||||
{
|
||||
static const char *pad_chars = "0123456789+-*/\015,.?()";
|
||||
static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
|
||||
|
||||
if (up_flag)
|
||||
return; /* no action, if this is a key release */
|
||||
|
||||
/* kludge... shift forces cursor/number keys */
|
||||
if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
|
||||
applkey(app_map[value], 1);
|
||||
return;
|
||||
}
|
||||
if (!vc_kbd_led(kbd,VC_NUMLOCK))
|
||||
switch (value) {
|
||||
case KVAL(K_PCOMMA):
|
||||
case KVAL(K_PDOT):
|
||||
do_fn(KVAL(K_REMOVE), 0);
|
||||
return;
|
||||
case KVAL(K_P0):
|
||||
do_fn(KVAL(K_INSERT), 0);
|
||||
return;
|
||||
case KVAL(K_P1):
|
||||
do_fn(KVAL(K_SELECT), 0);
|
||||
return;
|
||||
case KVAL(K_P2):
|
||||
do_cur(KVAL(K_DOWN), 0);
|
||||
return;
|
||||
case KVAL(K_P3):
|
||||
do_fn(KVAL(K_PGDN), 0);
|
||||
return;
|
||||
case KVAL(K_P4):
|
||||
do_cur(KVAL(K_LEFT), 0);
|
||||
return;
|
||||
case KVAL(K_P6):
|
||||
do_cur(KVAL(K_RIGHT), 0);
|
||||
return;
|
||||
case KVAL(K_P7):
|
||||
do_fn(KVAL(K_FIND), 0);
|
||||
return;
|
||||
case KVAL(K_P8):
|
||||
do_cur(KVAL(K_UP), 0);
|
||||
return;
|
||||
case KVAL(K_P9):
|
||||
do_fn(KVAL(K_PGUP), 0);
|
||||
return;
|
||||
case KVAL(K_P5):
|
||||
applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
|
||||
return;
|
||||
}
|
||||
|
||||
put_queue(pad_chars[value]);
|
||||
|
||||
if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
|
||||
put_queue(10);
|
||||
|
||||
}
|
||||
|
||||
static void do_cur(unsigned char value, char up_flag)
|
||||
{
|
||||
static const char *cur_chars = "BDCA";
|
||||
if (up_flag)
|
||||
return;
|
||||
|
||||
applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
|
||||
}
|
||||
|
||||
static void do_shift(unsigned char value, char up_flag)
|
||||
{
|
||||
int old_state = shift_state;
|
||||
|
||||
if (rep)
|
||||
return;
|
||||
|
||||
/* Mimic typewriter:
|
||||
a CapsShift key acts like Shift but undoes CapsLock */
|
||||
if (value == KVAL(K_CAPSSHIFT)) {
|
||||
value = KVAL(K_SHIFT);
|
||||
if (!up_flag)
|
||||
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
|
||||
}
|
||||
|
||||
if (up_flag) {
|
||||
/* handle the case that two shift or control
|
||||
keys are depressed simultaneously */
|
||||
if (k_down[value])
|
||||
k_down[value]--;
|
||||
} else
|
||||
k_down[value]++;
|
||||
|
||||
if (k_down[value])
|
||||
shift_state |= (1 << value);
|
||||
else
|
||||
shift_state &= ~ (1 << value);
|
||||
|
||||
/* kludge */
|
||||
if (up_flag && shift_state != old_state && npadch != -1) {
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(npadch & 0xffff);
|
||||
else
|
||||
put_queue(npadch & 0xff);
|
||||
npadch = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* called after returning from RAW mode or when changing consoles -
|
||||
recompute k_down[] and shift_state from key_down[] */
|
||||
/* maybe called when keymap is undefined, so that shiftkey release is seen */
|
||||
void compute_shiftstate(void)
|
||||
{
|
||||
int i, j, k, sym, val;
|
||||
|
||||
shift_state = 0;
|
||||
for(i=0; i < SIZE(k_down); i++)
|
||||
k_down[i] = 0;
|
||||
|
||||
for(i=0; i < SIZE(key_down); i++)
|
||||
if(atomic_load(key_down + i)) { /* skip this word if not a single bit on */
|
||||
k = i*KBD_BITS_PER_ELEMENT;
|
||||
for(j=0; j<KBD_BITS_PER_ELEMENT; j++,k++)
|
||||
if(kbd_test_bit(k, key_down)) {
|
||||
sym = U(plain_map[k]);
|
||||
if(KTYP(sym) == KT_SHIFT) {
|
||||
val = KVAL(sym);
|
||||
if (val == KVAL(K_CAPSSHIFT))
|
||||
val = KVAL(K_SHIFT);
|
||||
k_down[val]++;
|
||||
shift_state |= (1<<val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void do_meta(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag)
|
||||
return;
|
||||
|
||||
if (vc_kbd_mode(kbd, VC_META)) {
|
||||
put_queue('\033');
|
||||
put_queue(value);
|
||||
} else
|
||||
put_queue(value | 0x80);
|
||||
}
|
||||
|
||||
static void do_ascii(unsigned char value, char up_flag)
|
||||
{
|
||||
int base;
|
||||
|
||||
if (up_flag)
|
||||
return;
|
||||
|
||||
if (value < 10) /* decimal input of code, while Alt depressed */
|
||||
base = 10;
|
||||
else { /* hexadecimal input of code, while AltGr depressed */
|
||||
value -= 10;
|
||||
base = 16;
|
||||
}
|
||||
|
||||
if (npadch == -1)
|
||||
npadch = value;
|
||||
else
|
||||
npadch = npadch * base + value;
|
||||
}
|
||||
|
||||
static void do_lock(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag || rep)
|
||||
return;
|
||||
chg_vc_kbd_lock(kbd, value);
|
||||
}
|
||||
|
||||
static void do_slock(unsigned char value, char up_flag)
|
||||
{
|
||||
if (up_flag || rep)
|
||||
return;
|
||||
|
||||
chg_vc_kbd_slock(kbd, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
|
||||
* or (ii) whatever pattern of lights people want to show using KDSETLED,
|
||||
* or (iii) specified bits of specified words in kernel memory.
|
||||
*/
|
||||
|
||||
static unsigned char ledstate = 0xff; /* undefined */
|
||||
static unsigned char ledioctl;
|
||||
|
||||
unsigned char getledstate(void) {
|
||||
return ledstate;
|
||||
}
|
||||
|
||||
void setledstate(struct kbd_struct *kbd, unsigned int led) {
|
||||
if (!(led & ~7)) {
|
||||
ledioctl = led;
|
||||
kbd->ledmode = LED_SHOW_IOCTL;
|
||||
} else
|
||||
;
|
||||
kbd->ledmode = LED_SHOW_FLAGS;
|
||||
set_leds();
|
||||
}
|
||||
|
||||
static struct ledptr {
|
||||
unsigned int *addr;
|
||||
unsigned int mask;
|
||||
unsigned char valid:1;
|
||||
} ledptrs[3];
|
||||
|
||||
void register_leds(
|
||||
int console,
|
||||
unsigned int led,
|
||||
unsigned int *addr,
|
||||
unsigned int mask
|
||||
)
|
||||
{
|
||||
struct kbd_struct *kbd = kbd_table + console;
|
||||
|
||||
if (led < 3) {
|
||||
ledptrs[led].addr = addr;
|
||||
ledptrs[led].mask = mask;
|
||||
ledptrs[led].valid = 1;
|
||||
kbd->ledmode = LED_SHOW_MEM;
|
||||
} else
|
||||
kbd->ledmode = LED_SHOW_FLAGS;
|
||||
}
|
||||
|
||||
static inline unsigned char getleds(void)
|
||||
{
|
||||
|
||||
struct kbd_struct *kbd = kbd_table + fg_console;
|
||||
|
||||
unsigned char leds;
|
||||
|
||||
if (kbd->ledmode == LED_SHOW_IOCTL)
|
||||
return ledioctl;
|
||||
leds = kbd->ledflagstate;
|
||||
if (kbd->ledmode == LED_SHOW_MEM) {
|
||||
if (ledptrs[0].valid) {
|
||||
if (*ledptrs[0].addr & ledptrs[0].mask)
|
||||
leds |= 1;
|
||||
else
|
||||
leds &= ~1;
|
||||
}
|
||||
if (ledptrs[1].valid) {
|
||||
if (*ledptrs[1].addr & ledptrs[1].mask)
|
||||
leds |= 2;
|
||||
else
|
||||
leds &= ~2;
|
||||
}
|
||||
if (ledptrs[2].valid) {
|
||||
if (*ledptrs[2].addr & ledptrs[2].mask)
|
||||
leds |= 4;
|
||||
else
|
||||
leds &= ~4;
|
||||
}
|
||||
}
|
||||
return leds;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is the bottom half of the keyboard interrupt
|
||||
* routine, and runs with all interrupts enabled. It does
|
||||
* console changing, led setting and copy_to_cooked, which can
|
||||
* take a reasonably long time.
|
||||
*
|
||||
* Aside from timing (which isn't really that important for
|
||||
* keyboard interrupts as they happen often), using the software
|
||||
* interrupt routines for this thing allows us to easily mask
|
||||
* this when we don't want any of the above to happen. Not yet
|
||||
* used, but this allows for easy and efficient race-condition
|
||||
* prevention later on.
|
||||
*/
|
||||
static void kbd_bh(void)
|
||||
{
|
||||
unsigned char leds = getleds();
|
||||
if (leds != ledstate) {
|
||||
ledstate = leds;
|
||||
kbd_leds(leds);
|
||||
}
|
||||
}
|
||||
|
||||
void set_leds(void)
|
||||
{
|
||||
kbd_bh();
|
||||
}
|
||||
|
||||
int kbd_init(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
struct kbd_struct kbd0;
|
||||
kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
|
||||
kbd0.ledmode = LED_SHOW_MEM;
|
||||
kbd0.lockstate = KBD_DEFLOCK;
|
||||
kbd0.slockstate = 0;
|
||||
kbd0.modeflags = KBD_DEFMODE;
|
||||
kbd0.kbdmode = VC_XLATE;
|
||||
|
||||
for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
|
||||
kbd_table[i] = kbd0;
|
||||
|
||||
kbd_init_hw();
|
||||
mark_bh(KEYBOARD_BH);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
* outch.c - This file contains code for displaying characters
|
||||
* on the console uisng information that should be
|
||||
* maintained by the BIOS in its data Area.
|
||||
*
|
||||
* Copyright (C) 1998 Eric Valette (valette@crf.canon.fr)
|
||||
* Canon Centre Recherche France.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Till Straumann <strauman@slac.stanford.edu>, 2003/9:
|
||||
* - added handling of basic escape sequences (cursor movement
|
||||
* and erasing; just enough for the line editor 'libtecla' to
|
||||
* work...)
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <crt.h>
|
||||
|
||||
extern void wr_cursor(int, unsigned short);
|
||||
|
||||
#define TAB_SPACE 4
|
||||
static unsigned short *bitMapBaseAddr;
|
||||
static unsigned short ioCrtBaseAddr;
|
||||
static unsigned short maxCol;
|
||||
static unsigned short maxRow;
|
||||
static unsigned char row;
|
||||
static unsigned char column;
|
||||
static unsigned short attribute;
|
||||
static unsigned int nLines;
|
||||
|
||||
static void
|
||||
scroll(void)
|
||||
{
|
||||
int i, j; /* Counters */
|
||||
unsigned short *pt_scroll, *pt_bitmap; /* Pointers on the bit-map */
|
||||
|
||||
pt_bitmap = bitMapBaseAddr;
|
||||
j = 0;
|
||||
pt_bitmap = pt_bitmap + j;
|
||||
pt_scroll = pt_bitmap + maxCol;
|
||||
for (i = j; i < (maxRow - 1) * maxCol; i++) {
|
||||
*pt_bitmap++ = *pt_scroll++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Blank characters are displayed on the last line.
|
||||
*/
|
||||
for (i = 0; i < maxCol; i++) {
|
||||
*pt_bitmap++ = (short) (' ' | attribute);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
doCRNL(int cr, int nl)
|
||||
{
|
||||
if (nl) {
|
||||
if (++row == maxRow) {
|
||||
scroll(); /* Scroll the screen now */
|
||||
row = maxRow - 1;
|
||||
}
|
||||
nLines++;
|
||||
}
|
||||
if (cr)
|
||||
column = 0;
|
||||
/* Move cursor on the next location */
|
||||
if (cr || nl)
|
||||
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
|
||||
}
|
||||
|
||||
int (*videoHook)(char, int *)=0;
|
||||
|
||||
static void
|
||||
advanceCursor(void)
|
||||
{
|
||||
if (++column == maxCol)
|
||||
doCRNL(1,1);
|
||||
else
|
||||
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
|
||||
}
|
||||
|
||||
static void
|
||||
gotorc(int r, int c)
|
||||
{
|
||||
column = c;
|
||||
row = r;
|
||||
|
||||
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
|
||||
}
|
||||
|
||||
#define ESC ((char)27)
|
||||
/* erase current location without moving the cursor */
|
||||
#define BLANK ((char)0x7f)
|
||||
|
||||
static void
|
||||
videoPutChar(char car)
|
||||
{
|
||||
unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column;
|
||||
|
||||
switch (car) {
|
||||
case '\b': {
|
||||
if (column) column--;
|
||||
/* Move cursor on the previous location */
|
||||
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
|
||||
return;
|
||||
}
|
||||
case '\t': {
|
||||
int i;
|
||||
|
||||
i = TAB_SPACE - (column & (TAB_SPACE - 1));
|
||||
column += i;
|
||||
if (column >= maxCol) {
|
||||
doCRNL(1,1);
|
||||
return;
|
||||
}
|
||||
while (i--) *pt_bitmap++ = ' ' | attribute;
|
||||
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
|
||||
return;
|
||||
}
|
||||
case '\n': {
|
||||
doCRNL(0,1);
|
||||
return;
|
||||
}
|
||||
case 7: { /* Bell code must be inserted here */
|
||||
return;
|
||||
}
|
||||
case '\r' : {
|
||||
doCRNL(1,0);
|
||||
return;
|
||||
}
|
||||
case BLANK: {
|
||||
*pt_bitmap = ' ' | attribute;
|
||||
/* DONT move the cursor... */
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
*pt_bitmap = (unsigned char)car | attribute;
|
||||
advanceCursor();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* trivial state machine to handle escape sequences:
|
||||
*
|
||||
* ---------------------------------
|
||||
* | |
|
||||
* | |
|
||||
* KEY: esc V [ DCABHKJ esc |
|
||||
* STATE: 0 -----> 27 -----> '[' ----------> -1 -----
|
||||
* ^\ \ \ \
|
||||
* KEY: | \other \ other \ other \ other
|
||||
* <-------------------------------------
|
||||
*
|
||||
* in state '-1', the DCABHKJ cases are handled
|
||||
*
|
||||
* (cursor motion and screen clearing)
|
||||
*/
|
||||
|
||||
#define DONE (-1)
|
||||
|
||||
static int
|
||||
handleEscape(int oldState, char car)
|
||||
{
|
||||
int rval = 0;
|
||||
int ro,co;
|
||||
|
||||
switch ( oldState ) {
|
||||
case DONE: /* means the previous char terminated an ESC sequence... */
|
||||
case 0:
|
||||
if ( 27 == car ) {
|
||||
rval = 27; /* START of an ESC sequence */
|
||||
}
|
||||
break;
|
||||
|
||||
case 27:
|
||||
if ( '[' == car ) {
|
||||
rval = car; /* received ESC '[', so far */
|
||||
} else {
|
||||
/* dump suppressed 'ESC'; outch will append the char */
|
||||
videoPutChar(ESC);
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
/* handle 'ESC' '[' sequences here */
|
||||
ro = row; co = column;
|
||||
rval = DONE; /* done */
|
||||
|
||||
switch (car) {
|
||||
case 'D': /* left */
|
||||
if ( co > 0 ) co--;
|
||||
break;
|
||||
case 'C': /* right */
|
||||
if ( co < maxCol ) co++;
|
||||
break;
|
||||
case 'A': /* up */
|
||||
if ( ro > 0 ) ro--;
|
||||
break;
|
||||
case 'B': /* down */
|
||||
if ( ro < maxRow ) ro++;
|
||||
break;
|
||||
case 'H': /* home */
|
||||
ro = co = 0;
|
||||
break;
|
||||
case 'K': /* clear to end of line */
|
||||
while ( column < maxCol - 1 )
|
||||
videoPutChar(' ');
|
||||
videoPutChar(BLANK);
|
||||
break;
|
||||
case 'J': /* clear to end of screen */
|
||||
while ( ((row < maxRow-1) || (column < maxCol-1)) )
|
||||
videoPutChar(' ');
|
||||
videoPutChar(BLANK);
|
||||
break;
|
||||
default:
|
||||
videoPutChar(ESC);
|
||||
videoPutChar('[');
|
||||
/* DONT move the cursor */
|
||||
ro = -1;
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
/* reset cursor */
|
||||
if ( ro >= 0)
|
||||
gotorc(ro,co);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_screen(void)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
for (j = 0; j <= maxRow; j++) {
|
||||
for (i = 0; i <= maxCol; i++) {
|
||||
videoPutChar(' ');
|
||||
}
|
||||
}
|
||||
column = 0;
|
||||
row = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _IBMPC_outch
|
||||
| Description: Higher level (console) interface to consPutc.
|
||||
| Global Variables: None.
|
||||
| Arguments: c - character to write to console.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
_IBMPC_outch(char c)
|
||||
{
|
||||
static int escaped = 0;
|
||||
|
||||
if ( ! (escaped = handleEscape(escaped, c)) ) {
|
||||
if ( '\n' == c )
|
||||
videoPutChar('\r');
|
||||
videoPutChar(c);
|
||||
}
|
||||
} /* _IBMPC_outch */
|
||||
|
||||
/*-------------------------------------------------------------------------+
|
||||
| Function: _IBMPC_initVideo
|
||||
| Description: Video system initialization. Hook for any early setup.
|
||||
| Global Variables: bitMapBaseAddr, ioCrtBaseAddr, maxCol, maxRow, row
|
||||
| column, attribute, nLines;
|
||||
| Arguments: None.
|
||||
| Returns: Nothing.
|
||||
+--------------------------------------------------------------------------*/
|
||||
void
|
||||
_IBMPC_initVideo(void)
|
||||
{
|
||||
unsigned char* pt = (unsigned char*) (VIDEO_MODE_ADDR);
|
||||
|
||||
if (*pt == VGAMODE7) {
|
||||
bitMapBaseAddr = (unsigned short*) V_MONO;
|
||||
}
|
||||
else {
|
||||
bitMapBaseAddr = (unsigned short*) V_COLOR;
|
||||
}
|
||||
ioCrtBaseAddr = *(unsigned short*) DISPLAY_CRT_BASE_IO_ADDR;
|
||||
maxCol = * (unsigned short*) NB_MAX_COL_ADDR;
|
||||
maxRow = * (unsigned char*) NB_MAX_ROW_ADDR;
|
||||
column = 0;
|
||||
row = 0;
|
||||
attribute = ((BLACK << 4) | WHITE)<<8;
|
||||
nLines = 0;
|
||||
clear_screen();
|
||||
#ifdef DEBUG_EARLY_STAGE
|
||||
printk("bitMapBaseAddr = %X, display controller base IO = %X\n",
|
||||
(unsigned) bitMapBaseAddr,
|
||||
(unsigned) ioCrtBaseAddr);
|
||||
videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow);
|
||||
#endif
|
||||
} /* _IBMPC_initVideo */
|
||||
|
||||
/* for old DOS compatibility n-curses type of applications */
|
||||
void gotoxy( int x, int y );
|
||||
int whereX( void );
|
||||
int whereY( void );
|
||||
|
||||
void gotoxy( int x, int y )
|
||||
{
|
||||
gotorc(y,x);
|
||||
}
|
||||
|
||||
int whereX( void )
|
||||
{
|
||||
return row;
|
||||
}
|
||||
|
||||
int whereY( void )
|
||||
{
|
||||
return column;
|
||||
}
|
||||
@@ -1,627 +0,0 @@
|
||||
/*
|
||||
* linux/drivers/char/pc_keyb.c
|
||||
*
|
||||
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
|
||||
* See keyboard.c for the whole history.
|
||||
*
|
||||
* Major cleanup by Martin Mares, May 1997
|
||||
*
|
||||
* Combined the keyboard and PS/2 mouse handling into one file,
|
||||
* because they share the same hardware.
|
||||
* Johan Myreen <jem@iki.fi> 1998-10-08.
|
||||
*
|
||||
* Code fixes to handle mouse ACKs properly.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
|
||||
*
|
||||
* Ported to RTEMS by Rosimildo da Silva
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/keyboard.h>
|
||||
#include "i386kbd.h"
|
||||
|
||||
static unsigned char handle_kbd_event(void);
|
||||
static void kbd_write_command_w(int data);
|
||||
static void kbd_write_output_w(int data);
|
||||
|
||||
/* Some configuration switches are present in the include file... */
|
||||
|
||||
/* Simple translation table for the SysRq keys */
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
unsigned char pckbd_sysrq_xlate[128] =
|
||||
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
|
||||
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
|
||||
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
|
||||
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
|
||||
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
|
||||
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
||||
"\r\000/"; /* 0x60 - 0x6f */
|
||||
#endif
|
||||
|
||||
/* used only by send_data - set by keyboard_interrupt */
|
||||
static volatile unsigned char reply_expected = 0;
|
||||
static volatile unsigned char acknowledge = 0;
|
||||
static volatile unsigned char resend = 0;
|
||||
|
||||
/*
|
||||
* Translation of escaped scancodes to keycodes.
|
||||
* This is now user-settable.
|
||||
* The keycodes 1-88,96-111,119 are fairly standard, and
|
||||
* should probably not be changed - changing might confuse X.
|
||||
* X also interprets scancode 0x5d (KEY_Begin).
|
||||
*
|
||||
* For 1-88 keycode equals scancode.
|
||||
*/
|
||||
|
||||
#define E0_KPENTER 96
|
||||
#define E0_RCTRL 97
|
||||
#define E0_KPSLASH 98
|
||||
#define E0_PRSCR 99
|
||||
#define E0_RALT 100
|
||||
#define E0_BREAK 101 /* (control-pause) */
|
||||
#define E0_HOME 102
|
||||
#define E0_UP 103
|
||||
#define E0_PGUP 104
|
||||
#define E0_LEFT 105
|
||||
#define E0_RIGHT 106
|
||||
#define E0_END 107
|
||||
#define E0_DOWN 108
|
||||
#define E0_PGDN 109
|
||||
#define E0_INS 110
|
||||
#define E0_DEL 111
|
||||
|
||||
#define E1_PAUSE 119
|
||||
|
||||
/*
|
||||
* The keycodes below are randomly located in 89-95,112-118,120-127.
|
||||
* They could be thrown away (and all occurrences below replaced by 0),
|
||||
* but that would force many users to use the `setkeycodes' utility, where
|
||||
* they needed not before. It does not matter that there are duplicates, as
|
||||
* long as no duplication occurs for any single keyboard.
|
||||
*/
|
||||
#define SC_LIM 89
|
||||
|
||||
#define FOCUS_PF1 85 /* actual code! */
|
||||
#define FOCUS_PF2 89
|
||||
#define FOCUS_PF3 90
|
||||
#define FOCUS_PF4 91
|
||||
#define FOCUS_PF5 92
|
||||
#define FOCUS_PF6 93
|
||||
#define FOCUS_PF7 94
|
||||
#define FOCUS_PF8 95
|
||||
#define FOCUS_PF9 120
|
||||
#define FOCUS_PF10 121
|
||||
#define FOCUS_PF11 122
|
||||
#define FOCUS_PF12 123
|
||||
|
||||
#define JAP_86 124
|
||||
/* tfj@olivia.ping.dk:
|
||||
* The four keys are located over the numeric keypad, and are
|
||||
* labelled A1-A4. It's an rc930 keyboard, from
|
||||
* Regnecentralen/RC International, Now ICL.
|
||||
* Scancodes: 59, 5a, 5b, 5c.
|
||||
*/
|
||||
#define RGN1 124
|
||||
#define RGN2 125
|
||||
#define RGN3 126
|
||||
#define RGN4 127
|
||||
|
||||
static unsigned char high_keys[128 - SC_LIM] = {
|
||||
RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
|
||||
0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
|
||||
0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
|
||||
FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
|
||||
FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
|
||||
};
|
||||
|
||||
/* BTC */
|
||||
#define E0_MACRO 112
|
||||
/* LK450 */
|
||||
#define E0_F13 113
|
||||
#define E0_F14 114
|
||||
#define E0_HELP 115
|
||||
#define E0_DO 116
|
||||
#define E0_F17 117
|
||||
#define E0_KPMINPLUS 118
|
||||
/*
|
||||
* My OmniKey generates e0 4c for the "OMNI" key and the
|
||||
* right alt key does nada. [kkoller@nyx10.cs.du.edu]
|
||||
*/
|
||||
#define E0_OK 124
|
||||
/*
|
||||
* New microsoft keyboard is rumoured to have
|
||||
* e0 5b (left window button), e0 5c (right window button),
|
||||
* e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
|
||||
* [or: Windows_L, Windows_R, TaskMan]
|
||||
*/
|
||||
#define E0_MSLW 125
|
||||
#define E0_MSRW 126
|
||||
#define E0_MSTM 127
|
||||
|
||||
static unsigned char e0_keys[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
|
||||
0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
|
||||
0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
|
||||
E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
|
||||
E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
|
||||
E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
|
||||
E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
|
||||
0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
|
||||
0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
|
||||
};
|
||||
|
||||
static void mdelay( unsigned long t )
|
||||
{
|
||||
Wait_X_ms( t );
|
||||
}
|
||||
|
||||
int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
|
||||
{
|
||||
if (scancode < SC_LIM || scancode > 255 || keycode > 127)
|
||||
return -EINVAL;
|
||||
if (scancode < 128)
|
||||
high_keys[scancode - SC_LIM] = keycode;
|
||||
else
|
||||
e0_keys[scancode - 128] = keycode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pckbd_getkeycode(unsigned int scancode)
|
||||
{
|
||||
return
|
||||
(scancode < SC_LIM || scancode > 255) ? -EINVAL :
|
||||
(scancode < 128) ? high_keys[scancode - SC_LIM] :
|
||||
e0_keys[scancode - 128];
|
||||
}
|
||||
|
||||
static int do_acknowledge(unsigned char scancode)
|
||||
{
|
||||
if (reply_expected) {
|
||||
/* Unfortunately, we must recognise these codes only if we know they
|
||||
* are known to be valid (i.e., after sending a command), because there
|
||||
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
|
||||
* keys with such codes :(
|
||||
*/
|
||||
if (scancode == KBD_REPLY_ACK) {
|
||||
acknowledge = 1;
|
||||
reply_expected = 0;
|
||||
return 0;
|
||||
} else if (scancode == KBD_REPLY_RESEND) {
|
||||
resend = 1;
|
||||
reply_expected = 0;
|
||||
return 0;
|
||||
}
|
||||
/* Should not happen... */
|
||||
printk( "keyboard reply expected - got %02x\n", scancode);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pckbd_translate(unsigned char scancode, unsigned char *keycode,
|
||||
char raw_mode)
|
||||
{
|
||||
static int prev_scancode = 0;
|
||||
|
||||
/* special prefix scancodes.. */
|
||||
if (scancode == 0xe0 || scancode == 0xe1) {
|
||||
prev_scancode = scancode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
|
||||
if (scancode == 0x00 || scancode == 0xff) {
|
||||
prev_scancode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
scancode &= 0x7f;
|
||||
|
||||
if (prev_scancode) {
|
||||
/*
|
||||
* usually it will be 0xe0, but a Pause key generates
|
||||
* e1 1d 45 e1 9d c5 when pressed, and nothing when released
|
||||
*/
|
||||
if (prev_scancode != 0xe0) {
|
||||
if (prev_scancode == 0xe1 && scancode == 0x1d) {
|
||||
prev_scancode = 0x100;
|
||||
return 0;
|
||||
} else if (prev_scancode == 0x100 && scancode == 0x45) {
|
||||
*keycode = E1_PAUSE;
|
||||
prev_scancode = 0;
|
||||
} else {
|
||||
#ifdef KBD_REPORT_UNKN
|
||||
if (!raw_mode)
|
||||
printk("keyboard: unknown e1 escape sequence\n");
|
||||
#endif
|
||||
prev_scancode = 0;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
prev_scancode = 0;
|
||||
/*
|
||||
* The keyboard maintains its own internal caps lock and
|
||||
* num lock statuses. In caps lock mode E0 AA precedes make
|
||||
* code and E0 2A follows break code. In num lock mode,
|
||||
* E0 2A precedes make code and E0 AA follows break code.
|
||||
* We do our own book-keeping, so we will just ignore these.
|
||||
*/
|
||||
/*
|
||||
* For my keyboard there is no caps lock mode, but there are
|
||||
* both Shift-L and Shift-R modes. The former mode generates
|
||||
* E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
|
||||
* So, we should also ignore the latter. - aeb@cwi.nl
|
||||
*/
|
||||
if (scancode == 0x2a || scancode == 0x36)
|
||||
return 0;
|
||||
|
||||
if (e0_keys[scancode])
|
||||
*keycode = e0_keys[scancode];
|
||||
else {
|
||||
#ifdef KBD_REPORT_UNKN
|
||||
if (!raw_mode)
|
||||
printk( "keyboard: unknown scancode e0 %02x\n",
|
||||
scancode);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (scancode >= SC_LIM) {
|
||||
/* This happens with the FOCUS 9000 keyboard
|
||||
Its keys PF1..PF12 are reported to generate
|
||||
55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
|
||||
Moreover, unless repeated, they do not generate
|
||||
key-down events, so we have to zero up_flag below */
|
||||
/* Also, Japanese 86/106 keyboards are reported to
|
||||
generate 0x73 and 0x7d for \ - and \ | respectively. */
|
||||
/* Also, some Brazilian keyboard is reported to produce
|
||||
0x73 and 0x7e for \ ? and KP-dot, respectively. */
|
||||
|
||||
*keycode = high_keys[scancode - SC_LIM];
|
||||
if (!*keycode) {
|
||||
if (!raw_mode) {
|
||||
#ifdef KBD_REPORT_UNKN
|
||||
printk( "keyboard: unrecognized scancode (%02x)"
|
||||
" - ignored\n", scancode);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
*keycode = scancode;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char pckbd_unexpected_up(unsigned char keycode)
|
||||
{
|
||||
/* unexpected, but this can happen: maybe this was a key release for a
|
||||
FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
|
||||
if (keycode >= SC_LIM || keycode == 85)
|
||||
return 0;
|
||||
else
|
||||
return 0200;
|
||||
}
|
||||
|
||||
static void kb_wait(void)
|
||||
{
|
||||
unsigned long timeout = KBC_TIMEOUT;
|
||||
|
||||
do {
|
||||
/*
|
||||
* "handle_kbd_event()" will handle any incoming events
|
||||
* while we wait - keypresses or mouse movement.
|
||||
*/
|
||||
unsigned char status = handle_kbd_event();
|
||||
|
||||
if (! (status & KBD_STAT_IBF))
|
||||
return;
|
||||
mdelay(1);
|
||||
timeout--;
|
||||
} while (timeout);
|
||||
#ifdef KBD_REPORT_TIMEOUTS
|
||||
printk( "Keyboard timed out[1]\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This reads the keyboard status port, and does the
|
||||
* appropriate action.
|
||||
*
|
||||
* It requires that we hold the keyboard controller
|
||||
* spinlock.
|
||||
*/
|
||||
static unsigned char handle_kbd_event(void)
|
||||
{
|
||||
unsigned char status = kbd_read_status();
|
||||
unsigned int work = 10000;
|
||||
|
||||
while (status & KBD_STAT_OBF) {
|
||||
unsigned char scancode;
|
||||
|
||||
scancode = kbd_read_input();
|
||||
if (status & KBD_STAT_MOUSE_OBF) {
|
||||
#if 0
|
||||
handle_mouse_event(scancode);
|
||||
#endif
|
||||
} else {
|
||||
if (do_acknowledge(scancode))
|
||||
handle_scancode(scancode, !(scancode & 0x80));
|
||||
mark_bh(KEYBOARD_BH);
|
||||
}
|
||||
|
||||
status = kbd_read_status();
|
||||
|
||||
if(!work--)
|
||||
{
|
||||
printk( "pc_keyb: controller jammed (0x%02X).\n", status);
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* the commands to set the leds for some reason, returns 0x14, 0x16
|
||||
* and I am intepreting as an ACK, because the original code from
|
||||
* Linux was timeing out here...
|
||||
*/
|
||||
acknowledge = 1;
|
||||
reply_expected = 0;
|
||||
resend = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
void keyboard_interrupt(void *unused)
|
||||
{
|
||||
handle_kbd_event();
|
||||
}
|
||||
|
||||
/*
|
||||
* send_data sends a character to the keyboard and waits
|
||||
* for an acknowledge, possibly retrying if asked to. Returns
|
||||
* the success status.
|
||||
*
|
||||
* Don't use 'jiffies', so that we don't depend on interrupts
|
||||
*/
|
||||
static int send_data(unsigned char data)
|
||||
{
|
||||
int retries = 3;
|
||||
|
||||
do {
|
||||
unsigned long timeout = KBD_TIMEOUT;
|
||||
|
||||
acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
|
||||
resend = 0;
|
||||
reply_expected = 1;
|
||||
kbd_write_output_w(data);
|
||||
for (;;) {
|
||||
if (acknowledge)
|
||||
return 1;
|
||||
if (resend)
|
||||
break;
|
||||
mdelay(1);
|
||||
if (!--timeout) {
|
||||
#ifdef KBD_REPORT_TIMEOUTS
|
||||
printk("Keyboard timeout[2]\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} while (retries-- > 0);
|
||||
#ifdef KBD_REPORT_TIMEOUTS
|
||||
printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pckbd_leds(unsigned char leds)
|
||||
{
|
||||
if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
|
||||
send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
|
||||
}
|
||||
|
||||
/*
|
||||
* In case we run on a non-x86 hardware we need to initialize both the
|
||||
* keyboard controller and the keyboard. On a x86, the BIOS will
|
||||
* already have initialized them.
|
||||
*
|
||||
* Some x86 BIOSes do not correctly initialize the keyboard, so the
|
||||
* "kbd-reset" command line options can be given to force a reset.
|
||||
* [Ranger]
|
||||
*/
|
||||
#ifdef __i386__
|
||||
int kbd_startup_reset = 0;
|
||||
#else
|
||||
int kbd_startup_reset = 1;
|
||||
#endif
|
||||
|
||||
/* for "kbd-reset" cmdline param */
|
||||
void kbd_reset_setup(char *str, int *ints)
|
||||
{
|
||||
kbd_startup_reset = 1;
|
||||
}
|
||||
|
||||
#define KBD_NO_DATA (-1) /* No data */
|
||||
#define KBD_BAD_DATA (-2) /* Parity or other error */
|
||||
|
||||
static int kbd_read_data(void)
|
||||
{
|
||||
int retval = KBD_NO_DATA;
|
||||
unsigned char status;
|
||||
|
||||
status = kbd_read_status();
|
||||
if (status & KBD_STAT_OBF) {
|
||||
unsigned char data = kbd_read_input();
|
||||
|
||||
retval = data;
|
||||
if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
|
||||
retval = KBD_BAD_DATA;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void kbd_clear_input(void)
|
||||
{
|
||||
int maxread = 100; /* Random number */
|
||||
|
||||
do {
|
||||
if (kbd_read_data() == KBD_NO_DATA)
|
||||
break;
|
||||
} while (--maxread);
|
||||
}
|
||||
|
||||
static int kbd_wait_for_input(void)
|
||||
{
|
||||
long timeout = KBD_INIT_TIMEOUT;
|
||||
|
||||
do {
|
||||
int retval = kbd_read_data();
|
||||
if (retval >= 0)
|
||||
return retval;
|
||||
mdelay(1);
|
||||
} while (--timeout);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void kbd_write_command_w(int data)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_command(data);
|
||||
}
|
||||
|
||||
static void kbd_write_output_w(int data)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_output(data);
|
||||
}
|
||||
|
||||
static char * initialize_kbd(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Test the keyboard interface.
|
||||
* This seems to be the only way to get it going.
|
||||
* If the test is successful a x55 is placed in the input buffer.
|
||||
*/
|
||||
kbd_write_command_w(KBD_CCMD_SELF_TEST);
|
||||
if (kbd_wait_for_input() != 0x55)
|
||||
return "Keyboard failed self test";
|
||||
|
||||
/*
|
||||
* Perform a keyboard interface test. This causes the controller
|
||||
* to test the keyboard clock and data lines. The results of the
|
||||
* test are placed in the input buffer.
|
||||
*/
|
||||
kbd_write_command_w(KBD_CCMD_KBD_TEST);
|
||||
if (kbd_wait_for_input() != 0x00)
|
||||
return "Keyboard interface failed self test";
|
||||
|
||||
/*
|
||||
* Enable the keyboard by allowing the keyboard clock to run.
|
||||
*/
|
||||
kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
|
||||
|
||||
/*
|
||||
* Reset keyboard. If the read times out
|
||||
* then the assumption is that no keyboard is
|
||||
* plugged into the machine.
|
||||
* This defaults the keyboard to scan-code set 2.
|
||||
*
|
||||
* Set up to try again if the keyboard asks for RESEND.
|
||||
*/
|
||||
do {
|
||||
kbd_write_output_w(KBD_CMD_RESET);
|
||||
status = kbd_wait_for_input();
|
||||
if (status == KBD_REPLY_ACK)
|
||||
break;
|
||||
if (status != KBD_REPLY_RESEND)
|
||||
return "Keyboard reset failed, no ACK";
|
||||
} while (1);
|
||||
|
||||
if (kbd_wait_for_input() != KBD_REPLY_POR)
|
||||
return "Keyboard reset failed, no POR";
|
||||
|
||||
/*
|
||||
* Set keyboard controller mode. During this, the keyboard should be
|
||||
* in the disabled state.
|
||||
*
|
||||
* Set up to try again if the keyboard asks for RESEND.
|
||||
*/
|
||||
do {
|
||||
kbd_write_output_w(KBD_CMD_DISABLE);
|
||||
status = kbd_wait_for_input();
|
||||
if (status == KBD_REPLY_ACK)
|
||||
break;
|
||||
if (status != KBD_REPLY_RESEND)
|
||||
return "Disable keyboard: no ACK";
|
||||
} while (1);
|
||||
|
||||
kbd_write_command_w(KBD_CCMD_WRITE_MODE);
|
||||
kbd_write_output_w(KBD_MODE_KBD_INT
|
||||
| KBD_MODE_SYS
|
||||
| KBD_MODE_DISABLE_MOUSE
|
||||
| KBD_MODE_KCC);
|
||||
|
||||
/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
|
||||
kbd_write_command_w(KBD_CCMD_READ_MODE);
|
||||
if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
|
||||
/*
|
||||
* If the controller does not support conversion,
|
||||
* Set the keyboard to scan-code set 1.
|
||||
*/
|
||||
kbd_write_output_w(0xF0);
|
||||
kbd_wait_for_input();
|
||||
kbd_write_output_w(0x01);
|
||||
kbd_wait_for_input();
|
||||
}
|
||||
|
||||
kbd_write_output_w(KBD_CMD_ENABLE);
|
||||
if (kbd_wait_for_input() != KBD_REPLY_ACK)
|
||||
return "Enable keyboard: no ACK";
|
||||
/*
|
||||
* Finally, set the typematic rate to maximum.
|
||||
*/
|
||||
kbd_write_output_w(KBD_CMD_SET_RATE);
|
||||
if (kbd_wait_for_input() != KBD_REPLY_ACK)
|
||||
return "Set rate: no ACK";
|
||||
kbd_write_output_w(0x00);
|
||||
if (kbd_wait_for_input() != KBD_REPLY_ACK)
|
||||
return "Set rate: no ACK";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pckbd_init_hw(void)
|
||||
{
|
||||
/* kbd_request_region(); */
|
||||
|
||||
/* Flush any pending input. */
|
||||
kbd_clear_input();
|
||||
|
||||
if (kbd_startup_reset) {
|
||||
char *msg = initialize_kbd();
|
||||
if (msg)
|
||||
printk( "initialize_kbd: %s\n", msg);
|
||||
}
|
||||
|
||||
#if defined CONFIG_PSMOUSE
|
||||
psaux_init();
|
||||
#endif
|
||||
|
||||
/* Ok, finally allocate the IRQ, and off we go.. */
|
||||
#if 0
|
||||
kbd_request_irq( keyboard_interrupt );
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* @file
|
||||
*
|
||||
* @ingroup Console
|
||||
*
|
||||
* @brief printk support routines
|
||||
*
|
||||
* This file contains the required printk support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2012.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#if BSP_ENABLE_VGA
|
||||
#include <rtems/keyboard.h>
|
||||
#endif
|
||||
#include <bsp.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
rtems_device_minor_number BSPPrintkPort = 0;
|
||||
|
||||
void BSP_outch(char ch);
|
||||
int BSP_inch(void);
|
||||
|
||||
void BSP_outch(char ch)
|
||||
{
|
||||
#if BSP_ENABLE_VGA
|
||||
bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA;
|
||||
#else
|
||||
bool isVga = false;
|
||||
#endif
|
||||
|
||||
if ( !isVga ) {
|
||||
console_tbl *port = Console_Port_Tbl[BSPPrintkPort];
|
||||
if (port->pDeviceFns && port->pDeviceFns->deviceWritePolled) {
|
||||
port->pDeviceFns->deviceWritePolled( BSPPrintkPort, ch );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if BSP_ENABLE_VGA
|
||||
_IBMPC_outch( ch );
|
||||
#endif
|
||||
}
|
||||
|
||||
int BSP_inch(void)
|
||||
{
|
||||
#if BSP_ENABLE_VGA
|
||||
bool isVga = BSPPrintkPort == BSP_CONSOLE_VGA;
|
||||
#else
|
||||
bool isVga = false;
|
||||
#endif
|
||||
|
||||
int result = -1;
|
||||
|
||||
if ( !isVga ) {
|
||||
console_tbl *port = Console_Port_Tbl[BSPPrintkPort];
|
||||
if (port->pDeviceFns && port->pDeviceFns->deviceRead) {
|
||||
do {
|
||||
result = port->pDeviceFns->deviceRead( BSPPrintkPort );
|
||||
} while (result == -1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#if BSP_ENABLE_VGA
|
||||
result = BSP_wait_polled_input();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = BSP_outch;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = BSP_inch;
|
||||
@@ -1,562 +0,0 @@
|
||||
/*
|
||||
* linux/drivers/char/pc_keyb.c
|
||||
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
|
||||
* See keyboard.c for the whole history.
|
||||
* Major cleanup by Martin Mares, May 1997
|
||||
* Combined the keyboard and PS/2 mouse handling into one file,
|
||||
* because they share the same hardware.
|
||||
* Johan Myreen <jem@iki.fi> 1998-10-08.
|
||||
* Code fixes to handle mouse ACKs properly.
|
||||
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
|
||||
*
|
||||
* RTEMS port: by Rosimildo da Silva.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <termios.h>
|
||||
#include <i386_io.h>
|
||||
#include <rtems/mw_uid.h>
|
||||
#include <rtems/mouse_parser.h>
|
||||
|
||||
#define INITIALIZE_MOUSE
|
||||
/* Some configuration switches are present in the include file... */
|
||||
#include <rtems/ps2_drv.h>
|
||||
#include "ps2_mouse.h"
|
||||
|
||||
static void kbd_write_command_w(int data);
|
||||
#if 0
|
||||
static void kbd_write_output_w(int data);
|
||||
#endif
|
||||
|
||||
static unsigned char handle_kbd_event(void);
|
||||
static void ps2_set_driver_handler(int port, mouse_parser_enqueue_handler handler);
|
||||
|
||||
/* used only by send_data - set by keyboard_interrupt */
|
||||
static volatile unsigned char reply_expected = 0;
|
||||
static volatile unsigned char acknowledge = 0;
|
||||
static volatile unsigned char resend = 0;
|
||||
|
||||
/*
|
||||
* PS/2 Auxiliary Device
|
||||
*/
|
||||
static int psaux_init(void);
|
||||
|
||||
static struct aux_queue *queue; /* Mouse data buffer. */
|
||||
static int aux_count = 0;
|
||||
/* used when we send commands to the mouse that expect an ACK. */
|
||||
static unsigned char mouse_reply_expected = 0;
|
||||
|
||||
#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
|
||||
#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
|
||||
#define MAX_RETRIES 60 /* some aux operations take long time*/
|
||||
|
||||
static void ps2_mouse_interrupt(void *);
|
||||
static mouse_parser_enqueue_handler driver_input_handler_ps2 = NULL;
|
||||
|
||||
/*
|
||||
* This routine sets the handler to handle the characters received
|
||||
* from the serial port.
|
||||
*/
|
||||
static void ps2_set_driver_handler(
|
||||
int port,
|
||||
mouse_parser_enqueue_handler handler
|
||||
)
|
||||
{
|
||||
driver_input_handler_ps2 = handler;
|
||||
}
|
||||
|
||||
static void mdelay( unsigned long t )
|
||||
{
|
||||
Wait_X_ms( t );
|
||||
}
|
||||
|
||||
static void* termios_ttyp_paux = NULL;
|
||||
|
||||
/*
|
||||
* Wait for keyboard controller input buffer to drain.
|
||||
*
|
||||
* Don't use 'jiffies' so that we don't depend on
|
||||
* interrupts..
|
||||
*
|
||||
* Quote from PS/2 System Reference Manual:
|
||||
*
|
||||
* "Address hex 0060 and address hex 0064 should be written only when
|
||||
* the input-buffer-full bit and output-buffer-full bit in the
|
||||
* Controller Status register are set 0."
|
||||
*/
|
||||
|
||||
static void kb_wait(void)
|
||||
{
|
||||
unsigned long timeout = KBC_TIMEOUT;
|
||||
|
||||
do {
|
||||
/*
|
||||
* "handle_kbd_event()" will handle any incoming events
|
||||
* while we wait - keypresses or mouse movement.
|
||||
*/
|
||||
unsigned char status = handle_kbd_event();
|
||||
|
||||
if (! (status & KBD_STAT_IBF))
|
||||
return;
|
||||
|
||||
mdelay(1);
|
||||
timeout--;
|
||||
} while (timeout);
|
||||
|
||||
#ifdef KBD_REPORT_TIMEOUTS
|
||||
printk( "Keyboard timed out[1]\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int do_acknowledge(unsigned char scancode)
|
||||
{
|
||||
if (reply_expected) {
|
||||
|
||||
/* Unfortunately, we must recognise these codes only if we know they
|
||||
* are known to be valid (i.e., after sending a command), because there
|
||||
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
|
||||
* keys with such codes :(
|
||||
*/
|
||||
if (scancode == KBD_REPLY_ACK) {
|
||||
acknowledge = 1;
|
||||
reply_expected = 0;
|
||||
return 0;
|
||||
} else if (scancode == KBD_REPLY_RESEND) {
|
||||
resend = 1;
|
||||
reply_expected = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Should not happen... */
|
||||
#if 0
|
||||
printk( "keyboard reply expected - got %02x\n", scancode);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void handle_mouse_event(unsigned char scancode)
|
||||
{
|
||||
if (mouse_reply_expected) {
|
||||
if (scancode == AUX_ACK) {
|
||||
mouse_reply_expected--;
|
||||
return;
|
||||
}
|
||||
mouse_reply_expected = 0;
|
||||
}
|
||||
|
||||
if (aux_count) {
|
||||
int head = queue->head;
|
||||
queue->buf[head] = scancode;
|
||||
head = (head + 1) & (AUX_BUF_SIZE-1);
|
||||
if (head != queue->tail) {
|
||||
queue->head = head;
|
||||
}
|
||||
|
||||
/* if the input queue is active, add to it */
|
||||
if( driver_input_handler_ps2 ) {
|
||||
driver_input_handler_ps2( &scancode, 1 );
|
||||
} else {
|
||||
/* post this byte to termios */
|
||||
rtems_termios_enqueue_raw_characters( termios_ttyp_paux, (char *)&scancode, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This reads the keyboard status port, and does the
|
||||
* appropriate action.
|
||||
*
|
||||
* It requires that we hold the keyboard controller
|
||||
* spinlock.
|
||||
*/
|
||||
static unsigned char handle_kbd_event(void)
|
||||
{
|
||||
unsigned char status = kbd_read_status();
|
||||
unsigned int work = 10000;
|
||||
|
||||
while (status & KBD_STAT_OBF) {
|
||||
unsigned char scancode;
|
||||
scancode = kbd_read_input();
|
||||
if (status & KBD_STAT_MOUSE_OBF) {
|
||||
handle_mouse_event(scancode);
|
||||
} else {
|
||||
do_acknowledge(scancode);
|
||||
printk("pc_keyb: %X ", scancode );
|
||||
}
|
||||
status = kbd_read_status();
|
||||
if(!work--) {
|
||||
printk("pc_keyb: controller jammed (0x%02X).\n", status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ps2_mouse_interrupt(void * unused)
|
||||
{
|
||||
handle_kbd_event();
|
||||
}
|
||||
|
||||
static void kbd_write_command_w(int data)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_command(data);
|
||||
}
|
||||
|
||||
static void kbd_write_cmd(int cmd)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_command(KBD_CCMD_WRITE_MODE);
|
||||
kb_wait();
|
||||
kbd_write_output(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this is a dual port controller.
|
||||
*/
|
||||
static int detect_auxiliary_port(void)
|
||||
{
|
||||
int loops = 10;
|
||||
int retval = 0;
|
||||
|
||||
/* Put the value 0x5A in the output buffer using the "Write
|
||||
* Auxiliary Device Output Buffer" command (0xD3). Poll the
|
||||
* Status Register for a while to see if the value really
|
||||
* turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
|
||||
* bit is also set to 1 in the Status Register, we assume this
|
||||
* controller has an Auxiliary Port (a.k.a. Mouse Port).
|
||||
*/
|
||||
kb_wait();
|
||||
kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
|
||||
|
||||
kb_wait();
|
||||
kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
|
||||
|
||||
do {
|
||||
unsigned char status = kbd_read_status();
|
||||
if (status & KBD_STAT_OBF) {
|
||||
kbd_read_input();
|
||||
if (status & KBD_STAT_MOUSE_OBF) {
|
||||
printk( "Detected PS/2 Mouse Port.\n");
|
||||
retval = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
} while (--loops);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a byte to the mouse.
|
||||
*/
|
||||
static void aux_write_dev(int val)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
|
||||
kb_wait();
|
||||
kbd_write_output(val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a byte to the mouse & handle returned ack
|
||||
*/
|
||||
static void aux_write_ack(int val)
|
||||
{
|
||||
kb_wait();
|
||||
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
|
||||
kb_wait();
|
||||
kbd_write_output(val);
|
||||
/* we expect an ACK in response. */
|
||||
mouse_reply_expected++;
|
||||
kb_wait();
|
||||
}
|
||||
|
||||
static unsigned char get_from_queue(void)
|
||||
{
|
||||
unsigned char result;
|
||||
result = queue->buf[queue->tail];
|
||||
queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int queue_empty(void)
|
||||
{
|
||||
return queue->head == queue->tail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Random magic cookie for the aux device
|
||||
*/
|
||||
#define AUX_DEV ((void *)queue)
|
||||
|
||||
static int release_aux(void)
|
||||
{
|
||||
rtems_status_code status;
|
||||
if (--aux_count)
|
||||
return 0;
|
||||
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
|
||||
kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
|
||||
status = rtems_interrupt_handler_remove(
|
||||
AUX_IRQ,
|
||||
ps2_mouse_interrupt,
|
||||
NULL
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install interrupt handler.
|
||||
* Enable auxiliary device.
|
||||
*/
|
||||
|
||||
static int open_aux(void)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
if (aux_count++) {
|
||||
return 0;
|
||||
}
|
||||
queue->head = queue->tail = 0; /* Flush input queue */
|
||||
|
||||
status = rtems_interrupt_handler_install(
|
||||
AUX_IRQ,
|
||||
"ps2_mouse",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
ps2_mouse_interrupt,
|
||||
NULL
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
|
||||
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on
|
||||
controller. */
|
||||
aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
|
||||
kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put bytes from input queue to buffer.
|
||||
*/
|
||||
size_t read_aux(char * buffer, size_t count )
|
||||
{
|
||||
size_t i = count;
|
||||
unsigned char c;
|
||||
|
||||
if (queue_empty()) {
|
||||
return 0;
|
||||
}
|
||||
while (i > 0 && !queue_empty()) {
|
||||
c = get_from_queue();
|
||||
*buffer++ = c;
|
||||
i--;
|
||||
}
|
||||
return count-i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the aux device.
|
||||
*/
|
||||
static int write_aux( int minor, const char * buffer, int count )
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (count) {
|
||||
int written = 0;
|
||||
if (count > 32)
|
||||
count = 32; /* Limit to 32 bytes. */
|
||||
do {
|
||||
char c;
|
||||
c = *buffer++;
|
||||
aux_write_dev(c);
|
||||
written++;
|
||||
} while (--count);
|
||||
retval = -EIO;
|
||||
if (written) {
|
||||
retval = written;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int psaux_init( void )
|
||||
{
|
||||
if( !detect_auxiliary_port() ) {
|
||||
printk( "PS/2 - mouse not found.\n" );
|
||||
return -EIO;
|
||||
}
|
||||
queue = (struct aux_queue *)malloc( sizeof(*queue) );
|
||||
memset(queue, 0, sizeof(*queue));
|
||||
queue->head = queue->tail = 0;
|
||||
queue->proc_list = NULL;
|
||||
|
||||
#ifdef INITIALIZE_MOUSE
|
||||
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
|
||||
aux_write_ack(AUX_SET_SAMPLE);
|
||||
aux_write_ack(100); /* 100 samples/sec */
|
||||
aux_write_ack(AUX_SET_RES);
|
||||
aux_write_ack(3); /* 8 counts per mm */
|
||||
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
|
||||
#endif /* INITIALIZE_MOUSE */
|
||||
kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
|
||||
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* paux device driver INITIALIZE entry point.
|
||||
*/
|
||||
rtems_device_driver paux_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
/*
|
||||
* Set up TERMIOS
|
||||
*/
|
||||
rtems_termios_initialize();
|
||||
|
||||
printk( "PS/2 mouse probe.\n" );
|
||||
if( psaux_init() < 0 ) {
|
||||
printk("Error detecting PS/2 mouse --\n");
|
||||
/* we might want to finish the application here !!! */
|
||||
}
|
||||
open_aux();
|
||||
|
||||
/*
|
||||
* Register the device
|
||||
*/
|
||||
status = rtems_io_register_name ("/dev/mouse", major, 0);
|
||||
if (status != RTEMS_SUCCESSFUL) {
|
||||
printk("Error registering paux device!\n");
|
||||
rtems_fatal_error_occurred (status);
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} /* tty_initialize */
|
||||
|
||||
static int paux_last_close(int major, int minor, void *arg)
|
||||
{
|
||||
release_aux();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the aux device. This routine is invoked by the
|
||||
* termios framework whenever the "ECHO" feature is on.
|
||||
* It does nothing write now.
|
||||
*/
|
||||
static ssize_t write_aux_echo( int minor, const char * buffer, size_t count )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* paux device driver OPEN entry point
|
||||
*/
|
||||
rtems_device_driver paux_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
rtems_status_code status;
|
||||
static rtems_termios_callbacks cb =
|
||||
{
|
||||
NULL, /* firstOpen */
|
||||
paux_last_close, /* lastClose */
|
||||
NULL, /* poll read */
|
||||
write_aux_echo, /* write */
|
||||
NULL, /* setAttributes */
|
||||
NULL, /* stopRemoteTx */
|
||||
NULL, /* startRemoteTx */
|
||||
0 /* outputUsesInterrupts */
|
||||
};
|
||||
|
||||
status = rtems_termios_open (major, minor, arg, &cb );
|
||||
termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* paux device driver CLOSE entry point
|
||||
*/
|
||||
rtems_device_driver paux_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return (rtems_termios_close (arg));
|
||||
}
|
||||
|
||||
/*
|
||||
* paux device driver READ entry point.
|
||||
* Read characters from the PS/2 mouse.
|
||||
*/
|
||||
rtems_device_driver paux_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
return rtems_termios_read (arg);
|
||||
} /* tty_read */
|
||||
|
||||
/*
|
||||
* paux device driver WRITE entry point.
|
||||
* Write characters to the PS/2 mouse.
|
||||
*/
|
||||
rtems_device_driver paux_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
|
||||
char *buffer = rw_args->buffer;
|
||||
int maximum = rw_args->count;
|
||||
rw_args->bytes_moved = write_aux( minor, buffer, maximum );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} /* tty_write */
|
||||
|
||||
/*
|
||||
* Handle ioctl request.
|
||||
*/
|
||||
rtems_device_driver paux_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = arg;
|
||||
|
||||
switch( args->command ) {
|
||||
default:
|
||||
return rtems_termios_ioctl (arg);
|
||||
break;
|
||||
|
||||
case MW_UID_REGISTER_DEVICE:
|
||||
printk( "PS2 Mouse: registering\n" );
|
||||
mouse_parser_initialize( "ps2" );
|
||||
ps2_set_driver_handler( minor, mouse_parser_enqueue );
|
||||
break;
|
||||
|
||||
case MW_UID_UNREGISTER_DEVICE:
|
||||
/*
|
||||
unregister_mou_msg_queue( -1 );
|
||||
*/
|
||||
ps2_set_driver_handler( minor, NULL );
|
||||
break;
|
||||
}
|
||||
args->ioctl_return = 0;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup i386_pc386
|
||||
*
|
||||
* @brief Keyboard and mouse definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* include/linux/pc_keyb.h
|
||||
* PC Keyboard And Keyboard Controller
|
||||
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
||||
*
|
||||
* RTEMS port: by Rosimildo da Silva.
|
||||
*
|
||||
* This module was ported from Linux.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configuration Switches
|
||||
*/
|
||||
|
||||
#undef KBD_REPORT_ERR /* Report keyboard errors */
|
||||
#define KBD_REPORT_UNKN /* Report unknown scan codes */
|
||||
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
|
||||
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
|
||||
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
|
||||
|
||||
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
|
||||
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
|
||||
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
|
||||
|
||||
/*
|
||||
* Internal variables of the driver
|
||||
*/
|
||||
|
||||
extern unsigned char pckbd_read_mask;
|
||||
extern unsigned char aux_device_present;
|
||||
|
||||
/*
|
||||
* Keyboard Controller Registers on normal PCs.
|
||||
*/
|
||||
|
||||
#define KBD_STATUS_REG 0x64 /* Status register (R) */
|
||||
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
|
||||
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
|
||||
|
||||
/*
|
||||
* Keyboard Controller Commands
|
||||
*/
|
||||
|
||||
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
|
||||
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
|
||||
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
|
||||
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
|
||||
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
|
||||
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
|
||||
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
|
||||
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
|
||||
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
|
||||
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
|
||||
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
|
||||
initiated by the auxiliary device */
|
||||
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
|
||||
|
||||
/*
|
||||
* Keyboard Commands
|
||||
*/
|
||||
|
||||
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
|
||||
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
|
||||
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
|
||||
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
|
||||
#define KBD_CMD_RESET 0xFF /* Reset */
|
||||
|
||||
/*
|
||||
* Keyboard Replies
|
||||
*/
|
||||
|
||||
#define KBD_REPLY_POR 0xAA /* Power on reset */
|
||||
#define KBD_REPLY_ACK 0xFA /* Command ACK */
|
||||
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
|
||||
|
||||
/*
|
||||
* Status Register Bits
|
||||
*/
|
||||
|
||||
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
|
||||
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
|
||||
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
|
||||
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
|
||||
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
|
||||
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
|
||||
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
|
||||
#define KBD_STAT_PERR 0x80 /* Parity error */
|
||||
|
||||
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
|
||||
|
||||
/*
|
||||
* Controller Mode Register Bits
|
||||
*/
|
||||
|
||||
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
|
||||
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
|
||||
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
|
||||
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
|
||||
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
|
||||
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
|
||||
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
|
||||
#define KBD_MODE_RFU 0x80
|
||||
|
||||
/*
|
||||
* Mouse Commands
|
||||
*/
|
||||
|
||||
#define AUX_SET_RES 0xE8 /* Set resolution */
|
||||
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
|
||||
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
|
||||
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
|
||||
#define AUX_SET_STREAM 0xEA /* Set stream mode */
|
||||
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
|
||||
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
|
||||
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
|
||||
#define AUX_RESET 0xFF /* Reset aux device */
|
||||
#define AUX_ACK 0xFA /* Command byte ACK. */
|
||||
|
||||
#define AUX_BUF_SIZE 512 /* This might be better divisible by
|
||||
three to make overruns stay in sync
|
||||
but then the read function would need
|
||||
a lock etc - ick */
|
||||
|
||||
struct aux_queue {
|
||||
unsigned long head;
|
||||
unsigned long tail;
|
||||
struct wait_queue *proc_list;
|
||||
struct fasync_struct *fasync;
|
||||
unsigned char buf[AUX_BUF_SIZE];
|
||||
};
|
||||
|
||||
/* How to access the keyboard macros on this platform. */
|
||||
#define kbd_read_input() inb(KBD_DATA_REG)
|
||||
#define kbd_read_status() inb(KBD_STATUS_REG)
|
||||
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
|
||||
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
|
||||
|
||||
/*
|
||||
* Machine specific bits for the PS/2 driver
|
||||
*/
|
||||
|
||||
#define AUX_IRQ 12
|
||||
@@ -1,109 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Driver for RTD316 ISA SCC Board
|
||||
*
|
||||
* The RTD316 has a single Z85C30.
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2014.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <bsp.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rtems/termiostypes.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/z85c30.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <bsp/rtd316.h>
|
||||
#include <rtems/score/i386.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
#define RTD_CLOCK_RATE (460800 * 32)
|
||||
|
||||
uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg)
|
||||
{
|
||||
register uint8_t val = 0;
|
||||
|
||||
outport_byte( addr, reg );
|
||||
/* It appears the no delay is needed between the accesses. */
|
||||
inport_byte( addr, val );
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void rtd316_com_set_register(uint32_t addr,uint8_t reg, uint8_t val)
|
||||
{
|
||||
outport_byte( addr, reg );
|
||||
/* It appears the no delay is needed between the accesses. */
|
||||
outport_byte( addr, val );
|
||||
}
|
||||
|
||||
rtems_device_driver rtd316_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor_arg,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
int p;
|
||||
console_tbl *ports;
|
||||
console_tbl *port_p;
|
||||
|
||||
/*
|
||||
* Now allocate array of device structures and fill them in
|
||||
*/
|
||||
ports = calloc( 2, sizeof( console_tbl ) );
|
||||
port_p = ports;
|
||||
|
||||
for ( p=0 ; p<2 ; p++ ) {
|
||||
char name[32];
|
||||
sprintf( name, "/dev/rtd316_1_%d", p );
|
||||
printk("Found %s\n", name );
|
||||
port_p->sDeviceName = strdup( name );
|
||||
port_p->deviceType = SERIAL_Z85C30;
|
||||
#if 0
|
||||
port_p->pDeviceFns = &z85c30_fns_polled;
|
||||
#else
|
||||
port_p->pDeviceFns = &z85c30_fns;
|
||||
#endif
|
||||
|
||||
port_p->deviceProbe = NULL;
|
||||
port_p->pDeviceFlow = NULL;
|
||||
port_p->ulMargin = 16;
|
||||
port_p->ulHysteresis = 8;
|
||||
port_p->pDeviceParams = (void *) 9600;
|
||||
port_p->getRegister = rtd316_com_get_register;
|
||||
port_p->setRegister = rtd316_com_set_register;
|
||||
port_p->getData = NULL;
|
||||
port_p->setData = NULL;
|
||||
port_p->ulClock = RTD_CLOCK_RATE;
|
||||
port_p->ulIntVector = 9;
|
||||
|
||||
if ( p==0 ) {
|
||||
port_p->ulDataPort = 0;
|
||||
port_p->ulCtrlPort1 = 0x340;
|
||||
port_p->ulCtrlPort2 = 0x341;
|
||||
} else {
|
||||
port_p->ulDataPort = 1;
|
||||
port_p->ulCtrlPort1 = 0x342;
|
||||
port_p->ulCtrlPort2 = 0x343;
|
||||
}
|
||||
port_p++;
|
||||
} /* end ports */
|
||||
|
||||
/*
|
||||
* Register the devices
|
||||
*/
|
||||
console_register_devices( ports, 2 );
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <bsp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
/* select which serial port the mouse is connected to */
|
||||
#if defined(SERIAL_MOUSE_COM2)
|
||||
#define MOUSE_DEVICE "/dev/com2"
|
||||
#else
|
||||
#define MOUSE_DEVICE "/dev/com1"
|
||||
#endif
|
||||
|
||||
static const char *SerialMouseDevice = MOUSE_DEVICE;
|
||||
|
||||
bool bsp_get_serial_mouse_device(
|
||||
const char **name,
|
||||
const char **type
|
||||
)
|
||||
{
|
||||
const char *consname;
|
||||
|
||||
*name = SerialMouseDevice;
|
||||
*type = "ms";
|
||||
|
||||
/* Check if this port is not been used as console */
|
||||
consname = Console_Port_Tbl[ Console_Port_Minor ]->sDeviceName;
|
||||
if ( !strcmp(MOUSE_DEVICE, consname) ) {
|
||||
printk( "SERIAL MOUSE: port selected as console.(%s)\n", *name );
|
||||
rtems_fatal_error_occurred( -1 );
|
||||
}
|
||||
|
||||
printk("Mouse Device: %s\n", *name );
|
||||
return name;
|
||||
}
|
||||
@@ -1,477 +0,0 @@
|
||||
/*
|
||||
* This file was brought over from FreeBSD for the PCI device table.
|
||||
* The code for using the table is RTEMS specific is also under the
|
||||
* FreeBSD license.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2012.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Marcel Moolenaar
|
||||
* Copyright (c) 2001 M. Warner Losh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __rtems__
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <i386_io.h>
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
|
||||
#endif
|
||||
|
||||
#define DEFAULT_RCLK 1843200
|
||||
|
||||
#ifndef __rtems__
|
||||
static int uart_pci_probe(device_t dev);
|
||||
|
||||
static device_method_t uart_pci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, uart_pci_probe),
|
||||
DEVMETHOD(device_attach, uart_bus_attach),
|
||||
DEVMETHOD(device_detach, uart_bus_detach),
|
||||
DEVMETHOD(device_resume, uart_bus_resume),
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t uart_pci_driver = {
|
||||
uart_driver_name,
|
||||
uart_pci_methods,
|
||||
sizeof(struct uart_softc),
|
||||
};
|
||||
#endif
|
||||
|
||||
struct pci_id {
|
||||
uint16_t vendor;
|
||||
uint16_t device;
|
||||
uint16_t subven;
|
||||
uint16_t subdev;
|
||||
const char *desc;
|
||||
int rid;
|
||||
int rclk;
|
||||
int regshft;
|
||||
};
|
||||
|
||||
static const struct pci_id pci_ns8250_ids[] = {
|
||||
{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14,
|
||||
128 * DEFAULT_RCLK },
|
||||
{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14,
|
||||
128 * DEFAULT_RCLK },
|
||||
{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 },
|
||||
{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 },
|
||||
{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2",
|
||||
0x10 },
|
||||
{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 },
|
||||
{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 },
|
||||
{ 0x103c, 0x3301, 0xffff, 0, "HP iLO serial port", 0x10 },
|
||||
{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 },
|
||||
{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 },
|
||||
{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 },
|
||||
{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 },
|
||||
{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 },
|
||||
{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 },
|
||||
{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 },
|
||||
{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 },
|
||||
{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 },
|
||||
{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 },
|
||||
{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 },
|
||||
{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 },
|
||||
{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530",
|
||||
0x18 },
|
||||
{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 },
|
||||
{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 },
|
||||
{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 },
|
||||
{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART",
|
||||
0x10, 16384000 },
|
||||
{ 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART",
|
||||
0x10 },
|
||||
{ 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10},
|
||||
{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 },
|
||||
{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10,
|
||||
8 * DEFAULT_RCLK },
|
||||
{ 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10,
|
||||
24 * DEFAULT_RCLK, 2 },
|
||||
{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10,
|
||||
24 * DEFAULT_RCLK, 2 },
|
||||
{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
|
||||
{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
|
||||
{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 },
|
||||
{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 },
|
||||
{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 },
|
||||
{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller",
|
||||
0x10 },
|
||||
{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 },
|
||||
{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 },
|
||||
{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 },
|
||||
{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 },
|
||||
{ 0x8086, 0x8c3d, 0xffff, 0, "Intel Lynx Point KT Controller", 0x10 },
|
||||
{ 0x8086, 0x8cbd, 0xffff, 0, "Intel Wildcat Point KT Controller", 0x10 },
|
||||
{ 0x8086, 0x9c3d, 0xffff, 0, "Intel Lynx Point-LP HECI KT", 0x10 },
|
||||
{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 },
|
||||
{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 },
|
||||
{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 },
|
||||
{ 0x9710, 0x9900, 0xa000, 0x1000,
|
||||
"MosChip MCS9900 PCIe to Peripheral Controller", 0x10 },
|
||||
{ 0x9710, 0x9901, 0xa000, 0x1000,
|
||||
"MosChip MCS9901 PCIe to Peripheral Controller", 0x10 },
|
||||
{ 0x9710, 0x9904, 0xa000, 0x1000,
|
||||
"MosChip MCS9904 PCIe to Peripheral Controller", 0x10 },
|
||||
{ 0x9710, 0x9922, 0xa000, 0x1000,
|
||||
"MosChip MCS9922 PCIe to Peripheral Controller", 0x10 },
|
||||
{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 },
|
||||
{ 0xffff, 0, 0xffff, 0, NULL, 0, 0}
|
||||
};
|
||||
|
||||
#ifndef __rtems__
|
||||
const static struct pci_id *
|
||||
uart_pci_match(device_t dev, const struct pci_id *id)
|
||||
{
|
||||
uint16_t device, subdev, subven, vendor;
|
||||
|
||||
vendor = pci_get_vendor(dev);
|
||||
device = pci_get_device(dev);
|
||||
while (id->vendor != 0xffff &&
|
||||
(id->vendor != vendor || id->device != device))
|
||||
id++;
|
||||
if (id->vendor == 0xffff)
|
||||
return (NULL);
|
||||
if (id->subven == 0xffff)
|
||||
return (id);
|
||||
subven = pci_get_subvendor(dev);
|
||||
subdev = pci_get_subdevice(dev);
|
||||
while (id->vendor == vendor && id->device == device &&
|
||||
(id->subven != subven || id->subdev != subdev))
|
||||
id++;
|
||||
return ((id->vendor == vendor && id->device == device) ? id : NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
uart_pci_probe(device_t dev)
|
||||
{
|
||||
struct uart_softc *sc;
|
||||
const struct pci_id *id;
|
||||
int result;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
id = uart_pci_match(dev, pci_ns8250_ids);
|
||||
if (id != NULL) {
|
||||
sc->sc_class = &uart_ns8250_class;
|
||||
goto match;
|
||||
}
|
||||
/* Add checks for non-ns8250 IDs here. */
|
||||
return (ENXIO);
|
||||
|
||||
match:
|
||||
result = uart_bus_probe(dev, id->regshft, id->rclk, id->rid, 0);
|
||||
/* Bail out on error. */
|
||||
if (result > 0)
|
||||
return (result);
|
||||
/* Set/override the device description. */
|
||||
if (id->desc)
|
||||
device_set_desc(dev, id->desc);
|
||||
return (result);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef __rtems__
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/bspimpl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/pci.h>
|
||||
#include "../../../../../../../bsps/shared/dev/serial/legacy-console.h"
|
||||
|
||||
#define MAX_BOARDS 4
|
||||
|
||||
/*
|
||||
* Information saved from PCI scan
|
||||
*/
|
||||
typedef struct {
|
||||
bool found;
|
||||
const char* desc;
|
||||
uint32_t base;
|
||||
uint8_t irq;
|
||||
uint8_t bus;
|
||||
uint8_t slot;
|
||||
int ports;
|
||||
uint32_t clock;
|
||||
} port_instance_conf_t;
|
||||
|
||||
/*
|
||||
* Memory Mapped Register Access Routines
|
||||
*/
|
||||
|
||||
#define UART_PCI_IO (0)
|
||||
|
||||
static uint8_t pci_ns16550_mem_get_register(uint32_t addr, uint8_t i)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
|
||||
val = *reg;
|
||||
if (UART_PCI_IO)
|
||||
printk( "RD(%p -> 0x%02x) ", reg, val );
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pci_ns16550_mem_set_register(uint32_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
|
||||
if (UART_PCI_IO)
|
||||
printk( "WR(%p <- 0x%02x) ", reg, val );
|
||||
*reg = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Register Access Routines
|
||||
*/
|
||||
static uint8_t pci_ns16550_io_get_register(uint32_t addr, uint8_t i)
|
||||
{
|
||||
uint8_t val = rtems_inb(addr + i);
|
||||
if (UART_PCI_IO)
|
||||
printk( "RD(%p -> 0x%02x) ", (void*) addr + i, val );
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pci_ns16550_io_set_register(uint32_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
if (UART_PCI_IO)
|
||||
printk( "WR(%p <- 0x%02x) ", (void*) addr + i, val );
|
||||
rtems_outb(addr + i, val);
|
||||
}
|
||||
|
||||
void pci_uart_probe(void)
|
||||
{
|
||||
port_instance_conf_t conf[MAX_BOARDS];
|
||||
int boards = 0;
|
||||
int b = 0;
|
||||
console_tbl *ports;
|
||||
console_tbl *port_p;
|
||||
int bus;
|
||||
int dev;
|
||||
int fun;
|
||||
int status;
|
||||
int instance;
|
||||
int i;
|
||||
int total_ports = 0;
|
||||
|
||||
for ( b=0 ; b<MAX_BOARDS ; b++ ) {
|
||||
conf[b].found = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan for Serial port boards
|
||||
*/
|
||||
for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
|
||||
|
||||
for ( i=0 ; pci_ns8250_ids[i].vendor != 0xffff ; i++ ) {
|
||||
if ( pci_ns8250_ids[i].vendor == 0xffff ) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
printk("Looking for 0x%04x:0x%04x\n",
|
||||
pci_ns8250_ids[i].vendor,
|
||||
pci_ns8250_ids[i].device);
|
||||
*/
|
||||
status = pci_find_device(
|
||||
pci_ns8250_ids[i].vendor,
|
||||
pci_ns8250_ids[i].device,
|
||||
instance,
|
||||
&bus,
|
||||
&dev,
|
||||
&fun
|
||||
);
|
||||
if ( status == PCIB_ERR_SUCCESS ) {
|
||||
uint8_t irq;
|
||||
uint32_t base;
|
||||
bool io;
|
||||
|
||||
pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0, &base );
|
||||
|
||||
/*
|
||||
* Reject memory mapped 64-bit boards. We need 2 BAR registers and the
|
||||
* driver's base field is only 32-bits any way.
|
||||
*/
|
||||
io = (base & 1) == 1;
|
||||
if (io || (!io && (((base >> 1) & 3) != 2))) {
|
||||
boards++;
|
||||
conf[instance].found = true;
|
||||
conf[instance].desc = pci_ns8250_ids[i].desc;
|
||||
conf[instance].clock = pci_ns8250_ids[i].rclk;
|
||||
conf[instance].ports = 1;
|
||||
total_ports += conf[instance].ports;
|
||||
|
||||
pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
|
||||
|
||||
conf[instance].irq = irq;
|
||||
conf[instance].base = base;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now allocate array of device structures and fill them in
|
||||
*/
|
||||
if (boards) {
|
||||
int device_instance;
|
||||
|
||||
ports = calloc( total_ports, sizeof( console_tbl ) );
|
||||
if (ports != NULL) {
|
||||
port_p = ports;
|
||||
device_instance = 1;
|
||||
for (b = 0; b < MAX_BOARDS; b++) {
|
||||
uint32_t base = 0;
|
||||
bool io;
|
||||
const char* locatable = "";
|
||||
const char* prefectable = locatable;
|
||||
char name[32];
|
||||
if ( conf[b].found == false )
|
||||
continue;
|
||||
sprintf( name, "/dev/pcicom%d", device_instance++ );
|
||||
port_p->sDeviceName = strdup( name );
|
||||
port_p->deviceType = SERIAL_NS16550;
|
||||
if ( conf[b].irq <= 15 ) {
|
||||
port_p->pDeviceFns = &ns16550_fns;
|
||||
} else {
|
||||
printk(
|
||||
"%s IRQ=%d >= 16 requires APIC support, using polling\n",
|
||||
name,
|
||||
conf[b].irq
|
||||
);
|
||||
port_p->pDeviceFns = &ns16550_fns_polled;
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI BAR (http://wiki.osdev.org/PCI#Base_Address_Registers):
|
||||
*
|
||||
* Bit 0: 0 = memory, 1 = IO
|
||||
*
|
||||
* Memory:
|
||||
* Bit 2-1 : 0 = any 32bit address,
|
||||
* 1 = < 1M
|
||||
* 2 = any 64bit address
|
||||
* Bit 3 : 0 = no, 1 = yes
|
||||
* Bit 31-4 : base address (16-byte aligned)
|
||||
*
|
||||
* IO:
|
||||
* Bit 1 : reserved
|
||||
* Bit 31-2 : base address (4-byte aligned)
|
||||
*/
|
||||
|
||||
io = (conf[b].base & 1) == 1;
|
||||
|
||||
if (io) {
|
||||
base = conf[b].base & 0xfffffffc;
|
||||
} else {
|
||||
int loc = (conf[b].base >> 1) & 3;
|
||||
if (loc == 0) {
|
||||
base = conf[b].base & 0xfffffff0;
|
||||
locatable = ",A32";
|
||||
} else if (loc == 1) {
|
||||
base = conf[b].base & 0x0000fff0;
|
||||
locatable = ",A16";
|
||||
}
|
||||
prefectable = (conf[b].base & (1 << 3)) == 0 ? ",no-prefech" : ",prefetch";
|
||||
}
|
||||
|
||||
port_p->deviceProbe = NULL;
|
||||
port_p->pDeviceFlow = NULL;
|
||||
port_p->ulMargin = 16;
|
||||
port_p->ulHysteresis = 8;
|
||||
port_p->pDeviceParams = (void *) 9600;
|
||||
port_p->ulCtrlPort1 = base;
|
||||
port_p->ulCtrlPort2 = 0; /* NA */
|
||||
port_p->ulDataPort = 0; /* NA */
|
||||
if (io) {
|
||||
port_p->getRegister = pci_ns16550_io_get_register;
|
||||
port_p->setRegister = pci_ns16550_io_set_register;
|
||||
} else {
|
||||
port_p->getRegister = pci_ns16550_mem_get_register;
|
||||
port_p->setRegister = pci_ns16550_mem_set_register;
|
||||
}
|
||||
port_p->getData = NULL; /* NA */
|
||||
port_p->setData = NULL; /* NA */
|
||||
port_p->ulClock = conf[b].clock;
|
||||
port_p->ulIntVector = conf[b].irq;
|
||||
|
||||
|
||||
printk(
|
||||
"%s:%d:%s,%s:0x%lx%s%s,irq:%d,clk:%lu\n", /* */
|
||||
name, b, conf[b].desc,
|
||||
io ? "io" : "mem", base, locatable, prefectable,
|
||||
conf[b].irq, conf[b].clock
|
||||
);
|
||||
|
||||
|
||||
port_p++;
|
||||
} /* end boards */
|
||||
|
||||
/*
|
||||
* Register the devices
|
||||
*/
|
||||
console_register_devices( ports, total_ports );
|
||||
|
||||
/*
|
||||
* Do not free the ports memory, the console hold this memory for-ever.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* This file contains the termios TTY driver for the i386
|
||||
* vga.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libchip/serial.h>
|
||||
#include <rtems/vgacons.h>
|
||||
#include <rtems/keyboard.h>
|
||||
#include <libchip/sersupp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp.h>
|
||||
#include <crt.h>
|
||||
#include <assert.h>
|
||||
#include <rtems/keyboard.h>
|
||||
|
||||
#define VGACONS_STATIC static
|
||||
|
||||
/*
|
||||
* vgacons_init
|
||||
*
|
||||
* This function initializes the VGA console to a quiecsent state.
|
||||
*/
|
||||
VGACONS_STATIC void vgacons_init(int minor)
|
||||
{
|
||||
/*
|
||||
* Note: We do not initialize the KBD interface here since
|
||||
* it was initialized regardless of whether the
|
||||
* vga is available or not. Therefore it is initialized
|
||||
* in bsp_start.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_open
|
||||
*
|
||||
* This function opens a port for communication.
|
||||
*
|
||||
* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
|
||||
*/
|
||||
VGACONS_STATIC int vgacons_open(
|
||||
int major,
|
||||
int minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_close
|
||||
*
|
||||
* This function shuts down the requested port.
|
||||
*/
|
||||
VGACONS_STATIC int vgacons_close(
|
||||
int major,
|
||||
int minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return(RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_write_polled
|
||||
*
|
||||
* This routine polls out the requested character.
|
||||
*/
|
||||
VGACONS_STATIC void vgacons_write_polled(
|
||||
int minor,
|
||||
char c
|
||||
)
|
||||
{
|
||||
_IBMPC_outch( c );
|
||||
if( c == '\n')
|
||||
_IBMPC_outch( '\r' ); /* LF = LF + CR */
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_write_support_polled
|
||||
*
|
||||
* Console Termios output entry point when using polled output.
|
||||
*
|
||||
*/
|
||||
VGACONS_STATIC ssize_t vgacons_write_support_polled(
|
||||
int minor,
|
||||
const char *buf,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
int nwrite = 0;
|
||||
|
||||
/*
|
||||
* poll each byte in the string out of the port.
|
||||
*/
|
||||
while (nwrite < len) {
|
||||
vgacons_write_polled(minor, *buf++);
|
||||
nwrite++;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the number of bytes written.
|
||||
*/
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_inbyte_nonblocking_polled
|
||||
*
|
||||
* Console Termios polling input entry point.
|
||||
*/
|
||||
VGACONS_STATIC int vgacons_inbyte_nonblocking_polled(
|
||||
int minor
|
||||
)
|
||||
{
|
||||
if( rtems_kbpoll() ) {
|
||||
int c = getch();
|
||||
return c;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* vgacons_set_attributes
|
||||
*
|
||||
* This function sets the UART channel to reflect the requested termios
|
||||
* port settings.
|
||||
*/
|
||||
VGACONS_STATIC int vgacons_set_attributes(
|
||||
int minor,
|
||||
const struct termios *t
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool vgacons_probe(
|
||||
int minor
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
static bool firstTime = true;
|
||||
|
||||
if ((*(unsigned char*) NB_MAX_ROW_ADDR == 0) &&
|
||||
(*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a video card, let's assume there is also a keyboard.
|
||||
* The means that we need the ISR installed in case someone wants to
|
||||
* use the Keyboard or PS2 Mouse. With Microwindows, the console
|
||||
* can be COM1 and you can still use the mouse/VGA for graphics.
|
||||
*/
|
||||
if ( firstTime ) {
|
||||
status = rtems_interrupt_handler_install(
|
||||
BSP_KEYBOARD,
|
||||
"vgacons",
|
||||
RTEMS_INTERRUPT_UNIQUE,
|
||||
keyboard_interrupt,
|
||||
NULL
|
||||
);
|
||||
assert(status == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
firstTime = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const console_fns vgacons_fns =
|
||||
{
|
||||
libchip_serial_default_probe, /* deviceProbe */
|
||||
vgacons_open, /* deviceFirstOpen */
|
||||
vgacons_close, /* deviceLastClose */
|
||||
vgacons_inbyte_nonblocking_polled, /* deviceRead */
|
||||
vgacons_write_support_polled, /* deviceWrite */
|
||||
vgacons_init, /* deviceInitialize */
|
||||
vgacons_write_polled, /* deviceWritePolled */
|
||||
vgacons_set_attributes, /* deviceSetAttributes */
|
||||
FALSE, /* deviceOutputUsesInterrupts */
|
||||
};
|
||||
@@ -1,757 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
|
||||
* Copyright (c) 1991 David I. Bell
|
||||
* Permission is granted to use, distribute, or modify this source,
|
||||
* provided that this copyright notice remains intact.
|
||||
*
|
||||
* Alternate EGA/VGA Screen Driver Init, direct hw programming
|
||||
*/
|
||||
#include <i386_io.h>
|
||||
|
||||
#ifdef __rtems__
|
||||
#define ROMFONT 0 /* =0 no bios rom fonts available*/
|
||||
#else
|
||||
#define ROMFONT 1 /* =1 uses PC rom fonts */
|
||||
#endif
|
||||
|
||||
/* defines are defined in device.h of the MicroWindows package */
|
||||
#define MODE_SET 0 /* draw pixels as given (default) */
|
||||
#define MODE_XOR 1 /* draw pixels using XOR */
|
||||
#define MODE_OR 2 /* draw pixels using OR (notimp)*/
|
||||
#define MODE_AND 3 /* draw pixels using AND (notimp)*/
|
||||
#define MODE_MAX 3
|
||||
typedef int MODE; /* drawing mode*/
|
||||
|
||||
/* Define one and only one of the following to be nonzero*/
|
||||
#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/
|
||||
#define VGA_STANDARD 1 /* standard VGA 640x480*/
|
||||
#define EGA_STANDARD 0 /* standard EGA 640x350*/
|
||||
|
||||
#define DONE 0
|
||||
#define IN 1
|
||||
#define OUT 2
|
||||
|
||||
#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */
|
||||
#define FONT_CHARS 256 /* number of characters in font tables */
|
||||
#define CHAR_WIDTH 8 /* number of pixels for character width */
|
||||
|
||||
#define PALREG 0x3c0
|
||||
#define SEQREG 0x3c4
|
||||
#define SEQVAL 0x3c5
|
||||
#define GRREG 0x3ce
|
||||
#define GRVAL 0x3cf
|
||||
#define ATTRREG 0x3da
|
||||
#define CRTCREG 0x3d4
|
||||
#define CRTCVAL 0x3d5
|
||||
|
||||
#define GENREG1 0x3c2
|
||||
#define GENREG2 0x3cc
|
||||
#define GENREG3 0x3ca
|
||||
|
||||
#define DATA_ROTATE 3 /* register number for data rotate */
|
||||
|
||||
typedef struct {
|
||||
int action;
|
||||
int port1;
|
||||
int data1;
|
||||
int port2;
|
||||
int data2;
|
||||
} REGIO;
|
||||
|
||||
#if ROMFONT
|
||||
extern FARADDR rom_char_addr; /* address of ROM font*/
|
||||
extern int ROM_CHAR_HEIGHT; /* ROM character height*/
|
||||
#endif
|
||||
|
||||
/* local data*/
|
||||
static REGIO graphics_on[];
|
||||
static REGIO graph_off[];
|
||||
|
||||
/* entry points*/
|
||||
void ega_hwinit(void);
|
||||
void ega_hwterm(void);
|
||||
|
||||
/* local routines*/
|
||||
static void writeregs(REGIO *rp);
|
||||
static void out_word(unsigned int p,unsigned int d);
|
||||
static void setmode(MODE mode);
|
||||
|
||||
void
|
||||
ega_hwinit(void)
|
||||
{
|
||||
writeregs(graphics_on);
|
||||
}
|
||||
|
||||
void
|
||||
ega_hwterm(void)
|
||||
{
|
||||
setmode(MODE_SET);
|
||||
|
||||
/* Copy character table from ROM back into bit plane 2 before turning
|
||||
* off graphics.
|
||||
*/
|
||||
out_word(SEQREG, 0x0100); /* syn reset */
|
||||
out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */
|
||||
out_word(SEQREG, 0x0704); /* sequential addressing */
|
||||
out_word(SEQREG, 0x0300); /* clear synchronous reset */
|
||||
|
||||
out_word(GRREG, 0x0204); /* select map 2 for CPU reads */
|
||||
out_word(GRREG, 0x0005); /* disable odd-even addressing */
|
||||
|
||||
#if ROMFONT
|
||||
{
|
||||
FARADDR srcoffset;
|
||||
FARADDR destoffset;
|
||||
int data;
|
||||
int ch;
|
||||
int row;
|
||||
|
||||
srcoffset = rom_char_addr;
|
||||
destoffset = EGA_BASE;
|
||||
for (ch = 0; ch < FONT_CHARS; ch++) {
|
||||
for(row = 0; row < ROM_CHAR_HEIGHT; row++) {
|
||||
data = GETBYTE_FP(srcoffset++);
|
||||
PUTBYTE_FP(destoffset++, data);
|
||||
}
|
||||
destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally set the registers back for text mode. */
|
||||
writeregs(graph_off);
|
||||
}
|
||||
|
||||
/* Set the graphics registers as indicated by the given table */
|
||||
static void
|
||||
writeregs(REGIO *rp)
|
||||
{
|
||||
for (; rp->action != DONE; rp++) {
|
||||
switch (rp->action) {
|
||||
case IN:
|
||||
inp(rp->port1);
|
||||
break;
|
||||
case OUT:
|
||||
outp(rp->port1, rp->data1);
|
||||
if (rp->port2)
|
||||
outp(rp->port2, rp->data2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a word to an I/O port. */
|
||||
static void
|
||||
out_word(unsigned int p,unsigned int d)
|
||||
{
|
||||
outp(p, d & 0xff);
|
||||
outp(p + 1, (d >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/* Values for the data rotate register to implement drawing modes. */
|
||||
static unsigned char mode_table[MODE_MAX + 1] = {
|
||||
0x00, 0x18, 0x10, 0x08
|
||||
};
|
||||
|
||||
/* Set the drawing mode.
|
||||
* This is either SET, OR, AND, or XOR.
|
||||
*/
|
||||
static void
|
||||
setmode(MODE mode)
|
||||
{
|
||||
if (mode > MODE_MAX)
|
||||
return;
|
||||
outp(GRREG, DATA_ROTATE);
|
||||
outp(GRVAL, mode_table[mode]);
|
||||
}
|
||||
|
||||
#if VGA_ET4000
|
||||
|
||||
/* VGA 800x600 16-color graphics (BIOS mode 0x29).
|
||||
*/
|
||||
REGIO graphics_on[] = {
|
||||
/* Reset attr F/F */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Disable palette */
|
||||
OUT, PALREG, 0, 0, 0,
|
||||
|
||||
/* Reset sequencer regs */
|
||||
OUT, SEQREG, 0, SEQVAL, 0,
|
||||
OUT, SEQREG, 1, SEQVAL, 1,
|
||||
OUT, SEQREG, 2, SEQVAL, 0x0f,
|
||||
OUT, SEQREG, 3, SEQVAL, 0,
|
||||
OUT, SEQREG, 4, SEQVAL, 6,
|
||||
|
||||
/* Misc out reg */
|
||||
OUT, GENREG1, 0xe3, 0, 0,
|
||||
|
||||
/* Sequencer enable */
|
||||
OUT, SEQREG, 0, SEQVAL, 0x03,
|
||||
|
||||
/* Unprotect crtc regs 0-7 */
|
||||
OUT, CRTCREG, 0x11, CRTCVAL, 0,
|
||||
|
||||
/* Crtc */
|
||||
OUT, CRTCREG, 0, CRTCVAL, 0x7a,
|
||||
OUT, CRTCREG, 1, CRTCVAL, 0x63,
|
||||
OUT, CRTCREG, 2, CRTCVAL, 0x64,
|
||||
OUT, CRTCREG, 3, CRTCVAL, 0x1d,
|
||||
OUT, CRTCREG, 4, CRTCVAL, 0x68,
|
||||
OUT, CRTCREG, 5, CRTCVAL, 0x9a,
|
||||
OUT, CRTCREG, 6, CRTCVAL, 0x78,
|
||||
OUT, CRTCREG, 7, CRTCVAL, 0xf0,
|
||||
OUT, CRTCREG, 8, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 9, CRTCVAL, 0x60,
|
||||
OUT, CRTCREG, 10, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 11, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 12, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 13, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 14, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 15, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 16, CRTCVAL, 0x5c,
|
||||
OUT, CRTCREG, 17, CRTCVAL, 0x8e,
|
||||
OUT, CRTCREG, 18, CRTCVAL, 0x57,
|
||||
OUT, CRTCREG, 19, CRTCVAL, 0x32,
|
||||
OUT, CRTCREG, 20, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 21, CRTCVAL, 0x5b,
|
||||
OUT, CRTCREG, 22, CRTCVAL, 0x75,
|
||||
OUT, CRTCREG, 23, CRTCVAL, 0xc3,
|
||||
OUT, CRTCREG, 24, CRTCVAL, 0xff,
|
||||
|
||||
/* Graphics controller */
|
||||
OUT, GENREG2, 0x00, 0, 0,
|
||||
OUT, GENREG3, 0x01, 0, 0,
|
||||
OUT, GRREG, 0, GRVAL, 0x00,
|
||||
OUT, GRREG, 1, GRVAL, 0x00,
|
||||
OUT, GRREG, 2, GRVAL, 0x00,
|
||||
OUT, GRREG, 3, GRVAL, 0x00,
|
||||
OUT, GRREG, 4, GRVAL, 0x00,
|
||||
OUT, GRREG, 5, GRVAL, 0x00,
|
||||
OUT, GRREG, 6, GRVAL, 0x05,
|
||||
OUT, GRREG, 7, GRVAL, 0x0f,
|
||||
OUT, GRREG, 8, GRVAL, 0xff,
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Palette */
|
||||
OUT, PALREG, 0, PALREG, 0x00,
|
||||
OUT, PALREG, 1, PALREG, 0x01,
|
||||
OUT, PALREG, 2, PALREG, 0x02,
|
||||
OUT, PALREG, 3, PALREG, 0x03,
|
||||
OUT, PALREG, 4, PALREG, 0x04,
|
||||
OUT, PALREG, 5, PALREG, 0x05,
|
||||
OUT, PALREG, 6, PALREG, 0x06,
|
||||
OUT, PALREG, 7, PALREG, 0x07,
|
||||
OUT, PALREG, 8, PALREG, 0x38,
|
||||
OUT, PALREG, 9, PALREG, 0x39,
|
||||
OUT, PALREG, 10, PALREG, 0x3a,
|
||||
OUT, PALREG, 11, PALREG, 0x3b,
|
||||
OUT, PALREG, 12, PALREG, 0x3c,
|
||||
OUT, PALREG, 13, PALREG, 0x3d,
|
||||
OUT, PALREG, 14, PALREG, 0x3e,
|
||||
OUT, PALREG, 15, PALREG, 0x3f,
|
||||
OUT, PALREG, 16, PALREG, 0x01,
|
||||
OUT, PALREG, 17, PALREG, 0x00,
|
||||
OUT, PALREG, 18, PALREG, 0x0f,
|
||||
OUT, PALREG, 19, PALREG, 0x00,
|
||||
|
||||
/* Enable palette */
|
||||
OUT, PALREG, 0x20, 0, 0,
|
||||
|
||||
/* End of table */
|
||||
DONE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* VGA 80x25 text (BIOS mode 3).
|
||||
*/
|
||||
static REGIO graph_off[] = {
|
||||
/* Reset attr F/F */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Disable palette */
|
||||
OUT, PALREG, 0, 0, 0,
|
||||
|
||||
/* Reset sequencer regs */
|
||||
OUT, SEQREG, 0, SEQVAL, 1,
|
||||
OUT, SEQREG, 1, SEQVAL, 1,
|
||||
OUT, SEQREG, 2, SEQVAL, 3,
|
||||
OUT, SEQREG, 3, SEQVAL, 0,
|
||||
OUT, SEQREG, 4, SEQVAL, 2,
|
||||
|
||||
/* Misc out reg */
|
||||
OUT, GENREG1, 0x63, 0, 0,
|
||||
|
||||
/* Sequencer enable */
|
||||
OUT, SEQREG, 0, SEQVAL, 3,
|
||||
|
||||
/* Unprotect crtc regs 0-7 */
|
||||
OUT, CRTCREG, 0x11, CRTCVAL, 0,
|
||||
|
||||
/* Crtc */
|
||||
OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
|
||||
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
|
||||
OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
|
||||
OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
|
||||
OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
|
||||
OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
|
||||
OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
|
||||
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
|
||||
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
|
||||
OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
|
||||
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
|
||||
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
|
||||
OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
|
||||
OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
|
||||
OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
|
||||
OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
|
||||
OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
|
||||
OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
|
||||
OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
|
||||
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
|
||||
OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
|
||||
OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
|
||||
OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
|
||||
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
|
||||
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
|
||||
|
||||
/* Graphics controller */
|
||||
OUT, GENREG2, 0x00, 0, 0,
|
||||
OUT, GENREG3, 0x01, 0, 0,
|
||||
OUT, GRREG, 0, GRVAL, 0x00,
|
||||
OUT, GRREG, 1, GRVAL, 0x00,
|
||||
OUT, GRREG, 2, GRVAL, 0x00,
|
||||
OUT, GRREG, 3, GRVAL, 0x00,
|
||||
OUT, GRREG, 4, GRVAL, 0x00,
|
||||
OUT, GRREG, 5, GRVAL, 0x10,
|
||||
OUT, GRREG, 6, GRVAL, 0x0e,
|
||||
OUT, GRREG, 7, GRVAL, 0x00,
|
||||
OUT, GRREG, 8, GRVAL, 0xff,
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Palette */
|
||||
OUT, PALREG, 0, PALREG, 0x00,
|
||||
OUT, PALREG, 1, PALREG, 0x01,
|
||||
OUT, PALREG, 2, PALREG, 0x02,
|
||||
OUT, PALREG, 3, PALREG, 0x03,
|
||||
OUT, PALREG, 4, PALREG, 0x04,
|
||||
OUT, PALREG, 5, PALREG, 0x05,
|
||||
OUT, PALREG, 6, PALREG, 0x06,
|
||||
OUT, PALREG, 7, PALREG, 0x07,
|
||||
OUT, PALREG, 8, PALREG, 0x10,
|
||||
OUT, PALREG, 9, PALREG, 0x11,
|
||||
OUT, PALREG, 10, PALREG, 0x12,
|
||||
OUT, PALREG, 11, PALREG, 0x13,
|
||||
OUT, PALREG, 12, PALREG, 0x14,
|
||||
OUT, PALREG, 13, PALREG, 0x15,
|
||||
OUT, PALREG, 14, PALREG, 0x16,
|
||||
OUT, PALREG, 15, PALREG, 0x17,
|
||||
OUT, PALREG, 16, PALREG, 0x08,
|
||||
OUT, PALREG, 17, PALREG, 0x00,
|
||||
OUT, PALREG, 18, PALREG, 0x0f,
|
||||
OUT, PALREG, 19, PALREG, 0x00,
|
||||
|
||||
/* Enable palette */
|
||||
OUT, PALREG, 0x20, 0, 0,
|
||||
|
||||
/* End of table */
|
||||
DONE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if VGA_STANDARD
|
||||
|
||||
/* VGA 640x480 16-color graphics (BIOS mode 0x12).
|
||||
*/
|
||||
static REGIO graphics_on[] = {
|
||||
/* Reset attr F/F */
|
||||
{ IN, ATTRREG, 0, 0, 0 },
|
||||
|
||||
/* Disable palette */
|
||||
{ OUT, PALREG, 0, 0, 0 },
|
||||
|
||||
/* Reset sequencer regs */
|
||||
{ OUT, SEQREG, 0, SEQVAL, 0 },
|
||||
{ OUT, SEQREG, 1, SEQVAL, 1 },
|
||||
{ OUT, SEQREG, 2, SEQVAL, 0x0f },
|
||||
{ OUT, SEQREG, 3, SEQVAL, 0 },
|
||||
{ OUT, SEQREG, 4, SEQVAL, 6 },
|
||||
|
||||
/* Misc out reg */
|
||||
{ OUT, GENREG1, 0xe3, 0, 0 },
|
||||
|
||||
/* Sequencer enable */
|
||||
{ OUT, SEQREG, 0, SEQVAL, 0x03 },
|
||||
|
||||
/* Unprotect crtc regs 0-7 */
|
||||
{ OUT, CRTCREG, 0x11, CRTCVAL, 0 },
|
||||
|
||||
/* Crtc */
|
||||
{ OUT, CRTCREG, 0, CRTCVAL, 0x5f },
|
||||
{ OUT, CRTCREG, 1, CRTCVAL, 0x4f },
|
||||
{ OUT, CRTCREG, 2, CRTCVAL, 0x50 },
|
||||
{ OUT, CRTCREG, 3, CRTCVAL, 0x82 },
|
||||
{ OUT, CRTCREG, 4, CRTCVAL, 0x54 },
|
||||
{ OUT, CRTCREG, 5, CRTCVAL, 0x80 },
|
||||
{ OUT, CRTCREG, 6, CRTCVAL, 0x0b },
|
||||
{ OUT, CRTCREG, 7, CRTCVAL, 0x3e },
|
||||
{ OUT, CRTCREG, 8, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 9, CRTCVAL, 0x40 },
|
||||
{ OUT, CRTCREG, 10, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 11, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 12, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 13, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 14, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 15, CRTCVAL, 0x59 },
|
||||
{ OUT, CRTCREG, 16, CRTCVAL, 0xea },
|
||||
{ OUT, CRTCREG, 17, CRTCVAL, 0x8c },
|
||||
{ OUT, CRTCREG, 18, CRTCVAL, 0xdf },
|
||||
{ OUT, CRTCREG, 19, CRTCVAL, 0x28 },
|
||||
{ OUT, CRTCREG, 20, CRTCVAL, 0x00 },
|
||||
{ OUT, CRTCREG, 21, CRTCVAL, 0xe7 },
|
||||
{ OUT, CRTCREG, 22, CRTCVAL, 0x04 },
|
||||
{ OUT, CRTCREG, 23, CRTCVAL, 0xe3 },
|
||||
{ OUT, CRTCREG, 24, CRTCVAL, 0xff },
|
||||
|
||||
/* Graphics controller */
|
||||
{ OUT, GENREG2, 0x00, 0, 0 },
|
||||
{ OUT, GENREG3, 0x01, 0, 0 },
|
||||
{ OUT, GRREG, 0, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 1, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 2, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 3, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 4, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 5, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 6, GRVAL, 0x05 },
|
||||
{ OUT, GRREG, 7, GRVAL, 0x0f },
|
||||
{ OUT, GRREG, 8, GRVAL, 0xff },
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
{ IN, ATTRREG, 0, 0, 0 },
|
||||
|
||||
/* Palette */
|
||||
{ OUT, PALREG, 0, PALREG, 0x00 },
|
||||
{ OUT, PALREG, 1, PALREG, 0x01 },
|
||||
{ OUT, PALREG, 2, PALREG, 0x02 },
|
||||
{ OUT, PALREG, 3, PALREG, 0x03 },
|
||||
{ OUT, PALREG, 4, PALREG, 0x04 },
|
||||
{ OUT, PALREG, 5, PALREG, 0x05 },
|
||||
{ OUT, PALREG, 6, PALREG, 0x06 },
|
||||
{ OUT, PALREG, 7, PALREG, 0x07 },
|
||||
{ OUT, PALREG, 8, PALREG, 0x38 },
|
||||
{ OUT, PALREG, 9, PALREG, 0x39 },
|
||||
{ OUT, PALREG, 10, PALREG, 0x3a },
|
||||
{ OUT, PALREG, 11, PALREG, 0x3b },
|
||||
{ OUT, PALREG, 12, PALREG, 0x3c },
|
||||
{ OUT, PALREG, 13, PALREG, 0x3d },
|
||||
{ OUT, PALREG, 14, PALREG, 0x3e },
|
||||
{ OUT, PALREG, 15, PALREG, 0x3f },
|
||||
{ OUT, PALREG, 16, PALREG, 0x01 },
|
||||
{ OUT, PALREG, 17, PALREG, 0x00 },
|
||||
{ OUT, PALREG, 18, PALREG, 0x0f },
|
||||
{ OUT, PALREG, 19, PALREG, 0x00 },
|
||||
|
||||
/* Enable palette */
|
||||
{ OUT, PALREG, 0x20, 0, 0 },
|
||||
|
||||
/* End of table */
|
||||
{ DONE, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* VGA 80x25 text (BIOS mode 3).
|
||||
*/
|
||||
static REGIO graph_off[] = {
|
||||
/* Reset attr F/F */
|
||||
{ IN, ATTRREG, 0, 0, 0 },
|
||||
|
||||
/* Disable palette */
|
||||
{ OUT, PALREG, 0, 0, 0 },
|
||||
|
||||
/* Reset sequencer regs */
|
||||
{ OUT, SEQREG, 0, SEQVAL, 1 },
|
||||
{ OUT, SEQREG, 1, SEQVAL, 1 },
|
||||
{ OUT, SEQREG, 2, SEQVAL, 3 },
|
||||
{ OUT, SEQREG, 3, SEQVAL, 0 },
|
||||
{ OUT, SEQREG, 4, SEQVAL, 2 },
|
||||
|
||||
/* Misc out reg */
|
||||
{ OUT, GENREG1, 0x63, 0, 0 },
|
||||
|
||||
/* Sequencer enable */
|
||||
{ OUT, SEQREG, 0, SEQVAL, 3 },
|
||||
|
||||
/* Unprotect crtc regs 0-7 */
|
||||
{ OUT, CRTCREG, 0x11, CRTCVAL, 0 },
|
||||
|
||||
/* Crtc */
|
||||
{ OUT, CRTCREG, 0, CRTCVAL, 0x5f }, /* horiz total */
|
||||
{ OUT, CRTCREG, 1, CRTCVAL, 0x4f }, /* horiz end */
|
||||
{ OUT, CRTCREG, 2, CRTCVAL, 0x50 }, /* horiz blank */
|
||||
{ OUT, CRTCREG, 3, CRTCVAL, 0x82 }, /* end blank */
|
||||
{ OUT, CRTCREG, 4, CRTCVAL, 0x55 }, /* horiz retrace */
|
||||
{ OUT, CRTCREG, 5, CRTCVAL, 0x81 }, /* end retrace */
|
||||
{ OUT, CRTCREG, 6, CRTCVAL, 0xbf }, /* vert total */
|
||||
{ OUT, CRTCREG, 7, CRTCVAL, 0x1f }, /* overflows */
|
||||
{ OUT, CRTCREG, 8, CRTCVAL, 0x00 }, /* row scan */
|
||||
{ OUT, CRTCREG, 9, CRTCVAL, 0x4f }, /* max scan line */
|
||||
{ OUT, CRTCREG, 10, CRTCVAL, 0x00 }, /* cursor start */
|
||||
{ OUT, CRTCREG, 11, CRTCVAL, 0x0f }, /* cursor end */
|
||||
{ OUT, CRTCREG, 12, CRTCVAL, 0x0e }, /* start high addr */
|
||||
{ OUT, CRTCREG, 13, CRTCVAL, 0xb0 }, /* low addr */
|
||||
{ OUT, CRTCREG, 14, CRTCVAL, 0x16 }, /* cursor high */
|
||||
{ OUT, CRTCREG, 15, CRTCVAL, 0x30 }, /* cursor low */
|
||||
{ OUT, CRTCREG, 16, CRTCVAL, 0x9c }, /* vert retrace */
|
||||
{ OUT, CRTCREG, 17, CRTCVAL, 0x8e }, /* retrace end */
|
||||
{ OUT, CRTCREG, 18, CRTCVAL, 0x8f }, /* vert end */
|
||||
{ OUT, CRTCREG, 19, CRTCVAL, 0x28 }, /* offset */
|
||||
{ OUT, CRTCREG, 20, CRTCVAL, 0x1f }, /* underline */
|
||||
{ OUT, CRTCREG, 21, CRTCVAL, 0x96 }, /* vert blank */
|
||||
{ OUT, CRTCREG, 22, CRTCVAL, 0xb9 }, /* end blank */
|
||||
{ OUT, CRTCREG, 23, CRTCVAL, 0xa3 }, /* crt mode */
|
||||
{ OUT, CRTCREG, 24, CRTCVAL, 0xff }, /* line compare */
|
||||
|
||||
/* Graphics controller */
|
||||
{ OUT, GENREG2, 0x00, 0, 0 },
|
||||
{ OUT, GENREG3, 0x01, 0, 0 },
|
||||
{ OUT, GRREG, 0, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 1, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 2, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 3, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 4, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 5, GRVAL, 0x10 },
|
||||
{ OUT, GRREG, 6, GRVAL, 0x0e },
|
||||
{ OUT, GRREG, 7, GRVAL, 0x00 },
|
||||
{ OUT, GRREG, 8, GRVAL, 0xff },
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
{ IN, ATTRREG, 0, 0, 0 },
|
||||
|
||||
/* Palette */
|
||||
{ OUT, PALREG, 0, PALREG, 0x00 },
|
||||
{ OUT, PALREG, 1, PALREG, 0x01 },
|
||||
{ OUT, PALREG, 2, PALREG, 0x02 },
|
||||
{ OUT, PALREG, 3, PALREG, 0x03 },
|
||||
{ OUT, PALREG, 4, PALREG, 0x04 },
|
||||
{ OUT, PALREG, 5, PALREG, 0x05 },
|
||||
{ OUT, PALREG, 6, PALREG, 0x06 },
|
||||
{ OUT, PALREG, 7, PALREG, 0x07 },
|
||||
{ OUT, PALREG, 8, PALREG, 0x10 },
|
||||
{ OUT, PALREG, 9, PALREG, 0x11 },
|
||||
{ OUT, PALREG, 10, PALREG, 0x12 },
|
||||
{ OUT, PALREG, 11, PALREG, 0x13 },
|
||||
{ OUT, PALREG, 12, PALREG, 0x14 },
|
||||
{ OUT, PALREG, 13, PALREG, 0x15 },
|
||||
{ OUT, PALREG, 14, PALREG, 0x16 },
|
||||
{ OUT, PALREG, 15, PALREG, 0x17 },
|
||||
{ OUT, PALREG, 16, PALREG, 0x08 },
|
||||
{ OUT, PALREG, 17, PALREG, 0x00 },
|
||||
{ OUT, PALREG, 18, PALREG, 0x0f },
|
||||
{ OUT, PALREG, 19, PALREG, 0x00 },
|
||||
|
||||
/* Enable palette */
|
||||
{ OUT, PALREG, 0x20, 0, 0 },
|
||||
|
||||
/* End of table */
|
||||
{ DONE, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if EGA_STANDARD
|
||||
|
||||
/* EGA 640x350 16-color graphics (BIOS mode 0x10).
|
||||
*/
|
||||
static REGIO graphics_on[] = {
|
||||
/* Reset attr F/F */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Disable palette */
|
||||
OUT, PALREG, 0, 0, 0,
|
||||
|
||||
/* Reset sequencer regs */
|
||||
OUT, SEQREG, 0, SEQVAL, 0,
|
||||
OUT, SEQREG, 1, SEQVAL, 1,
|
||||
OUT, SEQREG, 2, SEQVAL, 0x0f,
|
||||
OUT, SEQREG, 3, SEQVAL, 0,
|
||||
OUT, SEQREG, 4, SEQVAL, 6,
|
||||
|
||||
/* Misc out reg */
|
||||
OUT, GENREG1, 0xa7, 0, 0,
|
||||
|
||||
/* Sequencer enable */
|
||||
OUT, SEQREG, 0, SEQVAL, 0x03,
|
||||
|
||||
/* Unprotect crtc regs 0-7 */
|
||||
OUT, CRTCREG, 0x11, CRTCVAL, 0,
|
||||
|
||||
/* Crtc */
|
||||
OUT, CRTCREG, 0, CRTCVAL, 0x5b,
|
||||
OUT, CRTCREG, 1, CRTCVAL, 0x4f,
|
||||
OUT, CRTCREG, 2, CRTCVAL, 0x53,
|
||||
OUT, CRTCREG, 3, CRTCVAL, 0x37,
|
||||
OUT, CRTCREG, 4, CRTCVAL, 0x52,
|
||||
OUT, CRTCREG, 5, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 6, CRTCVAL, 0x6c,
|
||||
OUT, CRTCREG, 7, CRTCVAL, 0x1f,
|
||||
OUT, CRTCREG, 8, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 9, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 10, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 11, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 12, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 13, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 14, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 15, CRTCVAL, 0x00,
|
||||
OUT, CRTCREG, 16, CRTCVAL, 0x5e,
|
||||
OUT, CRTCREG, 17, CRTCVAL, 0x2b,
|
||||
OUT, CRTCREG, 18, CRTCVAL, 0x5d,
|
||||
OUT, CRTCREG, 19, CRTCVAL, 0x28,
|
||||
OUT, CRTCREG, 20, CRTCVAL, 0x0f,
|
||||
OUT, CRTCREG, 21, CRTCVAL, 0x5f,
|
||||
OUT, CRTCREG, 22, CRTCVAL, 0x0a,
|
||||
OUT, CRTCREG, 23, CRTCVAL, 0xe3,
|
||||
OUT, CRTCREG, 24, CRTCVAL, 0xff,
|
||||
|
||||
/* Graphics controller */
|
||||
OUT, GENREG2, 0x00, 0, 0,
|
||||
OUT, GENREG3, 0x01, 0, 0,
|
||||
OUT, GRREG, 0, GRVAL, 0x00,
|
||||
OUT, GRREG, 1, GRVAL, 0x00,
|
||||
OUT, GRREG, 2, GRVAL, 0x00,
|
||||
OUT, GRREG, 3, GRVAL, 0x00,
|
||||
OUT, GRREG, 4, GRVAL, 0x00,
|
||||
OUT, GRREG, 5, GRVAL, 0x00,
|
||||
OUT, GRREG, 6, GRVAL, 0x05,
|
||||
OUT, GRREG, 7, GRVAL, 0x0f,
|
||||
OUT, GRREG, 8, GRVAL, 0xff,
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Palette */
|
||||
OUT, PALREG, 0, PALREG, 0x00,
|
||||
OUT, PALREG, 1, PALREG, 0x01,
|
||||
OUT, PALREG, 2, PALREG, 0x02,
|
||||
OUT, PALREG, 3, PALREG, 0x03,
|
||||
OUT, PALREG, 4, PALREG, 0x04,
|
||||
OUT, PALREG, 5, PALREG, 0x05,
|
||||
OUT, PALREG, 6, PALREG, 0x06,
|
||||
OUT, PALREG, 7, PALREG, 0x07,
|
||||
OUT, PALREG, 8, PALREG, 0x38,
|
||||
OUT, PALREG, 9, PALREG, 0x39,
|
||||
OUT, PALREG, 10, PALREG, 0x3a,
|
||||
OUT, PALREG, 11, PALREG, 0x3b,
|
||||
OUT, PALREG, 12, PALREG, 0x3c,
|
||||
OUT, PALREG, 13, PALREG, 0x3d,
|
||||
OUT, PALREG, 14, PALREG, 0x3e,
|
||||
OUT, PALREG, 15, PALREG, 0x3f,
|
||||
OUT, PALREG, 16, PALREG, 0x01,
|
||||
OUT, PALREG, 17, PALREG, 0x00,
|
||||
OUT, PALREG, 18, PALREG, 0x0f,
|
||||
OUT, PALREG, 19, PALREG, 0x00,
|
||||
|
||||
/* Enable palette */
|
||||
OUT, PALREG, 0x20, 0, 0,
|
||||
|
||||
/* End of table */
|
||||
DONE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* EGA 80x25 text (BIOS mode 3).
|
||||
*/
|
||||
static REGIO graph_off[] = {
|
||||
/* Reset attr F/F */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Disable palette */
|
||||
OUT, PALREG, 0, 0, 0,
|
||||
|
||||
/* Reset sequencer regs */
|
||||
OUT, SEQREG, 0, SEQVAL, 1,
|
||||
OUT, SEQREG, 1, SEQVAL, 1,
|
||||
OUT, SEQREG, 2, SEQVAL, 3,
|
||||
OUT, SEQREG, 3, SEQVAL, 0,
|
||||
OUT, SEQREG, 4, SEQVAL, 3,
|
||||
|
||||
/* Misc out reg */
|
||||
OUT, GENREG1, 0xa7, 0, 0,
|
||||
|
||||
/* Sequencer enable */
|
||||
OUT, SEQREG, 0, SEQVAL, 3,
|
||||
|
||||
/* Crtc */
|
||||
OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */
|
||||
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
|
||||
OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */
|
||||
OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */
|
||||
OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */
|
||||
OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */
|
||||
OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */
|
||||
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
|
||||
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
|
||||
OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */
|
||||
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
|
||||
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
|
||||
OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */
|
||||
OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */
|
||||
OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */
|
||||
OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */
|
||||
OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */
|
||||
OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */
|
||||
OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */
|
||||
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
|
||||
OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */
|
||||
OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */
|
||||
OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */
|
||||
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
|
||||
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
|
||||
|
||||
/* Graphics controller */
|
||||
OUT, GENREG2, 0x00, 0, 0,
|
||||
OUT, GENREG3, 0x01, 0, 0,
|
||||
OUT, GRREG, 0, GRVAL, 0x00,
|
||||
OUT, GRREG, 1, GRVAL, 0x00,
|
||||
OUT, GRREG, 2, GRVAL, 0x00,
|
||||
OUT, GRREG, 3, GRVAL, 0x00,
|
||||
OUT, GRREG, 4, GRVAL, 0x00,
|
||||
OUT, GRREG, 5, GRVAL, 0x10,
|
||||
OUT, GRREG, 6, GRVAL, 0x0e,
|
||||
OUT, GRREG, 7, GRVAL, 0x00,
|
||||
OUT, GRREG, 8, GRVAL, 0xff,
|
||||
|
||||
/* Reset attribute flip/flop */
|
||||
IN, ATTRREG, 0, 0, 0,
|
||||
|
||||
/* Palette */
|
||||
OUT, PALREG, 0, PALREG, 0x00,
|
||||
OUT, PALREG, 1, PALREG, 0x01,
|
||||
OUT, PALREG, 2, PALREG, 0x02,
|
||||
OUT, PALREG, 3, PALREG, 0x03,
|
||||
OUT, PALREG, 4, PALREG, 0x04,
|
||||
OUT, PALREG, 5, PALREG, 0x05,
|
||||
OUT, PALREG, 6, PALREG, 0x14,
|
||||
OUT, PALREG, 7, PALREG, 0x07,
|
||||
OUT, PALREG, 8, PALREG, 0x38,
|
||||
OUT, PALREG, 9, PALREG, 0x39,
|
||||
OUT, PALREG, 10, PALREG, 0x3a,
|
||||
OUT, PALREG, 11, PALREG, 0x3b,
|
||||
OUT, PALREG, 12, PALREG, 0x3c,
|
||||
OUT, PALREG, 13, PALREG, 0x3d,
|
||||
OUT, PALREG, 14, PALREG, 0x3e,
|
||||
OUT, PALREG, 15, PALREG, 0x3f,
|
||||
OUT, PALREG, 16, PALREG, 0x08,
|
||||
OUT, PALREG, 17, PALREG, 0x00,
|
||||
OUT, PALREG, 18, PALREG, 0x0f,
|
||||
OUT, PALREG, 19, PALREG, 0x00,
|
||||
|
||||
/* Enable palette */
|
||||
OUT, PALREG, 0x20, 0, 0,
|
||||
|
||||
/* End of table */
|
||||
DONE, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* videoAsm.S - This file contains code for displaying cursor on the console
|
||||
*
|
||||
* Copyright (C) 1998 valette@crf.canon.fr
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
.file "videoAsm.s"
|
||||
|
||||
#include <crt.h>
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl wr_cursor /* Move cursor position */
|
||||
|
||||
/*
|
||||
* void wr_cursor(newPosition, ioBaseAddr)
|
||||
*/
|
||||
|
||||
wr_cursor: pushl %ecx
|
||||
movl 8(%esp), %ecx /* Get new cursor position */
|
||||
movb $CC_CURSHIGH, %al /* Cursor high location */
|
||||
movl 12(%esp), %edx /* Get IO base address */
|
||||
outb (%dx)
|
||||
incw %dx /* Program Data register */
|
||||
movb %ch, %al
|
||||
outb (%dx) /* Update high location cursor */
|
||||
decw %dx /* Program Index Register */
|
||||
movb $CC_CURSLOW, %al /* Cursor low location */
|
||||
outb (%dx)
|
||||
incw %dx /* Program Data Register */
|
||||
movb %cl, %al
|
||||
outb (%dx) /* Update low location cursor */
|
||||
popl %ecx
|
||||
ret
|
||||
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* linux/drivers/char/vt.c
|
||||
*
|
||||
* Copyright (C) 1992 obz under the linux copyright
|
||||
*
|
||||
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
|
||||
* Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
|
||||
* Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
|
||||
* Some code moved for less code duplication - Andi Kleen - Mar 1997
|
||||
*
|
||||
*
|
||||
* by: Rosimildo da Silva --
|
||||
* Ported to RTEMS to provide the basic interface to the console
|
||||
* driver. Removed all stuff not required, such as VT_, Fonts, etc.
|
||||
*/
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <i386_io.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/kd.h>
|
||||
#include <rtems/keyboard.h>
|
||||
|
||||
/*
|
||||
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
|
||||
* experimentation and study of X386 SYSV handling.
|
||||
*
|
||||
* One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
|
||||
* /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
|
||||
* and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
|
||||
* always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
|
||||
* ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
|
||||
* /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
|
||||
* to the current console is done by the main ioctl code.
|
||||
*/
|
||||
|
||||
struct vt_struct *vt_cons[MAX_NR_CONSOLES];
|
||||
|
||||
/* Keyboard type: Default is KB_101, but can be set by machine
|
||||
* specific code.
|
||||
*/
|
||||
unsigned char keyboard_type = KB_101;
|
||||
|
||||
/*
|
||||
* Generates sound of some frequency for some number of clock ticks
|
||||
*
|
||||
* If freq is 0, will turn off sound, else will turn it on for that time.
|
||||
* If msec is 0, will return immediately, else will sleep for msec time, then
|
||||
* turn sound off.
|
||||
*
|
||||
* We also return immediately, which is what was implied within the X
|
||||
* comments - KDMKTONE doesn't put the process to sleep.
|
||||
*/
|
||||
|
||||
#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
|
||||
|| (defined(__mips__) && !defined(CONFIG_SGI))
|
||||
|
||||
static void
|
||||
kd_nosound(unsigned long ignored)
|
||||
{
|
||||
/* disable counter 2 */
|
||||
outb(inb_p(0x61)&0xFC, 0x61);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
_kd_mksound(unsigned int hz, unsigned int ticks)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
|
||||
if (hz > 20 && hz < 32767)
|
||||
count = 1193180 / hz;
|
||||
|
||||
rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
|
||||
/* del_timer(&sound_timer); */
|
||||
if (count) {
|
||||
/* enable counter 2 */
|
||||
outb_p(inb_p(0x61)|3, 0x61);
|
||||
/* set command for counter 2, 2 byte write */
|
||||
outb_p(0xB6, TIMER_MODE);
|
||||
/* select desired HZ */
|
||||
outb_p(count & 0xff, TIMER_CNTR2);
|
||||
outb((count >> 8) & 0xff, TIMER_CNTR2);
|
||||
|
||||
/*
|
||||
if (ticks) {
|
||||
sound_timer.expires = jiffies+ticks;
|
||||
add_timer(&sound_timer);
|
||||
}
|
||||
*/
|
||||
} else
|
||||
kd_nosound(0);
|
||||
|
||||
rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
_kd_mksound(unsigned int hz, unsigned int ticks)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
|
||||
|
||||
#define i (tmp.kb_index)
|
||||
#define s (tmp.kb_table)
|
||||
#define v (tmp.kb_value)
|
||||
static inline int
|
||||
do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd)
|
||||
{
|
||||
struct kbentry tmp;
|
||||
ushort *key_map, val;
|
||||
|
||||
tmp = *user_kbe;
|
||||
if (i >= NR_KEYS) /* s cannot be >= MAX_NR_KEYMAPS */
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
case KDGKBENT:
|
||||
key_map = key_maps[s];
|
||||
if (key_map) {
|
||||
val = U(key_map[i]);
|
||||
if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
|
||||
val = K_HOLE;
|
||||
} else
|
||||
val = (i ? K_HOLE : K_NOSUCHMAP);
|
||||
user_kbe->kb_value = val;
|
||||
return 0;
|
||||
|
||||
case KDSKBENT:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#undef i
|
||||
#undef s
|
||||
#undef v
|
||||
|
||||
#define HZ 100
|
||||
|
||||
static inline int
|
||||
do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm)
|
||||
{
|
||||
struct kbkeycode tmp;
|
||||
int kc = 0;
|
||||
|
||||
tmp = *user_kbkc;
|
||||
switch (cmd) {
|
||||
case KDGETKEYCODE:
|
||||
kc = getkeycode(tmp.scancode);
|
||||
if (kc >= 0)
|
||||
user_kbkc->keycode = kc;
|
||||
break;
|
||||
case KDSETKEYCODE:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
kc = setkeycode(tmp.scancode, tmp.keycode);
|
||||
break;
|
||||
}
|
||||
return kc;
|
||||
}
|
||||
|
||||
static inline int
|
||||
do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We handle the console-specific ioctl's here. We allow the
|
||||
* capability to modify any console, not just the fg_console.
|
||||
*/
|
||||
int vt_ioctl( unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int perm;
|
||||
unsigned int console;
|
||||
unsigned char ucval;
|
||||
struct kbd_struct * kbd;
|
||||
|
||||
console = 0;
|
||||
/*
|
||||
* To have permissions to do most of the vt ioctls, we either have
|
||||
* to be the owner of the tty, or super-user.
|
||||
*/
|
||||
perm = 1;
|
||||
kbd = kbd_table + console;
|
||||
switch (cmd) {
|
||||
case KIOCSOUND:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
if (arg)
|
||||
arg = 1193180 / arg;
|
||||
kd_mksound(arg, 0);
|
||||
return 0;
|
||||
|
||||
case KDMKTONE:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
{
|
||||
unsigned int ticks, count;
|
||||
|
||||
/*
|
||||
* Generate the tone for the appropriate number of ticks.
|
||||
* If the time is zero, turn off sound ourselves.
|
||||
*/
|
||||
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
|
||||
count = ticks ? (arg & 0xffff) : 0;
|
||||
if (count)
|
||||
count = 1193180 / count;
|
||||
kd_mksound(count, ticks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case KDGKBTYPE:
|
||||
/*
|
||||
* this is naive.
|
||||
*/
|
||||
ucval = keyboard_type;
|
||||
goto setchar;
|
||||
|
||||
case KDSETMODE:
|
||||
case KDGETMODE:
|
||||
return -EINVAL;
|
||||
|
||||
case KDSKBMODE:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
switch(arg) {
|
||||
case K_RAW:
|
||||
kbd->kbdmode = VC_RAW;
|
||||
break;
|
||||
case K_MEDIUMRAW:
|
||||
kbd->kbdmode = VC_MEDIUMRAW;
|
||||
break;
|
||||
case K_XLATE:
|
||||
kbd->kbdmode = VC_XLATE;
|
||||
compute_shiftstate();
|
||||
break;
|
||||
case K_UNICODE:
|
||||
kbd->kbdmode = VC_UNICODE;
|
||||
compute_shiftstate();
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case KDGKBMODE:
|
||||
ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
|
||||
(kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
|
||||
(kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
|
||||
K_XLATE);
|
||||
goto setint;
|
||||
|
||||
/* this could be folded into KDSKBMODE, but for compatibility
|
||||
reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
|
||||
case KDSKBMETA:
|
||||
switch(arg) {
|
||||
case K_METABIT:
|
||||
clr_vc_kbd_mode(kbd, VC_META);
|
||||
break;
|
||||
case K_ESCPREFIX:
|
||||
set_vc_kbd_mode(kbd, VC_META);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case KDGKBMETA:
|
||||
ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
|
||||
setint:
|
||||
*(int *)arg = ucval;
|
||||
return 0;
|
||||
|
||||
case KDGETKEYCODE:
|
||||
case KDSETKEYCODE:
|
||||
return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
|
||||
|
||||
case KDGKBENT:
|
||||
case KDSKBENT:
|
||||
return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd);
|
||||
|
||||
case KDGKBDIACR:
|
||||
{
|
||||
struct kbdiacrs *a = (struct kbdiacrs *)arg;
|
||||
a->kb_cnt = accent_table_size;
|
||||
memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
case KDSKBDIACR:
|
||||
{
|
||||
struct kbdiacrs *a = (struct kbdiacrs *)arg;
|
||||
unsigned int ct;
|
||||
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
ct = a->kb_cnt;
|
||||
if (ct >= MAX_DIACR)
|
||||
return -EINVAL;
|
||||
accent_table_size = ct;
|
||||
memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the ioctls below read/set the flags usually shown in the leds */
|
||||
/* don't use them - they will go away without warning */
|
||||
case KDGKBLED:
|
||||
ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
|
||||
goto setchar;
|
||||
|
||||
case KDSKBLED:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
if (arg & ~0x77)
|
||||
return -EINVAL;
|
||||
kbd->ledflagstate = (arg & 7);
|
||||
kbd->default_ledflagstate = ((arg >> 4) & 7);
|
||||
set_leds();
|
||||
return 0;
|
||||
|
||||
/* the ioctls below only set the lights, not the functions */
|
||||
/* for those, see KDGKBLED and KDSKBLED above */
|
||||
case KDGETLED:
|
||||
ucval = getledstate();
|
||||
setchar:
|
||||
*(char*)arg = ucval;
|
||||
return 0;
|
||||
|
||||
case KDSETLED:
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
setledstate(kbd, arg);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,8 @@ librtemsbsp_a_SOURCES += ../shared/startup/bspreset.c
|
||||
# clock
|
||||
librtemsbsp_a_SOURCES +=../../../../../../bsps/lm32/shared/clock/ckinit.c
|
||||
# console
|
||||
librtemsbsp_a_SOURCES += ../shared/console/console.c
|
||||
librtemsbsp_a_SOURCES += ../shared/console/uart.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/console.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/lm32/shared/console/uart.c
|
||||
# timer
|
||||
librtemsbsp_a_SOURCES += ../shared/timer/timer.c
|
||||
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Console driver for Lattice Mico32 (lm32).
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
|
||||
* Micro-Research Finland Oy
|
||||
*/
|
||||
|
||||
#define NO_BSP_INIT
|
||||
|
||||
#include <bsp.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/console.h>
|
||||
|
||||
/* console_initialize
|
||||
*
|
||||
* This routine initializes the console IO driver.
|
||||
*/
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
printk("console_initialize\n");
|
||||
|
||||
status = rtems_io_register_name(
|
||||
"/dev/console",
|
||||
major,
|
||||
(rtems_device_minor_number) 0
|
||||
);
|
||||
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(status);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/* inbyte
|
||||
*
|
||||
* This routine reads a character from the SOURCE.
|
||||
*/
|
||||
static int inbyte( void )
|
||||
{
|
||||
/*
|
||||
* If polling, wait until a character is available.
|
||||
*/
|
||||
return BSP_uart_polled_read();
|
||||
}
|
||||
|
||||
/* outbyte
|
||||
*
|
||||
* This routine transmits a character out the SOURCE. It may support
|
||||
* XON/XOFF flow control.
|
||||
*/
|
||||
static void outbyte(
|
||||
char ch
|
||||
)
|
||||
{
|
||||
/*
|
||||
* If polling, wait for the transmitter to be ready.
|
||||
* Check for flow control requests and process.
|
||||
* Then output the character.
|
||||
*/
|
||||
|
||||
BSP_uart_polled_write(ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open entry point
|
||||
*/
|
||||
rtems_device_driver console_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close entry point
|
||||
*/
|
||||
rtems_device_driver console_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* read bytes from the serial port. We only have stdin.
|
||||
*/
|
||||
rtems_device_driver console_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *rw_args;
|
||||
char *buffer;
|
||||
int maximum;
|
||||
int count = 0;
|
||||
|
||||
rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
|
||||
buffer = rw_args->buffer;
|
||||
maximum = rw_args->count;
|
||||
|
||||
for (count = 0; count < maximum; count++) {
|
||||
buffer[ count ] = inbyte();
|
||||
if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
|
||||
buffer[ count++ ] = '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rw_args->bytes_moved = count;
|
||||
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* write bytes to the serial port. Stdout and stderr are the same.
|
||||
*/
|
||||
rtems_device_driver console_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
int count;
|
||||
int maximum;
|
||||
rtems_libio_rw_args_t *rw_args;
|
||||
char *buffer;
|
||||
|
||||
rw_args = (rtems_libio_rw_args_t *) arg;
|
||||
|
||||
buffer = rw_args->buffer;
|
||||
maximum = rw_args->count;
|
||||
|
||||
for (count = 0; count < maximum; count++) {
|
||||
if ( buffer[ count ] == '\n') {
|
||||
outbyte('\r');
|
||||
}
|
||||
outbyte( buffer[ count ] );
|
||||
}
|
||||
|
||||
rw_args->bytes_moved = maximum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* IO Control entry point
|
||||
*/
|
||||
rtems_device_driver console_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
|
||||
BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Uart driver for Lattice Mico32 (lm32) UART
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
|
||||
* Micro-Research Finland Oy
|
||||
*/
|
||||
|
||||
#include "../include/system_conf.h"
|
||||
#include "uart.h"
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
static inline int uartread(unsigned int reg)
|
||||
{
|
||||
return *((int*)(UART_BASE_ADDRESS + reg));
|
||||
}
|
||||
|
||||
static inline void uartwrite(unsigned int reg, int value)
|
||||
{
|
||||
*((int*)(UART_BASE_ADDRESS + reg)) = value;
|
||||
}
|
||||
|
||||
void BSP_uart_init(int baud)
|
||||
{
|
||||
/* Disable UART interrupts */
|
||||
uartwrite(LM32_UART_IER, 0);
|
||||
|
||||
/* Line control 8 bit, 1 stop, no parity */
|
||||
uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT);
|
||||
|
||||
/* Modem control, DTR = 1, RTS = 1 */
|
||||
uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS);
|
||||
|
||||
/* Set baud rate */
|
||||
uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud);
|
||||
}
|
||||
|
||||
void BSP_uart_polled_write(char ch)
|
||||
{
|
||||
/* Insert CR before LF */
|
||||
if (ch == '\n')
|
||||
BSP_uart_polled_write('\r');
|
||||
/* Wait until THR is empty. */
|
||||
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE));
|
||||
uartwrite(LM32_UART_RBR, ch);
|
||||
}
|
||||
|
||||
int BSP_uart_polled_read( void )
|
||||
{
|
||||
/* Wait until there is a byte in RBR */
|
||||
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR));
|
||||
return (int) uartread(LM32_UART_RBR);
|
||||
}
|
||||
|
||||
char BSP_uart_is_character_ready(char *ch)
|
||||
{
|
||||
if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)
|
||||
{
|
||||
*ch = (char) uartread(LM32_UART_RBR);
|
||||
return true;
|
||||
}
|
||||
*ch = '0';
|
||||
return false;
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
* @ingroup lm32_shared lm32_uart
|
||||
* @brief LatticeMico32 UART definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains definitions for LatticeMico32 UART
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*
|
||||
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
|
||||
* Micro-Research Finland Oy
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lm32_uart LM32 UART
|
||||
* @ingroup lm32_shared
|
||||
* @brief LatticeMico32 UART definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _BSPUART_H
|
||||
#define _BSPUART_H
|
||||
|
||||
void BSP_uart_init(int baud);
|
||||
|
||||
/* Receive buffer register / transmit holding register */
|
||||
|
||||
#define LM32_UART_RBR (0x0000)
|
||||
|
||||
/* Interrupt enable register */
|
||||
|
||||
#define LM32_UART_IER (0x0004)
|
||||
#define LM32_UART_IER_RBRI (0x0001)
|
||||
#define LM32_UART_IER_THRI (0x0002)
|
||||
#define LM32_UART_IER_RLSI (0x0004)
|
||||
#define LM32_UART_IER_MSI (0x0008)
|
||||
|
||||
/* Interrupt identification register */
|
||||
|
||||
#define LM32_UART_IIR (0x0008)
|
||||
#define LM32_UART_IIR_STAT (0x0001)
|
||||
#define LM32_UART_IIR_ID0 (0x0002)
|
||||
#define LM32_UART_IIR_ID1 (0x0004)
|
||||
|
||||
/* Line control register */
|
||||
|
||||
#define LM32_UART_LCR (0x000C)
|
||||
#define LM32_UART_LCR_WLS0 (0x0001)
|
||||
#define LM32_UART_LCR_WLS1 (0x0002)
|
||||
#define LM32_UART_LCR_STB (0x0004)
|
||||
#define LM32_UART_LCR_PEN (0x0008)
|
||||
#define LM32_UART_LCR_EPS (0x0010)
|
||||
#define LM32_UART_LCR_SP (0x0020)
|
||||
#define LM32_UART_LCR_SB (0x0040)
|
||||
#define LM32_UART_LCR_5BIT (0)
|
||||
#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0)
|
||||
#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1)
|
||||
#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0)
|
||||
|
||||
/* Modem control register */
|
||||
|
||||
#define LM32_UART_MCR (0x0010)
|
||||
#define LM32_UART_MCR_DTR (0x0001)
|
||||
#define LM32_UART_MCR_RTS (0x0002)
|
||||
|
||||
/* Line status register */
|
||||
|
||||
#define LM32_UART_LSR (0x0014)
|
||||
#define LM32_UART_LSR_DR (0x0001)
|
||||
#define LM32_UART_LSR_OE (0x0002)
|
||||
#define LM32_UART_LSR_PE (0x0004)
|
||||
#define LM32_UART_LSR_FE (0x0008)
|
||||
#define LM32_UART_LSR_BI (0x0010)
|
||||
#define LM32_UART_LSR_THRE (0x0020)
|
||||
#define LM32_UART_LSR_TEMT (0x0040)
|
||||
|
||||
/* Modem status register */
|
||||
|
||||
#define LM32_UART_MSR (0x0018)
|
||||
#define LM32_UART_MSR_DCTS (0x0001)
|
||||
#define LM32_UART_MSR_DDSR (0x0002)
|
||||
#define LM32_UART_MSR_TERI (0x0004)
|
||||
#define LM32_UART_MSR_DDCD (0x0008)
|
||||
#define LM32_UART_MSR_CTS (0x0010)
|
||||
#define LM32_UART_MSR_DSR (0x0020)
|
||||
#define LM32_UART_MSR_RI (0x0040)
|
||||
#define LM32_UART_MSR_DCD (0x0000)
|
||||
|
||||
/* Baud-rate divisor register */
|
||||
|
||||
#define LM32_UART_DIV (0x001C)
|
||||
|
||||
#endif /* _BSPUART_H */
|
||||
|
||||
/** @} */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user