Wireless Programming with SST 25VF040B FLASH mem chip

Started by back2live, February 24, 2016, 01:59:37 AM

back2live

Hello,

im trying to wireless programm with this Flash chip.
http://ww1.microchip.com/downloads/en/DeviceDoc/20005051C.pdf

The Flash was detected as 0xBF25
With the SPIFlash_ReadWrite.ino i can write and dump, erase also works.

If i send the hex ota, the 328 will start with the old Programm. I cecked with SPIFlash_ReadWrite.ino and there are not the correct values in the Flash, the first 7 Bytes are FF and then the code starts.
On page 5 i found:
3.0 MEMORY ORGANIZATION
The SST25VF040B SuperFlash memory array is organized
in uniform 4 KByte erasable sectors with 32
KByte overlay blocks and 64 KByte overlay erasable
blocks.


In programming code these programming commands are used, so i think this should work.

The intructions of the Flash except powerdown commands are the same.

I dont have the logs from Windows sender and the Moteino aviable at the moment. But There everthing lookong fine. Transfer do work with 1 2 or 3 (fast)

Andy

Felix

Hi,
I don't have that chip but if the pinout and commands are the same I would expect the outcome to be the same.
You did not mention anything about your moteino or if you have a custom built one or just an atmega328, is it loaded with DualOptiboot?
Try to compare your FLASH content after the WP is complete. Do a dump and then check the first few dozen bytes or so. They should match the HEX data (without the HEX headers and checksum).

back2live

#2
Hi,

thank you for your answer.

as bootloader i use DualOptiboot_V5.0_atmega328_BlinkD9.hex
Monteino is R4 own build.
Fuses are: E:FD H:DC L:DE

After some hours i think it is maybe a Problem with self programming.


Windows side with OTA Programmer 1.3:
Opening COM6 @ 115200baud ...
SET TARGET: TO:2
Moteino: [TO:2:OK]
TARGET SET OK
FLX?
FLX?
Moteino: [FLX?OK]
HANDSHAKE OK!
TX > FLX:0:300000000C94E1000C941A170C9441170C9409010C9409010C9409010C94E5160C9409010C9409010C9409010C9409010C9409019B
Moteino: FLX:0:OK
TX > FLX:1:300030000C9409010C9409010C9409010C9409010C9468170C9409010C94671A0C94991A0C9409010C9409010C9409010C94090113
Moteino: FLX:1:OK
TX > FLX:2:300060000C946B150C9409010000000800020100000304070000000000000000010204081020408001020408102001020408102010
.
.
.
TX > FLX:395:3049D80064617461202E2E2E2000444F4E450000000000B21385135A1362137513841300000000A0190C1B22193B192D197E190D6E
Moteino: FLX:395:OK
TX > FLX:396:0E4A08000A006E616E00696E66006F766600D1
Moteino: FLX:396:OK
Moteino: [FLX?OK]
EOF 
SUCCESS! (time elapsed: 21,81s)


On Moteino side:
[254] FLX?FLX?OK (ACK sent)
Shifting channel to 869000000
radio [54] > 464c583a303a0c94e1000c941a170c9441170c9409010c9409010c9409010c94e5160c9409010c9409010c9409010c9409010c940901
FLX:0:OK
radio [54] > 464c583a313a0c9409010c9409010c9409010c9409010c9468170c9409010c94671a0c94991a0c9409010c9409010c9409010c940901
FLX:1:OK
radio [54] > 464c583a323a0c946b150c94090100000008000201000003040700000000000000000102040810204080010204081020010204081020
FLX:2:OK
.
.
.
radio [56] > 464c583a3339353a64617461202e2e2e2000444f4e450000000000b21385135a1362137513841300000000a0190c1b22193b192d197e190d
FLX:395:OK
radio [22] > 464c583a3339363a0a006e616e00696e66006f766600
FLX:396:OK
FLX?OK
UNShifting channel to 868000000
FLASH IMG TRANSMISSION SUCCESS!
REBOOTING...?

Then it does reset automaticaly by watchdog as it should.


After atomatic reset i flash SPIFlash_ReadWrite.ino and do for example "i" and then "d"
i get:
Start...Init OK!
DeviceID: BF25
Flash content:
FF.FF.FF.FF.FF.FF.FF.4A.16.3A.C.94.E1.0.C.94.1A.17.C.94.41.17.C.94.9.1.C.94.9.1.C.94.9.1.C.94.E5.16.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.68.17.C.94.9.1.C.94.67.1A.C.94.99.1A.C.94.9.1.C.94.9.1.C.94.9.1.C.94.9.1.C.94.6B.15.C.94.9.1.0.0.0.8.0.2.1.0.0.3.4.7.0.0.0.0.0.0.0.0.1.2.4.8.10.20.40.80.1.2.4.8.10.20.1.2.4.8.10.20.4.4.4.4.4.4.4.4.2.2.2.2.2.2.3.3.3.3.3.3.0.0.0.0.23.0.26.0.29.0.0.0.0.0.25.0.28.0.2B.0.0.0.0.0.24.0.27.0.2A.0.0.40.7A.10.F3.5A.0.A0.72.4E.18.9.0.10.A5.D4.E8.0.0.E8.76.48.17.0.0.E4.B.54.2.0.0.CA.9A.3B.0.0.0.E1.F5.5.0.0.80.96.98.0.0.0.40.42.F.0.0.

so it seems that dualoptiboot does erase the "FLXIMG:"  after selfprogramming but it does not work, the old programm is still there.

Andy

Felix

Yup that FLASH dump signature does not look right, it's blank.
If you look at the dualoptiboot source, you will notice that it will try to erase the whole 32k block, not just a few bytes.
Also, if you look at the WirelessHEX library, you will notice that the FLXIMG: header is written first, then the image, then the :NN: byte count part of the header, before the WDT reboot.
So I don't know what's deleting your header.
It's entirely possible that your chip won't allow additional writing once a block is written to, something to look into.

back2live

Yes you where right. If it was the BL then 32k.

So it seems that the function flash.writeBytes will not work with this flashchip.

I will look later why...

i do a change in WirelessHEX69.cpp

i replaced:
flash.writeBytes(0,"FLXIMG:", 7);


with:

  flash.writeByte(0,'F');
  flash.writeByte(1,'L');
  flash.writeByte(2,'X');
  flash.writeByte(3,'I');
  flash.writeByte(4,'M');
  flash.writeByte(5,'G');
  flash.writeByte(6,':');



and now it is working :)

thank you

Andy

Felix

Interesting, thanks for the update.
Let me know if you can debug the cause why the writeBytes does not work with that chip.

back2live

#6
Hi,

i do some test and look in the Datasheet of the Flashs.

something like this should work with both flashtypes:

void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
  uint16_t n;
  uint16_t maxBytes = 256-(addr%256);  // force the first set of bytes to stay within the first page
  uint16_t offset = 0;
  while (len>0)
  {
    n = (len<=maxBytes) ? len : maxBytes;
   
    for (uint16_t i = 0; i < n; i++)
	{
        command(SPIFLASH_BYTEPAGEPROGRAM, true);  // Byte/Page Program
        SPI.transfer(addr >> 16);
        SPI.transfer(addr >> 8);
        SPI.transfer(addr);
        SPI.transfer(((uint8_t*) buf)[offset + i]);
        unselect();
	addr++;
	}
    
    addr+=n;  // adjust the addresses and remaining bytes by what we've just transferred.
    offset +=n;
    len -= n;
    maxBytes = 256;   // now we can do up to 256 bytes per loop
  }
}


The Byte write command is a little different, so setting every Byte to the right write Position is working.