serial: rework functions to use struct device...

... instead of an array index to a global array. This is
an intermediate step to make the drivers conform to
the new driver model.

This only changes from using a direct array index to using
device structs. The UARTs are still staticlly defined.
Later patches will make the drivers utilize the driver
initialization procedure specified by the driver model.

Change-Id: I18041bbb4b0efdf8ae87088fd000b391d0827e9b
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2015-08-05 12:13:36 -07:00 committed by Anas Nashif
parent 179f805322
commit 1ad2a56ee3
31 changed files with 1053 additions and 398 deletions

View file

@ -5,6 +5,7 @@ ccflags-y +=-I$(srctree)/arch/arm/platforms/fsl_frdm_k64f
asflags-y := ${ccflags-y}
obj-y += platform_config.o
obj-y += system.o
obj-y += nmi_on_reset.o
obj-y += wdog.o

View file

@ -158,6 +158,7 @@ This header file is used to specify and describe board-level aspects for the
#ifndef _ASMLANGUAGE
#include <device.h>
#include <misc/util.h>
#include <drivers/rand32.h>
@ -167,11 +168,6 @@ This header file is used to specify and describe board-level aspects for the
#include <drivers/k20_pcr.h>
#define CONFIG_UART_NUM_SYSTEM_PORTS 5
#define CONFIG_UART_NUM_EXTRA_PORTS 0
#define CONFIG_UART_NUM_PORTS \
(CONFIG_UART_NUM_SYSTEM_PORTS + CONFIG_UART_NUM_EXTRA_PORTS)
#define CONFIG_UART_PORT_0_REGS PERIPH_ADDR_BASE_UART0
#define CONFIG_UART_PORT_0_IRQ IRQ_UART0_STATUS
#define CONFIG_UART_PORT_1_REGS PERIPH_ADDR_BASE_UART1
@ -183,30 +179,7 @@ This header file is used to specify and describe board-level aspects for the
#define CONFIG_UART_PORT_4_REGS PERIPH_ADDR_BASE_UART4
#define CONFIG_UART_PORT_4_IRQ IRQ_UART4_STATUS
#define UART_PORTS_CONFIGURE(__type, __name) \
static __type __name[CONFIG_UART_NUM_PORTS] = { \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_0_REGS, \
.irq = CONFIG_UART_PORT_0_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_1_REGS, \
.irq = CONFIG_UART_PORT_1_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_2_REGS, \
.irq = CONFIG_UART_PORT_2_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_3_REGS, \
.irq = CONFIG_UART_PORT_3_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_4_REGS, \
.irq = CONFIG_UART_PORT_4_IRQ \
} \
}
extern struct device uart_devs[];
/* Uart console settings */
@ -219,6 +192,9 @@ This header file is used to specify and describe board-level aspects for the
#define CONFIG_UART_CONSOLE_IRQ IRQ_UART0_STATUS
#define CONFIG_UART_CONSOLE_INT_PRI 3
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
/* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_BAUDRATE 115200

View file

@ -0,0 +1,147 @@
/*
* Copyright (c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Board config file
*/
#include <device.h>
#include <init.h>
#include <nanokernel.h>
#include "board.h"
#ifdef CONFIG_K20_UART
#include <drivers/uart.h>
#include <drivers/k20_uart.h>
static struct uart_device_config_t uart_dev_cfg_info[] = {
{
.base = (uint8_t *)CONFIG_UART_PORT_0_REGS,
.irq = CONFIG_UART_PORT_0_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_1_REGS,
.irq = CONFIG_UART_PORT_1_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_2_REGS,
.irq = CONFIG_UART_PORT_2_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_3_REGS,
.irq = CONFIG_UART_PORT_3_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_4_REGS,
.irq = CONFIG_UART_PORT_4_IRQ,
},
};
static struct device_config uart_dev_cfg[] = {
{
.name = CONFIG_UART_PORT_0_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[0],
},
{
.name = CONFIG_UART_PORT_1_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[1],
},
{
.name = CONFIG_UART_PORT_2_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[2],
},
{
.name = CONFIG_UART_PORT_3_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[2],
},
{
.name = CONFIG_UART_PORT_4_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[2],
},
};
static struct uart_k20_dev_data_t uart_dev_data[] = {
{
.seq_port_num = 0,
},
{
.seq_port_num = 1,
},
{
.seq_port_num = 2,
},
{
.seq_port_num = 3,
},
{
.seq_port_num = 4,
},
};
struct device uart_devs[] = {
{
.config = &uart_dev_cfg[0],
.driver_api = NULL,
.driver_data = &uart_dev_data[0],
},
{
.config = &uart_dev_cfg[1],
.driver_api = NULL,
.driver_data = &uart_dev_data[1],
},
{
.config = &uart_dev_cfg[2],
.driver_api = NULL,
.driver_data = &uart_dev_data[2],
},
{
.config = &uart_dev_cfg[3],
.driver_api = NULL,
.driver_data = &uart_dev_data[2],
},
{
.config = &uart_dev_cfg[4],
.driver_api = NULL,
.driver_data = &uart_dev_data[2],
},
};
#if defined(CONFIG_UART_CONSOLE_INDEX)
struct device * const uart_console_dev = &uart_devs[CONFIG_UART_CONSOLE_INDEX];
#endif
#endif /* CONFIG_K20_UART */

View file

@ -285,7 +285,7 @@ static void consoleInit(void)
port_pcr_p->port[port].pcr[rxPin] = pcr;
port_pcr_p->port[port].pcr[txPin] = pcr;
uart_init(CONFIG_UART_CONSOLE_INDEX, &info);
uart_init(UART_CONSOLE_DEV, &info);
uart_console_init();
}

View file

@ -5,6 +5,7 @@ ccflags-y +=-I$(srctree)/arch/arm/platforms/ti_lm3s6965
asflags-y := ${ccflags-y}
obj-y += platform_config.o
obj-y += system.o
obj-y += nmi_on_reset.o
obj-y += scp.o

View file

@ -100,15 +100,12 @@ the 'ti_lm3s6965' platform.
#ifndef _ASMLANGUAGE
#include <device.h>
#include <misc/util.h>
#include <drivers/rand32.h>
/* uart configuration settings */
#define CONFIG_UART_NUM_SYSTEM_PORTS 2
#define CONFIG_UART_NUM_EXTRA_PORTS 1
#define CONFIG_UART_NUM_PORTS \
(CONFIG_UART_NUM_SYSTEM_PORTS + CONFIG_UART_NUM_EXTRA_PORTS)
#define CONFIG_UART_PORT_0_REGS PERIPH_ADDR_BASE_UART0
#define CONFIG_UART_PORT_0_IRQ IRQ_UART0
#define CONFIG_UART_PORT_1_REGS PERIPH_ADDR_BASE_UART1
@ -116,21 +113,7 @@ the 'ti_lm3s6965' platform.
#define CONFIG_UART_PORT_2_REGS PERIPH_ADDR_BASE_UART2
#define CONFIG_UART_PORT_2_IRQ IRQ_UART2
#define UART_PORTS_CONFIGURE(__type, __name) \
static __type __name[CONFIG_UART_NUM_PORTS] = { \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_0_REGS, \
.irq = CONFIG_UART_PORT_0_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_1_REGS, \
.irq = CONFIG_UART_PORT_1_IRQ \
}, \
{ \
.base = (uint8_t *)CONFIG_UART_PORT_2_REGS, \
.irq = CONFIG_UART_PORT_2_IRQ \
} \
}
extern struct device uart_devs[];
/* Uart console configuration */
@ -138,6 +121,9 @@ the 'ti_lm3s6965' platform.
#define CONFIG_UART_CONSOLE_IRQ IRQ_UART0
#define CONFIG_UART_CONSOLE_INT_PRI 3
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
/* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_BAUDRATE 115200

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Board config file
*/
#include <device.h>
#include <init.h>
#include <nanokernel.h>
#include "board.h"
#ifdef CONFIG_STELLARIS_UART
#include <drivers/uart.h>
/* UART related structures */
static struct uart_device_config_t uart_dev_cfg_info[] = {
{
.base = (uint8_t *)CONFIG_UART_PORT_0_REGS,
.irq = CONFIG_UART_PORT_0_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_1_REGS,
.irq = CONFIG_UART_PORT_1_IRQ,
},
{
.base = (uint8_t *)CONFIG_UART_PORT_2_REGS,
.irq = CONFIG_UART_PORT_2_IRQ,
}
};
static struct device_config uart_dev_cfg[] = {
{
.name = CONFIG_UART_PORT_0_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[0],
},
{
.name = CONFIG_UART_PORT_1_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[1],
},
{
.name = CONFIG_UART_PORT_2_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[2],
},
};
struct device uart_devs[] = {
{
.config = &uart_dev_cfg[0],
.driver_api = NULL,
.driver_data = NULL,
},
{
.config = &uart_dev_cfg[1],
.driver_api = NULL,
.driver_data = NULL,
},
{
.config = &uart_dev_cfg[2],
.driver_api = NULL,
.driver_data = NULL,
},
};
#if defined(CONFIG_UART_CONSOLE_INDEX)
struct device * const uart_console_dev = &uart_devs[CONFIG_UART_CONSOLE_INDEX];
#endif
#endif /* CONFIG_STELLARIS_UART */

