Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bangle.js/SPIFLASH: improve SPI flash speed #1849

Closed
2 of 6 tasks
gfwilliams opened this issue Jun 5, 2020 · 2 comments
Closed
2 of 6 tasks

Bangle.js/SPIFLASH: improve SPI flash speed #1849

gfwilliams opened this issue Jun 5, 2020 · 2 comments

Comments

@gfwilliams
Copy link
Member

gfwilliams commented Jun 5, 2020

From http://forum.espruino.com/conversations/348553 - posting here because they'll get lost otherwise:

Some things that I think really might increase speed:

  • Create a spiFlashRead so that when you're reading data from flash you're not also writing - that would be a really easy win
  • Keep CS asserted on the flash chip after a read, and if the next byte(s) requested come right after the previous bytes requested then you don't need to send the 4 bytes of address again - you just clock out more data. That should be pretty easy as well.
  • Merging the writes - don't use OUTSET and OUTCLR but write directly to OUT - you may be able to change the clock and data at the same time on one of the clock edges which would help to overcome the 16Mhz limitation.
  • The original watch firmware actually used QSPI (so 4 data wires) but it did it in software so it was basically slower than just bit-banging with 1 data bit! It's a good example of why you need to actually benchmark before optimising :) With some thought you may be able to do it properly though - using multiply + shift (or just a lookup table) to get the bits in the correct places for their pins with only a few clock cycles (taking some inspiration from https://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits).
  • Using hardware SPI - you may be able to get this faster than bit-banged SPI, but supposedly the max bitrate is still 8Mbps
  • Preloading with hardware SPI and DMA - a lot of the time when executing from flash, Espruino will load data in chunks of 16 bytes. You could potentially pre-load the next 16 bytes using DMA while Espruino runs through the first 16 bytes
gfwilliams added a commit that referenced this issue Jun 5, 2020
@gfwilliams
Copy link
Member Author

function mandelbrot() {
 var tm = getTime();
 var sizex=32,sizey=32;
 for (var y=0;y<sizey;y++) {
  var line="";
  for (var x=0;x<sizex;x++) {
   var Xr=0;
   var Xi=0;
   var Cr=(4.0*x/sizex)-2.0;
   var Ci=(4.0*y/sizey)-2.0;
   var i=0;
   while ((i<16) && ((Xr*Xr+Xi*Xi)<4)) {
    var t=Xr*Xr - Xi*Xi + Cr;
    Xi=2*Xr*Xi+Ci;
    Xr=t;
    i++;
   }
   line += (i&1) ? "*" : " ";
  }
  print(line);
 }
 print(getTime()-tm);
}
// save to flash and then read&eval, so it'll end up in flash
require("Storage").write("mandeltest","("+mandelbrot.toString()+")");
mandelbrot = eval(require("Storage").read("mandeltest"));

// execute from flash
mandelbrot(); // 8.79 sec before
mandelbrot(); // 8.52 sec with most recent changes
require("Storage").write("test","",0,240*240*2)

t=getTime();g.drawImage({width:240,height:240,bpp:16,buffer:require("Storage").read("test")});print(getTime()-t);
// 0.47 before
// 0.36 with most recent changes

t=getTime();E.sum(require("Storage").read("test"));print(getTime()-t);
// 0.80 before
// 0.67 with most recent changes

@gfwilliams
Copy link
Member Author

Closing this as I think the initial changes did a pretty good job

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant