-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stm32: UART doesn't support IRQ sharing #39565
Comments
@erwango any idea? Is this indeed an unsupported feature? |
Indeed, driver can't support this configuration for now. |
Oh no.. |
I tried to understand and port what's been done in #37585 to the Correct me if I'm wrong, #37585 seems to address the scenario where all ADC instances share the same IRQ line, instead of some ADCs share a IRQ line while some others share the other IRQ line, like the UART: For the shared IRQ handler to work in the uart driver, we will need We might be able declare these variable with: #define STM32_UART_IRQ_IDX_INIT(index) static bool init_irq_##DT_INST_IRQN(index);
DT_INST_FOREACH_STATUS_OKAY(STM32_UART_IRQ_IDX_INIT) , which will generate a up to 2 But since we have a few IRQ lines, I think we will need one Any idea? @erwango @mcscholtz @mbolivar-nordic To simplify the questionI have these uarts enabled in devicetree (example):
and I'd like to enable interrupt driven APIs, how can I do the |
@mbolivar may I please have your input on this, regarding the DT part? |
@ycsin I didn't think about it for very long, but it should be possible to do this with some more help from the build system. Here is a hacky proposal you might be able to use to get started. Maybe you and @erwango can improve the idea from here. If you check cmake/extensions.cmake, you see we have several extension functions already which work using devicetree nodes:
One possible idea is to use CMake to loop over the nodes you care about, and define some macros that tell you which shared IRQ handlers you need to define. That lets you get the global view of the devicetree in CMake. Here is a rough sketch of how that might work:
The goal is to make sure STM32_NEED_SHARED_IRQ_29 is defined if any of USART3, USART4, etc. are enabled.
|
@mbolivar-nordic I don't have much experience with CMake apart from the basic one to get my application to compile, but I'm interested to learn and to give it a try if time permits.
I think the IRQ lines vary among different STM32 socs, so if this method is used I think we will have a very long irq init function? static void uart_stm32_irq_init(const struct device *dev)
{
if (!irq_init) {
...
#ifdef STM32_NEED_SHARED_IRQ_27
IRQ_CONNECT(27,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(27);
#endif
#ifdef STM32_NEED_SHARED_IRQ_28
IRQ_CONNECT(28,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(28);
#endif
#ifdef STM32_NEED_SHARED_IRQ_29
IRQ_CONNECT(29,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(29);
#endif
...
irq_init = true;
}
} Would it be possible to have something like #define INIT_IRQ(num) \
IRQ_CONNECT(num, \
0, \ ← need a way to get the priority
uart_stm32_shared_irq_handler, NULL, 0); \
irq_enable(num);
static void uart_stm32_irq_init(const struct device *dev)
{
if (!irq_init) {
DT_COMPAT_IRQ_NUM_FOREACH_STATUS_OKAY(INIT_IRQ, st_stm32_uart);
irq_init = true;
}
} |
Would you have one common IRQ init function like that? Wouldn't it be called again and again for each UART, which would make the IRQ_CONNECT() calls too many times?
I'm having trouble understanding what you're asking about, sorry. It looks like you want to know about every IRQ for a compatible, but that doesn't make sense to me. Are you looking to have something like Note that DT_FOREACH_PROP_ELEM probably won't work for you, for the same reason that we have to have DT_FOREACH_RANGE -- the |
I'm basing on the methodology of #37585, so the IRQ init function will be called multiple times. The first caller will connect all IRQ lines and set the I can't think of a better way to have separate IRQ init function for each UART, since some of them may share the same IRQ lines.
The issue with this that I can imagine is that different STM32 socs have different IRQ lines for UARTs, so it would be tedious to handle each of the
Please don't be. I'm sorry for not making my question clear enough.
This macro loops though some array/property of a single
For example:
(Based on the same methodology) If possible, for these 5 UARTs, I imagine that it would be nice if we have a DT macro that will loop through each distinct IRQ line once. For this example, it would be 3 iterations (27, 28, 29), so I can do this: #define INIT_IRQ(num) \
IRQ_CONNECT(num, \
0, \ ← need a way to get the priority
uart_stm32_shared_irq_handler, NULL, 0); \
irq_enable(num);
static void uart_stm32_irq_init(const struct device *dev)
{
if (!irq_init) {
DT_COMPAT_IRQ_NUM_FOREACH_STATUS_OKAY(INIT_IRQ, st_stm32_uart);
irq_init = true;
}
} which the compiler can resolve into: static void uart_stm32_irq_init(const struct device *dev)
{
if (!irq_init) {
IRQ_CONNECT(27,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(27);
IRQ_CONNECT(28,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(28);
IRQ_CONNECT(29,
0,
uart_stm32_shared_irq_handler, NULL, 0);
irq_enable(29);
irq_init = true;
}
} |
This probably can be done now using #61422 |
I'm trying to use the
lpuart1
in my g0b1re custom board and it can't compile whenusart5
is already enabled.I tried to enable
usart3
and it also won't compile. It seems like the current STM32 UART driver doesn't support uarts sharing the same interrupt?From the G0B1RE reference manual:
The text was updated successfully, but these errors were encountered: