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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.