- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)? ThanksLink Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you able to poll the CSR registers and see that data is being pushed onto the FIFO correctly?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks again! I will try with a smaller threshold. ;D
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page