Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
12409 Discussions

write continuous data to sdram on DE0 nano board



I want to write data to sdram via nios2, then read data out and connect to LEDs to see if the data is correct.

Below is my code and results.

In the code I add printf("isr\n") to make sure interrupt is in effect.

Before "return 0" in the main(), I add printf("b\n") to check if the program is executed outside of while(1) loop, which is not allowed.

But when I write to the 65th date, the program is stuck,

and the interrupt is not working also.

I don't know what happened,

could anyone help me?

thanks a lot!


2019/3/21 update:

I attach my fpga file,

for .elf file please use SPCM2.

#include <stdio.h> #include <unistd.h> #include "system.h" #include "alt_types.h" #include "io.h" #include "altera_avalon_pio_regs.h" #include "sys/alt_irq.h"   int bKeyPressed = 0; int cnt = 1; alt_u16 incre = 0; alt_u16 data, data0;   void KEY_ISR(void* context){ bKeyPressed = 1;   IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0); printf("isr\n"); }   void EnableKeyInterrupt(void){ int error;   IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE,0x03); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0);   bKeyPressed = 0; error = alt_irq_register (KEY_IRQ, 0, KEY_ISR); if (error) printf("Failed to register interrut\r\n"); }   int main() { EnableKeyInterrupt(); IOWR(LED_BASE, 0, (alt_u8)0);   while(1) { if(bKeyPressed) { bKeyPressed = 0;   *((alt_u8*)NEW_SDRAM_CONTROLLER_0_BASE + incre) = cnt; data = *((alt_u8*)NEW_SDRAM_CONTROLLER_0_BASE + incre);   printf("cnt = %d, ", cnt); printf("incre = %d, ", incre); printf("data=%d\n", data); IOWR(LED_BASE, 0, (alt_u8)data); cnt ++; incre += 1; } } printf("b\n"); return 0; }isr cnt = 1, incre = 0, data=1 isr cnt = 2, incre = 1, data=2 isr cnt = 3, incre = 2, data=3 isr cnt = 4, incre = 3, data=4 isr cnt = 5, incre = 4, data=5 isr cnt = 6, incre = 5, data=6 . . . . isr cnt = 65, incre = 64, data=65

0 Kudos
7 Replies
New Contributor II


Without your Qsys / Platform Designer code it is not easy to help you.

But based on what I see, there is no limit to the value that "incre" can have.

Therefore sooner or later you risk to write beyond the limits of the dedicated memory.

Also it is very well possible that you are writing into the zones that are used for other purposes hence making your system unstable.

Best Regards,




Hi Johi,

Thanks for the reply,

my qsys and top level are as below,

I use the onchip memory as nios2 cpu's memory.

Yes, it's very likely that data is written into the zone that is for other purpose,

is there any way to avoid it?





