Re: RFC: Counter driver API
Tseng, Kuo-Lang <kuo-lang.tseng@...>
toggle quoted messageShow quoted text
-----Original Message-----The AON counter and periodic timer on Quark are running off the 32,768Hz clock (RTC clock). By timebase, do you mean that? Yes, this can be an enhancement for future (as currently it is not supported in existing SoC to set the timebase). Yes, this can be added./**Do we need a write() function for future proofing? };features.
|
|
Re: RFC [2/3] - SoC, CPU LPS, Tickless idle and Device power management
Dirk Brandewie <dirk.j.brandewie@...>
On 02/29/2016 01:59 AM, Thomas, Ramesh wrote:
***These are implemented and under review***There is a basic disconnects between my original RFC and this one. In mine all drivers are required to provide an implementation of suspend/resume even if it is null. All the information for the system to interact with the driver is contained in the device structure. The new version of DEVICE_INIT() is there to keep everything compiling while *all* the drivers are updated to satisfy the requirement to support suspend/resume. Once that is done DEVICE_INIT_PM() turns into DEVICE_INIT() with a tree wide sed script. Moving *all* the drivers will be moderately painful but now is the right time to do it before we get a bunch more drivers added to the tree. To be honest if I had thought about it more when I was defining the device model we would no be here :-( --Dirk Following are the goals for providing this infrastructure:
|
|
Re: RFC: Counter driver API
Dirk Brandewie <dirk.j.brandewie@...>
On 02/26/2016 12:29 PM, Tseng, Kuo-Lang wrote:
Hi,I think it might be useful to add a function to retrieve the timebase of the counter. ATM the developer just needs to *know* what is being counted. A function to set the timebase may be needed in the future for IP blocks that don't have a fixed timebase/tick rate. /**Do we need a write() function for future proofing? The counter_input structure can be something like below:counter_init? uint32_t initial_value;countdown_value? void (*callback)(void);void (*callback)(void *context); void *context; lets the app pass in their context if needed. };
|
|
Re: STM32F103x port
Dirk Brandewie <dirk.j.brandewie@...>
On 02/29/2016 02:26 PM, Kalowsky, Daniel wrote:
-----Original Message----- Having thought about it for 10 seconds it seems reasonable :-) To theI'm not opposed to this.First suggestion, create an arch/arm/soc/stm32, and use the Kconfig toMakes sense. I think we should also add another 'MCU family' level of greatest extent reasonable please avoid link time binding of SOC specifc code into the generic stm32 code. We don't want to the next guy to wonder which init() function is called. If it turns out to painful we can "move the deck chairs around later" (tm) IMO having a soc specific defconfig would be great too. Right now there areDepending upon what you see going into such a file, this is a relatively reasonable idea.
|
|
Re: [RFC] uart: add ISR callback mechanism for UART drivers
Daniel Leung <daniel.leung@...>
On Tue, Mar 01, 2016 at 05:14:12PM +0200, Johan Hedberg wrote:
Hi Daniel,Thanks for letting me know about this. I will modify and re-submit. If anyone notices anything missing, please let me know. ----- Daniel Leung
|
|
Re: STM32F103x port
Pawel Wodnicki <root@...>
Hi,
I have been working with Dan's stm32 patch to add support for stm32f4xx and just wanted to share couple of thoughts. https://gerrit.zephyrproject.org/r/#/c/209/ I would second the idea of adding additional level of hierarchy under st_stm32 soc for functionality specific to the line of ST MCU's. Just looking at the STM32F chips there is 6 variants not even including STM32L. Organizing soc folders to reflect that hierarchy would help dealing with the variability within the STM32 line of mcu's without cluttering arch/arm/soc/ folder. arch/arm/soc/st_stm32/ arch/arm/soc/st_stm32/stm32f0xx/ arch/arm/soc/st_stm32/stm32f1xx/ arch/arm/soc/st_stm32/stm32f2xx/ arch/arm/soc/st_stm32/stm32f2xx/ arch/arm/soc/st_stm32/stm32f4xx/ arch/arm/soc/st_stm32/stm32f7xx/ Common functionality could be implemented at the arch/arm/soc/st_stm32/ level, ie: arch/arm/soc/st_stm32/soc.c:static int st_stm32_init(struct device *arg) But when needed SOC api could be structured in a hierarchical way, ie: arch/arm/soc/st_stm32/soc.c:void clock_init(void) arch/arm/soc/st_stm32/stm32f1xx/soc.c:void clock_init_stm32f1xx(void) .. arch/arm/soc/st_stm32/stm32f4xx/soc.c:void clock_init_stm32f4xx(void) As for drivers for specific stm32 peripherals some like the RCC (Reset & Clock Control) could be handled at the st_stm32 soc top level with #ifdefs but there are some peripherals that use different versions of the hardware IP (GPIO is a good example) and would be easier to handle at the level specific to the MCU soc. Cheers, Pawel Wodnicki
|
|
Re: RFC[1/2] Common logging infrastructure and API
Chereau, Fabien <fabien.chereau@...>
Hi,
toggle quoted messageShow quoted text
-----Original Message-----Indeed, my point was just to make sure at API level that such custom implementations are pluggable. incoming logs in a circular buffer in RAM (on both master and slave). This- Finally, another important feature we implemented is the buffering of
|
|
Re: RFC[1/2] Common logging infrastructure and API
Tomasz Bursztyka
Hi Luiz,
I don't see anything we could do about that in this logging API.- Another feature which is critical for Curie, is the support of multi-core logging. One core is the master outputting the log on the log_backend while other slaves cores send their logs to the master using an IPC mechanism. Each log message carries the information from which core it originates, + a unified timestamp.-1, this depends on the hardware architecture besides one can write a If there is something to be done, let's see it in another patch. Nanokernel could get it, it would run in low prio fiber and that's it.- Finally, another important feature we implemented is the buffering of incoming logs in a circular buffer in RAM (on both master and slave). This allow very short log time to avoid delaying the caller of the log function. The logs are finally output on the log backend in a low priority task, which reads from the circular buffer. In case there are too many incoming logs, some logs are lost instead of blocking the program execution.Provided the message order is keep that is probably ok, but if we do Imo, let's not bother fixing this right now in this API. This goes separately. (as I said, instead of having printk/printf we could have a new sys_log() functions that could act as a log buffering proxy, fully optional etc...) Tomasz
|
|
Re: RFC[1/2] Common logging infrastructure and API
Luiz Augusto von Dentz
Hi Fabian,
On Tue, Mar 1, 2016 at 12:40 PM, Chereau, Fabien <fabien.chereau(a)intel.com> wrote: Hello,Which is why I commented that having log level is not really necessary, perhaps this is even misleading since it should always be selected at build-time not runtime where perhaps the use of levels makes sense. - Another feature which is critical for Curie, is the support of multi-core logging. One core is the master outputting the log on the log_backend while other slaves cores send their logs to the master using an IPC mechanism. Each log message carries the information from which core it originates, + a unified timestamp.-1, this depends on the hardware architecture besides one can write a driver to just proxy the logs. - Finally, another important feature we implemented is the buffering of incoming logs in a circular buffer in RAM (on both master and slave). This allow very short log time to avoid delaying the caller of the log function. The logs are finally output on the log backend in a low priority task, which reads from the circular buffer. In case there are too many incoming logs, some logs are lost instead of blocking the program execution.Provided the message order is keep that is probably ok, but if we do add the timestamp support then it needs to be before it enters these buffers. Anyway we may add timestamp support for net_buf at some point. Btw, having it as a task probably limits this to microkernel only doesn't it?
|
|
Re: [RFC] uart: add ISR callback mechanism for UART drivers
Hi Daniel,
On Mon, Feb 29, 2016, Daniel Leung wrote: arch/arc/soc/quark_se_ss/Kconfig | 4 -It seems you've missed at least drivers/nble/uart.c that uses both IRQ_CONNECT and irq_enable. Otherwise the change looks fine to me. Johan
|
|
Re: [RFC] uart: add ISR callback mechanism for UART drivers
Dirk Brandewie <dirk.j.brandewie@...>
On 02/29/2016 03:51 PM, Daniel Leung wrote:
The peripherals utilizing UART were required to register their ownAcked-by: Dirk Brandewie <dirk.j.brandewie(a)intel.com> ---
|
|
Zephyr 1.1 merge window closes today
Nashif, Anas
Hi,
The last month has been very busy. Zephyr was launched, we had 2 releases and a lot of changes to address the launch of the project. Sorry about the late notice. Up to the release of the project we have followed a monthly release cycle with a 2-3 development phase (merge window) and a stabilisation period of ~ 1 week with a release at the end of the month. On the project level, we have started talking about the release cadence of the project and how we do releases and testing. While we wait for this to be finalised and until we reach an agreement on a new release cadence, we will continue with the existing release cadence of monthly releases. Today we will go through all remaining gerrit submissions and merge any major changes and fixes and tag rc1 of the 1.1 release. After the tagging of rc1 we will only accept and merge bug fixes. This stabilisation phase will be shorter than usual. Out goal is to get stable release by end of this week to get back on our monthly schedule. Comments, concerns or questions? Anas
|
|
Re: RFC - arm-gcc-embedded Toolchain Support
Nashif, Anas
Hi Hugo,
On 29 Feb 2016, at 18:18, Hugo Vincent <hugo.vincent(a)gmail.com> wrote:Yes, please do submit. Regards, Anas Thanks,
|
|
Re: RFC[1/2] Common logging infrastructure and API
Tomasz Bursztyka
Hi Fabien,
- Finally, another important feature we implemented is the buffering of incoming logs in a circular buffer in RAM (on both master and slave). This allow very short log time to avoid delaying the caller of the log function. The logs are finally output on the log backend in a low priority task, which reads from the circular buffer. In case there are too many incoming logs, some logs are lost instead of blocking the program execution.Very good point. We also experienced it with networking drivers where debugging in the middle or RX/TX just kills timing. This would need to be addressed, but besides this log macros API. Maybe introducing a sys_log() which would be a possible LOG_FN, such sys_log() would implement the deferred logging. It could be optional (on some targets, it may be difficult to get some space for such buffer). Tomasz
|
|
Re: RFC[1/2] Common logging infrastructure and API
Chereau, Fabien <fabien.chereau@...>
Hello,
FYI, in thunderdome we have also created a log system solving some of the problems you mention in your RFC. Here are my 2 cents following our experience: - In our implementation we now support only a global log level (INFO, WARNING, ERROR) + a special DEBUG level which is activated at compile time for each module separately. Originally we also had a log level per module but it quickly proved to be mostly unused by the users, while adding some complexity (conflicts between global log levels and per module log level), so we removed it, also to save space. - Another feature which is critical for Curie, is the support of multi-core logging. One core is the master outputting the log on the log_backend while other slaves cores send their logs to the master using an IPC mechanism. Each log message carries the information from which core it originates, + a unified timestamp. - Finally, another important feature we implemented is the buffering of incoming logs in a circular buffer in RAM (on both master and slave). This allow very short log time to avoid delaying the caller of the log function. The logs are finally output on the log backend in a low priority task, which reads from the circular buffer. In case there are too many incoming logs, some logs are lost instead of blocking the program execution. Fabien ________________________________________ From: Kalowsky, Daniel [daniel.kalowsky(a)intel.com] Sent: Monday, February 29, 2016 18:12 To: Nashif, Anas; Saucedo Tejada, Genaro; devel(a)lists.zephyrproject.org Subject: [devel] Re: Re: RFC[1/2] Common logging infrastructure and API -----Original Message-----So this works for a simple case. Can you expand on this for a more complex case? For example, let's take debugging the Galileo 2 pinmux, which has dependencies on I2C, GPIO, and the Pinmux. How would you setup the DOMAINs value then and parse it? Just use LOG_DOMAIN, no need to abbreviate this
|
|
[RFC] uart: add ISR callback mechanism for UART drivers
Daniel Leung <daniel.leung@...>
The peripherals utilizing UART were required to register their own
ISR rountines. This means that all those peripherals drivers need to know which IRQ line is attached to a UART controller, and all the other config values required to register a ISR. This causes scalibility issue as every board and peripherals have to define those values. Another reason for this patch is to support virtual serial ports. Virtual serial ports do not have physical interrupt lines to attach, and thus would not work. This patch adds a simple callback mechanism, which calls a function when UART interrupts are triggered. The low level plumbing still needs to be done by the peripheral drivers, as these drivers may need to access low level capability of UART to function correctly. This simply moves the interrupt setup into the UART drivers themselves. By doing this, the peripheral drivers do not need to know all the config values to properly setup the interrupts and attaching the ISR. One drawback is that this adds to the interrupt latency. Note that this patch breaks backward compatibility in terms of setting up interrupt for UART controller. How to use UART is still the same. This also addresses the following issues: () UART driver for Atmel SAM3 currently does not support interrupts. So remove the code from vector table. This will be updated when there is interrupt support for the driver. () Corrected some config options for Stellaris UART driver. This was tested with samples/shell on Arduino 101, and on QEMU (Cortex-M3 and x86). Origin: Origin Change-Id: Ib4593d8ccd711f4e97d388c7293205d213be1aec Signed-off-by: Daniel Leung <daniel.leung(a)intel.com> --- arch/arc/soc/quark_se_ss/Kconfig | 4 - arch/arm/soc/atmel_sam3/Kconfig | 4 - arch/arm/soc/atmel_sam3/irq_vector_table.c | 16 --- arch/arm/soc/fsl_frdm_k64f/Kconfig | 8 -- arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c | 51 +++++++--- arch/arm/soc/ti_lm3s6965/Kconfig | 20 ++-- arch/arm/soc/ti_lm3s6965/irq_vector_table.c | 39 ++++--- arch/x86/soc/atom/Kconfig | 12 --- arch/x86/soc/ia32/Kconfig | 12 --- arch/x86/soc/quark_d2000/Kconfig | 12 --- arch/x86/soc/quark_se/Kconfig | 8 -- arch/x86/soc/quark_x1000/Kconfig | 8 -- boards/arduino_101/Kconfig | 4 - drivers/bluetooth/Kconfig | 14 --- drivers/bluetooth/h4.c | 7 +- drivers/bluetooth/h5.c | 8 +- drivers/console/Kconfig | 28 ------ drivers/console/uart_console.c | 7 +- drivers/console/uart_pipe.c | 8 +- drivers/serial/uart_k20.c | 140 ++++++++++++++++++++++++++ drivers/serial/uart_k20.h | 26 +++++ drivers/serial/uart_ns16550.c | 79 +++++++++++++++ drivers/serial/uart_stellaris.c | 103 +++++++++++++++++++ drivers/serial/uart_stellaris.h | 26 +++++ include/drivers/console/uart_console.h | 2 - include/drivers/console/uart_pipe.h | 9 -- include/uart.h | 41 ++++++++ 27 files changed, 487 insertions(+), 209 deletions(-) create mode 100644 drivers/serial/uart_k20.h create mode 100644 drivers/serial/uart_stellaris.h diff --git a/arch/arc/soc/quark_se_ss/Kconfig b/arch/arc/soc/quark_se_ss/Kconfig index d6d1b90..827cafa 100644 --- a/arch/arc/soc/quark_se_ss/Kconfig +++ b/arch/arc/soc/quark_se_ss/Kconfig @@ -161,10 +161,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 42 -config UART_CONSOLE_IRQ_PRI - default 1 endif diff --git a/arch/arm/soc/atmel_sam3/Kconfig b/arch/arm/soc/atmel_sam3/Kconfig index a7cf5cc..9b880e9 100644 --- a/arch/arm/soc/atmel_sam3/Kconfig +++ b/arch/arm/soc/atmel_sam3/Kconfig @@ -148,10 +148,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 8 -config UART_CONSOLE_IRQ_PRI - default 3 endif # UART_CONSOLE diff --git a/arch/arm/soc/atmel_sam3/irq_vector_table.c b/arch/arm/soc/atmel_sam3/irq_vector_table.c index 24b1dcd..5f53773 100644 --- a/arch/arm/soc/atmel_sam3/irq_vector_table.c +++ b/arch/arm/soc/atmel_sam3/irq_vector_table.c @@ -32,11 +32,6 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) -#include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -50,20 +45,9 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) -{ - uart_console_isr(NULL); - _IntExit(); -} -#endif /* CONFIG_CONSOLE_HANDLER */ - /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif }; #endif /* CONFIG_SW_ISR_TABLE */ diff --git a/arch/arm/soc/fsl_frdm_k64f/Kconfig b/arch/arm/soc/fsl_frdm_k64f/Kconfig index 7ffec5e..7a1fa30 100644 --- a/arch/arm/soc/fsl_frdm_k64f/Kconfig +++ b/arch/arm/soc/fsl_frdm_k64f/Kconfig @@ -141,10 +141,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 31 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -152,10 +148,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 33 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c b/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c index d36abca..8c02ec4 100644 --- a/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c +++ b/arch/arm/soc/fsl_frdm_k64f/irq_vector_table.c @@ -31,15 +31,8 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) #include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - -#if defined(CONFIG_BLUETOOTH_UART) -#include <soc.h> -#include <bluetooth/uart.h> -#endif /* CONFIG_BLUETOOTH_UART */ +#include <serial/uart_k20.h> extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -54,10 +47,34 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +static void _uart_k20_0_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_0)); + _IntExit(); +} + +static void _uart_k20_1_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_1)); + _IntExit(); +} + +static void _uart_k20_2_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_2)); + _IntExit(); +} + +static void _uart_k20_3_isr(void) +{ + uart_k20_isr(DEVICE_GET(uart_k20_3)); + _IntExit(); +} + +static void _uart_k20_4_isr(void) { - uart_console_isr(NULL); + uart_k20_isr(DEVICE_GET(uart_k20_4)); _IntExit(); } #endif /* CONFIG_CONSOLE_HANDLER */ @@ -73,11 +90,13 @@ static void _bt_uart_isr(void) /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif -#if defined(CONFIG_BLUETOOTH_UART) - [CONFIG_BLUETOOTH_UART_IRQ] = _bt_uart_isr, + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + [CONFIG_UART_K20_PORT_0_IRQ] = _uart_k20_0_isr, + [CONFIG_UART_K20_PORT_1_IRQ] = _uart_k20_1_isr, + [CONFIG_UART_K20_PORT_2_IRQ] = _uart_k20_2_isr, + [CONFIG_UART_K20_PORT_3_IRQ] = _uart_k20_3_isr, + [CONFIG_UART_K20_PORT_4_IRQ] = _uart_k20_4_isr, #endif }; diff --git a/arch/arm/soc/ti_lm3s6965/Kconfig b/arch/arm/soc/ti_lm3s6965/Kconfig index a9b32a2..fa643ba 100644 --- a/arch/arm/soc/ti_lm3s6965/Kconfig +++ b/arch/arm/soc/ti_lm3s6965/Kconfig @@ -66,7 +66,9 @@ if UART_STELLARIS_PORT_0 config UART_STELLARIS_PORT_0_BASE_ADDR default 0x4000C000 config UART_STELLARIS_PORT_0_IRQ - default 6 + default 5 +config UART_STELLARIS_PORT_0_IRQ_PRI + default 3 config UART_STELLARIS_PORT_0_BAUD_RATE default 115200 config UART_STELLARIS_PORT_0_CLK_FREQ @@ -81,6 +83,8 @@ config UART_STELLARIS_PORT_1_BASE_ADDR default 0x4000D000 config UART_STELLARIS_PORT_1_IRQ default 6 +config UART_STELLARIS_PORT_1_IRQ_PRI + default 3 config UART_STELLARIS_PORT_1_BAUD_RATE default 115200 config UART_STELLARIS_PORT_1_CLK_FREQ @@ -94,6 +98,8 @@ config UART_STELLARIS_PORT_2_BASE_ADDR default 0x4000E000 config UART_STELLARIS_PORT_2_IRQ default 33 +config UART_STELLARIS_PORT_2_IRQ_PRI + default 3 config UART_STELLARIS_PORT_2_BAUD_RATE default 115200 config UART_STELLARIS_PORT_2_CLK_FREQ @@ -106,10 +112,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 5 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -117,10 +119,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 6 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -128,10 +126,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_2" -config UART_PIPE_IRQ - default 33 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/arm/soc/ti_lm3s6965/irq_vector_table.c b/arch/arm/soc/ti_lm3s6965/irq_vector_table.c index d36abca..4d931f6 100644 --- a/arch/arm/soc/ti_lm3s6965/irq_vector_table.c +++ b/arch/arm/soc/ti_lm3s6965/irq_vector_table.c @@ -31,15 +31,8 @@ #include <toolchain.h> #include <sections.h> -#if defined(CONFIG_CONSOLE_HANDLER) #include <soc.h> -#include <console/uart_console.h> -#endif /* CONFIG_CONSOLE_HANDLER */ - -#if defined(CONFIG_BLUETOOTH_UART) -#include <soc.h> -#include <bluetooth/uart.h> -#endif /* CONFIG_BLUETOOTH_UART */ +#include <serial/uart_stellaris.h> extern void _isr_wrapper(void); typedef void (*vth)(void); /* Vector Table Handler */ @@ -54,30 +47,34 @@ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { extern void _irq_spurious(void); -#if defined(CONFIG_CONSOLE_HANDLER) -static void _uart_console_isr(void) +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +static void _uart_stellaris_port_0_isr(void) +{ + uart_stellaris_isr(DEVICE_GET(uart_stellaris0)); + _IntExit(); +} + +static void _uart_stellaris_port_1_isr(void) { - uart_console_isr(NULL); + uart_stellaris_isr(DEVICE_GET(uart_stellaris1)); _IntExit(); } -#endif /* CONFIG_CONSOLE_HANDLER */ -#if defined(CONFIG_BLUETOOTH_UART) -static void _bt_uart_isr(void) +static void _uart_stellaris_port_2_isr(void) { - bt_uart_isr(NULL); + uart_stellaris_isr(DEVICE_GET(uart_stellaris2)); _IntExit(); } -#endif /* CONFIG_BLUETOOTH_UART */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ /* placeholders: fill with real ISRs */ vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = { [0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious, -#if defined(CONFIG_CONSOLE_HANDLER) - [CONFIG_UART_CONSOLE_IRQ] = _uart_console_isr, -#endif -#if defined(CONFIG_BLUETOOTH_UART) - [CONFIG_BLUETOOTH_UART_IRQ] = _bt_uart_isr, + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + [UART_STELLARIS_PORT_0_IRQ] = _uart_stellaris_port_0_isr, + [UART_STELLARIS_PORT_1_IRQ] = _uart_stellaris_port_1_isr, + [UART_STELLARIS_PORT_2_IRQ] = _uart_stellaris_port_2_isr, #endif }; diff --git a/arch/x86/soc/atom/Kconfig b/arch/x86/soc/atom/Kconfig index c9b7f5f..f085985 100644 --- a/arch/x86/soc/atom/Kconfig +++ b/arch/x86/soc/atom/Kconfig @@ -105,10 +105,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 4 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -116,10 +112,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 3 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -127,10 +119,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 3 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/ia32/Kconfig b/arch/x86/soc/ia32/Kconfig index f9916ba..6025697 100644 --- a/arch/x86/soc/ia32/Kconfig +++ b/arch/x86/soc/ia32/Kconfig @@ -105,10 +105,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 4 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -116,10 +112,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 3 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -127,10 +119,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 3 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_d2000/Kconfig b/arch/x86/soc/quark_d2000/Kconfig index da8a1be..5d11114 100644 --- a/arch/x86/soc/quark_d2000/Kconfig +++ b/arch/x86/soc/quark_d2000/Kconfig @@ -127,10 +127,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_0" -config UART_CONSOLE_IRQ - default 8 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -138,10 +134,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 6 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif @@ -149,10 +141,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default "UART_1" -config UART_PIPE_IRQ - default 6 -config UART_PIPE_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_se/Kconfig b/arch/x86/soc/quark_se/Kconfig index a17110d..8922f2d 100644 --- a/arch/x86/soc/quark_se/Kconfig +++ b/arch/x86/soc/quark_se/Kconfig @@ -376,10 +376,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 6 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -387,10 +383,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 38 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/arch/x86/soc/quark_x1000/Kconfig b/arch/x86/soc/quark_x1000/Kconfig index ed7514d..3357d2c 100644 --- a/arch/x86/soc/quark_x1000/Kconfig +++ b/arch/x86/soc/quark_x1000/Kconfig @@ -343,10 +343,6 @@ if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME default "UART_1" -config UART_CONSOLE_IRQ - default 17 -config UART_CONSOLE_IRQ_PRI - default 3 endif @@ -354,10 +350,6 @@ if BLUETOOTH_UART config BLUETOOTH_UART_ON_DEV_NAME default "UART_1" -config BLUETOOTH_UART_IRQ - default 17 -config BLUETOOTH_UART_IRQ_PRI - default 3 endif diff --git a/boards/arduino_101/Kconfig b/boards/arduino_101/Kconfig index 8d047dd..dafed3d 100644 --- a/boards/arduino_101/Kconfig +++ b/boards/arduino_101/Kconfig @@ -22,10 +22,6 @@ if UART_PIPE config UART_PIPE_ON_DEV_NAME default UART_NS16550_PORT_1_NAME -config UART_PIPE_IRQ - default UART_NS16550_PORT_1_IRQ -config UART_PIPE_IRQ_PRI - default UART_NS16550_PORT_1_IRQ_PRI endif diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index c48e3f5..879dd47 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -71,20 +71,6 @@ config BLUETOOTH_UART_ON_DEV_NAME This option specifies the name of UART device to be used for Bluetooth. -config BLUETOOTH_UART_IRQ - int "IRQ of UART Device for Bluetooth" - depends on BLUETOOTH_UART - help - This option specifies the IRQ of UART device to be used - for Bluetooth. - -config BLUETOOTH_UART_IRQ_PRI - int "IRQ Priority of UART Device for Bluetooth" - depends on BLUETOOTH_UART - help - This option specifies the IRQ priority of UART device to be used - for Bluetooth. - # Headroom that the driver needs for sending and receiving buffers. # Add a new 'default' entry for each new driver. diff --git a/drivers/bluetooth/h4.c b/drivers/bluetooth/h4.c index 6fbf7f2..0fc3abd 100644 --- a/drivers/bluetooth/h4.c +++ b/drivers/bluetooth/h4.c @@ -123,7 +123,7 @@ static struct net_buf *h4_acl_recv(int *remaining) return buf; } -void bt_uart_isr(void *unused) +static void bt_uart_isr(struct device *unused) { static struct net_buf *buf; static int remaining; @@ -223,9 +223,6 @@ static int h4_open(void) uart_irq_rx_disable(h4_dev); uart_irq_tx_disable(h4_dev); - IRQ_CONNECT(CONFIG_BLUETOOTH_UART_IRQ, CONFIG_BLUETOOTH_UART_IRQ_PRI, - bt_uart_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_BLUETOOTH_UART_IRQ); /* Drain the fifo */ while (uart_irq_rx_ready(h4_dev)) { @@ -234,6 +231,8 @@ static int h4_open(void) uart_fifo_read(h4_dev, &c, 1); } + uart_irq_callback_set(h4_dev, bt_uart_isr); + uart_irq_rx_enable(h4_dev); return 0; diff --git a/drivers/bluetooth/h5.c b/drivers/bluetooth/h5.c index 5a6a4ba..562b0e7 100644 --- a/drivers/bluetooth/h5.c +++ b/drivers/bluetooth/h5.c @@ -445,7 +445,7 @@ static void h5_process_complete_packet(uint8_t *hdr) } } -void bt_uart_isr(void *unused) +static void bt_uart_isr(struct device *unused) { static int remaining; uint8_t byte; @@ -748,10 +748,6 @@ static int h5_open(void) uart_irq_rx_disable(h5_dev); uart_irq_tx_disable(h5_dev); - IRQ_CONNECT(CONFIG_BLUETOOTH_UART_IRQ, CONFIG_BLUETOOTH_UART_IRQ_PRI, - bt_uart_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_BLUETOOTH_UART_IRQ); - /* Drain the fifo */ while (uart_irq_rx_ready(h5_dev)) { unsigned char c; @@ -759,6 +755,8 @@ static int h5_open(void) uart_fifo_read(h5_dev, &c, 1); } + uart_irq_callback_set(h5_dev, bt_uart_isr); + h5_init(); uart_irq_rx_enable(h5_dev); diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index c8dc686..0638f70 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -73,20 +73,6 @@ config UART_CONSOLE_ON_DEV_NAME This option specifies the name of UART device to be used for UART console. -config UART_CONSOLE_IRQ - int "IRQ of UART Device for UART Console" - depends on UART_CONSOLE - help - This option specifies the IRQ of UART device to be used for - UART console. - -config UART_CONSOLE_IRQ_PRI - int "IRQ of UART Device for UART Console" - depends on UART_CONSOLE - help - This option specifies the IRQ priorityof UART device to be - used for UART console. - config UART_CONSOLE_PRIORITY int prompt "Init priority" @@ -160,18 +146,4 @@ config UART_PIPE_ON_DEV_NAME This option specifies the name of UART device to be used for pipe UART. -config UART_PIPE_IRQ - int "IRQ for pipe UART" - depends on UART_PIPE - help - This option specifies the IRQ of UART device to be used - for pipe UART. - -config UART_PIPE_IRQ_PRI - int "IRQ Priority for pipe UART" - depends on UART_PIPE - help - This option specifies the IRQ priority of UART device - to be used for pipe UART. - endif diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c index 762b7aa..72c5631 100644 --- a/drivers/console/uart_console.c +++ b/drivers/console/uart_console.c @@ -278,7 +278,7 @@ ansi_cmd: atomic_clear_bit(&esc_state, ESC_ANSI); } -void uart_console_isr(void *unused) +void uart_console_isr(struct device *unused) { ARG_UNUSED(unused); @@ -373,9 +373,8 @@ static void console_input_init(void) uart_irq_rx_disable(uart_console_dev); uart_irq_tx_disable(uart_console_dev); - IRQ_CONNECT(CONFIG_UART_CONSOLE_IRQ, CONFIG_UART_CONSOLE_IRQ_PRI, - uart_console_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_UART_CONSOLE_IRQ); + + uart_irq_callback_set(uart_console_dev, uart_console_isr); /* Drain the fifo */ while (uart_irq_rx_ready(uart_console_dev)) { diff --git a/drivers/console/uart_pipe.c b/drivers/console/uart_pipe.c index f56f9b1..c8c89ae 100644 --- a/drivers/console/uart_pipe.c +++ b/drivers/console/uart_pipe.c @@ -36,7 +36,7 @@ static size_t recv_buf_len; static uart_pipe_recv_cb app_cb; static size_t recv_off; -void uart_pipe_isr(void *unused) +static void uart_pipe_isr(struct device *unused) { ARG_UNUSED(unused); @@ -77,10 +77,6 @@ static void uart_pipe_setup(struct device *uart) uart_irq_rx_disable(uart); uart_irq_tx_disable(uart); - IRQ_CONNECT(CONFIG_UART_PIPE_IRQ, CONFIG_UART_PIPE_IRQ_PRI, - uart_pipe_isr, 0, UART_IRQ_FLAGS); - irq_enable(CONFIG_UART_PIPE_IRQ); - /* Drain the fifo */ while (uart_irq_rx_ready(uart)) { unsigned char c; @@ -88,6 +84,8 @@ static void uart_pipe_setup(struct device *uart) uart_fifo_read(uart, &c, 1); } + uart_irq_callback_set(uart, uart_pipe_isr); + uart_irq_rx_enable(uart); } diff --git a/drivers/serial/uart_k20.c b/drivers/serial/uart_k20.c index 3f0985e..5c261f0 100644 --- a/drivers/serial/uart_k20.c +++ b/drivers/serial/uart_k20.c @@ -31,6 +31,7 @@ #include <toolchain.h> #include <sections.h> +#include "uart_k20.h" #include "uart_k20_priv.h" /* convenience defines */ @@ -45,6 +46,10 @@ /* Device data structure */ struct uart_k20_dev_data_t { uint32_t baud_rate; /* Baud rate */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_t cb; /**< Callback function pointer */ +#endif }; static struct uart_driver_api uart_k20_driver_api; @@ -90,6 +95,10 @@ static int uart_k20_init(struct device *dev) /* restore interrupt state */ irq_unlock(old_level); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + dev_cfg->irq_config_func(dev); +#endif + dev->driver_api = &uart_k20_driver_api; return DEV_OK; @@ -339,6 +348,41 @@ static int uart_k20_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_k20_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +void uart_k20_isr(void *arg) +{ + struct device *dev = arg; + struct uart_k20_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -360,6 +404,7 @@ static struct uart_driver_api uart_k20_driver_api = { .irq_err_disable = uart_k20_irq_err_disable, .irq_is_pending = uart_k20_irq_is_pending, .irq_update = uart_k20_irq_update, + .irq_callback_set = uart_k20_irq_callback_set, #endif }; @@ -367,9 +412,17 @@ static struct uart_driver_api uart_k20_driver_api = { #ifdef CONFIG_UART_K20_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_0 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_0_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_0 = { @@ -380,13 +433,32 @@ DEVICE_INIT(uart_k20_0, CONFIG_UART_K20_PORT_0_NAME, &uart_k20_init, &uart_k20_dev_data_0, &uart_k20_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_0_IRQ, + CONFIG_UART_K20_PORT_0_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_0 */ #ifdef CONFIG_UART_K20_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_1 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_1_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_1 = { @@ -397,13 +469,32 @@ DEVICE_INIT(uart_k20_1, CONFIG_UART_K20_PORT_1_NAME, &uart_k20_init, &uart_k20_dev_data_1, &uart_k20_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_1_IRQ, + CONFIG_UART_K20_PORT_1_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_1 */ #ifdef CONFIG_UART_K20_PORT_2 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_2 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_2_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_2_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_2, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_2 = { @@ -414,13 +505,32 @@ DEVICE_INIT(uart_k20_2, CONFIG_UART_K20_PORT_2_NAME, &uart_k20_init, &uart_k20_dev_data_2, &uart_k20_dev_cfg_2, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_2_IRQ, + CONFIG_UART_K20_PORT_2_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_2), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_2_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_2 */ #ifdef CONFIG_UART_K20_PORT_3 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_3(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_3 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_3_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_3_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_3, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_3 = { @@ -431,13 +541,32 @@ DEVICE_INIT(uart_k20_3, CONFIG_UART_K20_PORT_3_NAME, &uart_k20_init, &uart_k20_dev_data_3, &uart_k20_dev_cfg_3, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_3(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_3_IRQ, + CONFIG_UART_K20_PORT_3_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_3), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_3_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_3 */ #ifdef CONFIG_UART_K20_PORT_4 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_4(struct device *port); +#endif + static struct uart_device_config uart_k20_dev_cfg_4 = { .base = (uint8_t *)CONFIG_UART_K20_PORT_4_BASE_ADDR, .sys_clk_freq = CONFIG_UART_K20_PORT_4_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_4, +#endif }; static struct uart_k20_dev_data_t uart_k20_dev_data_4 = { @@ -448,4 +577,15 @@ DEVICE_INIT(uart_k20_4, CONFIG_UART_K20_PORT_4_NAME, &uart_k20_init, &uart_k20_dev_data_4, &uart_k20_dev_cfg_4, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_4(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_K20_PORT_4_IRQ, + CONFIG_UART_K20_PORT_4_IRQ_PRI, + uart_k20_isr, DEVICE_GET(uart_k20_4), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_K20_PORT_4_IRQ); +} +#endif + #endif /* CONFIG_UART_K20_PORT_4 */ diff --git a/drivers/serial/uart_k20.h b/drivers/serial/uart_k20.h new file mode 100644 index 0000000..ca92859 --- /dev/null +++ b/drivers/serial/uart_k20.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file UART header file for the K20 family of microprocessors.. + */ + +#ifndef _UART_K20_H_ +#define _UART_K20_H_ + +void uart_k20_isr(void *arg); + +#endif /* _UART_K20_H_ */ diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 543f7a0..f6b0b2e 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -210,6 +210,7 @@ struct uart_ns16550_dev_data_t { #ifdef CONFIG_UART_INTERRUPT_DRIVEN uint8_t iir_cache; /**< cache of IIR since it clears when read */ + uart_irq_callback_t cb; /**< Callback function pointer */ #endif #ifdef CONFIG_UART_NS16550_DLF @@ -336,6 +337,10 @@ static int uart_ns16550_init(struct device *dev) irq_unlock(old_level); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + DEV_CFG(dev)->irq_config_func(dev); +#endif + dev->driver_api = &uart_ns16550_driver_api; return DEV_OK; @@ -576,6 +581,41 @@ static int uart_ns16550_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_ns16550_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +static void uart_ns16550_isr(void *arg) +{ + struct device *dev = arg; + struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_UART_NS16550_LINE_CTRL @@ -671,6 +711,7 @@ static struct uart_driver_api uart_ns16550_driver_api = { .irq_err_disable = uart_ns16550_irq_err_disable, .irq_is_pending = uart_ns16550_irq_is_pending, .irq_update = uart_ns16550_irq_update, + .irq_callback_set = uart_ns16550_irq_callback_set, #endif @@ -685,6 +726,10 @@ static struct uart_driver_api uart_ns16550_driver_api = { #ifdef CONFIG_UART_NS16550_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + struct uart_device_config uart_ns16550_dev_cfg_0 = { .port = CONFIG_UART_NS16550_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_NS16550_PORT_0_CLK_FREQ, @@ -698,6 +743,10 @@ struct uart_device_config uart_ns16550_dev_cfg_0 = { .pci_dev.function = CONFIG_UART_NS16550_PORT_0_PCI_FUNC, .pci_dev.bar = CONFIG_UART_NS16550_PORT_0_PCI_BAR, #endif /* CONFIG_UART_NS16550_PORT_0_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_0 = { @@ -713,10 +762,25 @@ DEVICE_INIT(uart_ns16550_0, CONFIG_UART_NS16550_PORT_0_NAME, &uart_ns16550_init, &uart_ns16550_dev_data_0, &uart_ns16550_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_NS16550_PORT_0_IRQ, + CONFIG_UART_NS16550_PORT_0_IRQ_PRI, + uart_ns16550_isr, DEVICE_GET(uart_ns16550_0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_NS16550_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_NS16550_PORT_0 */ #ifdef CONFIG_UART_NS16550_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + struct uart_device_config uart_ns16550_dev_cfg_1 = { .port = CONFIG_UART_NS16550_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_NS16550_PORT_1_CLK_FREQ, @@ -730,6 +794,10 @@ struct uart_device_config uart_ns16550_dev_cfg_1 = { .pci_dev.function = CONFIG_UART_NS16550_PORT_1_PCI_FUNC, .pci_dev.bar = CONFIG_UART_NS16550_PORT_1_PCI_BAR, #endif /* CONFIG_UART_NS16550_PORT_1_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_1 = { @@ -745,4 +813,15 @@ DEVICE_INIT(uart_ns16550_1, CONFIG_UART_NS16550_PORT_1_NAME, &uart_ns16550_init, &uart_ns16550_dev_data_1, &uart_ns16550_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_NS16550_PORT_1_IRQ, + CONFIG_UART_NS16550_PORT_1_IRQ_PRI, + uart_ns16550_isr, DEVICE_GET(uart_ns16550_1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_NS16550_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_NS16550_PORT_1 */ diff --git a/drivers/serial/uart_stellaris.c b/drivers/serial/uart_stellaris.c index 3a6ea16..eaaa10e 100644 --- a/drivers/serial/uart_stellaris.c +++ b/drivers/serial/uart_stellaris.c @@ -34,6 +34,8 @@ #include <uart.h> #include <sections.h> +#include "uart_stellaris.h" + /* definitions */ /* Stellaris UART module */ @@ -76,6 +78,10 @@ struct _uart { /* Device data structure */ struct uart_stellaris_dev_data_t { uint32_t baud_rate; /* Baud rate */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_t cb; /**< Callback function pointer */ +#endif }; /* convenience defines */ @@ -271,6 +277,10 @@ static int uart_stellaris_init(struct device *dev) line_control_defaults_set(dev); enable(dev); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + DEV_CFG(dev)->irq_config_func(dev); +#endif + dev->driver_api = &uart_stellaris_driver_api; return DEV_OK; @@ -565,6 +575,41 @@ static int uart_stellaris_irq_update(struct device *dev) return 1; } +/** + * @brief Set the callback function pointer for IRQ. + * + * @param dev UART device struct + * @param cb Callback function pointer. + * + * @return N/A + */ +static void uart_stellaris_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_stellaris_dev_data_t * const dev_data = DEV_DATA(dev); + + dev_data->cb = cb; +} + +/** + * @brief Interrupt service routine. + * + * This simply calls the callback function, if one exists. + * + * @param arg Argument to ISR. + * + * @return N/A + */ +void uart_stellaris_isr(void *arg) +{ + struct device *dev = arg; + struct uart_stellaris_dev_data_t * const dev_data = DEV_DATA(dev); + + if (dev_data->cb) { + dev_data->cb(dev); + } +} + #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -586,6 +631,7 @@ static struct uart_driver_api uart_stellaris_driver_api = { .irq_err_disable = uart_stellaris_irq_err_disable, .irq_is_pending = uart_stellaris_irq_is_pending, .irq_update = uart_stellaris_irq_update, + .irq_callback_set = uart_stellaris_irq_callback_set, #endif }; @@ -593,9 +639,17 @@ static struct uart_driver_api uart_stellaris_driver_api = { #ifdef CONFIG_UART_STELLARIS_PORT_0 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_0 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_0_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_0_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_0, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_0 = { @@ -606,13 +660,32 @@ DEVICE_INIT(uart_stellaris0, CONFIG_UART_STELLARIS_PORT_0_NAME, &uart_stellaris_ &uart_stellaris_dev_data_0, &uart_stellaris_dev_cfg_0, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_0(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_0_IRQ, + CONFIG_UART_STELLARIS_PORT_0_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris0), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_0_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_0 */ #ifdef CONFIG_UART_STELLARIS_PORT_1 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_1 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_1_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_1_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_1, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_1 = { @@ -623,13 +696,32 @@ DEVICE_INIT(uart_stellaris1, CONFIG_UART_STELLARIS_PORT_1_NAME, &uart_stellaris_ &uart_stellaris_dev_data_1, &uart_stellaris_dev_cfg_1, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_1(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_1_IRQ, + CONFIG_UART_STELLARIS_PORT_1_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris1), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_1_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_1 */ #ifdef CONFIG_UART_STELLARIS_PORT_2 +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *port); +#endif + static struct uart_device_config uart_stellaris_dev_cfg_2 = { .base = (uint8_t *)CONFIG_UART_STELLARIS_PORT_2_BASE_ADDR, .sys_clk_freq = CONFIG_UART_STELLARIS_PORT_2_CLK_FREQ, + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .irq_config_func = irq_config_func_2, +#endif }; static struct uart_stellaris_dev_data_t uart_stellaris_dev_data_2 = { @@ -640,4 +732,15 @@ DEVICE_INIT(uart_stellaris2, CONFIG_UART_STELLARIS_PORT_2_NAME, &uart_stellaris_ &uart_stellaris_dev_data_2, &uart_stellaris_dev_cfg_2, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +static void irq_config_func_2(struct device *dev) +{ + IRQ_CONNECT(CONFIG_UART_STELLARIS_PORT_2_IRQ, + CONFIG_UART_STELLARIS_PORT_2_IRQ_PRI, + uart_stellaris_isr, DEVICE_GET(uart_stellaris2), + UART_IRQ_FLAGS); + irq_enable(CONFIG_UART_STELLARIS_PORT_2_IRQ); +} +#endif + #endif /* CONFIG_UART_STELLARIS_PORT_2 */ diff --git a/drivers/serial/uart_stellaris.h b/drivers/serial/uart_stellaris.h new file mode 100644 index 0000000..4a14ef3 --- /dev/null +++ b/drivers/serial/uart_stellaris.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Header file for Stellaris UART. + */ + +#ifndef _UART_STELLARIS_H_ +#define _UART_STELLARIS_H_ + +void uart_console_isr(void *arg); + +#endif /* _UART_STELLARIS_H_ */ diff --git a/include/drivers/console/uart_console.h b/include/drivers/console/uart_console.h index 4634e33..963e8af 100644 --- a/include/drivers/console/uart_console.h +++ b/include/drivers/console/uart_console.h @@ -46,8 +46,6 @@ struct uart_console_input { */ void uart_register_input(struct nano_fifo *avail, struct nano_fifo *lines); -void uart_console_isr(void *unused); - #ifdef __cplusplus } #endif diff --git a/include/drivers/console/uart_pipe.h b/include/drivers/console/uart_pipe.h index 3b7594a..2391bbd 100644 --- a/include/drivers/console/uart_pipe.h +++ b/include/drivers/console/uart_pipe.h @@ -62,15 +62,6 @@ void uart_pipe_register(uint8_t *buf, size_t len, uart_pipe_recv_cb cb); */ int uart_pipe_send(const uint8_t *data, int len); -/** @brief Simple UART interrupt handler. - * - * This function is called from an interrupt and should not be called by - * an application directly. - * - * @param unused unused - */ -void uart_pipe_isr(void *unused); - #ifdef __cplusplus } #endif diff --git a/include/uart.h b/include/uart.h index 66e5123..cba33c3 100644 --- a/include/uart.h +++ b/include/uart.h @@ -71,6 +71,16 @@ extern "C" { */ #define UART_ERROR_BREAK (1 << 3) +/** + * @brief Define the application callback function signature for UART. + * + * @param port Device struct for the UART device. + */ +typedef void (*uart_irq_callback_t)(struct device *port); + +/* For configuring IRQ on each individual UART device. Internal use only. */ +typedef void (*uart_irq_config_func_t)(struct device *port); + /** @brief UART device configuration.*/ struct uart_device_config { /** @@ -90,6 +100,10 @@ struct uart_device_config { #ifdef CONFIG_PCI struct pci_dev_info pci_dev; #endif /* CONFIG_PCI */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; +#endif }; /** @brief Driver API structure. */ @@ -145,6 +159,9 @@ struct uart_driver_api { /** Interrupt driven input hook function */ int (*irq_input_hook)(struct device *dev, uint8_t byte); + /** Set the callback function */ + void (*irq_callback_set)(struct device *dev, uart_irq_callback_t cb); + #endif #ifdef CONFIG_UART_LINE_CTRL @@ -516,6 +533,30 @@ static inline void uart_irq_input_hook_set(struct device *dev, } } + +/** + * @brief Set the IRQ callback function pointer. + * + * This sets up the callback for IRQ. When an IRQ is triggered, + * the specified function will be called. + * + * @param dev UART device structure. + * @param cb Pointer to the callback function. + * + * @return N/A + */ +static inline void uart_irq_callback_set(struct device *dev, + uart_irq_callback_t cb) +{ + struct uart_driver_api *api; + + api = (struct uart_driver_api *)dev->driver_api; + + if ((api != NULL) && (api->irq_callback_set != NULL)) { + api->irq_callback_set(dev, cb); + } +} + #endif #ifdef CONFIG_UART_LINE_CTRL -- 2.7.2
|
|
Re: RFC - arm-gcc-embedded Toolchain Support
Hugo Vincent
Hi Anas,
toggle quoted messageShow quoted text
Can you please confirm if you want me to progress this RFC (since it's more convenient to have the VARIANT set, rather than specifying CROSS_COMPILE each time)? If so, what if any changes would you like? Should I submit it to gerrit? Thanks, Hugo
On Mon, Feb 29, 2016 at 2:35 PM, Nashif, Anas <anas.nashif(a)intel.com> wrote:
Hugo,
|
|
Re: STM32F103x port
Kalowsky, Daniel <daniel.kalowsky@...>
toggle quoted messageShow quoted text
-----Original Message-----I'm not opposed to this. Ben/Dirk any commentary? IMO having a soc specific defconfig would be great too. Right now there areDepending upon what you see going into such a file, this is a relatively reasonable idea. That would be the very specific discussion. :-)Second thing to add, in your use of addresses, please add a commentOk. for higher speeds.The UART driver is still using polling, however drive init has been
|
|
Re: STM32F103x port
Maciek Borzecki <maciek.borzecki@...>
On 02/29 18:53, Kalowsky, Daniel wrote:
General feedback inline below.Makes sense. I think we should also add another 'MCU family' level of-----Original Message-----As said before, I've also been working on an STM32F2xx port. Looking hierarchy. We would have then: arch/ arm/ soc/ stm32/ stm32f1xx/ <soc specific> stm32f2xx/ <soc specific> stm32f4xx/ <soc specific> IMO having a soc specific defconfig would be great too. Right now there are only arch and board defconfigs. A soc defconfig would save a lot of typing and if'ing in Kconfigs, what happens to be really error prone by the way. Ok. Sure, I'd be glad to take a look. Are you referring to this discussion?The demo code has been archived in bboozzoo/stm32f103-demo branch.I need to look more at this, as in my own port for STM32F2xx I've left https://lists.zephyrproject.org/archives/list/devel(a)lists.zephyrproject.org/message/P6HMQUTHVAL4PZXSNRJCYTEBDGXFQWKH/ Agreed. I've just briefly looked at STM32F4xxxx Reference Manual. TheThe UART driver is still using polling, however drive init has been reworked toThe UART is looking like it is coming along nicely. Again I think register map looks the same. Specific registers (CR1, CR3) use a couple of bits more, but nothing that cannot be handled by #ifdefs. I expect that the lower families (2xxx, 3xxx) are also very much identical. Cheers, -- Maciek Borzecki
|
|
Re: RFC[1/2] Common logging infrastructure and API
Nashif, Anas
On 29/02/2016, 12:48, "Benjamin Walsh" <benjamin.walsh(a)windriver.com> wrote:
+1I agree this sounds awkward.We need to make sure we support logging for more than debugging andSo this works for a simple case. Can you expand on this for a more This sounds more scalable, basically removes the need for defining a domain and using the levels to do the selection of how verbose messages are for each domain. Anas
|
|