Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20639 Discussions

Max10 programming external flash

Jacob11
New Contributor II
1,017 Views

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.

 

 

0 Kudos
1 Solution
Jacob11
New Contributor II
873 Views

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.

 

 

View solution in original post

0 Kudos
15 Replies
YuanLi_S_Intel
Employee
1,000 Views

I think first of all, you need to do some setup before you run the TCL script. I would suggest you to source the TCL file first, then only execute the function. Copying the entire function wont work in system console.


You may refer to our system console user guide for the usage:

https://www.intel.com/content/dam/support/jp/ja/programmable/support-resources/bulk-container/pdfs/literature/ug/ug-system-console.pdf


0 Kudos
Jacob11
New Contributor II
987 Views

Thank you YuanLi_S.

 

That user guide does help but, i am still having some issues with writing and reading to the memory..

 

I was able to verify the clock and the jtag loop using the system console. So I can now at least communicate with my system through the system console.  Here is my qsys, HDL, and pinout for reference.

 

qsys.PNG

 

HDL.PNG

 

pins.PNG

 

The only purpose of this build is to program the external flash chip(from Winbond).

 

So, now I am trying to write and read from the external flash memory just a list of byte values using the commands listed in the user guide. My code:

 

set master_path [lindex [get_service_paths master] 0]

open_service master $master_path

set values [list 0xaa 0xff 0xaa 0xff]

master_write_memory $master_path 0x00000000 $values

master_read_memory $master_path 0x00000000 4

 

 

I also tried using the addressing from the bursting master in Qsys:

 

master_write_memory $master_path 0x00800000 $values

master_read_memory $master_path 0x01000120 4

 

Results:

If I read first, I can read from 0x00000000 and get some bytes back. They are not bytes which I placed there. When I then write to 0x00000000 it seems to go fine, but when i read again it locks up the system and i need to start over. 

 

using the bursting master addressing:

I can write to 0x00800000 and it seems to work fine, but when reading from 0x01000120 I just get 0x00 0x00 0x00 0x00 in return.

 

So, I am not fully understanding how this read/write operation should work. It seems like it should be pretty simple but it just isn't working for me.

 

I think this simple write/read is the first step towards understanding how to flash the board with a larger file.

 

Thank you,

Jacob

 

 

0 Kudos
Jacob11
New Contributor II
978 Views

As another test, I removed the serial flash controller and replaced it with an on chip RAM.

 

Did a write and read with no issues. It is just something to do with this external ram.

 

on_chip.PNG

 

 

So, i am understanding how to work with the system console, but something is wrong in either my qsys or it's a hardware issue.

0 Kudos
Jacob11
New Contributor II
926 Views

Good morning. Did you have any other advice for me??

 

Thanks,

Jacob

0 Kudos
Jacob11
New Contributor II
976 Views

I also removed the master burst controller, just to make the system as simple as possible.

 

When I use the off chip serial flash....I can write to 0x00000000 but reading from the same address locks up the system and never completes.

 

This is maddening haha.

0 Kudos
Jacob11
New Contributor II
975 Views

For your reference, I am using the reference design described here:

 

https://d2pgu9s4sfmw1s.cloudfront.net/DITA-technical-publications/PROD/PSG/ug-20198-683271-666560.pdf?Expires=1654256756&Key-Pair-Id=APKAJKRNIMMSNYXST6UA&Signature=f8gL5y7BYt-X3OQxoVEVNaEw~FB21lkVu-JhX7pJBEVDn9C-pHkbOJUS7aJjl1boJT6xTwmgzHaokcMsFee8LN3Pv1VUIyBERvx0VmU44w38ShJWdhmuq~yhe8i1JWb~Mh1mThFoHVeUtp2ffZ2qEgJEGCXKbsDW0q4dZdn7492e-d7LLacwLuKx6L...

 

this was downloaded direct from Intel. it does NOT list the Max 10 as a supported device. Could this be the issue?? Certainly the MAX 10 can support external flash programming?

0 Kudos
YuanLi_S_Intel
Employee
914 Views

I think the link attached is broken. If you are able to read register/address with TCL script. It means the setup is correct already. Since you are using generic serial flash IP, i would suggest you to refer to the user guide for the steps:

https://www.intel.com/content/www/us/en/docs/programmable/683419/21-2-20-1-1/device-family-support.html


0 Kudos
Jacob11
New Contributor II
904 Views

This is exactly the example design and script that I am following.

 

Strange that I can read the device ID. I can also write and read the control status register, but I cannot write anything into the memory space of the flash chip.

0 Kudos
Jacob11
New Contributor II
902 Views

As another test I also added a Nios device and created a C program to interface.

 

Same result. I can write and read to control registers, but when I write to a memory space address it locks up. Very strange.

0 Kudos
Jacob11
New Contributor II
895 Views

Also, the user guide mentions a HAL API that we can use in Nios:

 

https://www.intel.com/content/www/us/en/docs/programmable/683419/21-2-20-1-1/nios-ii-hal-driver.html

 

intel_generic_serial_flash_interface_top.h

and

intel_generic_serial_flash_interface_top.c

 

 

These do not exist for me. I get errors that they are not found, so I cannot use them. I tried to enable altera_safeclib in the BSP editor as mentioned, but altera_safeclib does not exist there.

 

The intel documentation is many times unclear and unhelpful.

0 Kudos
YuanLi_S_Intel
Employee
879 Views
0 Kudos
Jacob11
New Contributor II
874 Views

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.

 

 

0 Kudos
YuanLi_S_Intel
Employee
864 Views

Hi, i not sure which design example you are referring to. The previous link is not working. Can you share again? Anyway thanks for the info, it will sure help the community here.


0 Kudos
Jacob11
New Contributor II
854 Views

Basically it is the example design from the Generic Flash serial interface user guide

 

https://www.intel.com/content/www/us/en/docs/programmable/683419/21-2-20-1-1/user-guide.html

 

 

In the end we want to use the customizable flash programmer

 

https://www.intel.com/content/www/us/en/docs/programmable/683271/current/customizable-flash-programmer-overview.html

 

to load the board with a program to run. But first I need to understand how to talk with the memory. So now that works, and I can move to the next step, which is creating an rpd file.

0 Kudos
YuanLi_S_Intel
Employee
832 Views

Thanks for the info. Yes i think your approaches is suitable as well.


0 Kudos
Reply