module SPCM_NIOS(   //////////// CLOCK ////////// CLOCK_50,   //////////// LED ////////// LED,   //////////// KEY ////////// KEY,   //////////// SDRAM ////////// DRAM_ADDR, DRAM_BA, DRAM_CAS_N, DRAM_CKE, DRAM_CLK, DRAM_CS_N, DRAM_DQ, DRAM_DQM, DRAM_RAS_N, DRAM_WE_N,   //////////// GPIO_0, GPIO_0 connect to GPIO Default ////////// GP0, GP0_IN,   //////////// GPIO_1, GPIO_1 connect to GPIO Default ////////// GP1, GP1_IN );   //======================================================= // PARAMETER declarations //=======================================================     //======================================================= // PORT declarations //=======================================================   //////////// CLOCK ////////// input CLOCK_50;   //////////// LED ////////// output [7:0] LED;   //////////// KEY ////////// input [1:0] KEY;   //////////// SDRAM ////////// output [12:0] DRAM_ADDR; output [1:0] DRAM_BA; output DRAM_CAS_N; output DRAM_CKE; output DRAM_CLK; output DRAM_CS_N; inout [15:0] DRAM_DQ; output [1:0] DRAM_DQM; output DRAM_RAS_N; output DRAM_WE_N;   //////////// GPIO_0, GPIO_0 connect to GPIO Default ////////// inout [33:0] GP0; input [1:0] GP0_IN;   //////////// GPIO_1, GPIO_1 connect to GPIO Default ////////// inout [33:0] GP1; input [1:0] GP1_IN;       spcm_qsys u0 ( .clk_50_clk (CLOCK_50), // clk_50.clk .rst_n_reset (KEY[0]), // rst_n.reset .clk_sdram_clk_clk (DRAM_CLK), // clk_sdram_clk.clk .new_sdram_controller_0_wire_addr (DRAM_ADDR), // new_sdram_controller_0_wire.addr .new_sdram_controller_0_wire_ba (DRAM_BA), // .ba .new_sdram_controller_0_wire_cas_n (DRAM_CAS_N), // .cas_n .new_sdram_controller_0_wire_cke (DRAM_CKE), // .cke .new_sdram_controller_0_wire_cs_n (DRAM_CS_N), // .cs_n .new_sdram_controller_0_wire_dq (DRAM_DQ), // .dq .new_sdram_controller_0_wire_dqm (DRAM_DQM), // .dqm .new_sdram_controller_0_wire_ras_n (DRAM_RAS_N), // .ras_n .new_sdram_controller_0_wire_we_n (DRAM_WE_N), // .we_n .key_export (KEY), .led_export (LED) );       endmodule

I think the 0 in the middle should be a pointer to the edge capture pointer alt_irq_register (KEY_IRQ, 0, KEY_ISR); I have tried the enhanced Interrupt before, you need to modify the system.h file, Nios ii section, you will find: ALT_LEGACY_INTERRUPT_API_PRESENT change it to: ALT_ENHANCED_INTERRUPT_API_PRESENT Then, dont re-build or update the BSP, since it will change it back to legacy mode. This might be something like this: #include "sys/alt_irq.h" #include "system.h" /* Declare a global variable to hold the edge capture value. */ volatile int edge_capture; /* Initialize the button_pio. */ static void init_button_pio(){ /* Recast the edge_capture pointer to match the alt_irq_register() function prototype. */ void* edge_capture_ptr = (void*) &edge_capture; /* Enable all 4 button interrupts. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); /* Reset the edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0); /* Register the ISR. */ #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT alt_ic_isr_register(BUTTON_PIO_IRQ_INTERRUPT_CONTROLLER_ID, BUTTON_PIO_IRQ, handle_button_interrupts, edge_capture_ptr, 0x0); #else alt_irq_register( BUTTON_PIO_IRQ, edge_capture_ptr, handle_button_interrupts ); #endif }

Hi FJumaah,


Thanks for the reply!


Now I modify my code to use alt_ic_isr_register(...) function,


But unfortunately, the code is still stuck at the 65th press of the key😞


whether alt_ic_isr_register or alt_irq_register the results are the same.

#include <stdio.h> #include <unistd.h> #include "system.h" #include "alt_types.h" #include "io.h" #include "altera_avalon_pio_regs.h" #include "sys/alt_irq.h"   int bKeyPressed = 0; int cnt = 1; alt_u16 incre = 0; alt_u16 data; volatile int edge_capture;   void KEY_ISR(void* context){   bKeyPressed = 1;   // clear interrupt flag IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0); printf("isr\n"); }     static void init_button_pio(){   void* edge_capture_ptr = (void*) &edge_capture; // enable interrupt, 2-keybutton IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE,0x03); // clear capture flag IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0);   #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT alt_ic_isr_register( KEY_IRQ_INTERRUPT_CONTROLLER_ID, KEY_IRQ, KEY_ISR, edge_capture_ptr, 0x0); printf("ENHANCED mode\n"); #else alt_irq_register (KEY_IRQ, edge_capture_ptr, KEY_ISR); printf("LEGACY mode\n"); #endif   }     int main() { init_button_pio(); IOWR(LED_BASE, 0, (alt_u8)0);   while(1) { if(bKeyPressed) { bKeyPressed = 0;   *((alt_u8*)NEW_SDRAM_CONTROLLER_0_BASE + incre) = cnt; data = *((alt_u8*)NEW_SDRAM_CONTROLLER_0_BASE + incre);   printf("cnt = %d, ", cnt); printf("incre = %d, ", incre); printf("data=%x\n", data); IOWR(LED_BASE, 0, (alt_u8)data); cnt ++; incre += 1; } }   printf("b\n"); return 0; }



Thanks for your feedback. I will test on my board and let you know the feedback. Thanks
Hello, My apologize for the late reply. I was able to replicate your issue. I am still working on debugging it. Thanks