Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
2,132 Views

UART interrupt with HAL

Hello 

I read a lot of threads about interrupts and UART and good resolution was this (http://www.alteraforum.com/forum/showthread.php?t=17224) but I'm looking something without write own driver. I tried following code but it not work: 

 

 

#include "system.h"# include "sys/alt_stdio.h"# include "alt_types.h"# include "sys/alt_irq.h" void isr_timer_0(void* context); int main() { void *my_context; alt_ic_isr_register(UART0_IRQ_INTERRUPT_CONTROLLER_ID, UART0_IRQ, isr_timer_0, my_context, 0x0); while(1); return 0; } void isr_uart0(void* context) { alt_putchar(alt_getchar()); } 

 

Similar isr register for timer works great. I'm using RS-232 Serial Port from Qsys. 

Do you know any solution to use uart interrupt with build in uart driver? Mayby i should use another IP? 

 

Best regards 

Przemek
0 Kudos
4 Replies
Altera_Forum
Honored Contributor I
420 Views

From the software side of things, have you checked system.h from your BSP? Pretty often with our NIOS2 project the QSys project had the correct interrupt ID but when the BSP was created, system.h had it defined as '-1'. 

 

ALSO, in your isr register function you're telling it to use the 'isr_timer_0' callback rather than the defined 'isr_uart0' callback.
Altera_Forum
Honored Contributor I
420 Views

 

--- Quote Start ---  

From the software side of things, have you checked system.h from your BSP? 

--- Quote End ---  

 

Yes, I checked system.h and everything is ok: 

#define UART0_IRQ 3 # define UART0_IRQ_INTERRUPT_CONTROLLER_ID 0 

 

 

--- Quote Start ---  

ALSO, in your isr register function you're telling it to use the 'isr_timer_0' callback rather than the defined 'isr_uart0' callback. 

--- Quote End ---  

 

I cut my code to prepare minimal example and it was copy-paste error ;) in my code I have proper callback. 

I investigated this and I have problem as follows: 

int main() { alt_ic_isr_register(UART0_IRQ_INTERRUPT_CONTROLLER_ID, UART0_IRQ, isr_uart0, my_context, 0x0); alt_printf("Hello from main"); while(1); } void isr_uart0(void* context) { alt_printf("Hello from isr"); } 

 

When printf from main is executed program go to isr_uart0 callback and go to alt_irq_handler from alt_irq_handler.c and there is endless loop and nothing is printed to uart. 

For first printf: 

alt_putchar is called -> then in alt_putchar code for direct drivers is executed and alt_driver_write() calls altera_avalon_uart_write(). Last point of this chain is isr_irq_handler which calls my callback in endless loop with no output to terminal. 

 

I just want to get chars from terminal in isr but i think without using registers it is impossible.
Altera_Forum
Honored Contributor I
420 Views

Hello PrzemRS 

 

Using printf in an interrupt handler is not such a good practice.  

 

Better is to use a static volatile int variabele (example) as a flag that you increment in the interrupt handler. 

 

You can print the value of this variable from your main routine (while loop) using a loop with a delay in it (usleep). The delay is handy so you do not overload the usb link that transfers the debug output to your console window. (I assume you are using some DE board or the like) 

 

You need to declare the variable as volatile because otherwise the compiler might use register optimizations. 

 

On the other hand, if you only increment the value the primary cause of the interrupt in your handler, the reason of the interrupt is possibly not removed and the interrupt is not acknowledged so you keep ending up in the same interrupt routine. To do this you need to read/write some registers in the UART to tell it that you serviced the interrupt. 

 

You might consider writing an interrupt handler for a button with pio input, then see how it works and then go further to the UART. 

 

Best Regards, 

Johi.
Altera_Forum
Honored Contributor I
420 Views

Thanks for support. I used registers so everything is ok for now. I'm using my own custom board with Altera MAX10 :) 

From the other hand in the meanwhile I used something like this and it works great for my purpose: 

while(1) { ch = alt_getchar(); if(ch != 0x11 && ch != 0x13) { cmdlineInputFunc(ch, cliState); // My custom cmdlineMainLoop(cliState); // command line interpreter } }  

And I used command line intepreter :) I noticed alt_getchar() when there is no char to read returns 0x11 and 0x13 alternatively. 

 

My problem is solved, thank you very much for support!
Reply