Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

and another uart problem.

Altera_Forum
Honored Contributor II
2,412 Views

hello guys,  

 

i'm having a problem with my FIFOED UART, The only thing im trying to do i send a big file over the uart and show on the Nios 2 Console that the data actually is being received.  

the problem is that when i send a few characters with a terminal program. i do see the characters on the NIOS2 console but my variabele Fifo_index isn't increased. 

 

and when i try to send a lot of character, lets say 200+, my program freezes immediately. 

 

can someon help me with this? 

 

btw im using the FIFOED AVALON UART from this forum running on 9600 baud (for starters) with a Fifo of 512 words. 

 

to make this a little easier, the code: 

 

#include <stdio.h># include <string.h># include <system.h># include <sys/alt_irq.h># include <altera_avalon_pio_regs.h># include <fifoed_avalon_uart_regs.h> /*--------------------------------Definitions----------------------------------*/ /*---------------------------Only Capital letters-----------------------------*/ /*----------------------------------------------------------------------------*/ # define BAUDRATE 9600# define UART_RX_RINGBUFFER_SIZE 2048# define UART_TX_RINGBUFFER_SIZE 2048 /*--------------------------------Prototypes----------------------------------*/ void Uart_Init(); void FIFOED_AVALON_UART_0_ISR( void* context, alt_u32 id); /*--------------------------------Variabeles----------------------------------*/ unsigned int UART_Context, i, sleep; unsigned char Data, test, Heartbeat; /*----------------------------------------------------------------------------*/ /*------------------------------Main program--------------------------------*/ /*----------------------------------------------------------------------------*/  int main(){        Uart_Init();    printf( "Uart Initilisation \n\r");        for(;;){      // this is just a simple binary counter that counts to 255 and then starts with 0 again      // i did it so that i could see when my program freezes.      sleep = 100000;      IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, Heartbeat);      Heartbeat++;      usleep(sleep);          }  } /*----------------------------------------------------------------------------*/ /*--------------------------------Methods------------------------------------*/ /*----------------------------------------------------------------------------*/  void Uart_Init(){         unsigned int Divisor;            // calculate the divisor for the uart     Divisor = (ALT_CPU_FREQ/BAUDRATE) + 0.5;            // disable all the FIFOED uarts interrupts    IOWR_FIFOED_AVALON_UART_CONTROL(FIFOED_AVALON_UART_0_BASE, 0);    // set baudrate    IOWR_FIFOED_AVALON_UART_DIVISOR(FIFOED_AVALON_UART_0_BASE, Divisor);            // Registrate ISR    alt_irq_register(FIFOED_AVALON_UART_0_IRQ ,(void*) &UART_Context, FIFOED_AVALON_UART_0_ISR);        // enable the RX interrupt    IOWR_FIFOED_AVALON_UART_CONTROL(FIFOED_AVALON_UART_0_BASE,  FIFOED_AVALON_UART_CONTROL_RRDY_MSK );  }   /*---------------------------------------------------------------------------*/ /*---------------------Interrupt Service Routines (ISR)----------------------*/ /*---------------------------------------------------------------------------*/  void FIFOED_AVALON_UART_0_ISR(void* context, alt_u32 id){    unsigned char DataCharacter;    unsigned int Status, Control, TempStatus, Fifo_index;        // read both the status and control-register    Status = IORD_FIFOED_AVALON_UART_STATUS(FIFOED_AVALON_UART_0_BASE);    Control = IORD_FIFOED_AVALON_UART_CONTROL(FIFOED_AVALON_UART_0_BASE);          // Clear alle error Flags en Clear de Interrupts    IOWR_FIFOED_AVALON_UART_STATUS(FIFOED_AVALON_UART_0_BASE, 0);     /*----------------------------------------------------------------------------*/ /* ------------------------Uart_Receive_ISR-----------------------------------*/ /*----------------------------------------------------------------------------*/        // when the receive ready interrupts occurs store received data in DataCharacter    if ((Status & FIFOED_AVALON_UART_STATUS_RRDY_MSK) == FIFOED_AVALON_UART_STATUS_RRDY_MSK){      DataCharacter = IORD_FIFOED_AVALON_UART_RXDATA(FIFOED_AVALON_UART_0_BASE);      printf("received data from UART: %d, %c \n" , DataCharacter, DataCharacter);      Fifo_index = IORD_FIFOED_AVALON_UART_RX_FIFO_USED(FIFOED_AVALON_UART_0_BASE);      printf("Fifo_index: %d\n", Fifo_index);                      if (Status & FIFOED_AVALON_UART_STATUS_FE_MSK){        printf("framing error\n");      }else if (Status & FIFOED_AVALON_UART_STATUS_PE_MSK ){        printf("Parity error\n");      }else if(Status & FIFOED_AVALON_UART_STATUS_ROE_MSK ){        printf("Receive overrun error\n");      }else {        printf("no errors occured\n");            }        }   

 

 

and a little picture off the nios console 

 

picture nios 2 console (http://img174.imageshack.us/my.php?image=problemnm9.png

 

why isn&#39;t my Fifo_index increasing after that text, Fifo_index should equal 6 after that transmission???? 

 

Hope someone can help me with this 

 

note that im just a new at this programming. and i know its better to use the hal API instead of Directly accesing the registers. but before this i was more into AVR and Microchips.. so thats an old habit
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
438 Views

You probably need to do a while loop inside the ISR (I&#39;m guessing there should be a "FIFO is not empty" flag). 

 

Also use of printf in ISRs is a big no-no.
0 Kudos
Altera_Forum
Honored Contributor II
438 Views

I agree too. You should have a while loop and read data until there is no more. I usually use a timeout to determine when there is no more. When you don&#39;t receive any data for at least 1 byte... or you can you 2 bytes (10 bits @ 9600 bits per second) then you can exit the loop. I use the timestamp functions in the HAL to determine the time to use the timeout. 

 

Also... I have used printf&#39;s inside the interrupts with no problems however I only use them for debugging to make sure the interrupt is firing... then I comment them out.
0 Kudos
Altera_Forum
Honored Contributor II
438 Views

First of all thanks for the quick reply! 

 

I will try to implement the while loop tomorrow when I am at my trainee(ship) again.  

 

i know that printf&#39;s aren&#39;t good in a ISR but i couldn&#39;t find the problem so i was debugging in that way.. I was planning to remove them when its working.
0 Kudos
Altera_Forum
Honored Contributor II
438 Views

after a long day of trying and trying and trying.. it still doesn&#39;t work. 

 

i tried to implement a while loop based on the extra registers created by the FIFOED UART: FIFOED_AVALON_UART_RX_FIFO_USED also tried to use the RRDY bit. But I am not entirely sure which flags to use. 

 

in its current state( most working code the one posted here ) i get strange behaviour. I made an spreadsheet where the number of bytes is layed out against the fifo index.  

 

http://img88.imageshack.us/img88/3426/strangebehaviourbc7.th.png (http://img88.imageshack.us/my.php?image=strangebehaviourbc7.png

 

As you can see there isn&#39;t any logic to be seen in the results 

 

@ cfavreau: I&#39;ve written in another topic that you were able to get 2mb/s with this uart. Maybe you can give a piece of your code? maybe the piece with the while loop in it?  

 

Also I am trying to use the signaltap to figure some things out. But again I am not quite sure which signals to use. maybe someone can point them out? 

 

thanks for all the efforts of you guys.  

 

as a student i really appreciate it
0 Kudos
Reply