Using Storage with the W25 flash chips

Posted on
  • I got myself one of those W25 spi flash chips, and I was wondering if instead of using the W25 module, can we somehow abstract all of that with the Storage module?

    I saw that Bangle has this which makes all storage be saved in external flash https://www.espruino.com/Bangle.js+Techn­ical#software

    Does that mean I just need to recompile following that of Bangle and it should just work? (not at my dev machine atm but will try it out when I can).


    1 Attachment

    • IMG_20201006_184929.jpg
  • BTW my use case here would be to try and do a circular buffer for my air quality sensor https://hackaday.io/project/174293-bleif­ying-a-honeywell-pm-sensor

    Instead of saving the data onto an SD card, I thought of using spi flash instead which would be faster. That way I can query data for the past 100 points or so (depending on the size of the spi flash).

  • There is Flash api (blocks) and there is Storage api (files).

    With Bangle came the feature that the SPI flash can be used together with internal flash i.e. same Flash api works with both. SPI flash is mapped to address 0x60000000 see this.
    This is pretty generic feature you can enable too and I do this for my Espruino builds for P8 and other devices with SPI/flash - F07, DK08, B5.

    Then there is Storage which is layered on top of Flash and you select which address and how many blocks are used for files. So you can use internal flash or SPI flash based on the address you pick, for bangle this is here

    So with bangle both is in SPI flash. In my builds I keep Storage in internal flash but SPI is still accessible via Flash API over address 0x60000000 and up.

    Reason for such Storage setup is that internal flash is faster and you can use data and run javascript in place - big strings points directly to flash and no RAM is needed for that.

    The best would be to have two Storage 'drives' one for javascript code and some smaller data files and another bigger one in SPI flash. There is issue for that idea here https://github.com/espruino/Espruino/iss­ues/1899

    Anyway, if you want just block access - circular buffer then indeed you don't need W25 module and the functionality can be builtin via the Flash API https://www.espruino.com/Reference#Flash­ if you map the SPI flash in board file.

  • The best would be to have two Storage 'drives' one for javascript code and some smaller data files and another bigger one in SPI flash. There is issue for that idea here https://github.com/espruino/Espruino/iss­ues/1899

    Got it, this looks like the use case I'm looking for. I'm was interested in the Storage API abstracting the access to the notion of files and doing the flash management behind the scenes, but I guess just designing the data so it fits the blocks (and then writing blocks) would work as well.

  • So in this case,

      'SPIFLASH' : {
                'pin_cs' : 'D21',
                'pin_sck' : 'D19',
                'pin_mosi' : 'D27', # D0
                'pin_miso' : 'D20', # D1
                'pin_wp' : 'D31', # D2
                'pin_rst' : 'D17', # D3
                'size' : 4096*1024, # 4MB
                'memmap_base' : 0x60000000 # map into the address space (in software)
              }
    

    if I add something like that in a custom board file, is there anything else i need to do so I can have the same layout as you mentioned: Storage in internal flash and then SPI accessible via Flash API ? Or I just need to add that board definition and that's it?

  • Ah, looks like it's like this on the RAK5010

    # Use this for the 8mb external flash if chip is installed in board
    #    'address' : 0x60000000, # put this in external spiflash (see below)
    #    'page_size' : 4096,
    #    'pages' : 2048, # Entire 8MB of external flash
    #    'flash_available' : 512 - ((31 + 8 + 2)*4) # Softdevice uses 31 pages of flash, bootloader 8, FS 2. Each page is 4 kb.
      },
    };
    
    devices = {
      'LED1' : { 'pin' : 'D12' },
      # IS25WP064A QSPI flash
    #  'SPIFLASH' : { # Chip is not installed in board
    #            'pin_cs' : 'D42',  #  cs    P1.10
    #            'pin_sck' : 'D43', #  clk   P1.11
    #            'pin_mosi' : 'D3', #  d0    P0.03
    #            'pin_miso' : 'D47', #  d1    P1.15
    #            'pin_wp' : 'D46', #  d2    P1.14 
    #            'pin_rst' : 'D45', #  d3    P1.13
    #            'size' : 8192*1024, # 8MB
    #            'memmap_base' : 0x60000000 # map into the address space (in software)
    #          }
    };
    

    which I expect the commented out lines would relocate the storage to external flash

  • Yes, that's it. Keep storage (saved_code section) as is.

    Then use Flash.getFree() to see it is there, and then just read/write/erase it via adresses above 0x60000000.

    If the Flash api would return all zeroes then maybe you will also need to wake up SPI flash from deep sleep but maybe it will just work.

  • That's correct, yes - so if you just want the flash API you can do what you suggested. As soon as you try and access 0x60000000 and above then you'll be using the W25 :)

  • Thanks!

    One more question, I've got a few of the macronix qspi flash (the same one on the nRF52840DK)

    Does Espruino take advantage of quad spi on the nRF52840 or will it just run using normal spi?

  • It just uses normal SPI at the moment. As far as I know nRF52840 can actually map the memory into its address space in hardware, so that'd be an even better solution :)

  • Gotcha.

    Looking forward to the next Espruino board that incorporates the nRF52840 :)

  • Looks like everything's working:

    >require("Flash").getFree()
    =[
      { addr: 442368, length: 4096 },
      { addr: 1610612736, length: 16777216 }
     ]
    

    I used the common Arduino spi pins for the mapping:

      'SPIFLASH' : {
                'pin_cs' : 'D10', # cs
                'pin_mosi' : 'D11', # di
                'pin_miso' : 'D12', # do
                'pin_sck' : 'D13', # clk
                'size' : 8192*1024*2, # 16MB
                'memmap_base' : 0x60000000, # map into the address space (in software)
              },
    

    I wonder if we can just add in spiflash by default on the boards as a placeholder since spi can reuse the pins anyway (at least on the pixl, since it mimics the Arduino layout)? And maybe just pass in the cs pin when trying to use the Flash module just in case you'd want to reuse pin 10 for your own spi peripheral.


    1 Attachment

    • IMG_20201009_063322.jpg
  • That's great! I'm not so sure about having it built-in though - on Pixl.js I'm already having to leave out functionality I'd like (eg SHA256 and AES) just to get everything else in, so I think something like this probably isn't worth removing other functionality for.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Using Storage with the W25 flash chips

Posted by Avatar for parasquid @parasquid

Actions