View file

@ -95,7 +95,7 @@ static void consoleInit(void)
uart_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info);
uart_init(UART_CONSOLE_DEV, &info);
uart_console_init();
}

View file

@ -148,6 +148,8 @@ CONFIG_EXTRA_SERIAL_PORT=y
CONFIG_SERIAL_INTERRUPT_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN is not set

View file

@ -127,6 +127,8 @@ CONFIG_EXTRA_SERIAL_PORT=y
CONFIG_SERIAL_INTERRUPT_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN is not set

View file

@ -152,6 +152,8 @@ CONFIG_EXTRA_SERIAL_PORT=y
CONFIG_SERIAL_INTERRUPT_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN is not set

View file

@ -3,4 +3,5 @@ ccflags-y +=-I$(srctree)/include/drivers
ccflags-y +=-I$(srctree)/drivers
asflags-y := ${ccflags-y}
obj-y = system.o
obj-y += platform_config.o
obj-y += system.o

View file

@ -42,6 +42,7 @@ the 'ia32' platform.
#include <misc/util.h>
#ifndef _ASMLANGUAGE
#include <device.h>
#include <drivers/rand32.h>
#endif
@ -68,6 +69,8 @@ the 'ia32' platform.
/* serial port (aka COM port) information */
#ifdef CONFIG_NS16550
#define COM1_BASE_ADRS 0x3f8
#define COM1_INT_LVL 0x04 /* COM1 connected to IRQ4 */
#define COM1_INT_VEC (INT_VEC_IRQ0 + COM1_INT_LVL)
@ -86,32 +89,26 @@ the 'ia32' platform.
/* uart configuration settings */
/* Generic definitions */
#define CONFIG_UART_NUM_SYSTEM_PORTS 2
#define CONFIG_UART_NUM_EXTRA_PORTS 0
#define CONFIG_UART_BAUDRATE COM1_BAUD_RATE
#define CONFIG_UART_NUM_PORTS \
(CONFIG_UART_NUM_SYSTEM_PORTS + CONFIG_UART_NUM_EXTRA_PORTS)
#define CONFIG_UART_PORT_0_REGS COM1_BASE_ADRS
#define CONFIG_UART_PORT_0_IRQ COM1_INT_LVL
#define CONFIG_UART_PORT_0_IRQ_PRIORITY COM1_INT_PRI
#define CONFIG_UART_PORT_1_REGS COM2_BASE_ADRS
#define CONFIG_UART_PORT_1_IRQ COM2_INT_LVL
#define UART_PORTS_CONFIGURE(__type, __name) \
static __type __name[CONFIG_UART_NUM_PORTS] = { \
{ \
.port = CONFIG_UART_PORT_0_REGS, \
.irq = CONFIG_UART_PORT_0_IRQ \
}, \
{ \
.port = CONFIG_UART_PORT_1_REGS, \
.irq = CONFIG_UART_PORT_1_IRQ \
} \
}
#define CONFIG_UART_PORT_1_IRQ_PRIORITY COM2_INT_PRI
/* Console definitions */
#define CONFIG_UART_CONSOLE_IRQ COM1_INT_LVL
#define CONFIG_UART_CONSOLE_INT_PRI COM1_INT_PRI
#ifndef _ASMLANGUAGE
extern struct device uart_devs[];
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
#endif
/* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_IRQ COM2_INT_LVL
@ -119,6 +116,8 @@ the 'ia32' platform.
#define CONFIG_BLUETOOTH_UART_FREQ UART_XTAL_FREQ
#define CONFIG_BLUETOOTH_UART_BAUDRATE CONFIG_UART_BAUDRATE
#endif /* CONFIG_NS16550 */
#ifndef _ASMLANGUAGE
/*
* Device drivers utilize the macros PLB_BYTE_REG_WRITE() and

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Contains configuration for ia32 platforms.
*/
#include <stdio.h>
#include <stdint.h>
#include <device.h>
#include <init.h>
#include "board.h"
#ifdef CONFIG_NS16550
#include <drivers/uart.h>
#include <serial/ns16550.h>
static struct uart_device_config_t uart_dev_cfg_info[] = {
{
.port = CONFIG_UART_PORT_0_REGS,
.irq = CONFIG_UART_PORT_0_IRQ,
.int_pri = CONFIG_UART_PORT_0_IRQ_PRIORITY,
},
{
.port = CONFIG_UART_PORT_1_REGS,
.irq = CONFIG_UART_PORT_1_IRQ,
.int_pri = CONFIG_UART_PORT_1_IRQ_PRIORITY,
},
};
static struct device_config uart_dev_cfg[] = {
{
.name = CONFIG_UART_PORT_0_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[0],
},
{
.name = CONFIG_UART_PORT_1_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[1],
},
};
static struct uart_ns16550_dev_data_t uart_dev_data[2];
struct device uart_devs[] = {
{
.config = &uart_dev_cfg[0],
.driver_api = NULL,
.driver_data = &uart_dev_data[0],
},
{
.config = &uart_dev_cfg[1],
.driver_api = NULL,
.driver_data = &uart_dev_data[1],
},
};
#if defined(CONFIG_UART_CONSOLE_INDEX)
struct device * const uart_console_dev = &uart_devs[CONFIG_UART_CONSOLE_INDEX];
#endif
#endif

View file

@ -131,7 +131,7 @@ static void console_init(void)
struct uart_init_info info;
uart_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info);
uart_init(UART_CONSOLE_DEV, &info);
uart_console_init();
}

View file

@ -1,5 +1,7 @@
ccflags-y += -I$(srctree)/include/drivers
ccflags-y += -I$(srctree)/drivers
asflags-y := ${ccflags-y}
obj-y = system.o
obj-y += platform_config.o
obj-y += system.o

View file

@ -42,6 +42,7 @@ the 'ia32_pci' platform.
#include <misc/util.h>
#ifndef _ASMLANGUAGE
#include <device.h>
#include <drivers/rand32.h>
#endif
@ -65,14 +66,15 @@ the 'ia32_pci' platform.
#define CONFIG_UART_PCI_VENDOR_ID 0x8086
#define CONFIG_UART_PCI_DEVICE_ID 0x0936
#define CONFIG_UART_PCI_BAR 0
#define CONFIG_UART_NUM_SYSTEM_PORTS 2
#define CONFIG_UART_NUM_EXTRA_PORTS 0
#define CONFIG_UART_BAUDRATE COM1_BAUD_RATE
#define CONFIG_UART_NUM_PORTS \
(CONFIG_UART_NUM_SYSTEM_PORTS + CONFIG_UART_NUM_EXTRA_PORTS)
/* Console definitions */
#define CONFIG_UART_CONSOLE_PCI_IDX COM1_PCI_IDX
#ifndef _ASMLANGUAGE
extern struct device uart_devs[];
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
#endif
/*
* The irq_connect() API connects to a (virtualized) IRQ and the

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Contains configuration for ia32_pci platforms.
*/
#include <stdio.h>
#include <stdint.h>
#include <device.h>
#include <init.h>
#include "board.h"
#ifdef CONFIG_NS16550
#include <drivers/uart.h>
#include <serial/ns16550.h>
static struct uart_device_config_t uart_dev_cfg_info[] = {
/* The first CONFIG_NS16550_PCI_NUM_PORTS ports are reserved. */
{
.port = 0,
},
{
.port = 0,
},
/* Add pre-configured ports after this. */
};
static struct device_config uart_dev_cfg[] = {
/* The first CONFIG_NS16550_PCI_NUM_PORTS ports are reserved. */
{
.name = CONFIG_UART_PORT_0_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[0],
},
{
.name = CONFIG_UART_PORT_1_NAME,
.init = NULL,
.config_info = &uart_dev_cfg_info[1],
},
/* Add pre-configured ports after this. */
};
static struct uart_ns16550_dev_data_t uart_dev_data[2];
struct device uart_devs[] = {
/* The first CONFIG_NS16550_PCI_NUM_PORTS ports are reserved. */
{
.config = &uart_dev_cfg[0],
.driver_api = NULL,
.driver_data = &uart_dev_data[0],
},
{
.config = &uart_dev_cfg[1],
.driver_api = NULL,
.driver_data = &uart_dev_data[1],
},
/* Add pre-configured ports after this. */
};
#if defined(CONFIG_UART_CONSOLE_INDEX)
struct device * const uart_console_dev = &uart_devs[CONFIG_UART_CONSOLE_INDEX];
#endif
#endif

View file

@ -121,7 +121,7 @@ static void console_init(void)
struct uart_init_info info;
uart_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info);
uart_init(UART_CONSOLE_DEV, &info);
uart_console_init();
}

View file

@ -58,9 +58,10 @@
#define H4_SCO 0x03
#define H4_EVT 0x04
#define UART CONFIG_BLUETOOTH_UART_INDEX
#define UART (&uart_devs[CONFIG_BLUETOOTH_UART_INDEX])
static int bt_uart_read(int uart, uint8_t *buf, size_t len, size_t min)
static int bt_uart_read(struct device *uart, uint8_t *buf,
size_t len, size_t min)
{
int total = 0;
@ -85,7 +86,7 @@ static int bt_uart_read(int uart, uint8_t *buf, size_t len, size_t min)
return total;
}
static size_t bt_uart_discard(int uart, size_t len)
static size_t bt_uart_discard(struct device *uart, size_t len)
{
uint8_t buf[33];
@ -253,7 +254,7 @@ static int bt_uart_send(struct bt_buf *buf)
IRQ_CONNECT_STATIC(bluetooth, CONFIG_BLUETOOTH_UART_IRQ,
CONFIG_BLUETOOTH_UART_INT_PRI, bt_uart_isr, 0);
static void bt_uart_setup(int uart, struct uart_init_info *info)
static void bt_uart_setup(struct device *uart, struct uart_init_info *info)
{
BT_DBG("\n");
@ -282,7 +283,7 @@ static int bt_uart_open()
.int_pri = CONFIG_BLUETOOTH_UART_INT_PRI,
};
bt_uart_setup(CONFIG_BLUETOOTH_UART_INDEX, &info);
bt_uart_setup(UART, &info);
return 0;
}

View file

@ -50,11 +50,6 @@
#include <toolchain.h>
#include <sections.h>
#define UART CONFIG_UART_CONSOLE_INDEX
#if (UART < 0) || !(UART < CONFIG_UART_NUM_SYSTEM_PORTS)
#error UART number not within ranges (0 to CONFIG_UART_NUM_SYSTEM_PORTS-1)
#endif
#if 0 /* NOTUSED */
/**
*
@ -65,11 +60,15 @@
static int consoleIn(void)
{
#ifdef UART_CONSOLE_DEV
unsigned char c;
if (uart_poll_in(UART, &c) < 0)
if (uart_poll_in(UART_CONSOLE_DEV, &c) < 0)
return EOF;
else
return (int)c;
#else
return 0;
#endif
}
#endif
@ -86,11 +85,15 @@ static int consoleIn(void)
static int consoleOut(int c /* character to output */
)
{
uart_poll_out(UART, (unsigned char)c);
#ifdef UART_CONSOLE_DEV
uart_poll_out(UART_CONSOLE_DEV, (unsigned char)c);
if ('\n' == c) {
uart_poll_out(UART, (unsigned char)'\r');
uart_poll_out(UART_CONSOLE_DEV, (unsigned char)'\r');
}
return c;
#else
return 0;
#endif
}
#endif
@ -116,7 +119,7 @@ static size_t pos = 0;
static struct nano_fifo *avail_queue;
static struct nano_fifo *lines_queue;
static int read_uart(int uart, uint8_t *buf, unsigned int size)
static int read_uart(struct device *uart, uint8_t *buf, unsigned int size)
{
int rx;
@ -135,9 +138,10 @@ void uart_console_isr(void *unused)
{
ARG_UNUSED(unused);
while (uart_irq_update(UART) && uart_irq_is_pending(UART)) {
while (uart_irq_update(UART_CONSOLE_DEV)
&& uart_irq_is_pending(UART_CONSOLE_DEV)) {
/* Character(s) have been received */
if (uart_irq_rx_ready(UART)) {
if (uart_irq_rx_ready(UART_CONSOLE_DEV)) {
static struct uart_console_input *cmd;
uint8_t byte;
int rx;
@ -149,19 +153,19 @@ void uart_console_isr(void *unused)
return;
}
rx = read_uart(UART, &byte, 1);
rx = read_uart(UART_CONSOLE_DEV, &byte, 1);
if (rx < 0) {
nano_isr_fifo_put(avail_queue, cmd);
return;
}
/* Echo back to console */
uart_poll_out(UART, byte);
uart_poll_out(UART_CONSOLE_DEV, byte);
if (byte == '\r' || byte == '\n' ||
pos == sizeof(cmd->line) - 1) {
cmd->line[pos] = '\0';
uart_poll_out(UART, '\n');
uart_poll_out(UART_CONSOLE_DEV, '\n');
pos = 0;
nano_isr_fifo_put(lines_queue, cmd);
@ -181,16 +185,17 @@ static void console_input_init(void)
{
uint8_t c;
uart_irq_rx_disable(UART);
uart_irq_tx_disable(UART);
IRQ_CONFIG(console, uart_irq_get(UART));
irq_enable(uart_irq_get(UART));
uart_irq_rx_disable(UART_CONSOLE_DEV);
uart_irq_tx_disable(UART_CONSOLE_DEV);
IRQ_CONFIG(console, uart_irq_get(UART_CONSOLE_DEV));
irq_enable(uart_irq_get(UART_CONSOLE_DEV));
/* Drain the fifo */
while (uart_irq_rx_ready(UART))
uart_fifo_read(UART, &c, 1);
while (uart_irq_rx_ready(UART_CONSOLE_DEV)) {
uart_fifo_read(UART_CONSOLE_DEV, &c, 1);
}
uart_irq_rx_enable(UART);
uart_irq_rx_enable(UART_CONSOLE_DEV);
}
void uart_register_input(struct nano_fifo *avail, struct nano_fifo *lines)

View file

@ -69,6 +69,23 @@ config NS16550
This specific driver can be used for the serial hardware
available at the Generic PC and Quark.
config NS16550_PCI
bool "NS16550 PCI serial driver"
default n
depends on PCI && NS16550
help
This enables NS16550 to probe for PCI-based serial devices.
This option enables the driver to auto-detect the device
configuration required to access those ports.
config NS16550_PCI_NUM_PORTS
int "Number of PCI serial ports"
default 2
depends on NS16550_PCI
help
This indicates the number of PCI-based serial ports to probe.
config K20_UART
bool "K20 serial driver"
default n
@ -93,4 +110,60 @@ config UART_INTERRUPT_DRIVEN
This option enables interrupt support for UART allowing console
input and UART based drivers.
config UART_PORT_0_NAME
string
default "UART_0"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_1_NAME
string
default "UART_1"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_2_NAME
string
default "UART_2"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_3_NAME
string
default "UART_3"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_4_NAME
string
default "UART_4"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_5_NAME
string
default "UART_5"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_6_NAME
string
default "UART_6"
help
This is the device name for UART, and is included in the device
struct.
config UART_PORT_7_NAME
string
default "UART_7"
help
This is the device name for UART, and is included in the device
struct.
endmenu

View file

@ -51,13 +51,14 @@ INCLUDE FILES: drivers/serial/k20_uart.h
#include <toolchain.h>
#include <sections.h>
typedef struct {
uint8_t *base; /* base address of registers */
uint8_t irq; /* interrupt request level */
uint8_t intPri; /* interrupt priority */
} _k20Uart_t;
/* convenience defines */
UART_PORTS_CONFIGURE(_k20Uart_t, uart);
#define DEV_CFG(dev) \
((struct uart_device_config_t * const)(dev)->config->config_info)
#define DEV_DATA(dev) \
((struct uart_k20_dev_data_t *)(dev)->driver_data)
#define UART_STRUCT(dev) \
((K20_UART_t *)(DEV_CFG(dev))->base)
/**
*
@ -66,28 +67,33 @@ UART_PORTS_CONFIGURE(_k20Uart_t, uart);
* This routine is called to reset the chip in a quiescent state.
* It is assumed that this function is called only once per UART.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param init_info Initial configuration for UART
*
* @return N/A
*/
void uart_init(int port, /* UART channel to initialize */
void uart_init(struct device *dev,
const struct uart_init_info * const init_info
)
{
struct uart_k20_dev_data_t *dev_data = DEV_DATA(dev);
int oldLevel; /* old interrupt lock level */
K20_SIM_t *sim_p =
(K20_SIM_t *)PERIPH_ADDR_BASE_SIM; /* sys integ. ctl */
C1_t c1; /* UART C1 register value */
C2_t c2; /* UART C2 register value */
uart[port].intPri = init_info->int_pri;
DEV_CFG(dev)->int_pri = init_info->int_pri;
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
/* disable interrupts */
oldLevel = irq_lock();
/* enable clock to Uart - must be done prior to device access */
_k20SimUartClkEnable(sim_p, port);
_k20SimUartClkEnable(sim_p, dev_data->seq_port_num);
_k20UartBaudRateSet(uart_p, init_info->sys_clk_freq, init_info->baud_rate);
@ -111,14 +117,17 @@ void uart_init(int port, /* UART channel to initialize */
*
* @brief Poll the device for input.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param pChar Pointer to character
*
* @return 0 if a character arrived, -1 if the input buffer if empty.
*/
int uart_poll_in(int port, /* UART channel to select for input */
int uart_poll_in(struct device *dev,
unsigned char *pChar /* pointer to char */
)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
if (uart_p->s1.field.rxDataFull == 0)
return (-1);
@ -139,14 +148,16 @@ int uart_poll_in(int port, /* UART channel to select for input */
* If the hardware flow control is enabled then the handshake signal CTS has to
* be asserted in order to send a character.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param out_char Character to send
*
* @return sent character
*/
unsigned char uart_poll_out(
int port, /* UART channel to select for output */
unsigned char uart_poll_out(struct device *dev,
unsigned char outChar /* char to send */
)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
/* wait for transmitter to ready to accept a character */
while (uart_p->s1.field.txDataEmpty == 0)
@ -163,15 +174,19 @@ unsigned char uart_poll_out(
*
* @brief Fill FIFO with data
* @param dev UART device struct (of type struct uart_device_config_t)
* @param tx_data Data to transmit
* @param len Number of bytes to send
*
* @return number of bytes sent
*/
int uart_fifo_fill(int port, /* UART on port to send */
int uart_fifo_fill(struct device *dev,
const uint8_t *txData, /* data to transmit */
int len /* number of bytes to send */
)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uint8_t numTx = 0;
while ((len - numTx > 0) && (uart_p->s1.field.txDataEmpty == 1)) {
@ -185,15 +200,19 @@ int uart_fifo_fill(int port, /* UART on port to send */
*
* @brief Read data from FIFO
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param rxData Pointer to data container
* @param size Container size in bytes
*
* @return number of bytes read
*/
int uart_fifo_read(int port, /* UART to receive from */
int uart_fifo_read(struct device *dev,
uint8_t *rxData, /* data container */
const int size /* container size */
)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uint8_t numRx = 0;
while ((size - numRx > 0) && (uart_p->s1.field.rxDataFull == 0)) {
@ -207,14 +226,14 @@ int uart_fifo_read(int port, /* UART to receive from */
*
* @brief Enable TX interrupt
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_enable(int port /* UART to enable Tx
interrupt */
)
void uart_irq_tx_enable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uart_p->c2.field.txInt_DmaTx_en = 1;
}
@ -223,14 +242,14 @@ void uart_irq_tx_enable(int port /* UART to enable Tx
*
* @brief Disable TX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_disable(
int port /* UART to disable Tx interrupt */
)
void uart_irq_tx_disable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uart_p->c2.field.txInt_DmaTx_en = 0;
}
@ -239,13 +258,14 @@ void uart_irq_tx_disable(
*
* @brief Check if Tx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is ready, 0 otherwise
*/
int uart_irq_tx_ready(int port /* UART to check */
)
int uart_irq_tx_ready(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
return uart_p->s1.field.txDataEmpty;
}
@ -254,14 +274,14 @@ int uart_irq_tx_ready(int port /* UART to check */
*
* @brief Enable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_enable(int port /* UART to enable Rx
interrupt */
)
void uart_irq_rx_enable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uart_p->c2.field.rxFullInt_dmaTx_en = 1;
}
@ -270,14 +290,14 @@ void uart_irq_rx_enable(int port /* UART to enable Rx
*
* @brief Disable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_disable(
int port /* UART to disable Rx interrupt */
)
void uart_irq_rx_disable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
uart_p->c2.field.rxFullInt_dmaTx_en = 0;
}
@ -286,13 +306,14 @@ void uart_irq_rx_disable(
*
* @brief Check if Rx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is ready, 0 otherwise
*/
int uart_irq_rx_ready(int port /* UART to check */
)
int uart_irq_rx_ready(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
return uart_p->s1.field.rxDataFull;
}
@ -301,12 +322,14 @@ int uart_irq_rx_ready(int port /* UART to check */
*
* @brief Enable error interrupt
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_err_enable(int port)
void uart_irq_err_enable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
C3_t c3 = uart_p->c3;
c3.field.parityErrIntEn = 1;
@ -320,13 +343,14 @@ void uart_irq_err_enable(int port)
*
* @brief Disable error interrupt
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_err_disable(int port /* UART to disable Rx interrupt */
)
void uart_irq_err_disable(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
C3_t c3 = uart_p->c3;
c3.field.parityErrIntEn = 0;
@ -340,13 +364,14 @@ void uart_irq_err_disable(int port /* UART to disable Rx interrupt */
*
* @brief Check if Tx or Rx IRQ is pending
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if a Tx or Rx IRQ is pending, 0 otherwise
*/
int uart_irq_is_pending(int port /* UART to check */
)
int uart_irq_is_pending(struct device *dev)
{
K20_UART_t *uart_p = (K20_UART_t *)uart[port].base;
K20_UART_t *uart_p = UART_STRUCT(dev);
/* Look only at Tx and Rx data interrupt flags */
@ -359,10 +384,12 @@ int uart_irq_is_pending(int port /* UART to check */
*
* @brief Update IRQ status
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1
*/
int uart_irq_update(int port)
int uart_irq_update(struct device *dev)
{
return 1;
}
@ -373,12 +400,14 @@ int uart_irq_update(int port)
*
* Returns the IRQ number used by the specified UART port
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
unsigned int uart_irq_get(int port /* UART port */
)
unsigned int uart_irq_get(struct device *dev)
{
return (unsigned int)uart[port].irq;
return (unsigned int)DEV_CFG(dev)->irq;
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

View file

@ -69,6 +69,8 @@ INCLUDE FILES: drivers/uart.h
#include <pci/pci_mgr.h>
#endif /* CONFIG_PCI */
#include "ns16550.h"
/* register definitions */
#define REG_THR 0x00 /* Transmitter holding reg. */
@ -189,40 +191,31 @@ INCLUDE FILES: drivers/uart.h
/* convenience defines */
#define THR(n) (uart[n].port + REG_THR * UART_REG_ADDR_INTERVAL)
#define RDR(n) (uart[n].port + REG_RDR * UART_REG_ADDR_INTERVAL)
#define BRDL(n) (uart[n].port + REG_BRDL * UART_REG_ADDR_INTERVAL)
#define BRDH(n) (uart[n].port + REG_BRDH * UART_REG_ADDR_INTERVAL)
#define IER(n) (uart[n].port + REG_IER * UART_REG_ADDR_INTERVAL)
#define IIR(n) (uart[n].port + REG_IIR * UART_REG_ADDR_INTERVAL)
#define FCR(n) (uart[n].port + REG_FCR * UART_REG_ADDR_INTERVAL)
#define LCR(n) (uart[n].port + REG_LCR * UART_REG_ADDR_INTERVAL)
#define MDC(n) (uart[n].port + REG_MDC * UART_REG_ADDR_INTERVAL)
#define LSR(n) (uart[n].port + REG_LSR * UART_REG_ADDR_INTERVAL)
#define MSR(n) (uart[n].port + REG_MSR * UART_REG_ADDR_INTERVAL)
#define DEV_CFG(dev) \
((struct uart_device_config_t * const)(dev)->config->config_info)
#define DEV_DATA(dev) \
((struct uart_ns16550_dev_data_t *)(dev)->driver_data)
#define IIRC(n) uart[n].iirCache
#define THR(dev) (DEV_CFG(dev)->port + REG_THR * UART_REG_ADDR_INTERVAL)
#define RDR(dev) (DEV_CFG(dev)->port + REG_RDR * UART_REG_ADDR_INTERVAL)
#define BRDL(dev) (DEV_CFG(dev)->port + REG_BRDL * UART_REG_ADDR_INTERVAL)
#define BRDH(dev) (DEV_CFG(dev)->port + REG_BRDH * UART_REG_ADDR_INTERVAL)
#define IER(dev) (DEV_CFG(dev)->port + REG_IER * UART_REG_ADDR_INTERVAL)
#define IIR(dev) (DEV_CFG(dev)->port + REG_IIR * UART_REG_ADDR_INTERVAL)
#define FCR(dev) (DEV_CFG(dev)->port + REG_FCR * UART_REG_ADDR_INTERVAL)
#define LCR(dev) (DEV_CFG(dev)->port + REG_LCR * UART_REG_ADDR_INTERVAL)
#define MDC(dev) (DEV_CFG(dev)->port + REG_MDC * UART_REG_ADDR_INTERVAL)
#define LSR(dev) (DEV_CFG(dev)->port + REG_LSR * UART_REG_ADDR_INTERVAL)
#define MSR(dev) (DEV_CFG(dev)->port + REG_MSR * UART_REG_ADDR_INTERVAL)
#define IIRC(dev) (DEV_DATA(dev)->iir_cache)
#define INBYTE(x) inByte(x)
#define OUTBYTE(x, d) outByte(d, x)
#if defined(CONFIG_NS16550_PCI)
struct ns16550 {
uint32_t port; /* base port number or MM base address */
uint8_t irq; /* interrupt request level */
uint8_t intPri; /* interrupt priority */
uint8_t iirCache; /* cache of IIR since it clears when read */
};
#if !(defined(UART_PORTS_CONFIGURE)) && !(defined(CONFIG_PCI))
#error "CONFIG_PCI or UART_PORTS_CONFIGURE is needed"
#elif !(defined(UART_PORTS_CONFIGURE)) && defined(CONFIG_PCI)
static struct ns16550 uart[CONFIG_UART_NUM_SYSTEM_PORTS] = {};
static inline void ns16550_uart_init()
static inline void ns16550_pci_uart_scan(void)
{
/*
* This device information is specific to Quark UART
@ -236,26 +229,28 @@ static inline void ns16550_uart_init()
};
int i;
if (uart[0].port && uart[0].irq)
/*
* No need to probe if ports have been probed.
*/
if ((DEV_CFG(&uart_devs[0]))->port && (DEV_CFG(&uart_devs[0]))->irq) {
return;
}
pci_bus_scan_init();
for (i = 0; pci_bus_scan(&dev_info) &&
i < CONFIG_UART_NUM_SYSTEM_PORTS; i++) {
uart[i].port = dev_info.addr;
uart[i].irq = dev_info.irq;
i < CONFIG_NS16550_PCI_NUM_PORTS; i++) {
DEV_CFG(&uart_devs[i])->port = dev_info.addr;
DEV_CFG(&uart_devs[i])->irq = dev_info.irq;
}
}
#else
#define ns16550_uart_init() \
#define ns16550_pci_uart_scan() \
do {} while ((0))
UART_PORTS_CONFIGURE(struct ns16550, uart);
#endif /* UART_PORTS_CONFIGURE */
#endif /* CONFIG_NS16550_PCI */
/**
*
@ -263,20 +258,26 @@ UART_PORTS_CONFIGURE(struct ns16550, uart);
*
* This routine is called to reset the chip in a quiescent state.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param init_info Initial configuration for UART
*
* @return N/A
*/
void uart_init(int port, /* UART channel to initialize */
void uart_init(struct device *dev,
const struct uart_init_info * const init_info
)
{
struct uart_device_config_t * const dev_cfg = DEV_CFG(dev);
struct uart_ns16550_dev_data_t *const dev_data = DEV_DATA(dev);
int oldLevel; /* old interrupt lock level */
uint32_t divisor; /* baud rate divisor */
ns16550_uart_init();
ns16550_pci_uart_scan();
uart[port].intPri = init_info->int_pri;
uart[port].iirCache = 0;
dev_cfg->int_pri = init_info->int_pri;
dev_data->iir_cache = 0;
oldLevel = irq_lock();
@ -284,28 +285,28 @@ void uart_init(int port, /* UART channel to initialize */
divisor = (init_info->sys_clk_freq / init_info->baud_rate) >> 4;
/* set the DLAB to access the baud rate divisor registers */
OUTBYTE(LCR(port), LCR_DLAB);
OUTBYTE(BRDL(port), (unsigned char)(divisor & 0xff));
OUTBYTE(BRDH(port), (unsigned char)((divisor >> 8) & 0xff));
OUTBYTE(LCR(dev), LCR_DLAB);
OUTBYTE(BRDL(dev), (unsigned char)(divisor & 0xff));
OUTBYTE(BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));
/* 8 data bits, 1 stop bit, no parity, clear DLAB */
OUTBYTE(LCR(port), LCR_CS8 | LCR_1_STB | LCR_PDIS);
OUTBYTE(LCR(dev), LCR_CS8 | LCR_1_STB | LCR_PDIS);
OUTBYTE(MDC(port), MCR_OUT2 | MCR_RTS | MCR_DTR);
OUTBYTE(MDC(dev), MCR_OUT2 | MCR_RTS | MCR_DTR);
/*
* Program FIFO: enabled, mode 0 (set for compatibility with quark),
* generate the interrupt at 8th byte
* Clear TX and RX FIFO
*/
OUTBYTE(FCR(port),
OUTBYTE(FCR(dev),
FCR_FIFO | FCR_MODE0 | FCR_FIFO_8 | FCR_RCVRCLR | FCR_XMITCLR);
/* clear the port */
INBYTE(RDR(port));
INBYTE(RDR(dev));
/* disable interrupts */
OUTBYTE(IER(port), 0x00);
OUTBYTE(IER(dev), 0x00);
irq_unlock(oldLevel);
}
@ -314,18 +315,21 @@ void uart_init(int port, /* UART channel to initialize */
*
* @brief Poll the device for input.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param pChar Pointer to character
*
* @return 0 if a character arrived, -1 if the input buffer if empty.
*/
int uart_poll_in(int port, /* UART channel to select for input */
int uart_poll_in(struct device *dev,
unsigned char *pChar /* pointer to char */
)
{
if ((INBYTE(LSR(port)) & LSR_RXRDY) == 0x00)
if ((INBYTE(LSR(dev)) & LSR_RXRDY) == 0x00)
return (-1);
/* got a character */
*pChar = INBYTE(RDR(port));
*pChar = INBYTE(RDR(dev));
return 0;
}
@ -340,18 +344,20 @@ int uart_poll_in(int port, /* UART channel to select for input */
* If the hardware flow control is enabled then the handshake signal CTS has to
* be asserted in order to send a character.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param outChar Character to send
*
* @return sent character
*/
unsigned char uart_poll_out(
int port, /* UART channel to select for output */
unsigned char uart_poll_out(struct device *dev,
unsigned char outChar /* char to send */
)
{
/* wait for transmitter to ready to accept a character */
while ((INBYTE(LSR(port)) & LSR_TEMT) == 0)
while ((INBYTE(LSR(dev)) & LSR_TEMT) == 0)
;
OUTBYTE(THR(port), outChar);
OUTBYTE(THR(dev), outChar);
return outChar;
}
@ -361,18 +367,22 @@ unsigned char uart_poll_out(
*
* @brief Fill FIFO with data
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param txData Data to transmit
* @param size Number of bytes to send
*
* @return number of bytes sent
*/
int uart_fifo_fill(int port, /* UART on port to send */
int uart_fifo_fill(struct device *dev,
const uint8_t *txData, /* data to transmit */
int size /* number of bytes to send */
)
{
int i;
for (i = 0; i < size && (INBYTE(LSR(port)) & LSR_THRE) != 0; i++) {
OUTBYTE(THR(port), txData[i]);
for (i = 0; i < size && (INBYTE(LSR(dev)) & LSR_THRE) != 0; i++) {
OUTBYTE(THR(dev), txData[i]);
}
return i;
}
@ -381,18 +391,22 @@ int uart_fifo_fill(int port, /* UART on port to send */
*
* @brief Read data from FIFO
*
* @return number of bytes read
* @param dev UART device struct (of type struct uart_device_config_t)
* @param rxData Data container
* @param size Container size
*
* @return Number of bytes read
*/
int uart_fifo_read(int port, /* UART to receive from */
int uart_fifo_read(struct device *dev,
uint8_t *rxData, /* data container */
const int size /* container size */
)
{
int i;
for (i = 0; i < size && (INBYTE(LSR(port)) & LSR_RXRDY) != 0; i++) {
rxData[i] = INBYTE(RDR(port));
for (i = 0; i < size && (INBYTE(LSR(dev)) & LSR_RXRDY) != 0; i++) {
rxData[i] = INBYTE(RDR(dev));
}
return i;
@ -402,148 +416,157 @@ int uart_fifo_read(int port, /* UART to receive from */
*
* @brief Enable TX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_enable(int port /* UART to enable Tx
interrupt */
)
void uart_irq_tx_enable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) | IER_TBE);
OUTBYTE(IER(dev), INBYTE(IER(dev)) | IER_TBE);
}
/**
*
* @brief Disable TX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_disable(int port /* UART to disable Tx interrupt */
)
void uart_irq_tx_disable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) & (~IER_TBE));
OUTBYTE(IER(dev), INBYTE(IER(dev)) & (~IER_TBE));
}
/**
*
* @brief Check if Tx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
int uart_irq_tx_ready(int port /* UART to check */
)
int uart_irq_tx_ready(struct device *dev)
{
return ((IIRC(port) & IIR_ID) == IIR_THRE);
return ((IIRC(dev) & IIR_ID) == IIR_THRE);
}
/**
*
* @brief Enable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_enable(int port /* UART to enable Rx
interrupt */
)
void uart_irq_rx_enable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) | IER_RXRDY);
OUTBYTE(IER(dev), INBYTE(IER(dev)) | IER_RXRDY);
}
/**
*
* @brief Disable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_disable(int port /* UART to disable Rx interrupt */
)
void uart_irq_rx_disable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) & (~IER_RXRDY));
OUTBYTE(IER(dev), INBYTE(IER(dev)) & (~IER_RXRDY));
}
/**
*
* @brief Check if Rx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is ready, 0 otherwise
*/
int uart_irq_rx_ready(int port /* UART to check */
)
int uart_irq_rx_ready(struct device *dev)
{
return ((IIRC(port) & IIR_ID) == IIR_RBRF);
return ((IIRC(dev) & IIR_ID) == IIR_RBRF);
}
/**
*
* @brief Enable error interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_err_enable(int port /* UART to enable Rx interrupt */
)
void uart_irq_err_enable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) | IER_LSR);
OUTBYTE(IER(dev), INBYTE(IER(dev)) | IER_LSR);
}
/**
*
* @brief Disable error interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is ready, 0 otherwise
*/
void uart_irq_err_disable(int port /* UART to disable Rx interrupt */
)
void uart_irq_err_disable(struct device *dev)
{
OUTBYTE(IER(port), INBYTE(IER(port)) & (~IER_LSR));
OUTBYTE(IER(dev), INBYTE(IER(dev)) & (~IER_LSR));
}
/**
*
* @brief Check if any IRQ is pending
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is pending, 0 otherwise
*/
int uart_irq_is_pending(int port /* UART to check */
)
int uart_irq_is_pending(struct device *dev)
{
return (!(IIRC(port) & IIR_IP));
return (!(IIRC(dev) & IIR_IP));
}
/**
*
* @brief Update cached contents of IIR
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1
*/
int uart_irq_update(int port /* UART to update */
)
int uart_irq_update(struct device *dev)
{
IIRC(port) = INBYTE(IIR(port));
IIRC(dev) = INBYTE(IIR(dev));
return 1;
}
/**
*
* @brief Returns UART interrupt number
*
* Returns the IRQ number used by the specified UART port
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
unsigned int uart_irq_get(int port /* UART port */
)
unsigned int uart_irq_get(struct device *dev)
{
return (unsigned int)uart[port].irq;
return (unsigned int)DEV_CFG(dev)->irq;
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

45
drivers/serial/ns16550.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2015 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Header file for ns16550 UART driver
*/
#ifndef _DRIVERS_UART_NS16550_H_
#define _DRIVERS_UART_NS16550_H_
#include <drivers/uart.h>
/** Device data structure */
struct uart_ns16550_dev_data_t {
uint8_t iir_cache; /**< cache of IIR since it clears when read */
};
#endif /* _DRIVERS_UART_NS16550_H_ */

View file

@ -41,41 +41,41 @@
#define NSIM_UART_DATA 0
#define NSIM_UART_STATUS 1
#define DATA_REG(n) (uart[n].regs + NSIM_UART_DATA)
#define STATUS_REG(n) (uart[n].regs + NSIM_UART_STATUS)
#define DEV_CFG(dev) \
((struct uart_device_config_t * const)(dev)->config->config_info)
#define DATA_REG(dev) (DEV_CFG(dev)->regs + NSIM_UART_DATA)
#define STATUS_REG(dev) (DEV_CFG(dev)->regs + NSIM_UART_STATUS)
#define TXEMPTY 0x80 /* Transmit FIFO empty and next character can be sent */
struct uart {
uint32_t regs; /* MM base address */
};
static struct uart __noinit uart[CONFIG_UART_NUM_SYSTEM_PORTS];
/*
* @brief Initialize fake serial port
* @which: port number
* @init_info: pointer to initialization information
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param init_info Pointer to initialization information
*/
void uart_init(int which, const struct uart_init_info * const init_info)
void uart_init(struct device *dev,
const struct uart_init_info * const init_info)
{
int key = irq_lock();
uart[which].regs = init_info->regs;
DEV_CFG(dev)->regs = init_info->regs;
irq_unlock(key);
}
/*
* @brief Output a character to serial port
* @port: port number
* @c: character to output
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param c character to output
*/
unsigned char uart_poll_out(int port, unsigned char c)
unsigned char uart_poll_out(struct device *dev, unsigned char c)
{
/* wait for transmitter to ready to accept a character */
while ((_arc_v2_aux_reg_read(STATUS_REG(port)) & TXEMPTY) == 0)
while ((_arc_v2_aux_reg_read(STATUS_REG(dev)) & TXEMPTY) == 0)
;
_arc_v2_aux_reg_write(DATA_REG(port), c);
_arc_v2_aux_reg_write(DATA_REG(dev), c);
return c;
}

View file

@ -85,35 +85,42 @@ struct _Uart {
uint32_t PCellID3;
};
/* convenience defines */
#define DEV_CFG(dev) \
((struct uart_device_config_t * const)(dev)->config->config_info)
#define UART_STRUCT(dev) \
((volatile struct _Uart *)(DEV_CFG(dev))->base)
/* registers */
#define UARTDR(n) *((volatile uint32_t *)(ports[n].base + 0x000))
#define UARTSR(n) *((volatile uint32_t *)(ports[n].base + 0x004))
#define UARTCR(n) *((volatile uint32_t *)(ports[n].base + 0x004))
#define UARTFR(n) *((volatile uint32_t *)(ports[n].base + 0x018))
#define UARTILPR(n) *((volatile uint32_t *)(ports[n].base + 0x020))
#define UARTIBRD(n) *((volatile uint32_t *)(ports[n].base + 0x024))
#define UARTFBRD(n) *((volatile uint32_t *)(ports[n].base + 0x028))
#define UARTLCRH(n) *((volatile uint32_t *)(ports[n].base + 0x02C))
#define UARTCTL(n) *((volatile uint32_t *)(ports[n].base + 0x030))
#define UARTIFLS(n) *((volatile uint32_t *)(ports[n].base + 0x034))
#define UARTIM(n) *((volatile uint32_t *)(ports[n].base + 0x038))
#define UARTRIS(n) *((volatile uint32_t *)(ports[n].base + 0x03C))
#define UARTMIS(n) *((volatile uint32_t *)(ports[n].base + 0x040))
#define UARTICR(n) *((volatile uint32_t *)(ports[n].base + 0x044))
#define UARTDR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x000)))
#define UARTSR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x004)))
#define UARTCR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x004)))
#define UARTFR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x018)))
#define UARTILPR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x020)))
#define UARTIBRD(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x024)))
#define UARTFBRD(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x028)))
#define UARTLCRH(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x02C)))
#define UARTCTL(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x030)))
#define UARTIFLS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x034)))
#define UARTIM(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x038)))
#define UARTRIS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x03C)))
#define UARTMIS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x040)))
#define UARTICR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x044)))
/* ID registers: UARTPID = UARTPeriphID, UARTPCID = UARTPCellId */
#define UARTPID4(n) *((volatile uint32_t *)(ports[n].base + 0xFD0))
#define UARTPID5(n) *((volatile uint32_t *)(ports[n].base + 0xFD4))
#define UARTPID6(n) *((volatile uint32_t *)(ports[n].base + 0xFD8))
#define UARTPID7(n) *((volatile uint32_t *)(ports[n].base + 0xFDC))
#define UARTPID0(n) *((volatile uint32_t *)(ports[n].base + 0xFE0))
#define UARTPID1(n) *((volatile uint32_t *)(ports[n].base + 0xFE4))
#define UARTPID2(n) *((volatile uint32_t *)(ports[n].base + 0xFE8))
#define UARTPID3(n) *((volatile uint32_t *)(ports[n].base + 0xFEC))
#define UARTPCID0(n) *((volatile uint32_t *)(ports[n].base + 0xFF0))
#define UARTPCID1(n) *((volatile uint32_t *)(ports[n].base + 0xFF4))
#define UARTPCID2(n) *((volatile uint32_t *)(ports[n].base + 0xFF8))
#define UARTPCID3(n) *((volatile uint32_t *)(ports[n].base + 0xFFC))
#define UARTPID4(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD0)))
#define UARTPID5(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD4)))
#define UARTPID6(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD8)))
#define UARTPID7(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFDC)))
#define UARTPID0(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE0)))
#define UARTPID1(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE4)))
#define UARTPID2(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE8)))
#define UARTPID3(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFEC)))
#define UARTPCID0(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF0)))
#define UARTPCID1(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF4)))
#define UARTPCID2(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF8)))
#define UARTPCID3(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFFC)))
/* muxed UART registers */
#define sr u1._sr /* Read: receive status */
@ -145,27 +152,25 @@ struct _Uart {
#define UARTMIS_RXMIS 0x00000010
#define UARTMIS_TXMIS 0x00000020
struct _StellarisUartPort {
void *base; /* base address of registers */
uint8_t irq; /* interrupt request number */
uint8_t intPri; /* interrupt priority level */
};
UART_PORTS_CONFIGURE(struct _StellarisUartPort, ports);
/**
*
* @brief Set the baud rate
*
* This routine set the given baud rate for the UART.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param baudrate Baud rate
* @param sysClkFreqInHz System clock frequency in Hz
*
* @return N/A
*/
static void baudrateSet(int port, uint32_t baudrate, uint32_t sysClkFreqInHz)
static void baudrateSet(struct device *dev,
uint32_t baudrate, uint32_t sysClkFreqInHz)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
uint32_t brdi, brdf, div, rem;
/* upon reset, the system clock uses the intenal OSC @ 12MHz */
div = (16 * baudrate);
@ -190,12 +195,14 @@ static void baudrateSet(int port, uint32_t baudrate, uint32_t sysClkFreqInHz)
*
* This routine enables the given UART.
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
static inline void enable(int port)
static inline void enable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->ctl |= UARTCTL_UARTEN;
}
@ -206,12 +213,14 @@ static inline void enable(int port)
*
* This routine disables the given UART.
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
static inline void disable(int port)
static inline void disable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->ctl &= ~UARTCTL_UARTEN;
@ -239,12 +248,14 @@ static inline void disable(int port)
*
* This routine sets the given UART's line controls to their default settings.
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
static inline void lineControlDefaultsSet(int port)
static inline void lineControlDefaultsSet(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->lcrh = LINE_CONTROL_DEFAULTS;
}
@ -256,18 +267,22 @@ static inline void lineControlDefaultsSet(int port)
* This routine is called to reset the chip in a quiescent state.
* It is assumed that this function is called only once per UART.
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_init(int port, /* UART channel to initialize */
void uart_init(struct device *dev,
const struct uart_init_info * const init_info
)
{
ports[port].intPri = init_info->int_pri;
struct uart_device_config_t * const dev_cfg = DEV_CFG(dev);
disable(port);
baudrateSet(port, init_info->baud_rate, init_info->sys_clk_freq);
lineControlDefaultsSet(port);
enable(port);
dev_cfg->int_pri = init_info->int_pri;
disable(dev);
baudrateSet(dev, init_info->baud_rate, init_info->sys_clk_freq);
lineControlDefaultsSet(dev);
enable(dev);
}
/**
@ -276,12 +291,13 @@ void uart_init(int port, /* UART channel to initialize */
*
* This routine returns the given UART's transmit ready status.
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 0 if ready to transmit, 1 otherwise
*/
static int pollTxReady(int port)
static int pollTxReady(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
return (pUart->fr & UARTFR_TXFE);
}
@ -290,14 +306,17 @@ static int pollTxReady(int port)
*
* @brief Poll the device for input.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param pChar Pointer to character
*
* @return 0 if a character arrived, -1 if the input buffer if empty.
*/
int uart_poll_in(int port, /* UART channel to select for input */
int uart_poll_in(struct device *dev,
unsigned char *pChar /* pointer to char */
)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
if (pUart->fr & UARTFR_RXFE)
return (-1);
@ -315,13 +334,16 @@ int uart_poll_in(int port, /* UART channel to select for input */
* Checks if the transmitter is empty. If empty, a character is written to
* the data register.
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param c Character to send
*
* @return sent character
*/
unsigned char uart_poll_out(int port, unsigned char c)
unsigned char uart_poll_out(struct device *dev, unsigned char c)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
while (!pollTxReady(port))
while (!pollTxReady(dev))
;
/* send a character */
@ -335,15 +357,19 @@ unsigned char uart_poll_out(int port, unsigned char c)
*
* @brief Fill FIFO with data
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param txData Data to transmit
* @param len Number of bytes to send
*
* @return number of bytes sent
*/
int uart_fifo_fill(int port, /* UART on which to send */
int uart_fifo_fill(struct device *dev,
const uint8_t *txData, /* data to transmit */
int len /* number of bytes to send */
)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
uint8_t numTx = 0;
while ((len - numTx > 0) && ((pUart->fr & UARTFR_TXFF) == 0)) {
@ -357,15 +383,19 @@ int uart_fifo_fill(int port, /* UART on which to send */
*
* @brief Read data from FIFO
*
* @param dev UART device struct (of type struct uart_device_config_t)
* @param rxData Pointer to data container
* @param size Container size
*
* @return number of bytes read
*/
int uart_fifo_read(int port, /* UART to receive from */
int uart_fifo_read(struct device *dev,
uint8_t *rxData, /* data container */
const int size /* container size */
)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
uint8_t numRx = 0;
while ((size - numRx > 0) && ((pUart->fr & UARTFR_RXFE) == 0)) {
@ -379,11 +409,12 @@ int uart_fifo_read(int port, /* UART to receive from */
*
* @brief Enable TX interrupt
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
)
void uart_irq_tx_enable(struct device *dev)
{
static uint8_t first_time =
1; /* used to allow the first transmission */
@ -391,7 +422,7 @@ void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
uint32_t saved_ibrd; /* saved UARTIBRD (integer baud rate) register */
uint32_t saved_fbrd; /* saved UARTFBRD (fractional baud rate) register
*/
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
if (first_time) {
/*
@ -409,7 +440,7 @@ void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
saved_fbrd = pUart->fbrd;
/* send a character with default settings via loopback */
disable(port);
disable(dev);
pUart->fbrd = 0;
pUart->ibrd = 1;
pUart->lcrh = 0;
@ -420,10 +451,10 @@ void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
;
/* restore control and baud rate settings */
disable(port);
disable(dev);
pUart->ibrd = saved_ibrd;
pUart->fbrd = saved_fbrd;
lineControlDefaultsSet(port);
lineControlDefaultsSet(dev);
pUart->ctl = saved_ctl;
}
@ -434,13 +465,14 @@ void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
*
* @brief Disable TX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_tx_disable(int port /* UART to disable Tx interrupt */
)
void uart_irq_tx_disable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->im &= ~UARTTIM_TXIM;
}
@ -449,13 +481,14 @@ void uart_irq_tx_disable(int port /* UART to disable Tx interrupt */
*
* @brief Check if Tx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if a Tx IRQ is pending, 0 otherwise
*/
int uart_irq_tx_ready(int port /* UART to check */
)
int uart_irq_tx_ready(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
return ((pUart->mis & UARTMIS_TXMIS) == UARTMIS_TXMIS);
}
@ -464,13 +497,14 @@ int uart_irq_tx_ready(int port /* UART to check */
*
* @brief Enable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_enable(int port /* UART to enable Rx interrupt */
)
void uart_irq_rx_enable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->im |= UARTTIM_RXIM;
}
@ -479,13 +513,14 @@ void uart_irq_rx_enable(int port /* UART to enable Rx interrupt */
*
* @brief Disable RX interrupt in IER
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_rx_disable(int port /* UART to disable Rx interrupt */
)
void uart_irq_rx_disable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->im &= ~UARTTIM_RXIM;
}
@ -494,13 +529,14 @@ void uart_irq_rx_disable(int port /* UART to disable Rx interrupt */
*
* @brief Check if Rx IRQ has been raised
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if an IRQ is ready, 0 otherwise
*/
int uart_irq_rx_ready(int port /* UART to check */
)
int uart_irq_rx_ready(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
return ((pUart->mis & UARTMIS_RXMIS) == UARTMIS_RXMIS);
}
@ -509,13 +545,14 @@ int uart_irq_rx_ready(int port /* UART to check */
*
* @brief Enable error interrupts
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_err_enable(int port /* UART to enable interrupts for */
)
void uart_irq_err_enable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->im |= (UARTTIM_RTIM | UARTTIM_FEIM | UARTTIM_PEIM |
UARTTIM_BEIM | UARTTIM_OEIM);
@ -525,13 +562,14 @@ void uart_irq_err_enable(int port /* UART to enable interrupts for */
*
* @brief Disable error interrupts
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
void uart_irq_err_disable(int port /* UART to disable interrupts for */
)
void uart_irq_err_disable(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
pUart->im &= ~(UARTTIM_RTIM | UARTTIM_FEIM | UARTTIM_PEIM |
UARTTIM_BEIM | UARTTIM_OEIM);
@ -541,13 +579,14 @@ void uart_irq_err_disable(int port /* UART to disable interrupts for */
*
* @brief Check if Tx or Rx IRQ is pending
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return 1 if a Tx or Rx IRQ is pending, 0 otherwise
*/
int uart_irq_is_pending(int port /* UART to check */
)
int uart_irq_is_pending(struct device *dev)
{
volatile struct _Uart *pUart = ports[port].base;
volatile struct _Uart *pUart = UART_STRUCT(dev);
/* Look only at Tx and Rx data interrupt flags */
return ((pUart->mis & (UARTMIS_RXMIS | UARTMIS_TXMIS)) ? 1 : 0);
@ -557,10 +596,12 @@ int uart_irq_is_pending(int port /* UART to check */
*
* @brief Update IRQ status
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1
*/
int uart_irq_update(int port)
int uart_irq_update(struct device *dev)
{
return 1;
}
@ -571,12 +612,13 @@ int uart_irq_update(int port)
*
* Returns the IRQ number used by the specified UART port
*
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A
*/
unsigned int uart_irq_get(int port /* UART port */
)
unsigned int uart_irq_get(struct device *dev)
{
return (unsigned int)ports[port].irq;
return (unsigned int)DEV_CFG(dev)->irq;
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

View file

@ -44,7 +44,7 @@
#include <simple/uart.h>
#include <misc/printk.h>
#define UART CONFIG_UART_SIMPLE_INDEX
#define UART (&uart_devs[CONFIG_UART_SIMPLE_INDEX])
static uint8_t *recv_buf;
static size_t recv_buf_len;
@ -84,7 +84,7 @@ int uart_simple_send(const uint8_t *data, int len)
IRQ_CONNECT_STATIC(uart_simple, CONFIG_UART_SIMPLE_IRQ,
CONFIG_UART_SIMPLE_INT_PRI, uart_simple_isr, 0);
static void uart_simple_setup(int uart, struct uart_init_info *info)
static void uart_simple_setup(struct device *uart, struct uart_init_info *info)
{
uart_init(uart, info);

View file

@ -205,6 +205,11 @@ typedef volatile struct {
*/
} K20_UART_t; /* K20 Microntroller UART module */
/** Device data structure */
struct uart_k20_dev_data_t {
uint8_t seq_port_num; /**< Sequential port number */
};
static ALWAYS_INLINE void _k20UartBaudRateSet(K20_UART_t *uart_p,
uint32_t clkFreq,
uint32_t baudRate)

View file

@ -37,37 +37,63 @@
extern "C" {
#endif
/* generic UART info structure */
struct uart_init_info {
int baud_rate;
uint32_t sys_clk_freq; /* in Hz */
uint8_t options; /* HW Flow Control option */
uint8_t int_pri; /* interrupt priority level */
};
/* UART driver has to configure the device to 8n1 */
#include <device.h>
void uart_init(int port, const struct uart_init_info *const pinfo);
/* UART device configuration */
struct uart_device_config_t {
/**
* Base port number
* or memory mapped base address
* or register address
*/
union {
uint32_t port;
uint8_t *base;
uint32_t regs;
};
uint8_t irq; /**< interrupt request level */
uint8_t int_pri; /**< interrupt priority */
};
/** UART configuration structure */
struct uart_init_info {
int baud_rate; /* Baud rate */
uint32_t sys_clk_freq; /* System clock frequency in Hz */
uint8_t int_pri; /* Interrupt priority level */
uint8_t options; /* HW Flow Control option */
uint32_t regs; /* Register address */
};
/* UART driver has to configure the device to 8n1 */
void uart_init(struct device *dev,
const struct uart_init_info * const pinfo);
/* console I/O functions */
int uart_poll_in(int port, unsigned char *pChar);
unsigned char uart_poll_out(int port, unsigned char outChar);
int uart_poll_in(struct device *dev, unsigned char *p_char);
unsigned char uart_poll_out(struct device *dev, unsigned char out_char);
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
/* interrupt driven I/O functions */
int uart_fifo_fill(int port, const uint8_t *txData, int len);
int uart_fifo_read(int port, uint8_t *rxData, const int size);
void uart_irq_tx_enable(int port);
void uart_irq_tx_disable(int port);
int uart_irq_tx_ready(int port);
void uart_irq_rx_enable(int port);
void uart_irq_rx_disable(int port);
int uart_irq_rx_ready(int port);
void uart_irq_err_enable(int port);
void uart_irq_err_disable(int port);
int uart_irq_is_pending(int port);
int uart_irq_update(int port);
unsigned int uart_irq_get(int port);
int uart_fifo_fill(struct device *dev, const uint8_t *txData, int len);
int uart_fifo_read(struct device *dev, uint8_t *rxData, const int size);
void uart_irq_tx_enable(struct device *dev);
void uart_irq_tx_disable(struct device *dev);
int uart_irq_tx_ready(struct device *dev);
void uart_irq_rx_enable(struct device *dev);
void uart_irq_rx_disable(struct device *dev);
int uart_irq_rx_ready(struct device *dev);
void uart_irq_err_enable(struct device *dev);
void uart_irq_err_disable(struct device *dev);
int uart_irq_is_pending(struct device *dev);
int uart_irq_update(struct device *dev);
unsigned int uart_irq_get(struct device *dev);
void uart_generic_info_init(struct uart_init_info *p_info);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -37,7 +37,7 @@
#include <board.h>
#include <drivers/uart.h>
#define UART1 1
#define UART1 (&uart_devs[1])
#define UART1_IRQ COM2_INT_LVL
#define UART1_INT_PRI COM2_INT_PRI
#define BUF_MAXSIZE 256