Forum Discussion
Altera_Forum
Honored Contributor
11 years ago --- Quote Start --- Yes you have to use interrupts for accurate transmission. I had the same issue you have when using polling (the while loop in your code). This is because the while loop prevents the nios from doing other tasks. In other words, you are bottlenecking yourself. Interrupts allow you to receive and transmit messages exaclty when you want to, by temporarily pausing the nios to perform the uart task. To do interrupts, you must connect the interrupt (IRQ) column in qsys (that is a hardware enable). Then you must do a software enable (alt_ic_isr_register and alt_ic_irq_enable) --> this is slightly different than in the code provided. He uses alt_irq_register and alt_irq_enable which are outdated... Here is what I suggest: The code i linked to is using 2 uarts - because they are talking to each other. You only need 1. So you must go through the provided code and delete one of the uarts (UART2). To make life easy, make sure your uart module in qsys is named UART1. This is because his code expects system.h names to be Uart1 and Uart2. You can give it a different name, but you will have to scrub through the code to make the appropriate changes. Include InterruptHandlerforUart.h in your code. Now in main you want to initialize the uart and enable the software interrupts: int context_uart; InitUart1( <put in a baud rate if uart module did not have fixed baud rate... see the linked code>); alt_ic_isr_register(Uart1_IRQ_INTERRUPT_CONTROLLER_ID, Uart1_IRQ,IsrUart1,&context_uart,0x0); alt_ic_irq_enable(Uart1_IRQ_INTERRUPT_CONTROLLER_ID, Uart1_IRQ); finally to transmit, you just write: PutUart1( <some character> ); The C code provided takes care of the rest (uart statuses, fifoing, etc.) If you have lots of characters - which you do - then put the PutUart1 into a loop. --- Quote End --- Hi Krasner, My current system is done with polling as mentioned earlier using direct register method (IORD_ALTERA_AVALON_UART_STATUS (UART_BASE); IOWR_ALTERA_AVALON_UART_TXDATA(UART_BASE, txdata);etc)., now I would like to implement with interrupt as you recommended, but I have few issues I need to understand so that I can fix those errors: I am able to read serial port and plot the graph real time in Matlab. However, I am having the issue where the data is not updated as frequent as desired. I am using USB-to-Serial interface to the board FTDI UM245R module. I have a few questions about using interrupt for uart: I want to send data from Nios II to serial port to plot graph real time in Matlab. 1. In function void InitUart(), what is the "Uart1_IRQ_INTERRUPT_CONTROLLER_ID" for? I read in the I read in the Altera documentation (https://www.altera.com/en_us/pdfs/literature/hb/nios2/n2sw_nii52010.pdf), the interrupt controller ID is defined in system.h, but I couldn't find any info about it in system.h, should I generate or do something to get this controller id? 2. I assigned IRQ no.2 in Qsys, I dont understand how doesthe function in InitUart() know that Uart1_IRQ is 2? Is it done automatically or how should I assign? alt_ic_isr_register(Uart1_IRQ_INTERRUPT_CONTROLLER_ID, Uart1_IRQ,IsrUart1,&context_uart,0x0); alt_ic_irq_enable(Uart1_IRQ_INTERRUPT_CONTROLLER_ID, Uart1_IRQ); 3. i can't find how to set the flag to 0x0 as you have written 4. Regarding alt_ic_isr_register(Uart1_IRQ_INTERRUPT_CONTROLLER_ID, Uart1_IRQ,IsrUart1,&context_uart,0x0);, I know this sounds stupicd, can I write the above line twelve times so I can call the function IsrUart1 twelve times? Reason being, I need to send twelve sets of data, imagine I have twelve sets of "context_uart" , each set of data has 10 elements for instance. If it is not possible to call alt_ic_isr_register for 12 times, is there a smart way to do it? 5. In the main function, why do we need the two functions GetUart1() and PutUart2()? I thought in the IsUart1(), we have already transmitted the data 6. My current system is done with polling as mentioned earlier, now I would like to implement with interrupt as you recommended, since the current system can display data in correct value and order, but data is not updated as frequent as desired (I posted the thread here http://www.alteraforum.com/forum/showthread.php?t=48165), so do you think I still need to have those codes for buffer size, head and tail etc? In the function PutUart1(), if (++TxHead_1 > (TX_BUFFER_SIZE_1-1)) TxHead_1 = 0; z = IORD_ALTERA_AVALON_UART_CONTROL(UART1_BASE) | ALTERA_AVALON_UART_CONTROL_TRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(UART1_BASE, z); I am wondering what is the purpose of having the codes checking the buffer size and the head and tail? TxHead_1==TxTail_1 7. divisor = (ALT_CPU_FREQ/BaudRate) +1; I assume I dont need this as I have fixed baud rate 115200, am I right? I know I ask a lot and this is demanding, I really appreciate if you could just give short answer to my questions, really appreciate your help!!