-
Hi! I am implementing a system using the iCEBreaker board. I got neorv32 running and I can upload programs via serial port using the bootloader. All seems fine! Now, I want to store the software on flash, and I'm facing issues while accessing flash chip: << NEORV32 Bootloader >>
I believe to have properly set constraints: This is the pinout
But maybe my VHDL code is wrong somehow, because there's a little quirk about my design: I need SPI access to both the FLASH and also to an external device connected via one of the PMODs, so I had to multiplex some SPI signals out of my design:
I believe the VHDL is not wrong (though I wouldn't swear on it!), but of course, I've also synthesized a similar design without the second SPI port, just the Flash-SPI one. Also, I believe that code and pinout is fine because I can look at FLASH SPI signals using an oscilloscope, and I can see these three images: 1.- Chip Select and Clock: both look fine 2.- Chip Select and MOSI: both look fine 3.- Chip Select and MISO: CS is ok, but... there's nothing on MISO. Even if I change oscilloscope trigger to CH2 falling edge, it won't trigger, MISO is always high Even if my HDL code was wrong, specifically the MISO multiplexing, the flash should be answering to the WEL enable/disable commands that the bootloader is trying to perform to check communication with the flash. I added some extra debugging on bootloader to see what was happening: spi_flash_read_status() is always returning 0x000000ff (all ones, which matches what I see on the oscilloscope). Of course, I also tried to remove the second SPI port without any success, so I realy think I could in fact swear that the HDL code is right, but communication with the flash is still failing. On the other hand, when I program a new bitfile using iceprog, I do see the process of flashing the chip. So... maybe this isn't the same port that the FPGA is connected to? That's the only explanation, but that's not what I understand from the schematic as J15 and J16 do exist by default and it seems that they are indeed connecting MISO/MOSI signals from the flash directly to the pins I defined above on constraints file. So, right now I'm quite lost. What can I do to further investigate this? Does anyone have any idea on what's happening? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hey there!
I just got an iCEBreaker board myself and I am implementing a NEORV32-based SoC there as well - so, perfect timing! 😅
I think this is fine. Here is my SPI pin mapping (I am using Lattice Radiant so the pin mapping file looks a little bit different):
I am also "multiplexing" the SPI module to be used with the on-board flash and a peripheral connected via one of the PMOD ports. Your code looks fine, too. Anyway, here is mine: -- SPI --
flash_sck_o <= con_spi_sck;
pmod_sck_o <= con_spi_sck;
flash_sdo_o <= con_spi_sdo;
pmod_sdo_o <= con_spi_sdo;
flash_csn_o <= con_spi_csn(0);
pmod_csn_o <= con_spi_csn(1);
con_spi_sdi <= flash_sdi_i when (con_spi_csn(0) = '0') else pmod_sdi_i;
These images were captured while the NEORV32 bootloader tries to load an executable, right? Did you connect your scope to the Flash SPI pins? In general, the SPI transactions look pretty good. But it is strange that there is no output from the flash at all. Maybe this pin/signal is tied to a fixed level by the FPGA itself (so a problem caused by the synthesis tool). Using the sysCONFIG pins (the SPI pins the FPGA uses to fetch the bitstream) as GPIOs might be a bit complicated... Maybe your synthesis toolchain does not support that?! Could you try building a bitstream using Lattice Radiant? |
Beta Was this translation helpful? Give feedback.
-
Hi again! We got our answer! I asked on 1BitSquared discord and @gatecat was very kind to read the whole issue and solve it in one go:
I tested the "-s" parameter on icepack and it solved the issue. I've already stored and loaded my program from FLASH automatically after the 8s timeout. Now, this is one way to do it, but maybe it's better for the bootloader to wake the eeprom and put it to sleep back again? It probably doesn't need to test first if it's sleeping, just wake it up. Or maybe we don't want to put it to sleep again. I don't mind writing a patch for either case, but I'd like to know what's your opinion. I believe the right thing would be to wake it, regardless of its state on boot, and then put it to sleep again. It should be the user application code the one who wakes it up when/if needed and we would save some mW of power. |
Beta Was this translation helpful? Give feedback.
Hi again!
We got our answer! I asked on 1BitSquared discord and @gatecat was very kind to read the whole issue and solve it in one go: