Forum Discussion
Altera_Forum
Honored Contributor
21 years agoHow to set ISR in NiosII?
Hi all,
Now I want to receive info from a custom UART in NiosII IDE by Interruption. I notice the code for receiving interruption in NiosI goes like this: ----------- int main(void) { int context=0; .... nr_installuserisr(na_uart_1,receiver_routine,context); na_uart_1->np_uartcontrol=npuartcontrol_irrdy_mask; while(1) { rxchar=getchar_from_uart_1(); } .... } ---------------------- and the relevent subroutine goes like this: ---------------------- char getchar_from_uart_1(int context) { char c; c=na_uart_1->np_uartrxdata; return c; } --------------------- Here I have got a question about their counterparts in NiosII.I have scanned the docs shipped with NiosII, but I cannot find the info I need. Any suggestions? Thanks in advance! Regards, Don11 Replies
- Altera_Forum
Honored Contributor
Hi,
Read the "NIOS II Software Developpers Handbook", part 6 "Exception handling". There is an example on page 6-10 for the PIOs. In place of nr_installuserisr () I think that you have to use alt_irq_register () Regards, Jean LEE - Altera_Forum
Honored Contributor
Thanks Jean LEE!
But I have noticed that there only an example about PIO, instead of UART. Are their relevent routines the same? I wonder whether the UART's ISR routines in NiosII go the same as their counterparts in NiosI? - Altera_Forum
Honored Contributor
This is a part of my operation of ISR in the main() routine:
alt_irq_register(MY_UART_IRQ, (void*) &context, my_rxd); IOWR_ALTERA_AVALON_UART_CONTROL(MY_UART_BASE, ALTERA_AVALON_UART_STATUS_RRDY_MSK); Is the second sentence correct? I 'm not so sure... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/huh.gif - Altera_Forum
Honored Contributor
Don,
Why do you want to write your own ISR for the UART? The HAL already contains code for this and, if you use the IDE flow, it's likely you already have an ISR registered for the UART. Read through the section in the manual regarding the UART and you'll see what I mean. Unless you've disabled it, all interrupt-capable components will have registered ISRs following alt_sys_init(). Cheers, - slacker - Altera_Forum
Honored Contributor
Hi Slacker,
Sorry,perhaps I did not describe my problem explicitly, what I want is not writing a sheer ISR by myself, but I just want to take advantage of the ISR routines which are the NiosII provided and available to be used. The code I posted above previously is alt_irq_register(MY_UART_IRQ, (void*) &context, my_rxd); IOWR_ALTERA_AVALON_UART_CONTROL(MY_UART_BASE, ALTERA_AVALON_UART_STATUS_RRDY_MSK); I really don't know whether I 'm on the right way or not, could you give me some suggestions about that? Besides, I redirect my stdin and stdout in my system library properties both to "my_uart", is that right? Many thanks! Regards, Don - Altera_Forum
Honored Contributor
Assuming the UART you have in your system is just a standard Avalon UART. You should not need to write any software at all, you should just be able to use the driver supplied. If you direct stdout/stdin to your UART it should just work.
- Altera_Forum
Honored Contributor
Hi,
But the current device I'm tinkering with is a custom UART. I think there are two conventional approaches to receive data from that. One approach is through Interruption by registering the device with a ISR,and when a char comes in,the program would automatically jump into the receiver ISR and operate the code just received. The other alternative is requiring the relevent register(or checking the state), such as RRDY in the status register. But now, though both of the approaches I have tried, the UART device cannot receive any char,I really cannot figure out why. 1)The code for the first approach is like this : ------------ (the code in main) alt_irq_register(GSM_UART_IRQ, (void*) &context, gsm_rxd); IOWR_ALTERA_AVALON_UART_CONTROL(GSM_UART_BASE, ALTERA_AVALON_UART_STATUS_RRDY_MSK); ------------ and ------------ (the receiver ISR) void gsm_rxd(void* context, alt_u32 id) { rxbuffer[rxhead]= IORD(GSM_UART_BASE,0); IOWR_ALTERA_AVALON_UART_STATUS(GSM_UART_BASE, 0); printf("The char received are %c\n",rxbuffer[rxhead]); if( (++rxhead) > (SIZE-1) ) rxhead=1; } ------------ 2)And the code for the second approach is like following: ------------ void gsm_rxd() { while((IORD(GSM_UART_BASE,2)&0x80)!=0x80) ; rxbuffer[rxhead]= IORD(GSM_UART_BASE,0); printf("\nThe order received is:\n"); //printf("%x",IORD(GSM_UART_BASE,0)); printf("%x",rxbuffer[rxhead]); IOWR_ALTERA_AVALON_UART_STATUS(GSM_UART_BASE, 0); if( (++rxhead) > (SIZE-1) ) rxhead=1; } ------------- Please help me to figure out why the two type of routines just do not work. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/huh.gif Besides, the transmitting routine I wrote is like this: -------------- void gsm_txd(char data[],char length) { volatile char m; printf("\nThe command sent is:\n"); for(m=0;m<length;m++) { while((IORD(GSM_UART_BASE,2)&0x40)!=0x40) ; IOWR(GSM_UART_BASE,1,data[m]); printf("%c",IORD(GSM_UART_BASE,1)); } } Because it works so fine when it operates, so I made a receiving routine following the pattern of the transmitting routine, which is the code 2) I just wrote above. So the second question is why this receiver function do not work as its counterpart as a transimitter routine? Thank you for your suggestions and helps... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/wink.gif Regards, Don - Altera_Forum
Honored Contributor
If you wish to use an ISR you only need to call alt_irq_register as you do in your example 1.
It sounds to me like you either have a problem with your hardware or how you're controlling it, you need to look with the debugger to see if you're ever getting into your ISR and if not is the bit corresponding to your UART's IRQ getting set in the ipending register? Also I notice you're using printf inside your ISR you can't rely on this working. - Altera_Forum
Honored Contributor
--- Quote Start --- originally posted by rugbybloke@Aug 12 2005, 04:22 AM if you wish to use an isr you only need to call alt_irq_register as you do in your example 1.it sounds to me like you either have a problem with your hardware or how you're controlling it, you need to look with the debugger to see if you're ever getting into your isr and if not is the bit corresponding to your uart's irq getting set in the ipending register?
also i notice you're using printf inside your isr you can't rely on this working. --- Quote End --- Hi rugbybloke, Thank you for your suggestions to me! But I did use debugger in NiosII IDE to check my code, but everytime after its sending AT command to the UART, there always no response(It should response "OK" at least) from that.And when the debugger comes to the breakpoint at the --------------- while((IORD(GSM_UART_BASE,2)&0x80)!=0x80) ; --------------- It would stop forever, without any forward actions any more. Thus I really dont know where the rub of the code above is, besides, are the code following right when I register the interruption for my program? -------------- alt_irq_register(GSM_UART_IRQ, (void*) &context, gsm_rxd); IOWR_ALTERA_AVALON_UART_CONTROL(GSM_UART_BASE, ALTERA_AVALON_UART_STATUS_RRDY_MSK); -------------- Because I have not used interruption in NiosII, so I'm not sure about that... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/huh.gif Many thanks! Regards, Don
- Altera_Forum
Honored Contributor
Don,
Without knowing your hardware it's hard to comment further. Your code is spinning permanently waiting for bit 7 of your register. Have you got the addresses right? Is this signal asserted? I suspect you either have faulty hardware or your addresses are wrong.