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} asflags-y := ${ccflags-y}
obj-y += platform_config.o
obj-y += system.o obj-y += system.o
obj-y += nmi_on_reset.o obj-y += nmi_on_reset.o
obj-y += wdog.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 #ifndef _ASMLANGUAGE
#include <device.h>
#include <misc/util.h> #include <misc/util.h>
#include <drivers/rand32.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> #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_REGS PERIPH_ADDR_BASE_UART0
#define CONFIG_UART_PORT_0_IRQ IRQ_UART0_STATUS #define CONFIG_UART_PORT_0_IRQ IRQ_UART0_STATUS
#define CONFIG_UART_PORT_1_REGS PERIPH_ADDR_BASE_UART1 #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_REGS PERIPH_ADDR_BASE_UART4
#define CONFIG_UART_PORT_4_IRQ IRQ_UART4_STATUS #define CONFIG_UART_PORT_4_IRQ IRQ_UART4_STATUS
#define UART_PORTS_CONFIGURE(__type, __name) \ extern struct device uart_devs[];
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 \
} \
}
/* Uart console settings */ /* 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_IRQ IRQ_UART0_STATUS
#define CONFIG_UART_CONSOLE_INT_PRI 3 #define CONFIG_UART_CONSOLE_INT_PRI 3
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
/* Bluetooth UART definitions */ /* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1 #define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_BAUDRATE 115200 #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[rxPin] = pcr;
port_pcr_p->port[port].pcr[txPin] = 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(); uart_console_init();
} }

View file

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

View file

@ -100,15 +100,12 @@ the 'ti_lm3s6965' platform.
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
#include <device.h>
#include <misc/util.h> #include <misc/util.h>
#include <drivers/rand32.h> #include <drivers/rand32.h>
/* uart configuration settings */ /* 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_REGS PERIPH_ADDR_BASE_UART0
#define CONFIG_UART_PORT_0_IRQ IRQ_UART0 #define CONFIG_UART_PORT_0_IRQ IRQ_UART0
#define CONFIG_UART_PORT_1_REGS PERIPH_ADDR_BASE_UART1 #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_REGS PERIPH_ADDR_BASE_UART2
#define CONFIG_UART_PORT_2_IRQ IRQ_UART2 #define CONFIG_UART_PORT_2_IRQ IRQ_UART2
#define UART_PORTS_CONFIGURE(__type, __name) \ extern struct device uart_devs[];
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 \
} \
}
/* Uart console configuration */ /* Uart console configuration */
@ -138,6 +121,9 @@ the 'ti_lm3s6965' platform.
#define CONFIG_UART_CONSOLE_IRQ IRQ_UART0 #define CONFIG_UART_CONSOLE_IRQ IRQ_UART0
#define CONFIG_UART_CONSOLE_INT_PRI 3 #define CONFIG_UART_CONSOLE_INT_PRI 3
extern struct device * const uart_console_dev;
#define UART_CONSOLE_DEV uart_console_dev
/* Bluetooth UART definitions */ /* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1 #define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_BAUDRATE 115200 #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_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info); uart_init(UART_CONSOLE_DEV, &info);
uart_console_init(); uart_console_init();
} }

View file

@ -148,6 +148,8 @@ CONFIG_EXTRA_SERIAL_PORT=y
CONFIG_SERIAL_INTERRUPT_LEVEL=y CONFIG_SERIAL_INTERRUPT_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set # CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set # CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set # CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN 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_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set # CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set # CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set # CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN 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_LEVEL=y
# CONFIG_SERIAL_INTERRUPT_LOW is not set # CONFIG_SERIAL_INTERRUPT_LOW is not set
CONFIG_NS16550=y CONFIG_NS16550=y
CONFIG_NS16550_PCI=y
CONFIG_NS16550_PCI_NUM_PORTS=2
# CONFIG_K20_UART is not set # CONFIG_K20_UART is not set
# CONFIG_STELLARIS_UART is not set # CONFIG_STELLARIS_UART is not set
# CONFIG_UART_INTERRUPT_DRIVEN 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 ccflags-y +=-I$(srctree)/drivers
asflags-y := ${ccflags-y} 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> #include <misc/util.h>
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
#include <device.h>
#include <drivers/rand32.h> #include <drivers/rand32.h>
#endif #endif
@ -68,6 +69,8 @@ the 'ia32' platform.
/* serial port (aka COM port) information */ /* serial port (aka COM port) information */
#ifdef CONFIG_NS16550
#define COM1_BASE_ADRS 0x3f8 #define COM1_BASE_ADRS 0x3f8
#define COM1_INT_LVL 0x04 /* COM1 connected to IRQ4 */ #define COM1_INT_LVL 0x04 /* COM1 connected to IRQ4 */
#define COM1_INT_VEC (INT_VEC_IRQ0 + COM1_INT_LVL) #define COM1_INT_VEC (INT_VEC_IRQ0 + COM1_INT_LVL)
@ -86,32 +89,26 @@ the 'ia32' platform.
/* uart configuration settings */ /* uart configuration settings */
/* Generic definitions */ /* 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_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_REGS COM1_BASE_ADRS
#define CONFIG_UART_PORT_0_IRQ COM1_INT_LVL #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_REGS COM2_BASE_ADRS
#define CONFIG_UART_PORT_1_IRQ COM2_INT_LVL #define CONFIG_UART_PORT_1_IRQ COM2_INT_LVL
#define CONFIG_UART_PORT_1_IRQ_PRIORITY COM2_INT_PRI
#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 \
} \
}
/* Console definitions */ /* Console definitions */
#define CONFIG_UART_CONSOLE_IRQ COM1_INT_LVL #define CONFIG_UART_CONSOLE_IRQ COM1_INT_LVL
#define CONFIG_UART_CONSOLE_INT_PRI COM1_INT_PRI #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 */ /* Bluetooth UART definitions */
#define CONFIG_BLUETOOTH_UART_INDEX 1 #define CONFIG_BLUETOOTH_UART_INDEX 1
#define CONFIG_BLUETOOTH_UART_IRQ COM2_INT_LVL #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_FREQ UART_XTAL_FREQ
#define CONFIG_BLUETOOTH_UART_BAUDRATE CONFIG_UART_BAUDRATE #define CONFIG_BLUETOOTH_UART_BAUDRATE CONFIG_UART_BAUDRATE
#endif /* CONFIG_NS16550 */
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
/* /*
* Device drivers utilize the macros PLB_BYTE_REG_WRITE() and * 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; struct uart_init_info info;
uart_generic_info_init(&info); uart_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info); uart_init(UART_CONSOLE_DEV, &info);
uart_console_init(); uart_console_init();
} }

View file

@ -1,5 +1,7 @@
ccflags-y += -I$(srctree)/include/drivers ccflags-y += -I$(srctree)/include/drivers
ccflags-y += -I$(srctree)/drivers
asflags-y := ${ccflags-y} 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> #include <misc/util.h>
#ifndef _ASMLANGUAGE #ifndef _ASMLANGUAGE
#include <device.h>
#include <drivers/rand32.h> #include <drivers/rand32.h>
#endif #endif
@ -65,14 +66,15 @@ the 'ia32_pci' platform.
#define CONFIG_UART_PCI_VENDOR_ID 0x8086 #define CONFIG_UART_PCI_VENDOR_ID 0x8086
#define CONFIG_UART_PCI_DEVICE_ID 0x0936 #define CONFIG_UART_PCI_DEVICE_ID 0x0936
#define CONFIG_UART_PCI_BAR 0 #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_BAUDRATE COM1_BAUD_RATE
#define CONFIG_UART_NUM_PORTS \
(CONFIG_UART_NUM_SYSTEM_PORTS + CONFIG_UART_NUM_EXTRA_PORTS)
/* Console definitions */ #ifndef _ASMLANGUAGE
#define CONFIG_UART_CONSOLE_PCI_IDX COM1_PCI_IDX
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 * 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; struct uart_init_info info;
uart_generic_info_init(&info); uart_generic_info_init(&info);
uart_init(CONFIG_UART_CONSOLE_INDEX, &info); uart_init(UART_CONSOLE_DEV, &info);
uart_console_init(); uart_console_init();
} }

