FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6343 Discussions

Reading external data using On-chip FIFO and NIOS II

Altera_Forum
Honored Contributor II
1,891 Views

Hi all, 

 

I'm trying to read a 8-bit ADC with parallel output using NIOS II. I need to read the ADC at 24MHz to capture correct samples. I have been trying a 1K On-Chip FIFO to capture this data. I exported the FIFO in[31..0] signals and the in clock signal but the FIFO doesn't interrupt the NIOS. I attached my QSys File and the Circuit Diagram. 

 

I linked the oscillator clock directly in the fifo_in_clk only for test purposes. The write signal is HIGH when I press a button, also for testing purposes. 

 

Is there any problem in my design? Are the connections in qsys correct? 

 

Can I use PIO directly to do this task (using DMA)?  

 

Thanks
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
716 Views

Have you properly configured the CSR registers to generate the interrupts? 

Are you able to poll the CSR registers and see that data is being pushed onto the FIFO correctly?
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

I have configured the FIFO this way: 

 

int init_input_fifo() { int code = ALTERA_AVALON_FIFO_OK; code = altera_avalon_fifo_init(0x2001800, // Address 0x3F, // Enable interrupts 1, // Almost empty 1000); // Almost full if (code == ALTERA_AVALON_FIFO_EVENT_CLEAR_ERROR) printf("A\n"); else if (code == ALTERA_AVALON_FIFO_IENABLE_WRITE_ERROR) printf("B\n"); else if (code == ALTERA_AVALON_FIFO_THRESHOLD_WRITE_ERROR) printf("C\n"); //printf("CODE: %d\n", code); printf("ALMOSTEMPTY = %d\n", altera_avalon_fifo_read_almostempty(0x2001800)); printf("ALMOSTFULL = %d\n", altera_avalon_fifo_read_almostfull(0x2001800)); void* input_fifo_wrclk_irq_event_ptr = (void*) &input_fifo_wrclk_irq_event; alt_irq_register(16, input_fifo_wrclk_irq_event_ptr, handle_input_fifo_wrclk_interrupts); return code; } 

 

The ALMOSTEMPTY and ALMOSTFULL printed in the console are correct. My interrupt: 

 

static void handle_input_fifo_wrclk_interrupts(void* context, alt_u32 id) { volatile int* input_fifo_wrclk_irq_event_ptr = (volatile int*) context; *input_fifo_wrclk_irq_event_ptr = altera_avalon_fifo_read_event(0x2001800, ALTERA_AVALON_FIFO_EVENT_ALL); altera_avalon_fifo_clear_event(0x2001800, ALTERA_AVALON_FIFO_EVENT_ALL); printf("INTERRUPT!!!"); } 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

Are you able to poll the CSR registers and see that data is being pushed onto the FIFO correctly?

0 Kudos
Altera_Forum
Honored Contributor II
716 Views

I tried  

 

while(1) { alt_u32 level = altera_avalon_fifo_read_level(0x2001800); printf("LEVEL = %d\n", level); }  

 

and received "LEVEL = 0" in the polling.
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

The level register will read as zero if the FIFO is empty or if the FIFO is completely filled. The status register will tell you which case it is.

0 Kudos
Altera_Forum
Honored Contributor II
716 Views

Hi ted, 

 

I changed the ISR scheme from legacy to HAL Scheme. When I press the button the WRITE signal goes HIGH thus generating the interrupt. The interrupt occurs but the status isn't good after pressing the button.  

# include "alt_types.h" # include "altera_avalon_fifo_util.h" # include "altera_avalon_pio_regs.h" # include "altera_avalon_fifo_regs.h" # include "sys/alt_irq.h" # include "system.h" # include <stdio.h> # include <unistd.h> # define IN_CSR_ADDRESS 0x2001800 # define OUT_CSR_ADDRESS 0x2001820 # define OUT_ADDRESS 0x2001878 volatile int edge_capture; volatile alt_u8 global; //SDRAM volatile int interrupted = 0; //static void handle_input_fifo_wrclk_interrupts(void* context, alt_u32 id) static void handle_input_fifo_wrclk_interrupts(void* context) { volatile int* input_fifo_wrclk_irq_event_ptr = (volatile int*) context; *input_fifo_wrclk_irq_event_ptr = altera_avalon_fifo_read_event(IN_CSR_ADDRESS, ALTERA_AVALON_FIFO_EVENT_ALL); altera_avalon_fifo_clear_event(IN_CSR_ADDRESS, ALTERA_AVALON_FIFO_EVENT_ALL); altera_avalon_fifo_clear_event(OUT_CSR_ADDRESS, ALTERA_AVALON_FIFO_EVENT_ALL); altera_avalon_fifo_clear_event(OUT_ADDRESS, ALTERA_AVALON_FIFO_EVENT_ALL); interrupted = 1; } volatile int input_fifo_wrclk_irq_event; int init_input_fifo() { int code = ALTERA_AVALON_FIFO_OK; code = altera_avalon_fifo_init(IN_CSR_ADDRESS, // Address 0x3F, // Enable interrupts 500, // Almost empty 1000); // Almost full code = altera_avalon_fifo_init(OUT_CSR_ADDRESS, // Address 0x3F, // Enable interrupts 500, // Almost empty 1000); // Almost full printf("ALMOSTEMPTY = %d\n", altera_avalon_fifo_read_almostempty(IN_CSR_ADDRESS)); printf("ALMOSTFULL = %d\n", altera_avalon_fifo_read_almostfull(IN_CSR_ADDRESS)); printf("STATUS = %d\n", altera_avalon_fifo_read_status(IN_CSR_ADDRESS, ALTERA_AVALON_FIFO_STATUS_REG)); void* edge_capture_ptr = (void*) &edge_capture; alt_ic_isr_register(0, 16, handle_input_fifo_wrclk_interrupts, edge_capture_ptr, NULL); //IN_CSR_IRQ alt_ic_isr_register(0, 17, handle_input_fifo_wrclk_interrupts, edge_capture_ptr, NULL); //OUT_CSR_IRQ return code; } int main(void) { init_input_fifo(); while(1) { if (interrupted) { alt_u32 level = altera_avalon_fifo_read_level(0x2001800); printf("LEVEL: %u\n", level); printf("STATUS = %d\n", altera_avalon_fifo_read_status(IN_CSR_ADDRESS, ALTERA_AVALON_FIFO_STATUS_REG)); printf("\n"); interrupted = 0; } } return 0; }  

 

 

The output is (BEFORE press the button): 

status = 0 

 

The output is (AFTER press the button): 

level: 0 

status = 1 

 

The FIFO seems full (i_status = 1) in the first press and in the first time when I check the "interrupted" flag. How can it occurs? NIOS is running a 100MHz. Is it slow for this application? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

Maybe set your ALMOST_FULL threshold significantly lower? 

 

If it is a 1024 deep FIFO, and you set the threshold to 1000, then you only have (24) clocks to service the FIFO before it will fill. If you're pushing FIFO data at 24MHz and NIOS is running at 100MHz, then maybe you have around 100 clocks --- which is not a lot of time.
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

Thanks again! I will try with a smaller threshold. ;D

0 Kudos
Reply