You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • &~2047 means 'round down to the nearest 2048' - you need 2048 because that's the page size. What it's doing is setting the bottom 11 bits of the number to 0.

    So, (x+2047)&~2047 rounds up to the nearest 2048.

    The EEPROM emulation really isn't that bad. Think of it this way:

    • have one block of 2048 bytes
    • split it into 4 byte records (we have to write 4 bytes at once)
    • In each record, the first (top) byte can be a number that's the 'address', and the bottom 3 bytes is data
    • To write, you just write a new record on the end of the block (any unwritten value will be all 1s, so the value 0xFFFFFFFF)
    • To read, go through the whole block from the end backwards, looking for the record with the 'address' you want. If the same address was written more than once it doesn't matter, because we're only looking for the last one
    • When you write and the block is full, run through the block working out all the current values, erase it, and write them back in.

    I just had a go at doing this - just use the code below. At some point (if it works ok) I'll have a go at packing it into a module:

    var f = require("STM32F1Flash");
    f.unlock(); // unlock the memory
    
    var baseAddr = (process.memory().flash_binary_end+2047)­&~2047;
    var currentRecord = 0;
    // when we start up, find out how full we are
    while (f.read(baseAddr+currentRecord)!=-1)
      currentRecord+=4;
    
    // read data from the end backwards
    function read(addr) {
      var i = currentRecord-4;
      while (i>=0) {
        var d = f.read(baseAddr+i);
        if ((d>>>24) == addr) return d&0xFFFFFF;
        i-=4;
      }
    }
    
    function readAll() {
      var arr = [];
      for (var i=0;i<currentRecord;i+=4) {
        var d = f.read(baseAddr+i);
        arr[d>>24] = d&0xFFFFFF;
      }
      return arr;
    }
    
    function write(addr, data) {
      if (currentRecord < 2048) {
        f.write(baseAddr+currentRecord, (addr<<24)|(data&0xFFFFFF));
        currentRecord+=4;
      } else { 
       console.log("Compacting...");
       // we're full - we need to 'compact' the block
       // read data in
       var arr = readAll();
       // erase the block
       f.erase(baseAddr);
       currentRecord = 0;
       // write the data back
       for (var i in arr) write(i, arr[i]);
      }
    }
    
About

Avatar for Gordon @Gordon started