Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
19 years ago

and another uart problem.

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

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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