Close

Faster flash data loading!

A project log for MAINFRAME COMPUTE OBSERVATOR

A SciFi inspired PC Hardware Monitor

mangus-tiranusMangus Tiranus 04/17/2022 at 21:400 Comments

So while I have shown pushing to assets to flash via the serial is working, and loading assets to g ram was working. It was only working* ... 

It still wasnt perfect. The main issue I was having was with the way I was pushing data to ram. I had to push byte by byte through one command and this seemed to have several over heads. That meant putting 350k of data to the gram took about 10 seconds. 

Which was far too long in my book. Using the library normally would load assets from an SD card to gram and would do a full 1meg of data in about 3 or 4 seconds. 

Clearly this wasnt right. Today I was mostly looking into ways to make this faster.

My first approach was to reverse engineer the method the SD card was being pushed. And put my data in the place of the sd card data buffer. But for some reason that I've still yet to figure out, would cause the g ram to crash. No idea why. 

Looking a little more at the official library, funnily for pic chips. I found the method Bridgetek recommend for streaming bytes to g ram with little over head.

Going full into optimise mode, I first adapted this method to my project, and then stripped all the unnecessary stuff out. Going pretty bare bones (though not quite bare metal) streaming data out from flash and into gram via a loop. Ive got the loading time down to about 2 seconds from 10. 

I know there must be ways to make this faster. maybe I can link up the DMA between SPI 1 and SPI 2 and just stream the data directly without normal instructions. Sadly full hardware level stuff is still a little on the hard side. And given the time I have left to get this prototype functioning. Now is not the right time to try. 2 seconds is good enough for now :) 

if anyone cares to know heres the code to load the assets! Pretty basic really. Using the w25q16 library for arduino. Tweaked a little by me. 

#define MEM_WRITE   0x80            // FT800 Host Memory Write
void EVE_AddrForWr(uint32_t ftAddress) // <<< from the pic library
{
    // Send three bytes of a register address which has to be subsequently written. Ignore return values as this is an SPI write only.
   SPI.write(((ftAddress >> 16) | MEM_WRITE) );  // Send high byte of address with 'write' bits set
   SPI.write((ftAddress >> 8) );                 // Send middle byte of address
   SPI.write((ftAddress) );                      // Send low byte of address
}
void hwmon_loadAssets ()
{


  uint32_t offset = 0;
  uint32_t size = 329988;


  flash.notBusy();
  flash.initStreamRead (0, 0);


  GD.__end();

 digitalWrite(DEFAULT_CS,LOW);                                                              // CS low begins SPI transaction
 EVE_AddrForWr(0);//<< originally from pic library supplied by BridgeTek really stripped down to speed up as much as possible. 

  while (offset < size)
    {
    SPI.write(flash.streamRead());// << streaming the data
    offset++;
    }
  digitalWrite(DEFAULT_CS,LOW);
  flash.closeStreamRead ();

}

[edit}

This might actually be a fraction faster. 

void hwmon_loadAssets ()
{

  uint32_t offset = 0;
  const uint32_t size = 329988;

  flash.notBusy ();
  flash.initStreamRead (0, 0);

  GD.__end ();

  digitalWrite (DEFAULT_CS, LOW);                                                              // CS low begins SPI transaction
  EVE_AddrForWr (0);


  uint16_t n =0;
  byte buf[512];

  while (offset < size)
    {
      n = ((512) < (size - offset) ? (512) : (size - offset));
      for (uint16_t i = 0; i < n; i++)
        {
          buf[i] = flash.streamRead ();
        }
      SPI.write (buf, n);

      offset += n;
    }

  digitalWrite (DEFAULT_CS, LOW);
  flash.closeStreamRead ();

}

Discussions