View file

@ -58,9 +58,10 @@
#define H4_SCO 0x03 #define H4_SCO 0x03
#define H4_EVT 0x04 #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; 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; 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]; 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, IRQ_CONNECT_STATIC(bluetooth, CONFIG_BLUETOOTH_UART_IRQ,
CONFIG_BLUETOOTH_UART_INT_PRI, bt_uart_isr, 0); 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"); BT_DBG("\n");
@ -282,7 +283,7 @@ static int bt_uart_open()
.int_pri = CONFIG_BLUETOOTH_UART_INT_PRI, .int_pri = CONFIG_BLUETOOTH_UART_INT_PRI,
}; };
bt_uart_setup(CONFIG_BLUETOOTH_UART_INDEX, &info); bt_uart_setup(UART, &info);
return 0; return 0;
} }

View file

@ -50,11 +50,6 @@
#include <toolchain.h> #include <toolchain.h>
#include <sections.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 */ #if 0 /* NOTUSED */
/** /**
* *
@ -65,11 +60,15 @@
static int consoleIn(void) static int consoleIn(void)
{ {
#ifdef UART_CONSOLE_DEV
unsigned char c; unsigned char c;
if (uart_poll_in(UART, &c) < 0) if (uart_poll_in(UART_CONSOLE_DEV, &c) < 0)
return EOF; return EOF;
else else
return (int)c; return (int)c;
#else
return 0;
#endif
} }
#endif #endif
@ -86,11 +85,15 @@ static int consoleIn(void)
static int consoleOut(int c /* character to output */ 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) { if ('\n' == c) {
uart_poll_out(UART, (unsigned char)'\r'); uart_poll_out(UART_CONSOLE_DEV, (unsigned char)'\r');
} }
return c; return c;
#else
return 0;
#endif
} }
#endif #endif
@ -116,7 +119,7 @@ static size_t pos = 0;
static struct nano_fifo *avail_queue; static struct nano_fifo *avail_queue;
static struct nano_fifo *lines_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; int rx;
@ -135,9 +138,10 @@ void uart_console_isr(void *unused)
{ {
ARG_UNUSED(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 */ /* 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; static struct uart_console_input *cmd;
uint8_t byte; uint8_t byte;
int rx; int rx;
@ -149,19 +153,19 @@ void uart_console_isr(void *unused)
return; return;
} }
rx = read_uart(UART, &byte, 1); rx = read_uart(UART_CONSOLE_DEV, &byte, 1);
if (rx < 0) { if (rx < 0) {
nano_isr_fifo_put(avail_queue, cmd); nano_isr_fifo_put(avail_queue, cmd);
return; return;
} }
/* Echo back to console */ /* Echo back to console */
uart_poll_out(UART, byte); uart_poll_out(UART_CONSOLE_DEV, byte);
if (byte == '\r' || byte == '\n' || if (byte == '\r' || byte == '\n' ||
pos == sizeof(cmd->line) - 1) { pos == sizeof(cmd->line) - 1) {
cmd->line[pos] = '\0'; cmd->line[pos] = '\0';
uart_poll_out(UART, '\n'); uart_poll_out(UART_CONSOLE_DEV, '\n');
pos = 0; pos = 0;
nano_isr_fifo_put(lines_queue, cmd); nano_isr_fifo_put(lines_queue, cmd);
@ -181,16 +185,17 @@ static void console_input_init(void)
{ {
uint8_t c; uint8_t c;
uart_irq_rx_disable(UART); uart_irq_rx_disable(UART_CONSOLE_DEV);
uart_irq_tx_disable(UART); uart_irq_tx_disable(UART_CONSOLE_DEV);
IRQ_CONFIG(console, uart_irq_get(UART)); IRQ_CONFIG(console, uart_irq_get(UART_CONSOLE_DEV));
irq_enable(uart_irq_get(UART)); irq_enable(uart_irq_get(UART_CONSOLE_DEV));
/* Drain the fifo */ /* Drain the fifo */
while (uart_irq_rx_ready(UART)) while (uart_irq_rx_ready(UART_CONSOLE_DEV)) {
uart_fifo_read(UART, &c, 1); 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) 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 This specific driver can be used for the serial hardware
available at the Generic PC and Quark. 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 config K20_UART
bool "K20 serial driver" bool "K20 serial driver"
default n default n
@ -93,4 +110,60 @@ config UART_INTERRUPT_DRIVEN
This option enables interrupt support for UART allowing console This option enables interrupt support for UART allowing console
input and UART based drivers. 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 endmenu

View file

@ -51,13 +51,14 @@ INCLUDE FILES: drivers/serial/k20_uart.h
#include <toolchain.h> #include <toolchain.h>
#include <sections.h> #include <sections.h>
typedef struct { /* convenience defines */
uint8_t *base; /* base address of registers */
uint8_t irq; /* interrupt request level */
uint8_t intPri; /* interrupt priority */
} _k20Uart_t;
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. * This routine is called to reset the chip in a quiescent state.
* It is assumed that this function is called only once per UART. * 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 * @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 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 */ int oldLevel; /* old interrupt lock level */
K20_SIM_t *sim_p = K20_SIM_t *sim_p =
(K20_SIM_t *)PERIPH_ADDR_BASE_SIM; /* sys integ. ctl */ (K20_SIM_t *)PERIPH_ADDR_BASE_SIM; /* sys integ. ctl */
C1_t c1; /* UART C1 register value */ C1_t c1; /* UART C1 register value */
C2_t c2; /* UART C2 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 */ /* disable interrupts */
oldLevel = irq_lock(); oldLevel = irq_lock();
/* enable clock to Uart - must be done prior to device access */ /* 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); _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. * @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. * @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 */ 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) if (uart_p->s1.field.rxDataFull == 0)
return (-1); 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 * If the hardware flow control is enabled then the handshake signal CTS has to
* be asserted in order to send a character. * 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 * @return sent character
*/ */
unsigned char uart_poll_out( unsigned char uart_poll_out(struct device *dev,
int port, /* UART channel to select for output */
unsigned char outChar /* char to send */ 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 */ /* wait for transmitter to ready to accept a character */
while (uart_p->s1.field.txDataEmpty == 0) while (uart_p->s1.field.txDataEmpty == 0)
@ -163,15 +174,19 @@ unsigned char uart_poll_out(
* *
* @brief Fill FIFO with data * @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 * @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 */ const uint8_t *txData, /* data to transmit */
int len /* number of bytes to send */ 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; uint8_t numTx = 0;
while ((len - numTx > 0) && (uart_p->s1.field.txDataEmpty == 1)) { 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 * @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 * @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 */ uint8_t *rxData, /* data container */
const int size /* container size */ 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; uint8_t numRx = 0;
while ((size - numRx > 0) && (uart_p->s1.field.rxDataFull == 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 * @brief Enable TX interrupt
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_tx_enable(int port /* UART to enable Tx void uart_irq_tx_enable(struct device *dev)
interrupt */
)
{ {
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; 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 * @brief Disable TX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_tx_disable( void uart_irq_tx_disable(struct device *dev)
int port /* UART to disable Tx interrupt */
)
{ {
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; 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 * @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 * @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; 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 * @brief Enable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_rx_enable(int port /* UART to enable Rx void uart_irq_rx_enable(struct device *dev)
interrupt */
)
{ {
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; 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 * @brief Disable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_rx_disable( void uart_irq_rx_disable(struct device *dev)
int port /* UART to disable Rx interrupt */
)
{ {
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; 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 * @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 * @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; return uart_p->s1.field.rxDataFull;
} }
@ -301,12 +322,14 @@ int uart_irq_rx_ready(int port /* UART to check */
* *
* @brief Enable error interrupt * @brief Enable error interrupt
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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_t c3 = uart_p->c3;
c3.field.parityErrIntEn = 1; c3.field.parityErrIntEn = 1;
@ -320,13 +343,14 @@ void uart_irq_err_enable(int port)
* *
* @brief Disable error interrupt * @brief Disable error interrupt
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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_t c3 = uart_p->c3;
c3.field.parityErrIntEn = 0; 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 * @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 * @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 */ /* 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 * @brief Update IRQ status
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1 * @return always 1
*/ */
int uart_irq_update(int port) int uart_irq_update(struct device *dev)
{ {
return 1; return 1;
} }
@ -373,12 +400,14 @@ int uart_irq_update(int port)
* *
* Returns the IRQ number used by the specified UART 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 * @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 */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */

View file

@ -69,6 +69,8 @@ INCLUDE FILES: drivers/uart.h
#include <pci/pci_mgr.h> #include <pci/pci_mgr.h>
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#include "ns16550.h"
/* register definitions */ /* register definitions */
#define REG_THR 0x00 /* Transmitter holding reg. */ #define REG_THR 0x00 /* Transmitter holding reg. */
@ -189,40 +191,31 @@ INCLUDE FILES: drivers/uart.h
/* convenience defines */ /* convenience defines */
#define THR(n) (uart[n].port + REG_THR * UART_REG_ADDR_INTERVAL) #define DEV_CFG(dev) \
#define RDR(n) (uart[n].port + REG_RDR * UART_REG_ADDR_INTERVAL) ((struct uart_device_config_t * const)(dev)->config->config_info)
#define BRDL(n) (uart[n].port + REG_BRDL * UART_REG_ADDR_INTERVAL) #define DEV_DATA(dev) \
#define BRDH(n) (uart[n].port + REG_BRDH * UART_REG_ADDR_INTERVAL) ((struct uart_ns16550_dev_data_t *)(dev)->driver_data)
#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 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 INBYTE(x) inByte(x)
#define OUTBYTE(x, d) outByte(d, x) #define OUTBYTE(x, d) outByte(d, x)
#if defined(CONFIG_NS16550_PCI)
struct ns16550 { static inline void ns16550_pci_uart_scan(void)
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()
{ {
/* /*
* This device information is specific to Quark UART * This device information is specific to Quark UART
@ -236,26 +229,28 @@ static inline void ns16550_uart_init()
}; };
int i; 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; return;
}
pci_bus_scan_init(); pci_bus_scan_init();
for (i = 0; pci_bus_scan(&dev_info) && for (i = 0; pci_bus_scan(&dev_info) &&
i < CONFIG_UART_NUM_SYSTEM_PORTS; i++) { i < CONFIG_NS16550_PCI_NUM_PORTS; i++) {
uart[i].port = dev_info.addr; DEV_CFG(&uart_devs[i])->port = dev_info.addr;
uart[i].irq = dev_info.irq; DEV_CFG(&uart_devs[i])->irq = dev_info.irq;
} }
} }
#else #else
#define ns16550_uart_init() \ #define ns16550_pci_uart_scan() \
do {} while ((0)) do {} while ((0))
UART_PORTS_CONFIGURE(struct ns16550, uart); #endif /* CONFIG_NS16550_PCI */
#endif /* UART_PORTS_CONFIGURE */
/** /**
* *
@ -263,20 +258,26 @@ UART_PORTS_CONFIGURE(struct ns16550, uart);
* *
* This routine is called to reset the chip in a quiescent state. * 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 * @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 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 */ int oldLevel; /* old interrupt lock level */
uint32_t divisor; /* baud rate divisor */ uint32_t divisor; /* baud rate divisor */
ns16550_uart_init(); ns16550_pci_uart_scan();
uart[port].intPri = init_info->int_pri; dev_cfg->int_pri = init_info->int_pri;
uart[port].iirCache = 0; dev_data->iir_cache = 0;
oldLevel = irq_lock(); 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; divisor = (init_info->sys_clk_freq / init_info->baud_rate) >> 4;
/* set the DLAB to access the baud rate divisor registers */ /* set the DLAB to access the baud rate divisor registers */
OUTBYTE(LCR(port), LCR_DLAB); OUTBYTE(LCR(dev), LCR_DLAB);
OUTBYTE(BRDL(port), (unsigned char)(divisor & 0xff)); OUTBYTE(BRDL(dev), (unsigned char)(divisor & 0xff));
OUTBYTE(BRDH(port), (unsigned char)((divisor >> 8) & 0xff)); OUTBYTE(BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));
/* 8 data bits, 1 stop bit, no parity, clear DLAB */ /* 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), * Program FIFO: enabled, mode 0 (set for compatibility with quark),
* generate the interrupt at 8th byte * generate the interrupt at 8th byte
* Clear TX and RX FIFO * Clear TX and RX FIFO
*/ */
OUTBYTE(FCR(port), OUTBYTE(FCR(dev),
FCR_FIFO | FCR_MODE0 | FCR_FIFO_8 | FCR_RCVRCLR | FCR_XMITCLR); FCR_FIFO | FCR_MODE0 | FCR_FIFO_8 | FCR_RCVRCLR | FCR_XMITCLR);
/* clear the port */ /* clear the port */
INBYTE(RDR(port)); INBYTE(RDR(dev));
/* disable interrupts */ /* disable interrupts */
OUTBYTE(IER(port), 0x00); OUTBYTE(IER(dev), 0x00);
irq_unlock(oldLevel); irq_unlock(oldLevel);
} }
@ -314,18 +315,21 @@ void uart_init(int port, /* UART channel to initialize */
* *
* @brief Poll the device for input. * @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. * @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 */ unsigned char *pChar /* pointer to char */
) )
{ {
if ((INBYTE(LSR(port)) & LSR_RXRDY) == 0x00) if ((INBYTE(LSR(dev)) & LSR_RXRDY) == 0x00)
return (-1); return (-1);
/* got a character */ /* got a character */
*pChar = INBYTE(RDR(port)); *pChar = INBYTE(RDR(dev));
return 0; 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 * If the hardware flow control is enabled then the handshake signal CTS has to
* be asserted in order to send a character. * 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 * @return sent character
*/ */
unsigned char uart_poll_out( unsigned char uart_poll_out(struct device *dev,
int port, /* UART channel to select for output */
unsigned char outChar /* char to send */ unsigned char outChar /* char to send */
) )
{ {
/* wait for transmitter to ready to accept a character */ /* 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; return outChar;
} }
@ -361,18 +367,22 @@ unsigned char uart_poll_out(
* *
* @brief Fill FIFO with data * @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 * @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 */ const uint8_t *txData, /* data to transmit */
int size /* number of bytes to send */ int size /* number of bytes to send */
) )
{ {
int i; int i;
for (i = 0; i < size && (INBYTE(LSR(port)) & LSR_THRE) != 0; i++) { for (i = 0; i < size && (INBYTE(LSR(dev)) & LSR_THRE) != 0; i++) {
OUTBYTE(THR(port), txData[i]); OUTBYTE(THR(dev), txData[i]);
} }
return i; return i;
} }
@ -381,18 +391,22 @@ int uart_fifo_fill(int port, /* UART on port to send */
* *
* @brief Read data from FIFO * @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 */ uint8_t *rxData, /* data container */
const int size /* container size */ const int size /* container size */
) )
{ {
int i; int i;
for (i = 0; i < size && (INBYTE(LSR(port)) & LSR_RXRDY) != 0; i++) { for (i = 0; i < size && (INBYTE(LSR(dev)) & LSR_RXRDY) != 0; i++) {
rxData[i] = INBYTE(RDR(port)); rxData[i] = INBYTE(RDR(dev));
} }
return i; return i;
@ -402,148 +416,157 @@ int uart_fifo_read(int port, /* UART to receive from */
* *
* @brief Enable TX interrupt in IER * @brief Enable TX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_tx_enable(int port /* UART to enable Tx void uart_irq_tx_enable(struct device *dev)
interrupt */
)
{ {
OUTBYTE(IER(port), INBYTE(IER(port)) | IER_TBE); OUTBYTE(IER(dev), INBYTE(IER(dev)) | IER_TBE);
} }
/** /**
* *
* @brief Disable TX interrupt in IER * @brief Disable TX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 * @brief Check if Tx IRQ has been raised
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 * @brief Enable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @return N/A
*/ */
void uart_irq_rx_enable(int port /* UART to enable Rx void uart_irq_rx_enable(struct device *dev)
interrupt */
)
{ {
OUTBYTE(IER(port), INBYTE(IER(port)) | IER_RXRDY); OUTBYTE(IER(dev), INBYTE(IER(dev)) | IER_RXRDY);
} }
/** /**
* *
* @brief Disable RX interrupt in IER * @brief Disable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 * @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 * @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 * @brief Enable error interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 * @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 * @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 * @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 * @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 * @brief Update cached contents of IIR
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1 * @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; return 1;
} }
/** /**
*
* @brief Returns UART interrupt number * @brief Returns UART interrupt number
* *
* Returns the IRQ number used by the specified UART 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 * @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 */ #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_DATA 0
#define NSIM_UART_STATUS 1 #define NSIM_UART_STATUS 1
#define DATA_REG(n) (uart[n].regs + NSIM_UART_DATA) #define DEV_CFG(dev) \
#define STATUS_REG(n) (uart[n].regs + NSIM_UART_STATUS) ((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 */ #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 * @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(); int key = irq_lock();
uart[which].regs = init_info->regs; DEV_CFG(dev)->regs = init_info->regs;
irq_unlock(key); irq_unlock(key);
} }
/* /*
* @brief Output a character to serial port * @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 */ /* 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; return c;
} }

View file

@ -85,35 +85,42 @@ struct _Uart {
uint32_t PCellID3; 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 */ /* registers */
#define UARTDR(n) *((volatile uint32_t *)(ports[n].base + 0x000)) #define UARTDR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x000)))
#define UARTSR(n) *((volatile uint32_t *)(ports[n].base + 0x004)) #define UARTSR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x004)))
#define UARTCR(n) *((volatile uint32_t *)(ports[n].base + 0x004)) #define UARTCR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x004)))
#define UARTFR(n) *((volatile uint32_t *)(ports[n].base + 0x018)) #define UARTFR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x018)))
#define UARTILPR(n) *((volatile uint32_t *)(ports[n].base + 0x020)) #define UARTILPR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x020)))
#define UARTIBRD(n) *((volatile uint32_t *)(ports[n].base + 0x024)) #define UARTIBRD(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x024)))
#define UARTFBRD(n) *((volatile uint32_t *)(ports[n].base + 0x028)) #define UARTFBRD(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x028)))
#define UARTLCRH(n) *((volatile uint32_t *)(ports[n].base + 0x02C)) #define UARTLCRH(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x02C)))
#define UARTCTL(n) *((volatile uint32_t *)(ports[n].base + 0x030)) #define UARTCTL(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x030)))
#define UARTIFLS(n) *((volatile uint32_t *)(ports[n].base + 0x034)) #define UARTIFLS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x034)))
#define UARTIM(n) *((volatile uint32_t *)(ports[n].base + 0x038)) #define UARTIM(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x038)))
#define UARTRIS(n) *((volatile uint32_t *)(ports[n].base + 0x03C)) #define UARTRIS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x03C)))
#define UARTMIS(n) *((volatile uint32_t *)(ports[n].base + 0x040)) #define UARTMIS(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x040)))
#define UARTICR(n) *((volatile uint32_t *)(ports[n].base + 0x044)) #define UARTICR(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0x044)))
/* ID registers: UARTPID = UARTPeriphID, UARTPCID = UARTPCellId */ /* ID registers: UARTPID = UARTPeriphID, UARTPCID = UARTPCellId */
#define UARTPID4(n) *((volatile uint32_t *)(ports[n].base + 0xFD0)) #define UARTPID4(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD0)))
#define UARTPID5(n) *((volatile uint32_t *)(ports[n].base + 0xFD4)) #define UARTPID5(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD4)))
#define UARTPID6(n) *((volatile uint32_t *)(ports[n].base + 0xFD8)) #define UARTPID6(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFD8)))
#define UARTPID7(n) *((volatile uint32_t *)(ports[n].base + 0xFDC)) #define UARTPID7(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFDC)))
#define UARTPID0(n) *((volatile uint32_t *)(ports[n].base + 0xFE0)) #define UARTPID0(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE0)))
#define UARTPID1(n) *((volatile uint32_t *)(ports[n].base + 0xFE4)) #define UARTPID1(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE4)))
#define UARTPID2(n) *((volatile uint32_t *)(ports[n].base + 0xFE8)) #define UARTPID2(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFE8)))
#define UARTPID3(n) *((volatile uint32_t *)(ports[n].base + 0xFEC)) #define UARTPID3(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFEC)))
#define UARTPCID0(n) *((volatile uint32_t *)(ports[n].base + 0xFF0)) #define UARTPCID0(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF0)))
#define UARTPCID1(n) *((volatile uint32_t *)(ports[n].base + 0xFF4)) #define UARTPCID1(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF4)))
#define UARTPCID2(n) *((volatile uint32_t *)(ports[n].base + 0xFF8)) #define UARTPCID2(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFF8)))
#define UARTPCID3(n) *((volatile uint32_t *)(ports[n].base + 0xFFC)) #define UARTPCID3(dev) (*((volatile uint32_t *)(DEV_CFG(dev)->base + 0xFFC)))
/* muxed UART registers */ /* muxed UART registers */
#define sr u1._sr /* Read: receive status */ #define sr u1._sr /* Read: receive status */
@ -145,27 +152,25 @@ struct _Uart {
#define UARTMIS_RXMIS 0x00000010 #define UARTMIS_RXMIS 0x00000010
#define UARTMIS_TXMIS 0x00000020 #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 * @brief Set the baud rate
* *
* This routine set the given baud rate for the UART. * 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 * @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; uint32_t brdi, brdf, div, rem;
/* upon reset, the system clock uses the intenal OSC @ 12MHz */ /* upon reset, the system clock uses the intenal OSC @ 12MHz */
div = (16 * baudrate); div = (16 * baudrate);
@ -190,12 +195,14 @@ static void baudrateSet(int port, uint32_t baudrate, uint32_t sysClkFreqInHz)
* *
* This routine enables the given UART. * This routine enables the given UART.
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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; pUart->ctl |= UARTCTL_UARTEN;
} }
@ -206,12 +213,14 @@ static inline void enable(int port)
* *
* This routine disables the given UART. * This routine disables the given UART.
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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; 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. * 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 * @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; 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. * This routine is called to reset the chip in a quiescent state.
* It is assumed that this function is called only once per UART. * 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 * @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 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); dev_cfg->int_pri = init_info->int_pri;
baudrateSet(port, init_info->baud_rate, init_info->sys_clk_freq);
lineControlDefaultsSet(port); disable(dev);
enable(port); 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. * 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 * @return 0 if ready to transmit, 1 otherwise
*/ */
static int pollTxReady(struct device *dev)
static int pollTxReady(int port)
{ {
volatile struct _Uart *pUart = ports[port].base; volatile struct _Uart *pUart = UART_STRUCT(dev);
return (pUart->fr & UARTFR_TXFE); return (pUart->fr & UARTFR_TXFE);
} }
@ -290,14 +306,17 @@ static int pollTxReady(int port)
* *
* @brief Poll the device for input. * @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. * @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 */ 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) if (pUart->fr & UARTFR_RXFE)
return (-1); 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 * Checks if the transmitter is empty. If empty, a character is written to
* the data register. * the data register.
* *
* @param dev UART device struct (of type struct uart_device_config_t)
* @param c Character to send
*
* @return sent character * @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 */ /* send a character */
@ -335,15 +357,19 @@ unsigned char uart_poll_out(int port, unsigned char c)
* *
* @brief Fill FIFO with data * @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 * @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 */ const uint8_t *txData, /* data to transmit */
int len /* number of bytes to send */ 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; uint8_t numTx = 0;
while ((len - numTx > 0) && ((pUart->fr & UARTFR_TXFF) == 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 * @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 * @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 */ uint8_t *rxData, /* data container */
const int size /* container size */ const int size /* container size */
) )
{ {
volatile struct _Uart *pUart = ports[port].base; volatile struct _Uart *pUart = UART_STRUCT(dev);
uint8_t numRx = 0; uint8_t numRx = 0;
while ((size - numRx > 0) && ((pUart->fr & UARTFR_RXFE) == 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 * @brief Enable TX interrupt
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 = static uint8_t first_time =
1; /* used to allow the first transmission */ 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_ibrd; /* saved UARTIBRD (integer baud rate) register */
uint32_t saved_fbrd; /* saved UARTFBRD (fractional 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) { if (first_time) {
/* /*
@ -409,7 +440,7 @@ void uart_irq_tx_enable(int port /* UART to enable Tx interrupt */
saved_fbrd = pUart->fbrd; saved_fbrd = pUart->fbrd;
/* send a character with default settings via loopback */ /* send a character with default settings via loopback */
disable(port); disable(dev);
pUart->fbrd = 0; pUart->fbrd = 0;
pUart->ibrd = 1; pUart->ibrd = 1;
pUart->lcrh = 0; 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 */ /* restore control and baud rate settings */
disable(port); disable(dev);
pUart->ibrd = saved_ibrd; pUart->ibrd = saved_ibrd;
pUart->fbrd = saved_fbrd; pUart->fbrd = saved_fbrd;
lineControlDefaultsSet(port); lineControlDefaultsSet(dev);
pUart->ctl = saved_ctl; 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 * @brief Disable TX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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; 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 * @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 * @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); 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 * @brief Enable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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; 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 * @brief Disable RX interrupt in IER
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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; 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 * @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 * @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); 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 * @brief Enable error interrupts
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 | pUart->im |= (UARTTIM_RTIM | UARTTIM_FEIM | UARTTIM_PEIM |
UARTTIM_BEIM | UARTTIM_OEIM); UARTTIM_BEIM | UARTTIM_OEIM);
@ -525,13 +562,14 @@ void uart_irq_err_enable(int port /* UART to enable interrupts for */
* *
* @brief Disable error interrupts * @brief Disable error interrupts
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return N/A * @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 | pUart->im &= ~(UARTTIM_RTIM | UARTTIM_FEIM | UARTTIM_PEIM |
UARTTIM_BEIM | UARTTIM_OEIM); 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 * @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 * @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 */ /* Look only at Tx and Rx data interrupt flags */
return ((pUart->mis & (UARTMIS_RXMIS | UARTMIS_TXMIS)) ? 1 : 0); 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 * @brief Update IRQ status
* *
* @param dev UART device struct (of type struct uart_device_config_t)
*
* @return always 1 * @return always 1
*/ */
int uart_irq_update(int port) int uart_irq_update(struct device *dev)
{ {
return 1; return 1;
} }
@ -571,12 +612,13 @@ int uart_irq_update(int port)
* *
* Returns the IRQ number used by the specified UART 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 * @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 */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */

View file

@ -44,7 +44,7 @@
#include <simple/uart.h> #include <simple/uart.h>
#include <misc/printk.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 uint8_t *recv_buf;
static size_t recv_buf_len; 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, IRQ_CONNECT_STATIC(uart_simple, CONFIG_UART_SIMPLE_IRQ,
CONFIG_UART_SIMPLE_INT_PRI, uart_simple_isr, 0); 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); uart_init(uart, info);

View file

@ -205,6 +205,11 @@ typedef volatile struct {
*/ */
} K20_UART_t; /* K20 Microntroller UART module */ } 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, static ALWAYS_INLINE void _k20UartBaudRateSet(K20_UART_t *uart_p,
uint32_t clkFreq, uint32_t clkFreq,
uint32_t baudRate) uint32_t baudRate)

View file

@ -37,37 +37,63 @@
extern "C" { extern "C" {
#endif #endif
/* generic UART info structure */ #include <device.h>
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 */
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 */ /* console I/O functions */
int uart_poll_in(int port, unsigned char *pChar); int uart_poll_in(struct device *dev, unsigned char *p_char);
unsigned char uart_poll_out(int port, unsigned char outChar); unsigned char uart_poll_out(struct device *dev, unsigned char out_char);
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
/* interrupt driven I/O functions */ /* interrupt driven I/O functions */
int uart_fifo_fill(int port, const uint8_t *txData, int len); int uart_fifo_fill(struct device *dev, const uint8_t *txData, int len);
int uart_fifo_read(int port, uint8_t *rxData, const int size); int uart_fifo_read(struct device *dev, uint8_t *rxData, const int size);
void uart_irq_tx_enable(int port); void uart_irq_tx_enable(struct device *dev);
void uart_irq_tx_disable(int port); void uart_irq_tx_disable(struct device *dev);
int uart_irq_tx_ready(int port); int uart_irq_tx_ready(struct device *dev);
void uart_irq_rx_enable(int port); void uart_irq_rx_enable(struct device *dev);
void uart_irq_rx_disable(int port); void uart_irq_rx_disable(struct device *dev);
int uart_irq_rx_ready(int port); int uart_irq_rx_ready(struct device *dev);
void uart_irq_err_enable(int port); void uart_irq_err_enable(struct device *dev);
void uart_irq_err_disable(int port); void uart_irq_err_disable(struct device *dev);
int uart_irq_is_pending(int port); int uart_irq_is_pending(struct device *dev);
int uart_irq_update(int port); int uart_irq_update(struct device *dev);
unsigned int uart_irq_get(int port); unsigned int uart_irq_get(struct device *dev);
void uart_generic_info_init(struct uart_init_info *p_info); void uart_generic_info_init(struct uart_init_info *p_info);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

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