forked from Imagelibrary/rtems
libchip/serial: Add alternative NS16550 driver
Use the Termios device API.
This commit is contained in:
@@ -190,11 +190,8 @@ libbsp_a_SOURCES += ../shared/arm-gic-irq.c
|
|||||||
libbsp_a_SOURCES += network/network.c
|
libbsp_a_SOURCES += network/network.c
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_control.c
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_read.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_select_simple.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_write.c
|
|
||||||
libbsp_a_SOURCES += console/console-config.c
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
|
|
||||||
# Clock
|
# Clock
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Dornierstr. 4
|
* Dornierstr. 4
|
||||||
@@ -12,28 +12,23 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
#include <bsp/alt_clock_manager.h>
|
#include <bsp/alt_clock_manager.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
#include "socal/alt_rstmgr.h"
|
#include "socal/alt_rstmgr.h"
|
||||||
#include "socal/socal.h"
|
#include "socal/socal.h"
|
||||||
#include "socal/alt_uart.h"
|
#include "socal/alt_uart.h"
|
||||||
#include "socal/hps.h"
|
#include "socal/hps.h"
|
||||||
|
|
||||||
#ifdef BSP_USE_UART_INTERRUPTS
|
#ifdef BSP_USE_UART_INTERRUPTS
|
||||||
#define DEVICE_FNS &ns16550_fns
|
#define DEVICE_FNS &ns16550_handler_interrupt
|
||||||
#else
|
#else
|
||||||
#define DEVICE_FNS &ns16550_fns_polled
|
#define DEVICE_FNS &ns16550_handler_polled
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool altera_cyclone_v_uart_probe( int minor );
|
|
||||||
|
|
||||||
static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i)
|
static uint8_t altera_cyclone_v_uart_get_register(uintptr_t addr, uint8_t i)
|
||||||
{
|
{
|
||||||
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
volatile uint32_t *reg = (volatile uint32_t *) addr;
|
||||||
@@ -48,92 +43,25 @@ static void altera_cyclone_v_uart_set_register(uintptr_t addr, uint8_t i, uint8_
|
|||||||
reg [i] = val;
|
reg [i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
console_tbl Console_Configuration_Ports[] = {
|
static bool altera_cyclone_v_uart_probe(
|
||||||
#ifdef CYCLONE_V_CONFIG_CONSOLE
|
rtems_termios_device_context *base,
|
||||||
{
|
uint32_t uart_set_mask
|
||||||
.sDeviceName = "/dev/ttyS0",
|
)
|
||||||
.deviceType = SERIAL_NS16550,
|
|
||||||
.pDeviceFns = DEVICE_FNS,
|
|
||||||
.deviceProbe = altera_cyclone_v_uart_probe,
|
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *)CYCLONE_V_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = (uint32_t)ALT_UART0_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uint32_t)ALT_UART0_ADDR,
|
|
||||||
.getRegister = altera_cyclone_v_uart_get_register,
|
|
||||||
.setRegister = altera_cyclone_v_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
.ulIntVector = ALT_INT_INTERRUPT_UART0
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
#ifdef CYCLONE_V_CONFIG_UART_1
|
|
||||||
{
|
|
||||||
.sDeviceName = "/dev/ttyS1",
|
|
||||||
.deviceType = SERIAL_NS16550,
|
|
||||||
.pDeviceFns = DEVICE_FNS,
|
|
||||||
.deviceProbe = altera_cyclone_v_uart_probe,
|
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *)CYCLONE_V_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = (uint32_t)ALT_UART1_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uint32_t)ALT_UART1_ADDR,
|
|
||||||
.getRegister = altera_cyclone_v_uart_get_register,
|
|
||||||
.setRegister = altera_cyclone_v_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
.ulIntVector = ALT_INT_INTERRUPT_UART1
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned long Console_Configuration_Count =
|
|
||||||
RTEMS_ARRAY_SIZE(Console_Configuration_Ports);
|
|
||||||
|
|
||||||
bool altera_cyclone_v_uart_probe(int minor)
|
|
||||||
{
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
uint32_t uart_set_mask;
|
|
||||||
uint32_t ucr;
|
uint32_t ucr;
|
||||||
ALT_STATUS_CODE sc;
|
ALT_STATUS_CODE sc;
|
||||||
void* location;
|
void* location = (void *) ctx->port;
|
||||||
|
|
||||||
/* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs.
|
/* The ALT_CLK_L4_SP is required for all SoCFPGA UARTs.
|
||||||
* Check that it's enabled. */
|
* Check that it's enabled. */
|
||||||
assert( alt_clk_is_enabled(ALT_CLK_L4_SP) == ALT_E_TRUE );
|
|
||||||
if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) {
|
if ( alt_clk_is_enabled(ALT_CLK_L4_SP) != ALT_E_TRUE ) {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret ) {
|
if ( ret ) {
|
||||||
switch(minor)
|
sc = alt_clk_freq_get(ALT_CLK_L4_SP, &ctx->clock);
|
||||||
{
|
|
||||||
case(0):
|
|
||||||
/* UART 0 */
|
|
||||||
uart_set_mask = ALT_RSTMGR_PERMODRST_UART0_SET_MSK;
|
|
||||||
location = ALT_UART0_ADDR;
|
|
||||||
break;
|
|
||||||
case(1):
|
|
||||||
/* UART 1 */
|
|
||||||
uart_set_mask = ALT_RSTMGR_PERMODRST_UART1_SET_MSK;
|
|
||||||
location = ALT_UART1_ADDR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown case */
|
|
||||||
assert( minor == 0 || minor == 1 );
|
|
||||||
ret = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( ret ) {
|
|
||||||
sc = alt_clk_freq_get(ALT_CLK_L4_SP, &Console_Configuration_Ports[minor].ulClock);
|
|
||||||
assert( sc == ALT_E_SUCCESS );
|
|
||||||
if ( sc != ALT_E_SUCCESS ) {
|
if ( sc != ALT_E_SUCCESS ) {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -145,8 +73,6 @@ bool altera_cyclone_v_uart_probe(int minor)
|
|||||||
|
|
||||||
// Verify the UCR (UART Component Version)
|
// Verify the UCR (UART Component Version)
|
||||||
ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) );
|
ucr = alt_read_word( ALT_UART_UCV_ADDR( location ) );
|
||||||
|
|
||||||
assert( ucr == ALT_UART_UCV_UART_COMPONENT_VER_RESET );
|
|
||||||
if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) {
|
if ( ucr != ALT_UART_UCV_UART_COMPONENT_VER_RESET ) {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -158,22 +84,75 @@ bool altera_cyclone_v_uart_probe(int minor)
|
|||||||
|
|
||||||
// Read the MSR to work around case:119085.
|
// Read the MSR to work around case:119085.
|
||||||
(void)alt_read_word( ALT_UART_MSR_ADDR( location ) );
|
(void)alt_read_word( ALT_UART_MSR_ADDR( location ) );
|
||||||
|
|
||||||
|
ret = ns16550_probe( base );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_char(char c)
|
#ifdef CYCLONE_V_CONFIG_CONSOLE
|
||||||
|
static bool altera_cyclone_v_uart_probe_0(rtems_termios_device_context *base)
|
||||||
{
|
{
|
||||||
int minor = (int) Console_Port_Minor;
|
return altera_cyclone_v_uart_probe(base, ALT_RSTMGR_PERMODRST_UART0_SET_MSK);
|
||||||
console_tbl *ct = Console_Port_Tbl != NULL ?
|
|
||||||
Console_Port_Tbl[minor] : &Console_Configuration_Ports[minor];
|
|
||||||
|
|
||||||
if (c == '\n') {
|
|
||||||
ns16550_outch_polled( ct, '\r' );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ns16550_outch_polled( ct, c );
|
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_CONSOLE
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
ns16550_polled_putchar( ctx, '\r' );
|
||||||
|
}
|
||||||
|
|
||||||
|
ns16550_polled_putchar( ctx, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
BSP_output_char_function_type BSP_output_char = output_char;
|
BSP_output_char_function_type BSP_output_char = output_char;
|
||||||
|
|||||||
@@ -110,11 +110,8 @@ libbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c
|
|||||||
libbsp_a_SOURCES += irq/irq.c
|
libbsp_a_SOURCES += irq/irq.c
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_control.c
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_read.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_select.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_write.c
|
|
||||||
libbsp_a_SOURCES += console/console-config.c
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
|
|
||||||
# Clock
|
# Clock
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,12 +20,12 @@
|
|||||||
* http://www.rtems.com/license/LICENSE.
|
* http://www.rtems.com/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/io.h>
|
#include <bsp/io.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the uart register according to the current address.
|
* @brief Gets the uart register according to the current address.
|
||||||
@@ -62,97 +62,91 @@ static inline void lpc176x_uart_set_register(
|
|||||||
reg[ i ] = val;
|
reg[ i ] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#ifdef LPC176X_CONFIG_CONSOLE
|
||||||
* @brief Represents the uart configuration ports.
|
static ns16550_context lpc176x_uart_context_0 = {
|
||||||
*/
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||||
console_tbl Console_Configuration_Ports[] = {
|
.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
|
#ifdef LPC176X_CONFIG_CONSOLE
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS0",
|
.device_file = "/dev/ttyS0",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = console_device_probe_default,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc176x_uart_context_0.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC176X_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART0_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART0_BASE_ADDR,
|
|
||||||
.getRegister = lpc176x_uart_get_register,
|
|
||||||
.setRegister = lpc176x_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC176X_PCLK,
|
|
||||||
.ulIntVector = LPC176X_IRQ_UART_0
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC176X_CONFIG_UART_1
|
#ifdef LPC176X_CONFIG_UART_1
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc176x_uart_probe_1,
|
.context = &lpc176x_uart_context_1.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC176X_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART1_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART1_BASE_ADDR,
|
|
||||||
.getRegister = lpc176x_uart_get_register,
|
|
||||||
.setRegister = lpc176x_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC176X_PCLK,
|
|
||||||
.ulIntVector = LPC176X_IRQ_UART_1
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC176X_CONFIG_UART_2
|
#ifdef LPC176X_CONFIG_UART_2
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS2",
|
.device_file = "/dev/ttyS2",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc176x_uart_probe_2,
|
.context = &lpc176x_uart_context_2.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC176X_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART2_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART2_BASE_ADDR,
|
|
||||||
.getRegister = lpc176x_uart_get_register,
|
|
||||||
.setRegister = lpc176x_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC176X_PCLK,
|
|
||||||
.ulIntVector = LPC176X_IRQ_UART_2
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC176X_CONFIG_UART_3
|
#ifdef LPC176X_CONFIG_UART_3
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS3",
|
.device_file = "/dev/ttyS3",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc176x_uart_probe_3,
|
.context = &lpc176x_uart_context_3.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC176X_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART3_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART3_BASE_ADDR,
|
|
||||||
.getRegister = lpc176x_uart_get_register,
|
|
||||||
.setRegister = lpc176x_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC176X_PCLK,
|
|
||||||
.ulIntVector = LPC176X_IRQ_UART_3
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LPC176X_UART_COUNT ( sizeof( Console_Configuration_Ports ) \
|
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||||
/ sizeof( Console_Configuration_Ports[ 0 ] ) )
|
|
||||||
|
|
||||||
unsigned long Console_Configuration_Count = LPC176X_UART_COUNT;
|
|
||||||
|
|||||||
@@ -121,11 +121,8 @@ libbsp_a_SOURCES += irq/irq.c
|
|||||||
libbsp_a_SOURCES += irq/irq-dispatch.c
|
libbsp_a_SOURCES += irq/irq-dispatch.c
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_control.c
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
libbsp_a_SOURCES += ../../shared/console_read.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_select.c
|
|
||||||
libbsp_a_SOURCES += ../../shared/console_write.c
|
|
||||||
libbsp_a_SOURCES += console/console-config.c
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
libbsp_a_SOURCES += console/uart-probe-1.c
|
libbsp_a_SOURCES += console/uart-probe-1.c
|
||||||
libbsp_a_SOURCES += console/uart-probe-2.c
|
libbsp_a_SOURCES += console/uart-probe-2.c
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,13 +20,15 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
#include <rtems/console.h>
|
||||||
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/lpc24xx.h>
|
#include <bsp/lpc24xx.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
#include <bsp/io.h>
|
#include <bsp/io.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
|
|
||||||
static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i)
|
static uint8_t lpc24xx_uart_get_register(uintptr_t addr, uint8_t i)
|
||||||
{
|
{
|
||||||
@@ -42,94 +44,91 @@ static void lpc24xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
|||||||
reg [i] = val;
|
reg [i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
console_tbl Console_Configuration_Ports [] = {
|
#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
|
#ifdef LPC24XX_CONFIG_CONSOLE
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS0",
|
.device_file = "/dev/ttyS0",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = console_device_probe_default,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc24xx_uart_context_0.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC24XX_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART0_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART0_BASE_ADDR,
|
|
||||||
.getRegister = lpc24xx_uart_get_register,
|
|
||||||
.setRegister = lpc24xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC24XX_PCLK,
|
|
||||||
.ulIntVector = LPC24XX_IRQ_UART_0
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC24XX_CONFIG_UART_1
|
#ifdef LPC24XX_CONFIG_UART_1
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = lpc24xx_uart_probe_1,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc24xx_uart_probe_1,
|
.context = &lpc24xx_uart_context_1.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC24XX_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART1_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART1_BASE_ADDR,
|
|
||||||
.getRegister = lpc24xx_uart_get_register,
|
|
||||||
.setRegister = lpc24xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC24XX_PCLK,
|
|
||||||
.ulIntVector = LPC24XX_IRQ_UART_1
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC24XX_CONFIG_UART_2
|
#ifdef LPC24XX_CONFIG_UART_2
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS2",
|
.device_file = "/dev/ttyS2",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = lpc24xx_uart_probe_2,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc24xx_uart_probe_2,
|
.context = &lpc24xx_uart_context_2.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC24XX_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART2_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART2_BASE_ADDR,
|
|
||||||
.getRegister = lpc24xx_uart_get_register,
|
|
||||||
.setRegister = lpc24xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC24XX_PCLK,
|
|
||||||
.ulIntVector = LPC24XX_IRQ_UART_2
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC24XX_CONFIG_UART_3
|
#ifdef LPC24XX_CONFIG_UART_3
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS3",
|
.device_file = "/dev/ttyS3",
|
||||||
.deviceType = SERIAL_NS16550_WITH_FDR,
|
.probe = lpc24xx_uart_probe_3,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc24xx_uart_probe_3,
|
.context = &lpc24xx_uart_context_3.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC24XX_UART_BAUD,
|
|
||||||
.ulCtrlPort1 = UART3_BASE_ADDR,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = UART3_BASE_ADDR,
|
|
||||||
.getRegister = lpc24xx_uart_get_register,
|
|
||||||
.setRegister = lpc24xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = LPC24XX_PCLK,
|
|
||||||
.ulIntVector = LPC24XX_IRQ_UART_3
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LPC24XX_UART_COUNT \
|
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||||
(sizeof(Console_Configuration_Ports) \
|
|
||||||
/ sizeof(Console_Configuration_Ports [0]))
|
|
||||||
unsigned long Console_Configuration_Count = LPC24XX_UART_COUNT;
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2013 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,10 +20,12 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/io.h>
|
#include <bsp/io.h>
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_1(int minor)
|
bool lpc24xx_uart_probe_1(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
static const lpc24xx_pin_range pins [] = {
|
static const lpc24xx_pin_range pins [] = {
|
||||||
LPC24XX_PIN_UART_1_TXD_P0_15,
|
LPC24XX_PIN_UART_1_TXD_P0_15,
|
||||||
@@ -34,5 +36,5 @@ bool lpc24xx_uart_probe_1(int minor)
|
|||||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT);
|
lpc24xx_module_enable(LPC24XX_MODULE_UART_1, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2013 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,10 +20,12 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/io.h>
|
#include <bsp/io.h>
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_2(int minor)
|
bool lpc24xx_uart_probe_2(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
static const lpc24xx_pin_range pins [] = {
|
static const lpc24xx_pin_range pins [] = {
|
||||||
LPC24XX_PIN_UART_2_TXD_P0_10,
|
LPC24XX_PIN_UART_2_TXD_P0_10,
|
||||||
@@ -34,5 +36,5 @@ bool lpc24xx_uart_probe_2(int minor)
|
|||||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT);
|
lpc24xx_module_enable(LPC24XX_MODULE_UART_2, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2013 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,10 +20,12 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/io.h>
|
#include <bsp/io.h>
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_3(int minor)
|
bool lpc24xx_uart_probe_3(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
static const lpc24xx_pin_range pins [] = {
|
static const lpc24xx_pin_range pins [] = {
|
||||||
LPC24XX_PIN_UART_3_TXD_P0_0,
|
LPC24XX_PIN_UART_3_TXD_P0_0,
|
||||||
@@ -34,5 +36,5 @@ bool lpc24xx_uart_probe_3(int minor)
|
|||||||
lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT);
|
lpc24xx_module_enable(LPC24XX_MODULE_UART_3, LPC24XX_MODULE_PCLK_DEFAULT);
|
||||||
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
lpc24xx_pin_config(&pins [0], LPC24XX_PIN_SET_FUNCTION);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -53,6 +53,8 @@ extern "C" {
|
|||||||
|
|
||||||
struct rtems_bsdnet_ifconfig;
|
struct rtems_bsdnet_ifconfig;
|
||||||
|
|
||||||
|
struct rtems_termios_device_context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup lpc24xx LPC24XX Support
|
* @defgroup lpc24xx LPC24XX Support
|
||||||
*
|
*
|
||||||
@@ -111,11 +113,11 @@ void *bsp_idle_thread(uintptr_t ignored);
|
|||||||
|
|
||||||
void bsp_restart(void *addr);
|
void bsp_restart(void *addr);
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_1(int minor);
|
bool lpc24xx_uart_probe_1(struct rtems_termios_device_context *context);
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_2(int minor);
|
bool lpc24xx_uart_probe_2(struct rtems_termios_device_context *context);
|
||||||
|
|
||||||
bool lpc24xx_uart_probe_3(int minor);
|
bool lpc24xx_uart_probe_3(struct rtems_termios_device_context *context);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ include_bsp_HEADERS += include/lpc-clock-config.h
|
|||||||
include_bsp_HEADERS += include/lpc-ethernet-config.h
|
include_bsp_HEADERS += include/lpc-ethernet-config.h
|
||||||
include_bsp_HEADERS += include/nand-mlc.h
|
include_bsp_HEADERS += include/nand-mlc.h
|
||||||
include_bsp_HEADERS += include/boot.h
|
include_bsp_HEADERS += include/boot.h
|
||||||
|
include_bsp_HEADERS += include/hsu.h
|
||||||
include_bsp_HEADERS += include/i2c.h
|
include_bsp_HEADERS += include/i2c.h
|
||||||
include_bsp_HEADERS += include/emc.h
|
include_bsp_HEADERS += include/emc.h
|
||||||
|
|
||||||
@@ -111,13 +112,10 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
|
|||||||
libbsp_a_SOURCES += irq/irq.c
|
libbsp_a_SOURCES += irq/irq.c
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c \
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
../../shared/console_select.c \
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
console/console-config.c \
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
console/hsu.c \
|
libbsp_a_SOURCES += console/hsu.c
|
||||||
../../shared/console_read.c \
|
|
||||||
../../shared/console_write.c \
|
|
||||||
../../shared/console_control.c
|
|
||||||
|
|
||||||
# Clock
|
# Clock
|
||||||
libbsp_a_SOURCES += ../shared/lpc/clock/lpc-clock-config.c
|
libbsp_a_SOURCES += ../shared/lpc/clock/lpc-clock-config.c
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009
|
* Copyright (c) 2009-2014 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* D-82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
@@ -19,14 +20,13 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/lpc32xx.h>
|
#include <bsp/lpc32xx.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/hsu.h>
|
||||||
extern const console_fns lpc32xx_hsu_fns;
|
#include <bsp/console-termios.h>
|
||||||
|
|
||||||
static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i)
|
static uint8_t lpc32xx_uart_get_register(uintptr_t addr, uint8_t i)
|
||||||
{
|
{
|
||||||
@@ -43,18 +43,18 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LPC32XX_UART_3_BAUD
|
#ifdef LPC32XX_UART_3_BAUD
|
||||||
static bool lpc32xx_uart_probe_3(int minor)
|
static bool lpc32xx_uart_probe_3(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0);
|
LPC32XX_UARTCLK_CTRL |= BSP_BIT32(0);
|
||||||
LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
|
LPC32XX_U3CLK = LPC32XX_CONFIG_U3CLK;
|
||||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5);
|
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 4, 5);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LPC32XX_UART_4_BAUD
|
#ifdef LPC32XX_UART_4_BAUD
|
||||||
static bool lpc32xx_uart_probe_4(int minor)
|
static bool lpc32xx_uart_probe_4(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
volatile lpc32xx_gpio *gpio = &lpc32xx.gpio;
|
volatile lpc32xx_gpio *gpio = &lpc32xx.gpio;
|
||||||
|
|
||||||
@@ -68,12 +68,12 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
|||||||
LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
|
LPC32XX_U4CLK = LPC32XX_CONFIG_U4CLK;
|
||||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7);
|
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 6, 7);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LPC32XX_UART_6_BAUD
|
#ifdef LPC32XX_UART_6_BAUD
|
||||||
static bool lpc32xx_uart_probe_6(int minor)
|
static bool lpc32xx_uart_probe_6(rtems_termios_device_context *context)
|
||||||
{
|
{
|
||||||
/* Bypass the IrDA modulator/demodulator */
|
/* Bypass the IrDA modulator/demodulator */
|
||||||
LPC32XX_UART_CTRL |= BSP_BIT32(5);
|
LPC32XX_UART_CTRL |= BSP_BIT32(5);
|
||||||
@@ -82,163 +82,144 @@ static void lpc32xx_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
|||||||
LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
|
LPC32XX_U6CLK = LPC32XX_CONFIG_U6CLK;
|
||||||
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11);
|
LPC32XX_UART_CLKMODE = BSP_FLD32SET(LPC32XX_UART_CLKMODE, 0x2, 10, 11);
|
||||||
|
|
||||||
return true;
|
return ns16550_probe(context);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: Console selection */
|
/* FIXME: Console selection */
|
||||||
|
|
||||||
console_tbl Console_Configuration_Ports [] = {
|
#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
|
#ifdef LPC32XX_UART_5_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS5",
|
.device_file = "/dev/ttyS5",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = console_device_probe_default,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc32xx_uart_context_5.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_5_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_5,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = LPC32XX_BASE_UART_5,
|
|
||||||
.getRegister = lpc32xx_uart_get_register,
|
|
||||||
.setRegister = lpc32xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16 * LPC32XX_UART_5_BAUD,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_5
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_3_BAUD
|
#ifdef LPC32XX_UART_3_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS3",
|
.device_file = "/dev/ttyS3",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = lpc32xx_uart_probe_3,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc32xx_uart_probe_3,
|
.context = &lpc32xx_uart_context_3.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_3_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_3,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = LPC32XX_BASE_UART_3,
|
|
||||||
.getRegister = lpc32xx_uart_get_register,
|
|
||||||
.setRegister = lpc32xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16 * LPC32XX_UART_3_BAUD,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_3
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_4_BAUD
|
#ifdef LPC32XX_UART_4_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS4",
|
.device_file = "/dev/ttyS4",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = lpc32xx_uart_probe_4,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc32xx_uart_probe_4,
|
.context = &lpc32xx_uart_context_4.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_4_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_4,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = LPC32XX_BASE_UART_4,
|
|
||||||
.getRegister = lpc32xx_uart_get_register,
|
|
||||||
.setRegister = lpc32xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16 * LPC32XX_UART_4_BAUD,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_4
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_6_BAUD
|
#ifdef LPC32XX_UART_6_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS6",
|
.device_file = "/dev/ttyS6",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = lpc32xx_uart_probe_6,
|
||||||
.pDeviceFns = &ns16550_fns,
|
.handler = &ns16550_handler_interrupt,
|
||||||
.deviceProbe = lpc32xx_uart_probe_6,
|
.context = &lpc32xx_uart_context_6.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_6_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_6,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = LPC32XX_BASE_UART_6,
|
|
||||||
.getRegister = lpc32xx_uart_get_register,
|
|
||||||
.setRegister = lpc32xx_uart_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16 * LPC32XX_UART_6_BAUD,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_6
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_1_BAUD
|
#ifdef LPC32XX_UART_1_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
.deviceType = SERIAL_CUSTOM,
|
.probe = lpc32xx_hsu_probe,
|
||||||
.pDeviceFns = &lpc32xx_hsu_fns,
|
.handler = &lpc32xx_hsu_fns,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc32xx_uart_context_1.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_1_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_1,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = 0,
|
|
||||||
.getRegister = NULL,
|
|
||||||
.setRegister = NULL,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_1
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_2_BAUD
|
#ifdef LPC32XX_UART_2_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS2",
|
.device_file = "/dev/ttyS2",
|
||||||
.deviceType = SERIAL_CUSTOM,
|
.probe = lpc32xx_hsu_probe,
|
||||||
.pDeviceFns = &lpc32xx_hsu_fns,
|
.handler = &lpc32xx_hsu_fns,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc32xx_uart_context_2.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_2_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_2,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = 0,
|
|
||||||
.getRegister = NULL,
|
|
||||||
.setRegister = NULL,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_2
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef LPC32XX_UART_7_BAUD
|
#ifdef LPC32XX_UART_7_BAUD
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS7",
|
.device_file = "/dev/ttyS7",
|
||||||
.deviceType = SERIAL_CUSTOM,
|
.probe = lpc32xx_hsu_probe,
|
||||||
.pDeviceFns = &lpc32xx_hsu_fns,
|
.handler = &lpc32xx_hsu_fns,
|
||||||
.deviceProbe = NULL,
|
.context = &lpc32xx_uart_context_7.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) LPC32XX_UART_7_BAUD,
|
|
||||||
.ulCtrlPort1 = LPC32XX_BASE_UART_7,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = 0,
|
|
||||||
.getRegister = NULL,
|
|
||||||
.setRegister = NULL,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 16,
|
|
||||||
.ulIntVector = LPC32XX_IRQ_UART_7
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LPC32XX_UART_COUNT \
|
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||||
(sizeof(Console_Configuration_Ports) / sizeof(Console_Configuration_Ports [0]))
|
|
||||||
|
|
||||||
unsigned long Console_Configuration_Count = LPC32XX_UART_COUNT;
|
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010
|
* Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* D-82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
*
|
*
|
||||||
@@ -19,24 +20,10 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/libio.h>
|
|
||||||
#include <rtems/termiostypes.h>
|
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/sersupp.h>
|
|
||||||
|
|
||||||
#include <bsp.h>
|
#include <bsp.h>
|
||||||
#include <bsp/lpc32xx.h>
|
#include <bsp/lpc32xx.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/hsu.h>
|
||||||
typedef struct {
|
|
||||||
uint32_t fifo;
|
|
||||||
uint32_t level;
|
|
||||||
uint32_t iir;
|
|
||||||
uint32_t ctrl;
|
|
||||||
uint32_t rate;
|
|
||||||
} lpc32xx_hsu;
|
|
||||||
|
|
||||||
#define HSU_FIFO_SIZE 64
|
#define HSU_FIFO_SIZE 64
|
||||||
|
|
||||||
@@ -60,54 +47,29 @@ typedef struct {
|
|||||||
/* We are interested in RX timeout, RX trigger and TX trigger interrupts */
|
/* We are interested in RX timeout, RX trigger and TX trigger interrupts */
|
||||||
#define HSU_IIR_MASK 0x7U
|
#define HSU_IIR_MASK 0x7U
|
||||||
|
|
||||||
static int lpc32xx_hsu_first_open(int major, int minor, void *arg)
|
bool lpc32xx_hsu_probe(rtems_termios_device_context *base)
|
||||||
{
|
{
|
||||||
rtems_libio_open_close_args_t *oca = arg;
|
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||||
struct rtems_termios_tty *tty = oca->iop->data1;
|
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
|
||||||
console_data *cd = &Console_Port_Data [minor];
|
|
||||||
volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
|
|
||||||
|
|
||||||
cd->termios_data = tty;
|
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
|
||||||
rtems_termios_set_initial_baud(tty, (int32_t) ct->pDeviceParams);
|
|
||||||
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
|
|
||||||
|
|
||||||
return 0;
|
/* Drain FIFOs */
|
||||||
|
while (hsu->level != 0) {
|
||||||
|
hsu->fifo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t lpc32xx_hsu_write(int minor, const char *buf, size_t len)
|
return true;
|
||||||
{
|
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
|
||||||
console_data *cd = &Console_Port_Data [minor];
|
|
||||||
volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
cd->pDeviceContext = (void *) out;
|
|
||||||
cd->bActive = true;
|
|
||||||
hsu->ctrl = HSU_CTRL_RX_AND_TX_INTR_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpc32xx_hsu_interrupt_handler(void *arg)
|
static void lpc32xx_hsu_interrupt_handler(void *arg)
|
||||||
{
|
{
|
||||||
int minor = (int) arg;
|
rtems_termios_tty *tty = arg;
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
lpc32xx_hsu_context *ctx = rtems_termios_get_device_context(tty);
|
||||||
console_data *cd = &Console_Port_Data [minor];
|
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||||
volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
|
|
||||||
|
|
||||||
/* Iterate until no more interrupts are pending */
|
/* Iterate until no more interrupts are pending */
|
||||||
do {
|
do {
|
||||||
int chars_to_dequeue = (int) cd->pDeviceContext;
|
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char buf [HSU_FIFO_SIZE];
|
char buf [HSU_FIFO_SIZE];
|
||||||
@@ -125,49 +87,97 @@ static void lpc32xx_hsu_interrupt_handler(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
|
rtems_termios_enqueue_raw_characters(tty, buf, i);
|
||||||
|
|
||||||
/* Dequeue transmitted characters */
|
/* Dequeue transmitted characters */
|
||||||
cd->pDeviceContext = 0;
|
rv = rtems_termios_dequeue_characters(tty, (int) ctx->chars_in_transmission);
|
||||||
rv = rtems_termios_dequeue_characters(cd->termios_data, chars_to_dequeue);
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
/* Nothing to transmit */
|
/* Nothing to transmit */
|
||||||
cd->bActive = false;
|
|
||||||
hsu->ctrl = HSU_CTRL_RX_INTR_ENABLED;
|
|
||||||
hsu->iir = HSU_IIR_TX;
|
|
||||||
}
|
}
|
||||||
} while ((hsu->iir & HSU_IIR_MASK) != 0);
|
} while ((hsu->iir & HSU_IIR_MASK) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpc32xx_hsu_initialize(int minor)
|
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
|
||||||
|
)
|
||||||
{
|
{
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||||
console_data *cd = &Console_Port_Data [minor];
|
volatile lpc32xx_hsu *hsu = ctx->hsu;
|
||||||
volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
|
rtems_status_code sc;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
hsu->ctrl = HSU_CTRL_INTR_DISABLED;
|
sc = rtems_interrupt_handler_install(
|
||||||
|
ctx->irq,
|
||||||
cd->bActive = false;
|
|
||||||
cd->pDeviceContext = 0;
|
|
||||||
|
|
||||||
/* Drain FIFOs */
|
|
||||||
while (hsu->level != 0) {
|
|
||||||
hsu->fifo;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_interrupt_handler_install(
|
|
||||||
ct->ulIntVector,
|
|
||||||
"HSU",
|
"HSU",
|
||||||
RTEMS_INTERRUPT_UNIQUE,
|
RTEMS_INTERRUPT_UNIQUE,
|
||||||
lpc32xx_hsu_interrupt_handler,
|
lpc32xx_hsu_interrupt_handler,
|
||||||
(void *) minor
|
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 int lpc32xx_hsu_set_attributes(int minor, const struct termios *term)
|
static void lpc32xx_hsu_write(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
)
|
||||||
{
|
{
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
lpc32xx_hsu_context *ctx = (lpc32xx_hsu_context *) base;
|
||||||
volatile lpc32xx_hsu *hsu = (volatile lpc32xx_hsu *) ct->ulCtrlPort1;
|
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_cflag & CBAUD;
|
int baud_flags = term->c_cflag & CBAUD;
|
||||||
|
|
||||||
if (baud_flags != 0) {
|
if (baud_flags != 0) {
|
||||||
@@ -186,17 +196,13 @@ static int lpc32xx_hsu_set_attributes(int minor, const struct termios *term)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const console_fns lpc32xx_hsu_fns = {
|
const rtems_termios_device_handler lpc32xx_hsu_fns = {
|
||||||
.deviceProbe = libchip_serial_default_probe,
|
.first_open = lpc32xx_hsu_first_open,
|
||||||
.deviceFirstOpen = lpc32xx_hsu_first_open,
|
.last_close = lpc32xx_hsu_last_close,
|
||||||
.deviceLastClose = NULL,
|
.write = lpc32xx_hsu_write,
|
||||||
.deviceRead = NULL,
|
.set_attributes = lpc32xx_hsu_set_attributes,
|
||||||
.deviceWrite = lpc32xx_hsu_write,
|
.mode = TERMIOS_IRQ_DRIVEN
|
||||||
.deviceInitialize = lpc32xx_hsu_initialize,
|
|
||||||
.deviceWritePolled = NULL,
|
|
||||||
.deviceSetAttributes = lpc32xx_hsu_set_attributes,
|
|
||||||
.deviceOutputUsesInterrupts = true
|
|
||||||
};
|
};
|
||||||
|
|||||||
68
c/src/lib/libbsp/arm/lpc32xx/include/hsu.h
Normal file
68
c/src/lib/libbsp/arm/lpc32xx/include/hsu.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup lpc32xx_hsu
|
||||||
|
*
|
||||||
|
* @brief HSU support API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBBSP_ARM_LPC32XX_HSU_H
|
||||||
|
#define LIBBSP_ARM_LPC32XX_HSU_H
|
||||||
|
|
||||||
|
#include <rtems/termiostypes.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup lpc32xx_hsu HSU Support
|
||||||
|
*
|
||||||
|
* @ingroup arm_lpc32xx
|
||||||
|
*
|
||||||
|
* @brief HSU Support
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t fifo;
|
||||||
|
uint32_t level;
|
||||||
|
uint32_t iir;
|
||||||
|
uint32_t ctrl;
|
||||||
|
uint32_t rate;
|
||||||
|
} lpc32xx_hsu;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_termios_device_context base;
|
||||||
|
volatile lpc32xx_hsu *hsu;
|
||||||
|
size_t chars_in_transmission;
|
||||||
|
rtems_vector_number irq;
|
||||||
|
uint32_t initial_baud;
|
||||||
|
} lpc32xx_hsu_context;
|
||||||
|
|
||||||
|
extern const rtems_termios_device_handler lpc32xx_hsu_fns;
|
||||||
|
|
||||||
|
bool lpc32xx_hsu_probe(rtems_termios_device_context *base);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* LIBBSP_ARM_LPC32XX_HSU_H */
|
||||||
@@ -146,6 +146,10 @@ $(PROJECT_INCLUDE)/bsp/boot.h: include/boot.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
|||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/boot.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/boot.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/boot.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/boot.h
|
||||||
|
|
||||||
|
$(PROJECT_INCLUDE)/bsp/hsu.h: include/hsu.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/hsu.h
|
||||||
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/hsu.h
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/bsp/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
$(PROJECT_INCLUDE)/bsp/i2c.h: include/i2c.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
|
||||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2c.h
|
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/i2c.h
|
||||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2c.h
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/i2c.h
|
||||||
|
|||||||
@@ -82,12 +82,10 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
|
|||||||
libbsp_a_SOURCES += irq/irq.c
|
libbsp_a_SOURCES += irq/irq.c
|
||||||
|
|
||||||
# console
|
# console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c \
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
../../shared/console_select.c \
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
console/console-config.c \
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
../../shared/console_read.c \
|
|
||||||
../../shared/console_write.c \
|
|
||||||
../../shared/console_control.c
|
|
||||||
# bsp_i2c
|
# bsp_i2c
|
||||||
libbsp_a_SOURCES += i2c/i2c_init.c
|
libbsp_a_SOURCES += i2c/i2c_init.c
|
||||||
# bsp_spi
|
# bsp_spi
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2010 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,102 +20,90 @@
|
|||||||
|
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
#include "../../../shared/console_private.h"
|
|
||||||
|
|
||||||
#include <mpc83xx/mpc83xx.h>
|
#include <mpc83xx/mpc83xx.h>
|
||||||
|
|
||||||
#include <bspopts.h>
|
#include <bsp.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
#ifdef BSP_USE_UART2
|
|
||||||
#define PORT_COUNT 2
|
|
||||||
#else
|
|
||||||
#define PORT_COUNT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BSP_USE_UART_INTERRUPTS
|
#ifdef BSP_USE_UART_INTERRUPTS
|
||||||
#define DEVICE_FNS &ns16550_fns
|
#define DEVICE_FNS &ns16550_handler_interrupt
|
||||||
#else
|
#else
|
||||||
#define DEVICE_FNS &ns16550_fns_polled
|
#define DEVICE_FNS &ns16550_handler_polled
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint8_t gen83xx_console_get_register(uint32_t addr, uint8_t i)
|
static uint8_t gen83xx_console_get_register(uintptr_t addr, uint8_t i)
|
||||||
{
|
{
|
||||||
volatile uint8_t *reg = (volatile uint8_t *) addr;
|
volatile uint8_t *reg = (volatile uint8_t *) addr;
|
||||||
|
|
||||||
return reg [i];
|
return reg [i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen83xx_console_set_register(uint32_t addr, uint8_t i, uint8_t val)
|
static void gen83xx_console_set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||||
{
|
{
|
||||||
volatile uint8_t *reg = (volatile uint8_t *) addr;
|
volatile uint8_t *reg = (volatile uint8_t *) addr;
|
||||||
|
|
||||||
reg [i] = val;
|
reg [i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long Console_Configuration_Count = PORT_COUNT;
|
static ns16550_context gen83xx_uart_context_0 = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||||
console_tbl Console_Configuration_Ports [PORT_COUNT] = {
|
.get_reg = gen83xx_console_get_register,
|
||||||
{
|
.set_reg = gen83xx_console_set_register,
|
||||||
.sDeviceName = "/dev/ttyS0",
|
.port = (uintptr_t) &mpc83xx.duart[0],
|
||||||
.deviceType = SERIAL_NS16550,
|
|
||||||
.pDeviceFns = DEVICE_FNS,
|
|
||||||
.deviceProbe = NULL,
|
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) BSP_CONSOLE_BAUD,
|
|
||||||
.ulCtrlPort1 = (uint32_t) &mpc83xx.duart [0],
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uint32_t) &mpc83xx.duart [0],
|
|
||||||
.getRegister = gen83xx_console_get_register,
|
|
||||||
.setRegister = gen83xx_console_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
#if MPC83XX_CHIP_TYPE / 10 == 830
|
#if MPC83XX_CHIP_TYPE / 10 == 830
|
||||||
.ulIntVector = BSP_IPIC_IRQ_UART
|
.irq = BSP_IPIC_IRQ_UART,
|
||||||
#else
|
#else
|
||||||
.ulIntVector = BSP_IPIC_IRQ_UART1
|
.irq = BSP_IPIC_IRQ_UART1,
|
||||||
#endif
|
#endif
|
||||||
|
.initial_baud = BSP_CONSOLE_BAUD
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BSP_USE_UART2
|
||||||
|
static ns16550_context gen83xx_uart_context_1 = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||||
|
.get_reg = gen83xx_console_get_register,
|
||||||
|
.set_reg = gen83xx_console_set_register,
|
||||||
|
.port = (uintptr_t) &mpc83xx.duart[1],
|
||||||
|
#if MPC83XX_CHIP_TYPE / 10 == 830
|
||||||
|
.irq = BSP_IPIC_IRQ_UART,
|
||||||
|
#else
|
||||||
|
.irq = BSP_IPIC_IRQ_UART2,
|
||||||
|
#endif
|
||||||
|
.initial_baud = BSP_CONSOLE_BAUD
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const console_device console_device_table[] = {
|
||||||
|
{
|
||||||
|
.device_file = "/dev/ttyS0",
|
||||||
|
.probe = ns16550_probe,
|
||||||
|
.handler = DEVICE_FNS,
|
||||||
|
.context = &gen83xx_uart_context_0.base
|
||||||
}
|
}
|
||||||
#ifdef BSP_USE_UART2
|
#ifdef BSP_USE_UART2
|
||||||
, {
|
, {
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = DEVICE_FNS,
|
.handler = DEVICE_FNS,
|
||||||
.deviceProbe = NULL,
|
.context = &gen83xx_uart_context_1.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) BSP_CONSOLE_BAUD,
|
|
||||||
.ulCtrlPort1 = (uint32_t) &mpc83xx.duart [1],
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uint32_t) &mpc83xx.duart [1],
|
|
||||||
.getRegister = gen83xx_console_get_register,
|
|
||||||
.setRegister = gen83xx_console_set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
#if MPC83XX_CHIP_TYPE / 10 == 830
|
|
||||||
.ulIntVector = BSP_IPIC_IRQ_UART
|
|
||||||
#else
|
|
||||||
.ulIntVector = BSP_IPIC_IRQ_UART2
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||||
|
|
||||||
static void gen83xx_output_char(char c)
|
static void gen83xx_output_char(char c)
|
||||||
{
|
{
|
||||||
const console_fns *console = Console_Port_Tbl [Console_Port_Minor]->pDeviceFns;
|
rtems_termios_device_context *ctx = console_device_table[0].context;
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
console->deviceWritePolled((int) Console_Port_Minor, '\r');
|
ns16550_polled_putchar(ctx, '\r');
|
||||||
}
|
}
|
||||||
console->deviceWritePolled((int) Console_Port_Minor, c);
|
|
||||||
|
ns16550_polled_putchar(ctx, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
BSP_output_char_function_type BSP_output_char = gen83xx_output_char;
|
BSP_output_char_function_type BSP_output_char = gen83xx_output_char;
|
||||||
|
|||||||
@@ -7,12 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008
|
* Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved.
|
||||||
* Embedded Brains GmbH
|
*
|
||||||
* Obere Lagerstr. 30
|
* embedded brains GmbH
|
||||||
* D-82178 Puchheim
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* rtems@embedded-brains.de
|
* <info@embedded-brains.de>
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
||||||
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
|
|
||||||
#include <rtems/counter.h>
|
#include <rtems/counter.h>
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <libcpu/powerpc-utility.h>
|
#include <libcpu/powerpc-utility.h>
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
#include <bsp/irq-generic.h>
|
#include <bsp/irq-generic.h>
|
||||||
#include <bsp/linker-symbols.h>
|
#include <bsp/linker-symbols.h>
|
||||||
#include <bsp/u-boot.h>
|
#include <bsp/u-boot.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
|
|
||||||
/* Configuration parameters for console driver, ... */
|
/* Configuration parameters for console driver, ... */
|
||||||
unsigned int BSP_bus_frequency;
|
unsigned int BSP_bus_frequency;
|
||||||
@@ -54,6 +56,7 @@ void BSP_panic(char *s)
|
|||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
||||||
|
(void) level;
|
||||||
|
|
||||||
printk("%s PANIC %s\n", rtems_get_version_string(), s);
|
printk("%s PANIC %s\n", rtems_get_version_string(), s);
|
||||||
|
|
||||||
@@ -67,6 +70,7 @@ void _BSP_Fatal_error(unsigned n)
|
|||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
rtems_interrupt_disable( level);
|
rtems_interrupt_disable( level);
|
||||||
|
(void) level;
|
||||||
|
|
||||||
printk( "%s PANIC ERROR %u\n", rtems_get_version_string(), n);
|
printk( "%s PANIC ERROR %u\n", rtems_get_version_string(), n);
|
||||||
|
|
||||||
@@ -80,15 +84,12 @@ void bsp_start( void)
|
|||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
|
|
||||||
ppc_cpu_id_t myCpu;
|
|
||||||
ppc_cpu_revision_t myCpuRevision;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
||||||
* store the result in global variables so that it can be used latter...
|
* store the result in global variables so that it can be used latter...
|
||||||
*/
|
*/
|
||||||
myCpu = get_ppc_cpu_type();
|
get_ppc_cpu_type();
|
||||||
myCpuRevision = get_ppc_cpu_revision();
|
get_ppc_cpu_revision();
|
||||||
|
|
||||||
/* Basic CPU initialization */
|
/* Basic CPU initialization */
|
||||||
cpu_init();
|
cpu_init();
|
||||||
@@ -122,12 +123,13 @@ void bsp_start( void)
|
|||||||
rtems_counter_initialize_converter(bsp_time_base_frequency);
|
rtems_counter_initialize_converter(bsp_time_base_frequency);
|
||||||
|
|
||||||
/* Initialize some console parameters */
|
/* Initialize some console parameters */
|
||||||
for (i = 0; i < Console_Configuration_Count; ++i) {
|
for (i = 0; i < console_device_count; ++i) {
|
||||||
Console_Configuration_Ports [i].ulClock = BSP_bus_frequency;
|
ns16550_context *ctx = (ns16550_context *) console_device_table[i].context;
|
||||||
|
|
||||||
|
ctx->clock = BSP_bus_frequency;
|
||||||
|
|
||||||
#ifdef HAS_UBOOT
|
#ifdef HAS_UBOOT
|
||||||
Console_Configuration_Ports [i].pDeviceParams =
|
ctx->initial_baud = bsp_uboot_board_info.bi_baudrate;
|
||||||
(void *) bsp_uboot_board_info.bi_baudrate;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,15 +92,11 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
|
|||||||
libbsp_a_SOURCES += irq/irq.c
|
libbsp_a_SOURCES += irq/irq.c
|
||||||
|
|
||||||
# Console
|
# Console
|
||||||
libbsp_a_SOURCES += ../../shared/console.c \
|
libbsp_a_SOURCES += ../../shared/console-termios-init.c
|
||||||
../../shared/console_select.c \
|
libbsp_a_SOURCES += ../../shared/console-termios.c
|
||||||
console/uart-bridge-master.c \
|
libbsp_a_SOURCES += console/uart-bridge-master.c
|
||||||
console/uart-bridge-slave.c \
|
libbsp_a_SOURCES += console/uart-bridge-slave.c
|
||||||
console/console-config.c \
|
libbsp_a_SOURCES += console/console-config.c
|
||||||
../../shared/console_read.c \
|
|
||||||
../../shared/console_write.c \
|
|
||||||
../../shared/console_control.c
|
|
||||||
|
|
||||||
|
|
||||||
# RTC
|
# RTC
|
||||||
libbsp_a_SOURCES += ../../shared/tod.c \
|
libbsp_a_SOURCES += ../../shared/tod.c \
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2010-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -20,25 +20,16 @@
|
|||||||
* http://www.rtems.org/license/LICENSE.
|
* http://www.rtems.org/license/LICENSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <rtems/bspIo.h>
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
|
||||||
#include <libchip/ns16550.h>
|
#include <libchip/ns16550.h>
|
||||||
#include "../../../shared/console_private.h"
|
|
||||||
|
|
||||||
#include <bspopts.h>
|
#include <bsp.h>
|
||||||
#include <bsp/irq.h>
|
#include <bsp/irq.h>
|
||||||
#include <bsp/qoriq.h>
|
#include <bsp/qoriq.h>
|
||||||
#include <bsp/intercom.h>
|
#include <bsp/intercom.h>
|
||||||
#include <bsp/uart-bridge.h>
|
#include <bsp/uart-bridge.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
#define CONSOLE_COUNT \
|
|
||||||
(QORIQ_UART_0_ENABLE \
|
|
||||||
+ QORIQ_UART_1_ENABLE \
|
|
||||||
+ QORIQ_UART_BRIDGE_0_ENABLE \
|
|
||||||
+ QORIQ_UART_BRIDGE_1_ENABLE)
|
|
||||||
|
|
||||||
#if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \
|
#if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \
|
||||||
|| (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2)
|
|| (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2)
|
||||||
@@ -47,56 +38,10 @@
|
|||||||
#define BRIDGE_SLAVE
|
#define BRIDGE_SLAVE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BRIDGE_MASTER
|
|
||||||
#define BRIDGE_FNS &qoriq_uart_bridge_master
|
|
||||||
#if QORIQ_UART_BRIDGE_0_ENABLE
|
|
||||||
static uart_bridge_master_control bridge_0_control = {
|
|
||||||
.device_path = "/dev/ttyS0",
|
|
||||||
.type = INTERCOM_TYPE_UART_0,
|
|
||||||
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
|
||||||
bridge_0_control.transmit_fifo
|
|
||||||
)
|
|
||||||
};
|
|
||||||
#define BRIDGE_0_CONTROL &bridge_0_control
|
|
||||||
#endif
|
|
||||||
#if QORIQ_UART_BRIDGE_1_ENABLE
|
|
||||||
static uart_bridge_master_control bridge_1_control = {
|
|
||||||
.device_path = "/dev/ttyS1",
|
|
||||||
.type = INTERCOM_TYPE_UART_1,
|
|
||||||
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
|
||||||
bridge_1_control.transmit_fifo
|
|
||||||
)
|
|
||||||
};
|
|
||||||
#define BRIDGE_1_CONTROL &bridge_1_control
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BRIDGE_SLAVE
|
|
||||||
#define BRIDGE_FNS &qoriq_uart_bridge_slave
|
|
||||||
#if QORIQ_UART_BRIDGE_0_ENABLE
|
|
||||||
static uart_bridge_slave_control bridge_0_control = {
|
|
||||||
.type = INTERCOM_TYPE_UART_0,
|
|
||||||
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
|
||||||
bridge_0_control.transmit_fifo
|
|
||||||
)
|
|
||||||
};
|
|
||||||
#define BRIDGE_0_CONTROL &bridge_0_control
|
|
||||||
#endif
|
|
||||||
#if QORIQ_UART_BRIDGE_1_ENABLE
|
|
||||||
static uart_bridge_slave_control bridge_1_control = {
|
|
||||||
.type = INTERCOM_TYPE_UART_1,
|
|
||||||
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
|
||||||
bridge_1_control.transmit_fifo
|
|
||||||
)
|
|
||||||
};
|
|
||||||
#define BRIDGE_1_CONTROL &bridge_1_control
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BSP_USE_UART_INTERRUPTS
|
#ifdef BSP_USE_UART_INTERRUPTS
|
||||||
#define DEVICE_FNS &ns16550_fns
|
#define DEVICE_FNS &ns16550_handler_interrupt
|
||||||
#else
|
#else
|
||||||
#define DEVICE_FNS &ns16550_fns_polled
|
#define DEVICE_FNS &ns16550_handler_polled
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE
|
#if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE
|
||||||
@@ -115,90 +60,134 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned long Console_Configuration_Count = CONSOLE_COUNT;
|
#if QORIQ_UART_0_ENABLE
|
||||||
console_tbl Console_Configuration_Ports [CONSOLE_COUNT] = {
|
static ns16550_context qoriq_uart_context_0 = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
|
||||||
|
.get_reg = get_register,
|
||||||
|
.set_reg = set_register,
|
||||||
|
.port = (uintptr_t) &qoriq.uart_0,
|
||||||
|
.irq = QORIQ_IRQ_DUART,
|
||||||
|
.initial_baud = BSP_CONSOLE_BAUD
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if QORIQ_UART_1_ENABLE
|
||||||
|
static ns16550_context qoriq_uart_context_1 = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
|
||||||
|
.get_reg = get_register,
|
||||||
|
.set_reg = set_register,
|
||||||
|
.port = (uintptr_t) &qoriq.uart_1,
|
||||||
|
.irq = QORIQ_IRQ_DUART,
|
||||||
|
.initial_baud = BSP_CONSOLE_BAUD
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BRIDGE_MASTER
|
||||||
|
#define BRIDGE_PROBE qoriq_uart_bridge_master_probe
|
||||||
|
#define BRIDGE_FNS &qoriq_uart_bridge_master
|
||||||
|
#if QORIQ_UART_BRIDGE_0_ENABLE
|
||||||
|
static uart_bridge_master_context bridge_0_context = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
|
||||||
|
.device_path = "/dev/ttyS0",
|
||||||
|
.type = INTERCOM_TYPE_UART_0,
|
||||||
|
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
||||||
|
bridge_0_context.transmit_fifo
|
||||||
|
)
|
||||||
|
};
|
||||||
|
#define BRIDGE_0_CONTEXT &bridge_0_context
|
||||||
|
#endif
|
||||||
|
#if QORIQ_UART_BRIDGE_1_ENABLE
|
||||||
|
static uart_bridge_master_context bridge_1_context = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
|
||||||
|
.device_path = "/dev/ttyS1",
|
||||||
|
.type = INTERCOM_TYPE_UART_1,
|
||||||
|
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
||||||
|
bridge_1_context.transmit_fifo
|
||||||
|
)
|
||||||
|
};
|
||||||
|
#define BRIDGE_1_CONTEXT &bridge_1_context
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BRIDGE_SLAVE
|
||||||
|
#define BRIDGE_PROBE console_device_probe_default
|
||||||
|
#define BRIDGE_FNS &qoriq_uart_bridge_slave
|
||||||
|
#if QORIQ_UART_BRIDGE_0_ENABLE
|
||||||
|
static uart_bridge_slave_context bridge_0_context = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
|
||||||
|
.type = INTERCOM_TYPE_UART_0,
|
||||||
|
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
||||||
|
bridge_0_context.transmit_fifo
|
||||||
|
)
|
||||||
|
};
|
||||||
|
#define BRIDGE_0_CONTEXT &bridge_0_context
|
||||||
|
#endif
|
||||||
|
#if QORIQ_UART_BRIDGE_1_ENABLE
|
||||||
|
static uart_bridge_slave_context bridge_1_context = {
|
||||||
|
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
|
||||||
|
.type = INTERCOM_TYPE_UART_1,
|
||||||
|
.transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
|
||||||
|
bridge_1_context.transmit_fifo
|
||||||
|
)
|
||||||
|
};
|
||||||
|
#define BRIDGE_1_CONTEXT &bridge_1_context
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const console_device console_device_table[] = {
|
||||||
#if QORIQ_UART_0_ENABLE
|
#if QORIQ_UART_0_ENABLE
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS0",
|
.device_file = "/dev/ttyS0",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = DEVICE_FNS,
|
.handler = DEVICE_FNS,
|
||||||
.deviceProbe = NULL,
|
.context = &qoriq_uart_context_0.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) BSP_CONSOLE_BAUD,
|
|
||||||
.ulCtrlPort1 = (uintptr_t) &qoriq.uart_0,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uintptr_t) &qoriq.uart_0,
|
|
||||||
.getRegister = get_register,
|
|
||||||
.setRegister = set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
.ulIntVector = QORIQ_IRQ_DUART
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if QORIQ_UART_1_ENABLE
|
#if QORIQ_UART_1_ENABLE
|
||||||
{
|
{
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
.deviceType = SERIAL_NS16550,
|
.probe = ns16550_probe,
|
||||||
.pDeviceFns = DEVICE_FNS,
|
.handler = DEVICE_FNS,
|
||||||
.deviceProbe = NULL,
|
.context = &qoriq_uart_context_1.base
|
||||||
.pDeviceFlow = NULL,
|
|
||||||
.ulMargin = 16,
|
|
||||||
.ulHysteresis = 8,
|
|
||||||
.pDeviceParams = (void *) BSP_CONSOLE_BAUD,
|
|
||||||
.ulCtrlPort1 = (uintptr_t) &qoriq.uart_1,
|
|
||||||
.ulCtrlPort2 = 0,
|
|
||||||
.ulDataPort = (uintptr_t) &qoriq.uart_1,
|
|
||||||
.getRegister = get_register,
|
|
||||||
.setRegister = set_register,
|
|
||||||
.getData = NULL,
|
|
||||||
.setData = NULL,
|
|
||||||
.ulClock = 0,
|
|
||||||
.ulIntVector = QORIQ_IRQ_DUART
|
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if QORIQ_UART_BRIDGE_0_ENABLE
|
#if QORIQ_UART_BRIDGE_0_ENABLE
|
||||||
{
|
{
|
||||||
#if QORIQ_UART_1_ENABLE
|
#if QORIQ_UART_1_ENABLE
|
||||||
.sDeviceName = "/dev/ttyB0",
|
.device_file = "/dev/ttyB0",
|
||||||
#else
|
#else
|
||||||
.sDeviceName = "/dev/ttyS0",
|
.device_file = "/dev/ttyS0",
|
||||||
#endif
|
#endif
|
||||||
.deviceType = SERIAL_CUSTOM,
|
.probe = BRIDGE_PROBE,
|
||||||
.pDeviceFns = BRIDGE_FNS,
|
.handler = BRIDGE_FNS,
|
||||||
.pDeviceParams = BRIDGE_0_CONTROL
|
.context = BRIDGE_0_CONTEXT
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if QORIQ_UART_BRIDGE_1_ENABLE
|
#if QORIQ_UART_BRIDGE_1_ENABLE
|
||||||
{
|
{
|
||||||
#if QORIQ_UART_1_ENABLE
|
#if QORIQ_UART_1_ENABLE
|
||||||
.sDeviceName = "/dev/ttyB1",
|
.device_file = "/dev/ttyB1",
|
||||||
#else
|
#else
|
||||||
.sDeviceName = "/dev/ttyS1",
|
.device_file = "/dev/ttyS1",
|
||||||
#endif
|
#endif
|
||||||
.deviceType = SERIAL_CUSTOM,
|
.probe = BRIDGE_PROBE,
|
||||||
.pDeviceFns = BRIDGE_FNS,
|
.handler = BRIDGE_FNS,
|
||||||
.pDeviceParams = BRIDGE_1_CONTROL
|
.context = BRIDGE_1_CONTEXT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
|
||||||
|
|
||||||
static void output_char(char c)
|
static void output_char(char c)
|
||||||
{
|
{
|
||||||
int minor = (int) Console_Port_Minor;
|
rtems_termios_device_context *ctx = console_device_table[0].context;
|
||||||
const console_tbl **ct_tbl = Console_Port_Tbl;
|
|
||||||
|
|
||||||
if (ct_tbl != NULL) {
|
|
||||||
const console_fns *cf = ct_tbl[minor]->pDeviceFns;
|
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
(*cf->deviceWritePolled)(minor, '\r');
|
ns16550_polled_putchar(ctx, '\r');
|
||||||
}
|
}
|
||||||
|
|
||||||
(*cf->deviceWritePolled)(minor, c);
|
ns16550_polled_putchar(ctx, c);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BSP_output_char_function_type BSP_output_char = output_char;
|
BSP_output_char_function_type BSP_output_char = output_char;
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
#include <libchip/sersupp.h>
|
|
||||||
|
|
||||||
#include <bspopts.h>
|
#include <bspopts.h>
|
||||||
#include <bsp/uart-bridge.h>
|
#include <bsp/uart-bridge.h>
|
||||||
|
|
||||||
@@ -55,12 +53,12 @@ static void serial_settings(int fd)
|
|||||||
static void uart_bridge_master_service(intercom_packet *packet, void *arg)
|
static void uart_bridge_master_service(intercom_packet *packet, void *arg)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
uart_bridge_master_control *control = arg;
|
uart_bridge_master_context *ctx = arg;
|
||||||
|
|
||||||
sc = rtems_chain_append_with_notification(
|
sc = rtems_chain_append_with_notification(
|
||||||
&control->transmit_fifo,
|
&ctx->transmit_fifo,
|
||||||
&packet->glue.node,
|
&packet->glue.node,
|
||||||
control->transmit_task,
|
ctx->transmit_task,
|
||||||
TRANSMIT_EVENT
|
TRANSMIT_EVENT
|
||||||
);
|
);
|
||||||
assert(sc == RTEMS_SUCCESSFUL);
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
@@ -68,10 +66,10 @@ static void uart_bridge_master_service(intercom_packet *packet, void *arg)
|
|||||||
|
|
||||||
static void receive_task(rtems_task_argument arg)
|
static void receive_task(rtems_task_argument arg)
|
||||||
{
|
{
|
||||||
uart_bridge_master_control *control = (uart_bridge_master_control *) arg;
|
uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
|
||||||
intercom_type type = control->type;
|
intercom_type type = ctx->type;
|
||||||
|
|
||||||
int fd = open(control->device_path, O_RDONLY);
|
int fd = open(ctx->device_path, O_RDONLY);
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
serial_settings(fd);
|
serial_settings(fd);
|
||||||
@@ -94,10 +92,10 @@ static void receive_task(rtems_task_argument arg)
|
|||||||
static void transmit_task(rtems_task_argument arg)
|
static void transmit_task(rtems_task_argument arg)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
uart_bridge_master_control *control = (uart_bridge_master_control *) arg;
|
uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
|
||||||
rtems_chain_control *fifo = &control->transmit_fifo;
|
rtems_chain_control *fifo = &ctx->transmit_fifo;
|
||||||
|
|
||||||
int fd = open(control->device_path, O_WRONLY);
|
int fd = open(ctx->device_path, O_WRONLY);
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
serial_settings(fd);
|
serial_settings(fd);
|
||||||
@@ -119,12 +117,12 @@ static void transmit_task(rtems_task_argument arg)
|
|||||||
static rtems_id create_task(
|
static rtems_id create_task(
|
||||||
char name,
|
char name,
|
||||||
rtems_task_entry entry,
|
rtems_task_entry entry,
|
||||||
uart_bridge_master_control *control
|
uart_bridge_master_context *ctx
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
rtems_id task = RTEMS_ID_NONE;
|
rtems_id task = RTEMS_ID_NONE;
|
||||||
char index = (char) ('0' + control->type - INTERCOM_TYPE_UART_0);
|
char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0);
|
||||||
|
|
||||||
sc = rtems_task_create(
|
sc = rtems_task_create(
|
||||||
rtems_build_name('U', 'B', name, index),
|
rtems_build_name('U', 'B', name, index),
|
||||||
@@ -139,57 +137,45 @@ static rtems_id create_task(
|
|||||||
sc = rtems_task_start(
|
sc = rtems_task_start(
|
||||||
task,
|
task,
|
||||||
entry,
|
entry,
|
||||||
(rtems_task_argument) control
|
(rtems_task_argument) ctx
|
||||||
);
|
);
|
||||||
assert(sc == RTEMS_SUCCESSFUL);
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize(int minor)
|
bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base)
|
||||||
{
|
{
|
||||||
console_tbl *ct = Console_Port_Tbl [minor];
|
uart_bridge_master_context *ctx = (uart_bridge_master_context *) base;
|
||||||
uart_bridge_master_control *control = ct->pDeviceParams;
|
intercom_type type = ctx->type;
|
||||||
intercom_type type = control->type;
|
|
||||||
|
|
||||||
qoriq_intercom_service_install(type, uart_bridge_master_service, control);
|
qoriq_intercom_service_install(type, uart_bridge_master_service, ctx);
|
||||||
create_task('R', receive_task, control);
|
create_task('R', receive_task, ctx);
|
||||||
control->transmit_task = create_task('T', transmit_task, control);
|
ctx->transmit_task = create_task('T', transmit_task, ctx);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int first_open(int major, int minor, void *arg)
|
static bool first_open(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
struct termios *term,
|
||||||
|
rtems_libio_open_close_args_t *args
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int last_close(int major, int minor, void *arg)
|
static bool set_attributes(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const struct termios *term
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_polled(int minor)
|
const rtems_termios_device_handler qoriq_uart_bridge_master = {
|
||||||
{
|
.first_open = first_open,
|
||||||
return -1;
|
.set_attributes = set_attributes,
|
||||||
}
|
.mode = TERMIOS_POLLED
|
||||||
|
|
||||||
static void write_polled(int minor, char c)
|
|
||||||
{
|
|
||||||
/* Do nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_attributes(int minor, const struct termios *term)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const console_fns qoriq_uart_bridge_master = {
|
|
||||||
.deviceProbe = libchip_serial_default_probe,
|
|
||||||
.deviceFirstOpen = first_open,
|
|
||||||
.deviceLastClose = last_close,
|
|
||||||
.deviceRead = read_polled,
|
|
||||||
.deviceWrite = NULL,
|
|
||||||
.deviceInitialize = initialize,
|
|
||||||
.deviceWritePolled = write_polled,
|
|
||||||
.deviceSetAttributes = set_attributes,
|
|
||||||
.deviceOutputUsesInterrupts = false
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ static void restore_preemption(rtems_mode prev_mode)
|
|||||||
|
|
||||||
static void uart_bridge_slave_service(intercom_packet *packet, void *arg)
|
static void uart_bridge_slave_service(intercom_packet *packet, void *arg)
|
||||||
{
|
{
|
||||||
uart_bridge_slave_control *control = arg;
|
uart_bridge_slave_context *ctx = arg;
|
||||||
struct rtems_termios_tty *tty = control->tty;
|
struct rtems_termios_tty *tty = ctx->tty;
|
||||||
|
|
||||||
/* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */
|
/* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */
|
||||||
rtems_mode prev_mode = disable_preemption();
|
rtems_mode prev_mode = disable_preemption();
|
||||||
@@ -65,9 +65,9 @@ static void uart_bridge_slave_service(intercom_packet *packet, void *arg)
|
|||||||
static void transmit_task(rtems_task_argument arg)
|
static void transmit_task(rtems_task_argument arg)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
uart_bridge_slave_control *control = (uart_bridge_slave_control *) arg;
|
uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) arg;
|
||||||
rtems_chain_control *fifo = &control->transmit_fifo;
|
rtems_chain_control *fifo = &ctx->transmit_fifo;
|
||||||
struct rtems_termios_tty *tty = control->tty;
|
struct rtems_termios_tty *tty = ctx->tty;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
intercom_packet *packet = NULL;
|
intercom_packet *packet = NULL;
|
||||||
@@ -91,12 +91,12 @@ static void transmit_task(rtems_task_argument arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void create_transmit_task(
|
static void create_transmit_task(
|
||||||
uart_bridge_slave_control *control
|
uart_bridge_slave_context *ctx
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
rtems_id task = RTEMS_ID_NONE;
|
rtems_id task = RTEMS_ID_NONE;
|
||||||
char index = (char) ('0' + control->type - INTERCOM_TYPE_UART_0);
|
char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0);
|
||||||
|
|
||||||
sc = rtems_task_create(
|
sc = rtems_task_create(
|
||||||
rtems_build_name('U', 'B', 'T', index),
|
rtems_build_name('U', 'B', 'T', index),
|
||||||
@@ -111,54 +111,53 @@ static void create_transmit_task(
|
|||||||
sc = rtems_task_start(
|
sc = rtems_task_start(
|
||||||
task,
|
task,
|
||||||
transmit_task,
|
transmit_task,
|
||||||
(rtems_task_argument) control
|
(rtems_task_argument) ctx
|
||||||
);
|
);
|
||||||
assert(sc == RTEMS_SUCCESSFUL);
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
|
|
||||||
control->transmit_task = task;
|
ctx->transmit_task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize(int minor)
|
static bool first_open(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
struct termios *term,
|
||||||
|
rtems_libio_open_close_args_t *args
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/* Do nothing */
|
uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base;
|
||||||
}
|
intercom_type type = ctx->type;
|
||||||
|
|
||||||
static int first_open(int major, int minor, void *arg)
|
ctx->tty = tty;
|
||||||
{
|
|
||||||
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_tbl *ct = Console_Port_Tbl[minor];
|
|
||||||
console_data *cd = &Console_Port_Data [minor];
|
|
||||||
uart_bridge_slave_control *control = ct->pDeviceParams;
|
|
||||||
intercom_type type = control->type;
|
|
||||||
|
|
||||||
control->tty = tty;
|
|
||||||
cd->termios_data = tty;
|
|
||||||
rtems_termios_set_initial_baud(tty, 115200);
|
rtems_termios_set_initial_baud(tty, 115200);
|
||||||
create_transmit_task(control);
|
create_transmit_task(ctx);
|
||||||
qoriq_intercom_service_install(type, uart_bridge_slave_service, control);
|
qoriq_intercom_service_install(type, uart_bridge_slave_service, ctx);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int last_close(int major, int minor, void *arg)
|
static void last_close(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
rtems_libio_open_close_args_t *args
|
||||||
|
)
|
||||||
{
|
{
|
||||||
console_tbl *ct = Console_Port_Tbl[minor];
|
uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base;
|
||||||
uart_bridge_slave_control *control = ct->pDeviceParams;
|
|
||||||
|
|
||||||
qoriq_intercom_service_remove(control->type);
|
qoriq_intercom_service_remove(ctx->type);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t write_with_interrupts(int minor, const char *buf, size_t len)
|
static void write_with_interrupts(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
console_tbl *ct = Console_Port_Tbl[minor];
|
uart_bridge_slave_context *ctx = (uart_bridge_slave_context *) base;
|
||||||
uart_bridge_slave_control *control = ct->pDeviceParams;
|
|
||||||
intercom_packet *packet = qoriq_intercom_allocate_packet(
|
intercom_packet *packet = qoriq_intercom_allocate_packet(
|
||||||
control->type,
|
ctx->type,
|
||||||
INTERCOM_SIZE_64
|
INTERCOM_SIZE_64
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -170,44 +169,27 @@ static ssize_t write_with_interrupts(int minor, const char *buf, size_t len)
|
|||||||
* another context.
|
* another context.
|
||||||
*/
|
*/
|
||||||
sc = rtems_chain_append_with_notification(
|
sc = rtems_chain_append_with_notification(
|
||||||
&control->transmit_fifo,
|
&ctx->transmit_fifo,
|
||||||
&packet->glue.node,
|
&packet->glue.node,
|
||||||
control->transmit_task,
|
ctx->transmit_task,
|
||||||
TRANSMIT_EVENT
|
TRANSMIT_EVENT
|
||||||
);
|
);
|
||||||
assert(sc == RTEMS_SUCCESSFUL);
|
assert(sc == RTEMS_SUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_polled(int minor, char c)
|
static bool set_attributes(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const struct termios *term
|
||||||
|
)
|
||||||
{
|
{
|
||||||
console_tbl *ct = Console_Port_Tbl[minor];
|
return false;
|
||||||
uart_bridge_slave_control *control = ct->pDeviceParams;
|
|
||||||
intercom_packet *packet = qoriq_intercom_allocate_packet(
|
|
||||||
control->type,
|
|
||||||
INTERCOM_SIZE_64
|
|
||||||
);
|
|
||||||
char *data = packet->data;
|
|
||||||
data [0] = c;
|
|
||||||
packet->size = 1;
|
|
||||||
qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_MASTER_CORE, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_attribues(int minor, const struct termios *term)
|
const rtems_termios_device_handler qoriq_uart_bridge_slave = {
|
||||||
{
|
.first_open = first_open,
|
||||||
return -1;
|
.last_close = last_close,
|
||||||
}
|
.write = write_with_interrupts,
|
||||||
|
.set_attributes = set_attributes,
|
||||||
const console_fns qoriq_uart_bridge_slave = {
|
.mode = TERMIOS_IRQ_DRIVEN
|
||||||
.deviceProbe = libchip_serial_default_probe,
|
|
||||||
.deviceFirstOpen = first_open,
|
|
||||||
.deviceLastClose = last_close,
|
|
||||||
.deviceRead = NULL,
|
|
||||||
.deviceWrite = write_with_interrupts,
|
|
||||||
.deviceInitialize = initialize,
|
|
||||||
.deviceWritePolled = write_polled,
|
|
||||||
.deviceSetAttributes = set_attribues,
|
|
||||||
.deviceOutputUsesInterrupts = true
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 embedded brains GmbH. All rights reserved.
|
* Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved.
|
||||||
*
|
*
|
||||||
* embedded brains GmbH
|
* embedded brains GmbH
|
||||||
* Obere Lagerstr. 30
|
* Dornierstr. 4
|
||||||
* 82178 Puchheim
|
* 82178 Puchheim
|
||||||
* Germany
|
* Germany
|
||||||
* <rtems@embedded-brains.de>
|
* <rtems@embedded-brains.de>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H
|
#ifndef LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H
|
||||||
#define LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H
|
#define LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
#include <rtems/termiostypes.h>
|
||||||
|
|
||||||
#include <bsp/intercom.h>
|
#include <bsp/intercom.h>
|
||||||
|
|
||||||
@@ -42,22 +42,26 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
rtems_termios_device_context base;
|
||||||
const char *device_path;
|
const char *device_path;
|
||||||
intercom_type type;
|
intercom_type type;
|
||||||
rtems_id transmit_task;
|
rtems_id transmit_task;
|
||||||
rtems_chain_control transmit_fifo;
|
rtems_chain_control transmit_fifo;
|
||||||
} uart_bridge_master_control;
|
} uart_bridge_master_context;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
rtems_termios_device_context base;
|
||||||
struct rtems_termios_tty *tty;
|
struct rtems_termios_tty *tty;
|
||||||
intercom_type type;
|
intercom_type type;
|
||||||
rtems_id transmit_task;
|
rtems_id transmit_task;
|
||||||
rtems_chain_control transmit_fifo;
|
rtems_chain_control transmit_fifo;
|
||||||
} uart_bridge_slave_control;
|
} uart_bridge_slave_context;
|
||||||
|
|
||||||
extern const console_fns qoriq_uart_bridge_master;
|
bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base);
|
||||||
|
|
||||||
extern const console_fns qoriq_uart_bridge_slave;
|
extern const rtems_termios_device_handler qoriq_uart_bridge_master;
|
||||||
|
|
||||||
|
extern const rtems_termios_device_handler qoriq_uart_bridge_slave;
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <rtems/config.h>
|
#include <rtems/config.h>
|
||||||
#include <rtems/counter.h>
|
#include <rtems/counter.h>
|
||||||
|
|
||||||
#include <libchip/serial.h>
|
#include <libchip/ns16550.h>
|
||||||
|
|
||||||
#include <libcpu/powerpc-utility.h>
|
#include <libcpu/powerpc-utility.h>
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <bsp/linker-symbols.h>
|
#include <bsp/linker-symbols.h>
|
||||||
#include <bsp/mmu.h>
|
#include <bsp/mmu.h>
|
||||||
#include <bsp/qoriq.h>
|
#include <bsp/qoriq.h>
|
||||||
|
#include <bsp/console-termios.h>
|
||||||
|
|
||||||
LINKER_SYMBOL(bsp_exc_vector_base);
|
LINKER_SYMBOL(bsp_exc_vector_base);
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ void BSP_panic(char *s)
|
|||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
||||||
|
(void) level;
|
||||||
|
|
||||||
printk("%s PANIC %s\n", rtems_get_version_string(), s);
|
printk("%s PANIC %s\n", rtems_get_version_string(), s);
|
||||||
|
|
||||||
@@ -63,6 +65,7 @@ void _BSP_Fatal_error(unsigned n)
|
|||||||
rtems_interrupt_level level;
|
rtems_interrupt_level level;
|
||||||
|
|
||||||
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
||||||
|
(void) level;
|
||||||
|
|
||||||
printk("%s PANIC ERROR %u\n", rtems_get_version_string(), n);
|
printk("%s PANIC ERROR %u\n", rtems_get_version_string(), n);
|
||||||
|
|
||||||
@@ -75,15 +78,12 @@ void bsp_start(void)
|
|||||||
{
|
{
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
|
|
||||||
ppc_cpu_id_t myCpu;
|
|
||||||
ppc_cpu_revision_t myCpuRevision;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
|
||||||
* store the result in global variables so that it can be used latter...
|
* store the result in global variables so that it can be used latter...
|
||||||
*/
|
*/
|
||||||
myCpu = get_ppc_cpu_type();
|
get_ppc_cpu_type();
|
||||||
myCpuRevision = get_ppc_cpu_revision();
|
get_ppc_cpu_revision();
|
||||||
|
|
||||||
/* Initialize some device driver parameters */
|
/* Initialize some device driver parameters */
|
||||||
#ifdef HAS_UBOOT
|
#ifdef HAS_UBOOT
|
||||||
@@ -93,17 +93,25 @@ void bsp_start(void)
|
|||||||
rtems_counter_initialize_converter(BSP_bus_frequency / 8);
|
rtems_counter_initialize_converter(BSP_bus_frequency / 8);
|
||||||
|
|
||||||
/* Initialize some console parameters */
|
/* Initialize some console parameters */
|
||||||
for (i = 0; i < Console_Configuration_Count; ++i) {
|
for (i = 0; i < console_device_count; ++i) {
|
||||||
console_tbl *ct = &Console_Configuration_Ports[i];
|
const console_device *dev = &console_device_table[i];
|
||||||
|
const rtems_termios_device_handler *ns16550 =
|
||||||
|
#ifdef BSP_USE_UART_INTERRUPTS
|
||||||
|
&ns16550_handler_interrupt;
|
||||||
|
#else
|
||||||
|
&ns16550_handler_polled;
|
||||||
|
#endif
|
||||||
|
|
||||||
ct->ulClock = BSP_bus_frequency;
|
if (dev->handler == ns16550) {
|
||||||
|
ns16550_context *ctx = (ns16550_context *) dev->context;
|
||||||
|
|
||||||
|
ctx->clock = BSP_bus_frequency;
|
||||||
|
|
||||||
#ifdef HAS_UBOOT
|
#ifdef HAS_UBOOT
|
||||||
if (ct->deviceType == SERIAL_NS16550) {
|
ctx->initial_baud = bsp_uboot_board_info.bi_baudrate;
|
||||||
ct->pDeviceParams = (void *) bsp_uboot_board_info.bi_baudrate;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable decrementer */
|
/* Disable decrementer */
|
||||||
PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(BOOKE_TCR, BOOKE_TCR_DIE);
|
PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(BOOKE_TCR, BOOKE_TCR_DIE);
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ libserialio_a_SOURCES = serial/mc68681.c serial/mc68681_baud.c \
|
|||||||
serial/mc68681_reg8.c serial/ns16550.c serial/z85c30.c \
|
serial/mc68681_reg8.c serial/ns16550.c serial/z85c30.c \
|
||||||
serial/z85c30_reg.c serial/serprobe.c serial/mc68681_p.h \
|
serial/z85c30_reg.c serial/serprobe.c serial/mc68681_p.h \
|
||||||
serial/z85c30_p.h
|
serial/z85c30_p.h
|
||||||
|
libserialio_a_SOURCES += serial/ns16550-context.c
|
||||||
|
|
||||||
EXTRA_DIST += serial/README.mc68681 serial/README.ns16550 \
|
EXTRA_DIST += serial/README.mc68681 serial/README.ns16550 \
|
||||||
serial/README.xr88681 serial/README.z85c30 serial/STATUS
|
serial/README.xr88681 serial/README.z85c30 serial/STATUS
|
||||||
|
|||||||
677
c/src/libchip/serial/ns16550-context.c
Normal file
677
c/src/libchip/serial/ns16550-context.c
Normal file
@@ -0,0 +1,677 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* This file contains the TTY driver for the National Semiconductor NS16550.
|
||||||
|
*
|
||||||
|
* This part is widely cloned and second sourced. It is found in a number
|
||||||
|
* of "Super IO" controllers.
|
||||||
|
*
|
||||||
|
* This driver uses the termios pseudo driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* COPYRIGHT (c) 1998 by Radstone Technology
|
||||||
|
*
|
||||||
|
* THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
|
||||||
|
* AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
|
||||||
|
*
|
||||||
|
* You are hereby granted permission to use, copy, modify, and distribute
|
||||||
|
* this file, provided that this notice, plus the above copyright notice
|
||||||
|
* and disclaimer, appears in all copies. Radstone Technology will provide
|
||||||
|
* no support for this code.
|
||||||
|
*
|
||||||
|
* 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 <stdlib.h>
|
||||||
|
|
||||||
|
#include <rtems/bspIo.h>
|
||||||
|
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
#include "ns16550.h"
|
||||||
|
#include "ns16550_p.h"
|
||||||
|
|
||||||
|
#if defined(BSP_FEATURE_IRQ_EXTENSION)
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#elif defined(BSP_FEATURE_IRQ_LEGACY)
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#elif defined(__PPC__) || defined(__i386__)
|
||||||
|
#include <bsp/irq.h>
|
||||||
|
#define BSP_FEATURE_IRQ_LEGACY
|
||||||
|
#ifdef BSP_SHARED_HANDLER_SUPPORT
|
||||||
|
#define BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint32_t NS16550_GetBaudDivisor(ns16550_context *ctx, uint32_t baud)
|
||||||
|
{
|
||||||
|
uint32_t clock = ctx->clock;
|
||||||
|
uint32_t baudDivisor = (clock != 0 ? clock : 115200) / (baud * 16);
|
||||||
|
|
||||||
|
if (ctx->has_fractional_divider_register) {
|
||||||
|
uint32_t fractionalDivider = 0x10;
|
||||||
|
uint32_t err = baud;
|
||||||
|
uint32_t mulVal;
|
||||||
|
uint32_t divAddVal;
|
||||||
|
|
||||||
|
clock /= 16 * baudDivisor;
|
||||||
|
for (mulVal = 1; mulVal < 16; ++mulVal) {
|
||||||
|
for (divAddVal = 0; divAddVal < mulVal; ++divAddVal) {
|
||||||
|
uint32_t actual = (mulVal * clock) / (mulVal + divAddVal);
|
||||||
|
uint32_t newErr = actual > baud ? actual - baud : baud - actual;
|
||||||
|
|
||||||
|
if (newErr < err) {
|
||||||
|
err = newErr;
|
||||||
|
fractionalDivider = (mulVal << 4) | divAddVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*ctx->set_reg)(
|
||||||
|
ctx->port,
|
||||||
|
NS16550_FRACTIONAL_DIVIDER,
|
||||||
|
fractionalDivider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baudDivisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_enable_interrupts
|
||||||
|
*
|
||||||
|
* This routine initializes the port to have the specified interrupts masked.
|
||||||
|
*/
|
||||||
|
static void ns16550_enable_interrupts(
|
||||||
|
ns16550_context *ctx,
|
||||||
|
int mask
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(*ctx->set_reg)(ctx->port, NS16550_INTERRUPT_ENABLE, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_probe
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool ns16550_probe(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
uintptr_t pNS16550;
|
||||||
|
uint8_t ucDataByte;
|
||||||
|
uint32_t ulBaudDivisor;
|
||||||
|
ns16550_set_reg setReg;
|
||||||
|
ns16550_get_reg getReg;
|
||||||
|
|
||||||
|
ctx->modem_control = SP_MODEM_IRQ;
|
||||||
|
|
||||||
|
pNS16550 = ctx->port;
|
||||||
|
setReg = ctx->set_reg;
|
||||||
|
getReg = ctx->get_reg;
|
||||||
|
|
||||||
|
/* Clear the divisor latch, clear all interrupt enables,
|
||||||
|
* and reset and
|
||||||
|
* disable the FIFO's.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR );
|
||||||
|
|
||||||
|
/* Set the divisor latch and set the baud rate. */
|
||||||
|
|
||||||
|
ulBaudDivisor = NS16550_GetBaudDivisor(ctx, ctx->initial_baud);
|
||||||
|
ucDataByte = SP_LINE_DLAB;
|
||||||
|
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
|
||||||
|
|
||||||
|
/* XXX */
|
||||||
|
(*setReg)(pNS16550,NS16550_TRANSMIT_BUFFER,(uint8_t)(ulBaudDivisor & 0xffU));
|
||||||
|
(*setReg)(
|
||||||
|
pNS16550,NS16550_INTERRUPT_ENABLE,
|
||||||
|
(uint8_t)(( ulBaudDivisor >> 8 ) & 0xffU )
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Clear the divisor latch and set the character size to eight bits */
|
||||||
|
/* with one stop bit and no parity checking. */
|
||||||
|
ucDataByte = EIGHT_BITS;
|
||||||
|
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
|
||||||
|
|
||||||
|
/* Enable and reset transmit and receive FIFOs. TJA */
|
||||||
|
ucDataByte = SP_FIFO_ENABLE;
|
||||||
|
(*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
|
||||||
|
|
||||||
|
ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
|
||||||
|
(*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
|
||||||
|
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
|
||||||
|
|
||||||
|
/* Set data terminal ready. */
|
||||||
|
/* And open interrupt tristate line */
|
||||||
|
(*setReg)(pNS16550, NS16550_MODEM_CONTROL,ctx->modem_control);
|
||||||
|
|
||||||
|
(*getReg)(pNS16550, NS16550_LINE_STATUS );
|
||||||
|
(*getReg)(pNS16550, NS16550_RECEIVE_BUFFER );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process interrupt.
|
||||||
|
*/
|
||||||
|
static void ns16550_isr(void *arg)
|
||||||
|
{
|
||||||
|
rtems_termios_tty *tty = arg;
|
||||||
|
ns16550_context *ctx = rtems_termios_get_device_context(tty);
|
||||||
|
uint32_t port = ctx->port;
|
||||||
|
ns16550_get_reg get = ctx->get_reg;
|
||||||
|
int i = 0;
|
||||||
|
char buf [SP_FIFO_SIZE];
|
||||||
|
|
||||||
|
/* Iterate until no more interrupts are pending */
|
||||||
|
do {
|
||||||
|
/* Fetch received characters */
|
||||||
|
for (i = 0; i < SP_FIFO_SIZE; ++i) {
|
||||||
|
if ((get( port, NS16550_LINE_STATUS) & SP_LSR_RDY) != 0) {
|
||||||
|
buf [i] = (char) get(port, NS16550_RECEIVE_BUFFER);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enqueue fetched characters */
|
||||||
|
rtems_termios_enqueue_raw_characters(tty, buf, i);
|
||||||
|
|
||||||
|
/* Check if we can dequeue transmitted characters */
|
||||||
|
if (ctx->transmit_fifo_chars > 0
|
||||||
|
&& (get( port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
|
||||||
|
|
||||||
|
/* Dequeue transmitted characters */
|
||||||
|
rtems_termios_dequeue_characters(
|
||||||
|
tty,
|
||||||
|
ctx->transmit_fifo_chars
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} while ((get( port, NS16550_INTERRUPT_ID) & SP_IID_0) == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_initialize_interrupts
|
||||||
|
*
|
||||||
|
* This routine initializes the port to operate in interrupt driver mode.
|
||||||
|
*/
|
||||||
|
static void ns16550_initialize_interrupts(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
ns16550_context *ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#ifdef BSP_FEATURE_IRQ_EXTENSION
|
||||||
|
{
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
sc = rtems_interrupt_handler_install(
|
||||||
|
ctx->irq,
|
||||||
|
"NS16550",
|
||||||
|
RTEMS_INTERRUPT_SHARED,
|
||||||
|
ns16550_isr,
|
||||||
|
tty
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
/* FIXME */
|
||||||
|
printk( "%s: Error: Install interrupt handler\n", __func__);
|
||||||
|
rtems_fatal_error_occurred( 0xdeadbeef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(BSP_FEATURE_IRQ_LEGACY)
|
||||||
|
{
|
||||||
|
int rv = 0;
|
||||||
|
#ifdef BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
|
||||||
|
rtems_irq_connect_data cd = {
|
||||||
|
ctx->irq,
|
||||||
|
ns16550_isr,
|
||||||
|
tty,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
rv = BSP_install_rtems_shared_irq_handler( &cd);
|
||||||
|
#else
|
||||||
|
rtems_irq_connect_data cd = {
|
||||||
|
ctx->irq,
|
||||||
|
ns16550_isr,
|
||||||
|
tty,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
rv = BSP_install_rtems_irq_handler( &cd);
|
||||||
|
#endif
|
||||||
|
if (rv == 0) {
|
||||||
|
/* FIXME */
|
||||||
|
printk( "%s: Error: Install interrupt handler\n", __func__);
|
||||||
|
rtems_fatal_error_occurred( 0xdeadbeef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_open
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool ns16550_open(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
struct termios *term,
|
||||||
|
rtems_libio_open_close_args_t *args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
|
||||||
|
/* Set initial baud */
|
||||||
|
rtems_termios_set_initial_baud(tty, ctx->initial_baud);
|
||||||
|
|
||||||
|
if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
|
||||||
|
ns16550_initialize_interrupts(tty, ctx);
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ns16550_cleanup_interrupts(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
ns16550_context *ctx
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if defined(BSP_FEATURE_IRQ_EXTENSION)
|
||||||
|
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||||
|
sc = rtems_interrupt_handler_remove(
|
||||||
|
ctx->irq,
|
||||||
|
ns16550_isr,
|
||||||
|
tty
|
||||||
|
);
|
||||||
|
if (sc != RTEMS_SUCCESSFUL) {
|
||||||
|
/* FIXME */
|
||||||
|
printk("%s: Error: Remove interrupt handler\n", __func__);
|
||||||
|
rtems_fatal_error_occurred(0xdeadbeef);
|
||||||
|
}
|
||||||
|
#elif defined(BSP_FEATURE_IRQ_LEGACY)
|
||||||
|
int rv = 0;
|
||||||
|
rtems_irq_connect_data cd = {
|
||||||
|
.name = ctx->irq,
|
||||||
|
.hdl = ns16550_isr,
|
||||||
|
.handle = tty
|
||||||
|
};
|
||||||
|
rv = BSP_remove_rtems_irq_handler(&cd);
|
||||||
|
if (rv == 0) {
|
||||||
|
/* FIXME */
|
||||||
|
printk("%s: Error: Remove interrupt handler\n", __func__);
|
||||||
|
rtems_fatal_error_occurred(0xdeadbeef);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_close
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_close(
|
||||||
|
struct rtems_termios_tty *tty,
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
rtems_libio_open_close_args_t *args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
|
||||||
|
|
||||||
|
if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
|
||||||
|
ns16550_cleanup_interrupts(tty, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Polled write for NS16550.
|
||||||
|
*/
|
||||||
|
void ns16550_polled_putchar(rtems_termios_device_context *base, char out)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
uintptr_t port = ctx->port;
|
||||||
|
ns16550_get_reg get = ctx->get_reg;
|
||||||
|
ns16550_set_reg set = ctx->set_reg;
|
||||||
|
uint32_t status = 0;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
/* Save port interrupt mask */
|
||||||
|
uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE);
|
||||||
|
|
||||||
|
/* Disable port interrupts */
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
/* Try to transmit the character in a critical section */
|
||||||
|
rtems_termios_device_lock_acquire(&ctx->base, &lock_context);
|
||||||
|
|
||||||
|
/* Read the transmitter holding register and check it */
|
||||||
|
status = get( port, NS16550_LINE_STATUS);
|
||||||
|
if ((status & SP_LSR_THOLD) != 0) {
|
||||||
|
/* Transmit character */
|
||||||
|
set( port, NS16550_TRANSMIT_BUFFER, out);
|
||||||
|
|
||||||
|
/* Finished */
|
||||||
|
rtems_termios_device_lock_release(&ctx->base, &lock_context);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
rtems_termios_device_lock_release(&ctx->base, &lock_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for transmitter holding register to be empty */
|
||||||
|
do {
|
||||||
|
status = get( port, NS16550_LINE_STATUS);
|
||||||
|
} while ((status & SP_LSR_THOLD) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore port interrupt mask */
|
||||||
|
set( port, NS16550_INTERRUPT_ENABLE, interrupt_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These routines provide control of the RTS and DTR lines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_assert_RTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_assert_RTS(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assert RTS
|
||||||
|
*/
|
||||||
|
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||||
|
ctx->modem_control |= SP_MODEM_RTS;
|
||||||
|
(*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
|
||||||
|
rtems_termios_device_lock_release(base, &lock_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_negate_RTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_negate_RTS(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Negate RTS
|
||||||
|
*/
|
||||||
|
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||||
|
ctx->modem_control &= ~SP_MODEM_RTS;
|
||||||
|
(*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
|
||||||
|
rtems_termios_device_lock_release(base, &lock_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These flow control routines utilise a connection from the local DTR
|
||||||
|
* line to the remote CTS line
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_assert_DTR
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_assert_DTR(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assert DTR
|
||||||
|
*/
|
||||||
|
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||||
|
ctx->modem_control |= SP_MODEM_DTR;
|
||||||
|
(*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
|
||||||
|
rtems_termios_device_lock_release(base, &lock_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_negate_DTR
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_negate_DTR(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Negate DTR
|
||||||
|
*/
|
||||||
|
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||||
|
ctx->modem_control &=~SP_MODEM_DTR;
|
||||||
|
(*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL,ctx->modem_control);
|
||||||
|
rtems_termios_device_lock_release(base, &lock_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_set_attributes
|
||||||
|
*
|
||||||
|
* This function sets the channel to reflect the requested termios
|
||||||
|
* port settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool ns16550_set_attributes(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const struct termios *t
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
uint32_t pNS16550;
|
||||||
|
uint32_t ulBaudDivisor;
|
||||||
|
uint8_t ucLineControl;
|
||||||
|
uint32_t baud_requested;
|
||||||
|
ns16550_set_reg setReg;
|
||||||
|
rtems_interrupt_lock_context lock_context;
|
||||||
|
|
||||||
|
pNS16550 = ctx->port;
|
||||||
|
setReg = ctx->set_reg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the baud rate divisor
|
||||||
|
*/
|
||||||
|
|
||||||
|
baud_requested = rtems_termios_baud_to_number(t->c_cflag);
|
||||||
|
ulBaudDivisor = NS16550_GetBaudDivisor(ctx, baud_requested);
|
||||||
|
|
||||||
|
ucLineControl = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parity
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (t->c_cflag & PARENB) {
|
||||||
|
ucLineControl |= SP_LINE_PAR;
|
||||||
|
if (!(t->c_cflag & PARODD))
|
||||||
|
ucLineControl |= SP_LINE_ODD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Character Size
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (t->c_cflag & CSIZE) {
|
||||||
|
switch (t->c_cflag & CSIZE) {
|
||||||
|
case CS5: ucLineControl |= FIVE_BITS; break;
|
||||||
|
case CS6: ucLineControl |= SIX_BITS; break;
|
||||||
|
case CS7: ucLineControl |= SEVEN_BITS; break;
|
||||||
|
case CS8: ucLineControl |= EIGHT_BITS; break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stop Bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (t->c_cflag & CSTOPB) {
|
||||||
|
ucLineControl |= SP_LINE_STOP; /* 2 stop bits */
|
||||||
|
} else {
|
||||||
|
; /* 1 stop bit */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now actually set the chip
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtems_termios_device_lock_acquire(base, &lock_context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the baud rate
|
||||||
|
*
|
||||||
|
* NOTE: When the Divisor Latch Access Bit (DLAB) is set to 1,
|
||||||
|
* the transmit buffer and interrupt enable registers
|
||||||
|
* turn into the LSB and MSB divisor latch registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
|
||||||
|
(*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
|
||||||
|
(*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now write the line control
|
||||||
|
*/
|
||||||
|
(*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );
|
||||||
|
|
||||||
|
rtems_termios_device_lock_release(base, &lock_context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transmits up to @a len characters from @a buf.
|
||||||
|
*
|
||||||
|
* This routine is invoked either from task context with disabled interrupts to
|
||||||
|
* start a new transmission process with exactly one character in case of an
|
||||||
|
* idle output state or from the interrupt handler to refill the transmitter.
|
||||||
|
*
|
||||||
|
* Returns always zero.
|
||||||
|
*/
|
||||||
|
static void ns16550_write_support_int(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
uint32_t port = ctx->port;
|
||||||
|
ns16550_set_reg set = ctx->set_reg;
|
||||||
|
int i = 0;
|
||||||
|
int out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
|
||||||
|
|
||||||
|
for (i = 0; i < out; ++i) {
|
||||||
|
set( port, NS16550_TRANSMIT_BUFFER, buf [i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->transmit_fifo_chars = out;
|
||||||
|
|
||||||
|
if (out > 0) {
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR);
|
||||||
|
} else {
|
||||||
|
ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ns16550_write_support_polled
|
||||||
|
*
|
||||||
|
* Console Termios output entry point.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void ns16550_write_support_polled(
|
||||||
|
rtems_termios_device_context *base,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
)
|
||||||
|
{
|
||||||
|
size_t nwrite = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* poll each byte in the string out of the port.
|
||||||
|
*/
|
||||||
|
while (nwrite < len) {
|
||||||
|
/*
|
||||||
|
* transmit character
|
||||||
|
*/
|
||||||
|
ns16550_polled_putchar(base, *buf++);
|
||||||
|
nwrite++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug gets() support
|
||||||
|
*/
|
||||||
|
int ns16550_polled_getchar(rtems_termios_device_context *base)
|
||||||
|
{
|
||||||
|
ns16550_context *ctx = (ns16550_context *) base;
|
||||||
|
uint32_t pNS16550;
|
||||||
|
unsigned char ucLineStatus;
|
||||||
|
uint8_t cChar;
|
||||||
|
ns16550_get_reg getReg;
|
||||||
|
|
||||||
|
pNS16550 = ctx->port;
|
||||||
|
getReg = ctx->get_reg;
|
||||||
|
|
||||||
|
ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
|
||||||
|
if (ucLineStatus & SP_LSR_RDY) {
|
||||||
|
cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
|
||||||
|
return (int)cChar;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flow control is only supported when using interrupts
|
||||||
|
*/
|
||||||
|
|
||||||
|
const rtems_termios_device_flow ns16550_flow_rtscts = {
|
||||||
|
.stop_remote_tx = ns16550_negate_RTS,
|
||||||
|
.start_remote_tx = ns16550_assert_RTS
|
||||||
|
};
|
||||||
|
|
||||||
|
const rtems_termios_device_flow ns16550_flow_dtrcts = {
|
||||||
|
.stop_remote_tx = ns16550_negate_DTR,
|
||||||
|
.start_remote_tx = ns16550_assert_DTR
|
||||||
|
};
|
||||||
|
|
||||||
|
const rtems_termios_device_handler ns16550_handler_interrupt = {
|
||||||
|
.first_open = ns16550_open,
|
||||||
|
.last_close = ns16550_close,
|
||||||
|
.poll_read = NULL,
|
||||||
|
.write = ns16550_write_support_int,
|
||||||
|
.set_attributes = ns16550_set_attributes,
|
||||||
|
.mode = TERMIOS_IRQ_DRIVEN
|
||||||
|
};
|
||||||
|
|
||||||
|
const rtems_termios_device_handler ns16550_handler_polled = {
|
||||||
|
.first_open = ns16550_open,
|
||||||
|
.last_close = ns16550_close,
|
||||||
|
.poll_read = ns16550_polled_getchar,
|
||||||
|
.write = ns16550_write_support_polled,
|
||||||
|
.set_attributes = ns16550_set_attributes,
|
||||||
|
.mode = TERMIOS_POLLED
|
||||||
|
};
|
||||||
@@ -58,6 +58,82 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ucModemCtrl;
|
||||||
|
int transmitFifoChars;
|
||||||
|
} NS16550Context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_init(int minor);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_open(
|
||||||
|
int major,
|
||||||
|
int minor,
|
||||||
|
void * arg
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_close(
|
||||||
|
int major,
|
||||||
|
int minor,
|
||||||
|
void * arg
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_write_polled(
|
||||||
|
int minor,
|
||||||
|
char cChar
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_assert_RTS(
|
||||||
|
int minor
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_negate_RTS(
|
||||||
|
int minor
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_assert_DTR(
|
||||||
|
int minor
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_negate_DTR(
|
||||||
|
int minor
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_initialize_interrupts(int minor);
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_cleanup_interrupts(int minor);
|
||||||
|
|
||||||
|
NS16550_STATIC ssize_t ns16550_write_support_int(
|
||||||
|
int minor,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC ssize_t ns16550_write_support_polled(
|
||||||
|
int minor,
|
||||||
|
const char *buf,
|
||||||
|
size_t len
|
||||||
|
);
|
||||||
|
|
||||||
|
int ns16550_inbyte_nonblocking_polled(
|
||||||
|
int minor
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_enable_interrupts(
|
||||||
|
console_tbl *c,
|
||||||
|
int mask
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC int ns16550_set_attributes(
|
||||||
|
int minor,
|
||||||
|
const struct termios *t
|
||||||
|
);
|
||||||
|
|
||||||
|
NS16550_STATIC void ns16550_isr(void *arg);
|
||||||
|
|
||||||
static rtems_interrupt_lock ns16550_lock =
|
static rtems_interrupt_lock ns16550_lock =
|
||||||
RTEMS_INTERRUPT_LOCK_INITIALIZER("NS16550");
|
RTEMS_INTERRUPT_LOCK_INITIALIZER("NS16550");
|
||||||
|
|
||||||
@@ -142,12 +218,12 @@ void ns16550_init(int minor)
|
|||||||
uintptr_t pNS16550;
|
uintptr_t pNS16550;
|
||||||
uint8_t ucDataByte;
|
uint8_t ucDataByte;
|
||||||
uint32_t ulBaudDivisor;
|
uint32_t ulBaudDivisor;
|
||||||
ns16550_context *pns16550Context;
|
NS16550Context *pns16550Context;
|
||||||
setRegister_f setReg;
|
setRegister_f setReg;
|
||||||
getRegister_f getReg;
|
getRegister_f getReg;
|
||||||
console_tbl *c = Console_Port_Tbl [minor];
|
console_tbl *c = Console_Port_Tbl [minor];
|
||||||
|
|
||||||
pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context));
|
pns16550Context=(NS16550Context *)malloc(sizeof(NS16550Context));
|
||||||
|
|
||||||
if (pns16550Context == NULL) {
|
if (pns16550Context == NULL) {
|
||||||
printk( "%s: Error: Not enough memory\n", __func__);
|
printk( "%s: Error: Not enough memory\n", __func__);
|
||||||
@@ -328,10 +404,10 @@ NS16550_STATIC int ns16550_assert_RTS(int minor)
|
|||||||
{
|
{
|
||||||
uint32_t pNS16550;
|
uint32_t pNS16550;
|
||||||
rtems_interrupt_lock_context lock_context;
|
rtems_interrupt_lock_context lock_context;
|
||||||
ns16550_context *pns16550Context;
|
NS16550Context *pns16550Context;
|
||||||
setRegister_f setReg;
|
setRegister_f setReg;
|
||||||
|
|
||||||
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
|
pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
|
||||||
|
|
||||||
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
||||||
setReg = Console_Port_Tbl[minor]->setRegister;
|
setReg = Console_Port_Tbl[minor]->setRegister;
|
||||||
@@ -354,10 +430,10 @@ NS16550_STATIC int ns16550_negate_RTS(int minor)
|
|||||||
{
|
{
|
||||||
uint32_t pNS16550;
|
uint32_t pNS16550;
|
||||||
rtems_interrupt_lock_context lock_context;
|
rtems_interrupt_lock_context lock_context;
|
||||||
ns16550_context *pns16550Context;
|
NS16550Context *pns16550Context;
|
||||||
setRegister_f setReg;
|
setRegister_f setReg;
|
||||||
|
|
||||||
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
|
pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
|
||||||
|
|
||||||
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
||||||
setReg = Console_Port_Tbl[minor]->setRegister;
|
setReg = Console_Port_Tbl[minor]->setRegister;
|
||||||
@@ -385,10 +461,10 @@ NS16550_STATIC int ns16550_assert_DTR(int minor)
|
|||||||
{
|
{
|
||||||
uint32_t pNS16550;
|
uint32_t pNS16550;
|
||||||
rtems_interrupt_lock_context lock_context;
|
rtems_interrupt_lock_context lock_context;
|
||||||
ns16550_context *pns16550Context;
|
NS16550Context *pns16550Context;
|
||||||
setRegister_f setReg;
|
setRegister_f setReg;
|
||||||
|
|
||||||
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
|
pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
|
||||||
|
|
||||||
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
||||||
setReg = Console_Port_Tbl[minor]->setRegister;
|
setReg = Console_Port_Tbl[minor]->setRegister;
|
||||||
@@ -411,10 +487,10 @@ NS16550_STATIC int ns16550_negate_DTR(int minor)
|
|||||||
{
|
{
|
||||||
uint32_t pNS16550;
|
uint32_t pNS16550;
|
||||||
rtems_interrupt_lock_context lock_context;
|
rtems_interrupt_lock_context lock_context;
|
||||||
ns16550_context *pns16550Context;
|
NS16550Context *pns16550Context;
|
||||||
setRegister_f setReg;
|
setRegister_f setReg;
|
||||||
|
|
||||||
pns16550Context=(ns16550_context *) Console_Port_Data[minor].pDeviceContext;
|
pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
|
||||||
|
|
||||||
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
|
||||||
setReg = Console_Port_Tbl[minor]->setRegister;
|
setReg = Console_Port_Tbl[minor]->setRegister;
|
||||||
@@ -533,7 +609,7 @@ NS16550_STATIC void ns16550_process( int minor)
|
|||||||
{
|
{
|
||||||
console_tbl *c = Console_Port_Tbl [minor];
|
console_tbl *c = Console_Port_Tbl [minor];
|
||||||
console_data *d = &Console_Port_Data [minor];
|
console_data *d = &Console_Port_Data [minor];
|
||||||
ns16550_context *ctx = d->pDeviceContext;
|
NS16550Context *ctx = d->pDeviceContext;
|
||||||
uint32_t port = c->ulCtrlPort1;
|
uint32_t port = c->ulCtrlPort1;
|
||||||
getRegister_f get = c->getRegister;
|
getRegister_f get = c->getRegister;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -584,7 +660,7 @@ ssize_t ns16550_write_support_int(
|
|||||||
{
|
{
|
||||||
console_tbl *c = Console_Port_Tbl [minor];
|
console_tbl *c = Console_Port_Tbl [minor];
|
||||||
console_data *d = &Console_Port_Data [minor];
|
console_data *d = &Console_Port_Data [minor];
|
||||||
ns16550_context *ctx = d->pDeviceContext;
|
NS16550Context *ctx = d->pDeviceContext;
|
||||||
uint32_t port = c->ulCtrlPort1;
|
uint32_t port = c->ulCtrlPort1;
|
||||||
setRegister_f set = c->setRegister;
|
setRegister_f set = c->setRegister;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#ifndef _NS16550_H_
|
#ifndef _NS16550_H_
|
||||||
#define _NS16550_H_
|
#define _NS16550_H_
|
||||||
|
|
||||||
|
#include <rtems/termiostypes.h>
|
||||||
#include <libchip/serial.h>
|
#include <libchip/serial.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -53,6 +54,37 @@ extern const console_flow ns16550_flow_DTRCTS;
|
|||||||
void ns16550_outch_polled(console_tbl *c, char out);
|
void ns16550_outch_polled(console_tbl *c, char out);
|
||||||
int ns16550_inch_polled(console_tbl *c);
|
int ns16550_inch_polled(console_tbl *c);
|
||||||
|
|
||||||
|
/* Alternative NS16550 driver using the Termios device context */
|
||||||
|
|
||||||
|
typedef uint8_t (*ns16550_get_reg)(uintptr_t port, uint8_t reg);
|
||||||
|
|
||||||
|
typedef void (*ns16550_set_reg)(uintptr_t port, uint8_t reg, uint8_t value);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rtems_termios_device_context base;
|
||||||
|
ns16550_get_reg get_reg;
|
||||||
|
ns16550_set_reg set_reg;
|
||||||
|
uintptr_t port;
|
||||||
|
rtems_vector_number irq;
|
||||||
|
uint32_t clock;
|
||||||
|
uint32_t initial_baud;
|
||||||
|
bool has_fractional_divider_register;
|
||||||
|
uint8_t modem_control;
|
||||||
|
size_t transmit_fifo_chars;
|
||||||
|
} ns16550_context;
|
||||||
|
|
||||||
|
extern const rtems_termios_device_handler ns16550_handler_interrupt;
|
||||||
|
extern const rtems_termios_device_handler ns16550_handler_polled;
|
||||||
|
|
||||||
|
extern const rtems_termios_device_flow ns16550_flow_rtscts;
|
||||||
|
extern const rtems_termios_device_flow ns16550_flow_dtrcts;
|
||||||
|
|
||||||
|
void ns16550_polled_putchar(rtems_termios_device_context *base, char out);
|
||||||
|
|
||||||
|
int ns16550_polled_getchar(rtems_termios_device_context *base);
|
||||||
|
|
||||||
|
bool ns16550_probe(rtems_termios_device_context *base);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -131,82 +131,6 @@ extern "C" {
|
|||||||
#define SP_LSR_TX 0x40
|
#define SP_LSR_TX 0x40
|
||||||
#define SP_LSR_EFIFO 0x80
|
#define SP_LSR_EFIFO 0x80
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t ucModemCtrl;
|
|
||||||
int transmitFifoChars;
|
|
||||||
} ns16550_context;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Driver functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ns16550_init(int minor);
|
|
||||||
|
|
||||||
int ns16550_open(
|
|
||||||
int major,
|
|
||||||
int minor,
|
|
||||||
void * arg
|
|
||||||
);
|
|
||||||
|
|
||||||
int ns16550_close(
|
|
||||||
int major,
|
|
||||||
int minor,
|
|
||||||
void * arg
|
|
||||||
);
|
|
||||||
|
|
||||||
void ns16550_write_polled(
|
|
||||||
int minor,
|
|
||||||
char cChar
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC int ns16550_assert_RTS(
|
|
||||||
int minor
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC int ns16550_negate_RTS(
|
|
||||||
int minor
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC int ns16550_assert_DTR(
|
|
||||||
int minor
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC int ns16550_negate_DTR(
|
|
||||||
int minor
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC void ns16550_initialize_interrupts(int minor);
|
|
||||||
|
|
||||||
NS16550_STATIC void ns16550_cleanup_interrupts(int minor);
|
|
||||||
|
|
||||||
ssize_t ns16550_write_support_int(
|
|
||||||
int minor,
|
|
||||||
const char *buf,
|
|
||||||
size_t len
|
|
||||||
);
|
|
||||||
|
|
||||||
ssize_t ns16550_write_support_polled(
|
|
||||||
int minor,
|
|
||||||
const char *buf,
|
|
||||||
size_t len
|
|
||||||
);
|
|
||||||
|
|
||||||
int ns16550_inbyte_nonblocking_polled(
|
|
||||||
int minor
|
|
||||||
);
|
|
||||||
|
|
||||||
NS16550_STATIC void ns16550_enable_interrupts(
|
|
||||||
console_tbl *c,
|
|
||||||
int mask
|
|
||||||
);
|
|
||||||
|
|
||||||
int ns16550_set_attributes(
|
|
||||||
int minor,
|
|
||||||
const struct termios *t
|
|
||||||
);
|
|
||||||
|
|
||||||
void ns16550_isr(void *arg);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user