Re: Flash erase byte routine
Hi Sheldon,
Have you got the data sheet so that I can do some reading?
Re: Flash erase byte routine
Re: Flash erase byte routine
should be doable just break job up to small lumps
say you have a 1k ram block spare
step 1 erase a temp sector (64k) on the flash
1. read a k of old sector data
2 . does this k need to updated?
if yes update this 1k block
write this block to temp sector
3 repeat step 2 63 more times (for each 1k block)
4 erase old sector (now copied to temp with updates)
5 copy temp sector back to old sector
end
just had a look at your data sheet
looks like 256 byte blocks may be more appropriate
and 100,000 write cycles , how often will you be doing this
still think raspberry pi a more fitting machine for this type of work
Re: Flash erase byte routine
Reading the data sheet and your code example makes me think this statement is not true.
Quote:
The FLASH as i have learned is not the same as EEProm in that you cant just change bytes values as you may like to on the fly , changing byte to $FF requires your do a complete sector erase , depending on the chip and the size the sector erase can range from 4k bytes to 64k bytes at a time.
and a write to any location is possible. But I will keep reading
Re: Flash erase byte routine
Hi,
Yes, they can be programmed one byte at the time at any arbitrary memory location. However, "programming" means changing (or not changing) a "1" to a "0". You can't change a "0" to a "1".
So, before you can program a location it needs to be erased ("reset" to $FF). Erasing is done either sector by sector or the entire chip (bulk).
/Henrik.
Re: Flash erase byte routine
Quote:
Originally Posted by
HenrikOlsson
Hi,
Yes, they can be programmed one byte at the time at any arbitrary memory location. However, "programming" means changing (or not changing) a "1" to a "0". You can't change a "0" to a "1".
So, before you can program a location it needs to be erased ("reset" to $FF). Erasing is done either sector by sector or the entire chip (bulk).
/Henrik.
Yes I understand now. I was having difficulty finding the write command in the data sheet but as you explained the program command is used.
Re: Flash erase byte routine
yep have a look in the example of the code i have posted in the examples , but hendrik is correct the large bulk and sectors erase options suck for a byte change when the location has been written before
even with this routine its a time pain but Flash are large chips/cheep and if time is a worry then sram /eeproms are probably a option better suited , but there are time when only a few bytes changed option is very nice to have on flash chip
i am thinking maybe 2 x for, next loop based on the selected location for the change , eg , if selected page/byte is x then copy data to x-1 , and next loop x +1 , this is then done for lower address to lentght of data changed then set upper address
Re: Flash erase byte routine
Hi Sheldon,
Looking at the datasheet for your device it specifies a sector erase time of 3 seconds(!) and a bulk erase time of 20 seconds (!) - is that really correct?
The one I've been playing with is the SST25VF080B from Microchip, which is an 8Mbit SPI flash memory device with "only" 4k sectors. It specifies a sector erase time of 25ms and a chip erase time of 50ms (50ms vs 20s for a chip erase).
Using the SST25VF80 instead of the M25P80 should allow you to get the overall performance up due to the smaller sector size and cosiderably faster erase time - provided the 3second sector erase time is indeed correct. Then, of course, using bit banged SPI is really slow compared to using the MSSP module.
/Henrik.
Re: Flash erase byte routine
yes i have seen better chips and will change to them , the routines work for all the same size chip , ill how much i can get the SST25VF080B for ,
but ill also try W25Q80BV - have ordered 200 of these at 6c each + freight
these when they arrive they have a 4k erase space option , and have 25ms time to do it , plus other optionsthat come from the Q series of flash .
be it 4k or 64k , a routine to change say 1- 256k bytes in the same sector/page on the fly is really nice routine to have on hand on these chips and would be easy enought o change to the size that best suites your needs
http://www.adafruit.com/datasheets/W25Q80BV.pdf
Re: Flash erase byte routine
Quote:
Originally Posted by
longpole001
be it 4k or 64k , a routine to change say 1- 256k bytes in the same sector/page on the fly is really nice routine to have on hand on these chips and would be easy enough to change to the size that best suites your needs
We need to start on the routine or have you started?
Your approach in #1 is to copy sectors to be changed to sector 0. The routine will read from the sector 0 into say byte variables these will then be changed if required and written to Flash. This will be repeated for the whole 4k.
Any thoughts?
Re: Flash erase byte routine
yep steve i was thing something like this
1. erase sector 0
2 write the changed bytes to sector 0 for page / byte /length data
3. using the address and number of byte to change length( assumes 1- 256 bytes contiguous) get the all OTHER pages/ bytes in orginal sector and write to sector 0
so need to find value of entered page address and read into the buffer (256kb) , then write
a. input page + 1 (data above the input page) for next loop 1 -
b. input page -1 ( data below the input page) for next loop 2
c. allow for input page location = 0 or 255 - so for next loop 1 only
this then copy of all pages EXCEPT that which need to change
If the input length was 255 then sector 0 has copy of the completed changed data
if length <255 bytes change then
then use the input length and byte start address value to read / write
a. read bytes start address + length + 1 - for next loop1 - ( read the bytes above that dont need to change)
b. read bytes start address + length - 1 - for next loop2 - ( read the bytes below that dont need to change)
c. allow for input bytes location + length of 0 or 255 - so for next loop 1 only
this then copy of all bytes except that which have been changed
now do a sector erase of the orginal sector
now read/ write each page back from sector 0 each page
not easy but as hedric said the smaller the sector erase size the less time it takes
Re: Flash erase byte routine
Sorry to interrupt... I'm just following along for the sake of understanding how this is managed.
Do I read you right? Using sector 0 as a scratchpad? Reading X sector to 0 WITH changes, then erasing X sector, then writing sector 0 to X? Finally, erasing sector 0, so its blank for the next go-round? Or did I miss something?
I think I'll read your post a few more times... see if I can't follow your thinking better. Thanks.
Re: Flash erase byte routine
yes that what i am thinking
sector 0 is erased
if the bytes to be changed are say bytes 5 - 10 for sector 15, page 1 then you
write changed data to sector 0/ page 1 / bytes 5-10
you copy bytes 0-4 of sector 15/page1 to sector 0/page1/ bytes 0-4 - for next loop 1
you copy bytes 11-255 of sector 15/page1 to sector 0/page1/ bytes 11-255 - for , next loop2
copy all other pages from sector 15 to sector 0 -
erase sector 15
copy sector 0 to 15 ( in
as you can see the smaller the sector erase the chip supports the better for small changes
Re: Flash erase byte routine
steve you want to have a go at it ?
Re: Flash erase byte routine
Quote:
Originally Posted by
longpole001
steve you want to have a go at it ?
I could give it a go. How far have you got?
Re: Flash erase byte routine
Code:
Flash_Byte_Modify:
' assumes address , length ( upto 256bytes )
' assumes sector 0 is not protected
SDC_sector = 0
gosub Flash_Sec_Erase ' erase sector 0
SDC_address.byte2 = 0 ' use sector 0,instead of given sector , but use given page, byte length
gosub Flash_write ' Write the the changed data to sector 0
if SDC_page > 0 and SDC_page <255 then ' find the pages to copy
SDC_address.byte2 = 0
SDC_address.byte1 = SDC_page
if Data_Length < 255 then
SDC_address.byte0 = SDC_byte +1 -
well not far , this is the start
Re: Flash erase byte routine
bit more of an attempt , steve can you check the logic ,cleanup ,
Code:
Flash_Byte_Modify:
' assumes address , length ( upto 256bytes )
' assumes sector 0 is not protected
' assumes selectted sector is not protected
Flash_Addr_Copy.byte3 = Data_Length ' save the selected address & length
Flash_Addr_Copy.byte2 = SDC_Sector
Flash_Addr_Copy.byte1 = SDC_Page
Flash_Addr_Copy.byte0 = SDC_Byte
SDC_sector = 0
gosub Flash_Sec_Erase ' erase sector 0
SDC_sector = 0 ' use sector 0,instead of given sector , but use given page, byte length
gosub Flash_write ' Write the the changed data to sector 0
if Flash_Addr_Copy.byte1 = 0 then ' find the pages to copy - copy all pages/ bytes above 0 for given sector
for SDC_Page = 1 to 255 ' read all pages above 0 of selected sector
SDC_Sector = Flash_Addr_Copy.byte2 ' of read selected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Read ' read 255 bytes at a time
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Write ' write
next SDC_Page
endif
if Flash_Addr_Copy.byte1 = 255 then ' find the pages to copy - copy all pages/ bytes below given page/ byte of sector
for SDC_Page = 0 to 254 ' read all pages below 255 of selected sector
SDC_Sector = Flash_Addr_Copy.byte2 ' of read selected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Read ' read 255 bytes at a time
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Write ' write
next SDC_Page
endif
if Flash_Addr_Copy.byte1 >0 and Flash_Addr_Copy.byte1 < 254 then ' find the pages to copy - copy all pages/ bytes below given page/ byte of sector
for SDC_Page = 0 to Flash_Addr_Copy.byte1 - 1 ' read all pages from 0 to selected page -1
SDC_Sector = Flash_Addr_Copy.byte2 ' of read selected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Read ' read 255 bytes at a time
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Write ' write
next SDC_Page
endif
for SDC_Page = Flash_Addr_Copy.byte1 + 1 to 255 ' read all pages from selected page + 1 to 255
SDC_Sector = Flash_Addr_Copy.byte2 ' of read selected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Read ' read 255 bytes at a time
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_byte = 0 ' bytes 0 - 255
Data_Length = 255 ' all bytes
gosub Flash_Write ' write
next SDC_Page
endif
endif
if Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 < 255 then ' if the start byte + data length of the data changed is < 255 bytes ,
' then copy bytes below the selected changed data
SDC_Sector = Flash_Addr_Copy.byte2 ' read selected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = 0 ' start address bytes 0 to
Data_Length = Flash_Addr_Copy.byte0 - 1 ' selected byte - 1 ( length)
gosub Flash_Read ' read
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = 0 ' start address bytes 0 to
Data_Length = Flash_Addr_Copy.byte0 - 1 ' selected byte - 1 ( length)
gosub Flash_Write ' write
' then copy bytes above the selected changed data
SDC_Sector = Flash_Addr_Copy.byte2 ' read selected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 ' start address bytes above given address and length
Data_Length = 255 - SDC_byte ' data above changed bytes ( length = 255 bytes - given addrees + given length )
gosub Flash_Read ' read the data
SDC_Sector = 0 ' use sector 0
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 ' start address bytes above given address and length
Data_Length = 255 - SDC_byte ' data above changed bytes ( length = 255 bytes - given addrees + given length )
gosub Flash_Write ' write the data
endif
' Sector 0 should now have a complete copy of the data + changed data from the orginal selected sector
SDC_sector = Flash_Addr_Copy.byte2
gosub Flash_Sec_Erase ' erase orginal sector
for SDC_PAGE = 0 to 255 ' copy sector 0 pages to selected sector 0 ( 256bytes at a time)
SDC_Sector = 0 ' use sector 0
SDC_byte = 0
Data_Length = 255
gosub Flash_Read ' read the data
SDC_Sector = Flash_Addr_Copy.byte2 ' use selected sector
SDC_byte = 0
Data_Length = 255
next SDC_PAGE
SDC_sector = 0 ' clean up sector 0
gosub Flash_Sec_Erase ' erase orginal sector
return
Re: Flash erase byte routine
I will do! Just need a bit of time to absorb the logic.
Re: Flash erase byte routine
forgot to write the data at the end
Code:
' Sector 0 should now have a complete copy of the data + changed data from the orginal selected sector
SDC_sector = Flash_Addr_Copy.byte2
gosub Flash_Sec_Erase ' erase orginal sector
for SDC_PAGE = 0 to 255 ' copy sector 0 pages to selected sector 0 ( 256bytes at a time)
SDC_Sector = 0 ' use sector 0
SDC_byte = 0
Data_Length = 255
gosub Flash_Read ' read the data
SDC_Sector = Flash_Addr_Copy.byte2 ' use selected sector
SDC_byte = 0
Data_Length = 255
gosub Flash_write ' write the data
next SDC_PAGE
SDC_sector = 0 ' clean up sector 0
gosub Flash_Sec_Erase
return
Re: Flash erase byte routine
well approach seems to work , here is a rundown , the real key is USE A FLASH CHIP THAT SUPPORTS SMALL SECTOR ERASE SIZE AND USE THAT SETTING
3 new routines - to be added to examples i left
hope it save others time in the future
Regards
Sheldon
1. Flash_byte_modfy - use - change 1- 255 bytes of a selected sector/page ,
uses sector 0 as scratchpad and places changed code to sector 0 ,
copies all other pages / bytes not changed of the selected sector to sector 0
then erases the origin sector and copy complete sector 0 to origin
how to use
Code:
'---------- FLASH_MODIFY_BYTE TEST - example
Data_Length = 10 ' changed data length
For SDC_index = 0 to Data_Length
SDC_buffer[SDC_index] = SDC_index ' fill the changed data into buffer with values
next SDC_index
SDC_Sector = 1 ' sector start address for where data is to be placed
SDC_Page = 3 ' page start address for where data is to be placed
SDC_Byte = 16 ' byte start addresss for where data is to be placed
gosub Flash_Byte_Modify
Code:
Flash_Byte_Modify:
' assumes address , length ( upto 256bytes )
' asusmes bytes changed are in the same sector and no boundry cross
' assumes sector 0 is not protected
' assumes selected sector is not protected
Flash_Addr_Copy.byte3 = Data_Length ' save the selected address & length
Flash_Addr_Copy.byte2 = SDC_Sector
Flash_Addr_Copy.byte1 = SDC_Page
Flash_Addr_Copy.byte0 = SDC_Byte
SDC_sector = 0
gosub Flash_Sec_Erase ' erase sector 0
SDC_sector = 0 ' use sector 0,instead of given sector , but use given page, byte length
gosub Flash_write ' Write the data to sector 0
if Flash_Addr_Copy.byte1 = 0 then ' find the pages to copy - copy all pages/ bytes above 0 for given sector
Flash_Page_Orgin =1 ' start page of orgin
Flash_Page_length = 255 ' how many pages
Flash_Sec_Orgin = Flash_Addr_Copy.byte2 ' sector
Flash_Sec_Dest = 0
Flash_Page_Dest = 1
gosub Flash_Page_Copy
endif
if Flash_Addr_Copy.byte1 = 255 then ' find the pages to copy - copy all pages/ bytes below given page/ byte of sector
Flash_Page_Orgin =0 ' start page of orgin
Flash_Page_length = 254 ' how many pages
Flash_Sec_Orgin = Flash_Addr_Copy.byte2 ' sector
Flash_Sec_Dest = 0
Flash_Page_Dest = 0
gosub Flash_Page_Copy
endif
if Flash_Addr_Copy.byte1 >0 and Flash_Addr_Copy.byte1 < 254 then ' find the pages to copy - copy all pages/ bytes below given page/ byte of sector
Flash_Page_Orgin =0 ' start page of orgin
Flash_Page_length = Flash_Addr_Copy.byte1 - 1 ' how many pages
Flash_Sec_Orgin = Flash_Addr_Copy.byte2 ' sector
Flash_Sec_Dest = 0 ' start at same page value as orgin
Flash_Page_Dest = 0
gosub Flash_Page_Copy
Flash_Page_Orgin = Flash_Addr_Copy.byte1 + 1 ' start page of orgin
Flash_Page_length = 255 - Flash_Page_Orgin ' panges to copy = 255 - start address +1
Flash_Sec_Orgin = Flash_Addr_Copy.byte2 ' sector
Flash_Sec_Dest = 0
Flash_Page_Dest = Flash_Addr_Copy.byte1 + 1
gosub Flash_Page_Copy
endif
if Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 < 255 then ' if the start byte + data length of the data changed is < 255 bytes ,
' then copy bytes below the selected changed data
SDC_Sector = Flash_Addr_Copy.byte2 ' read selected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = 0 ' start address bytes 0 to
Data_Length = Flash_Addr_Copy.byte0 - 1 ' selected byte - 1 ( length)
gosub Flash_Read ' read
SDC_Sector = 0 ' use sector 0 aselected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = 0 ' start address bytes 0 to
Data_Length = Flash_Addr_Copy.byte0 - 1 ' selected byte - 1 ( length)
gosub Flash_Write ' write
' then copy bytes above the selected changed data
SDC_Sector = Flash_Addr_Copy.byte2 ' read selected sector
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 ' start address bytes above given address and length
Data_Length = 255 - SDC_byte ' data above changed bytes ( length = 255 bytes - given addrees + given length )
gosub Flash_Read ' read the data
SDC_Sector = 0 ' use sector 0
SDC_PAGE = Flash_Addr_Copy.byte1 ' of selected page
SDC_byte = Flash_Addr_Copy.byte0 + Flash_Addr_Copy.byte3 ' start address bytes above given address and length
Data_Length = 255 - SDC_byte ' data above changed bytes ( length = 255 bytes - given addrees + given length )
gosub Flash_Write ' write the data
endif
' Sector 0 should now have a complete copy of the data + changed data from the orginal selected sector
Flash_Sec_Orgin = 0 ' copy sector 0
Flash_Sec_dest = Flash_Addr_Copy.byte2 ' erase destination and copy data from flash orgin
Flash_clear = 1 ' set flag erase orgin sector 0 after copy
gosub Flash_Sec_Copy ' copy the sector
return
2. Sector copy routine - - this routine copy the data from the origin sector to destination sector
- will erase destination sector prior to copy
- option flag " Flash_clear " when set will Erase orgin sector after copy
- assumes no copy protect on destination or origin
how to use
Code:
Flash_Sec_Orgin = 0 ' sector origin - sector to copy
Flash_Sec_dest = 1 ' sector destination - will be erased then copy data from sector origin
Flash_clear = 1 ' option flag to erase origin sector after copy
gosub Flash_Sec_Copy ' copy the sector
Code:
Flash_Sec_Copy:
' copys data from 1 sector to another
' erases destination sector - optional clean of orginal sector
' assumes Flash_Sect_Orgin,Flash_Sect_Dest Flash_clear
' Erases wont work on sectors that are write protected
' sector erase take 600ms per instruction
SDC_Sector = Flash_Sec_Dest ' clear destination sector
gosub Flash_Sec_Erase ' use SDC_sector info to erase destination sector
for SDC_PAGE = 0 to 255 ' copy sector 0 pages to selected sector 0 ( 256bytes at a time)
SDC_Sector = Flash_Sec_Orgin ' sector to copy
SDC_byte = 0
Data_Length = 255
gosub Flash_Read ' read the data to buffer
SDC_Sector = Flash_Sec_Dest ' sector to copy to
SDC_byte = 0 ' use sector details for destination
Data_Length = 255
gosub Flash_Write ' write the data
next SDC_PAGE
if Flash_clear = 1 then
SDC_sector = Flash_Sec_Orgin ' clean up orgin sector
gosub Flash_Sec_Erase
endif
return
3. Page copy routine - this routine will copy pages 0-255 of origin to destination
- no sector boundry cross supported
- assumes destination is all "1" - no erase is required
- sector is not protected
how to use
Code:
' example copy sector 0/ page 0 50 pages to sector 0 , start page 125 ( page size number of bytes depends on chip)
Flash_Page_Orgin = 0 ' start address page of origin
Flash_Page_length = 50 ' number of pages to copy
Flash_Sec_Orgin = 0 ' sector origin address
Flash_Sec_Dest = 0 ' Sector destination
Flash_Page_Dest = 125 ' Page destination
gosub Flash_Page_Copy
Code:
Flash_Page_Copy:
' copys data from pages 0 -255 from orgin or destination sector
' assumes destination sector pages are Erased
' assumes pages orgin and pages destination do not cross sector boundrys
' assumes Flash_Page_Orgin,Flash_Page_dest ,Flash_Page_length, Flash_Sec_orgin ,Flash_Sec_dest
' writes wont work on sectors that are write protected
for Flash_tmp2 = Flash_Page_Orgin to Flash_Page_length ' copy sector 0 pages to selected sector 0 ( 256bytes at a time)
SDC_Sector = Flash_Sec_Orgin ' sector to copy
SDC_PAGE = Flash_tmp2
SDC_byte = 0
Data_Length = 255
gosub Flash_Read ' read the data to buffer
SDC_Sector = Flash_Sec_Dest ' sector to copy to
SDC_PAGE = Flash_Page_Dest ' page to copy to
SDC_byte = 0
Data_Length = 255
gosub Flash_Write ' write the data
Flash_Page_Dest = Flash_Page_Dest + 1 ' increment destination page
next Flash_tmp2
return