electro-smith / libDaisy

Hardware Library for the Daisy Audio Platform
https://www.electro-smith.com/daisy
MIT License
312 stars 131 forks source link

dfu-util: Last page at 0xfc08ffff is not writeable - initialized arrays in QSPIFLASH #545

Open eh2k opened 1 year ago

eh2k commented 1 year ago

Hi, I am not sure if I have completely understood the mechanism with the linker script and the different possibilities - but I'm currently trying to store an initialized LookupTable into QSPIFLASH on the Daisy submodule.

On the Teensy you can do this with the FLASHMEM macro, e.g. uint8_t FLASHMEM lut[] = { 1, 2, 3, 4 } As with the FLASHMEM, I use the DSY_QSPI_DATA macro here uint8_t DSY_QSPI_DATA lut[] = { 1, 2, 3, 4 }.

The bootloader (make programm-boot) and the flashing (make program-dfu) with APP_TYPE = BOOT_SRAM is working so far without any problems, except when adding the DSY_QSPI_DATA macro to an initialized array.

Then I get the following error:

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 4096
DfuSe interface name: "Flash "
Downloading to address = 0x90040000, size = 1812267008
dfu-util: Last page at 0xfc08ffff is not writeable
make: *** [lib/libDaisy/core/Makefile:330: program-dfu] Error 74

The flashing works if the array is declared with DSY_QSPI_BSS. The address is in the 9004xxxxx space, but not initialized as expected.

Another question of understanding: I assume that the bootloader stores the firmware in some area in the QSPIFLASH in the BOOT_SRAM case. At startup, the QSPIFLASH area would then have to be copied to the SRAM and executed there by the bootloader. Is there more information to this procedure, and/or an address area in the QSPIFLASH which is reserved for this, and which one should not write manually with "hw.qspi.Erase/Write"?

dmarman commented 1 year ago

I have the same issue, and I am unable to make it work even after reading the documentation, the examples and the forum... It looks like we are not the only ones, see:

https://forum.electro-smith.com/t/working-with-wav-files-without-sd-card/3009

Here a prototype of the issue:

#include "daisy_seed.h"
#include "daisysp.h"

using namespace daisy;
using namespace daisysp;

DaisySeed hw;
Line line;
uint8_t lineFinished;

const float DSY_QSPI_DATA clapWave[20] = { 
    0, 0.25, 0.5, 0.75, 1,
    0, 0.25, 0.5, 0.75, 1, 
    0, 0.25, 0.5, 0.75, 1, 
    0, 0.25, 0.5, 0.75, 1 
};

void AudioCallback(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size)
{
    for (size_t i = 0; i < size; i++) {
        if(lineFinished) line.Start(0, 19, 0.1);
        float wavePosition = line.Process(&lineFinished);
        float mix = clapWave[(int)wavePosition];

        out[0][i] = mix;
        out[1][i] = mix;
    }
}

int main(void)
{
    hw.Configure();
    hw.Init();
    hw.SetAudioBlockSize(64);
    hw.SetAudioSampleRate(SaiHandle::Config::SampleRate::SAI_48KHZ);

    line.Init(48000);
    lineFinished = 1;

    hw.StartLog();
    hw.StartAudio(AudioCallback);
}
eh2k commented 1 year ago

after some trial and error, I found a workaround - but I think the solution belongs in the bootloader (closed source).

By the way, my workaround (tricking the bootloader - for advanced users):

  1. modifying the STM32H750IB_sram.lds -> QSPIFLASH Origin = 0x900C0000 ( => QSPI Origin + 512kB )
  2. patching the hex file -> Move lines that are in the address range >= 0x900C0000 to the address range 0x24080000, offset = (-0x900C00000 + 0x24080000).
    • 0x24080000 = SRAM Origin + 512KB
  3. convert the hex file into a bin, and flash it with dfu-util - BOOT_SRAM case (and current daisy bootloader)
    • The bootloader will write the whole firmware into the address range >= 0x9004000, the QSPI_DATA ends up again in the original address range 0x900C00000
Electro-Jam commented 11 months ago

Hi, I ran into this as well. I tried a slightly simpler solution for the moment and changed the following in the SRAM.LDS file from this:

 QSPIFLASH (RX): ORIGIN = 0x90040000, LENGTH = 7936K

to this:

 QSPIFLASH (RX): ORIGIN = 0x90040000, LENGTH = 7M

It seems to be working for me in this configuration.
Downside I lose a little storage here, and I will update this if I find anything else that may work better here for a simpler fix and/or if I find any other issues with this approach.