Forum Discussion

Jacob11's avatar
Jacob11
Icon for Occasional Contributor rankOccasional Contributor
3 years ago
Solved

Max10 programming external flash

Hello guys. I am trying to figure out how to write to an external flash. Micron mt25QL02 is what is on the board.

I don't want to use Nios, or the flash memory programming tool. I am trying to use the tcl scripting included in the Generic Serial flash user guide found here:

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug-gen-sfi.pdf

So, what I have done is created a very simple qsys file which includes:

clock

jtag to avalon master bridge

intel avMM bursting master

Generic Serial Flash interface

After constraining pins, compiling, and burning the .POF file to the board, I try the commands in the user guide via the tcl script. And literally nothing happens.

No response. It just goes to the tcl>cursor.

For example, I am trying to simply read the device ID, so I copy and paste the following at the tcl> prompt:

proc read_memory_id {} {
global mp flash_cmd_ctrl flash_cmd_read_data_0
set_flash_cmd_setting 0x0000489F
master_write_32 $mp $flash_cmd_ctrl 0x1
set id [master_read_32 $mp $flash_cmd_read_data_0 1]
puts "This is from Micron package"
return $id
}

I get nothing in return. Shouldn't i see some kind of output on the console or something?? I have nothing here.

Overall, what I want to accomplish is to have a bootloader in the on-chip flash(already built and burned to board with a custom .hex file). I also have a 2nd custom .hex file which initializes all peripherals, and I want to copy this 2nd .hex file onto the external Micron Flash using a .tcl script.

So my question is what do I do with this tcl console?? Even when i copy and paste directly from the user guide, I get no response whatsoever.

  • After much trial and error, I have it working. Now I can write to and read from/erase the memory. Basically, I found and error in the Intel example design. Once I corrected it, everything works.

    For anyone else who might try it using Nios.

    First you have to do a write enable like this:

    IOWR(EXT_FLASH_AVL_CSR_BASE,0x7,0x00000006);
    IOWR(EXT_FLASH_AVL_CSR_BASE,0x8,0x1);

    then you can write 0xabcd1234 into the memory like this(this is where the example design had mistakes):
    IOWR(EXT_FLASH_AVL_MEM_BASE,0x00000000,0xabcd1234);

    Then to read it back, do it like this:

    IOWR(EXT_FLASH_AVL_CSR_BASE,0x4,0x00000000);
    IOWR(EXT_FLASH_AVL_CSR_BASE,0x0,0x00000101);
    IOWR(EXT_FLASH_AVL_CSR_BASE,0x5,0x00000003);
    return IORD(EXT_FLASH_AVL_MEM_BASE,0x00000000);

    The most confusing parts are these offsets 0x4, 0x5....etc. I have figured out what most of them are, so I will list them below:

    0x0 control register

    0x4 operating protocols

    0x5 read instructions

    0x6 write instructions

    0x7 flash command setting

    0x8 flash command control(basically always write 0x1 here when writing into the status registers to begin the operation)

    0x9 flash command address register

    0xA flash command write data

    0xC flash command read data

    Why this isnt included in any documentation I have no idea. Basically, once I understood what these offsets were doing I had it up and running in just a few minutes. Hopefully these short notes help the next person.

15 Replies