• AVR Freaks

AnsweredHot!Flash writing

Page: 12 > Showing page 1 of 2
Author
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
2018/10/17 06:53:34 (permalink)
0

Flash writing

Hello,
 
I did not know if I should post this new thread here or in the XC16 section. So, sorry if I chose the wrong one.
 
I want to write one word in the Flah Memory (sometimes I saw the "EEPROM Data" term ... is the EEPROM a specific section of the FLASH ?)
I also want to use XC16 built-in-functions (just to try ...)
 
Down here what I did:
c_uint_test is a global variable, defined as this
const unsigned int c_uint_test=0xAAAA;
 
In a first time I tried to read this variable, thanks to built in functions:
unsigned char uint_page = __builtin_tblpage(&c_uint_test);
unsigned int uint_offset=__builtin_tbloffset(&c_uint_test);
    
TBLPAG=uint_page;
unsigned int uint_test= __builtin_tblrdl(uint_offset);

 
Everything's OK.
 
Then I tried to write another value in the FLASH, in the same adress:
unsigned int uint_NewValue=0xBBBB;
    
__builtin_tblwtl(uint_offset,uint_NewValue);
    
__asm__ __volatile__(
        "MOV #0x4003,W0     \n"
        "MOV W0,NVMCON      \n"
        "PUSH SR            \n"
        "MOV #0x00E0,W0     \n"
        "IOR SR             \n"
        );
  
__builtin_write_NVM();
__asm__ __volatile__("POP   SR");
uint_test= __builtin_tblrdl(uint_offset);

 
Neither c_uint_test nor uint_test is changed !
 
Can someone tell me why ?
 
Thank you so much.
Vincent.
 
PS: I checked the assembly code, every thing seems to be OK (down here)
      Line      Address       Opcode      Label                             DisAssy                         
      504    03EE          BB0801                  TBLWTL W1, [W0]                                           
      505    03F0          240030                  MOV #0x4003, W0                                           
      506    03F2          883B00                  MOV W0, NVMCON                                            
      507    03F4          F80042                  PUSH SR                                                   
      508    03F6          200E00                  MOV #0xE0, W0                                             
      509    03F8          B72042                  IOR SR                                                    
      510    03FA          200550                  MOV #0x55, W0                                             
      511    03FC          883B30                  MOV W0, NVMKEY                                            
      512    03FE          200AA0                  MOV #0xAA, W0                                             
      513    0400          883B30                  MOV W0, NVMKEY                                            
      514    0402          A8E761                  BSET 0x761, #7                                            


#1
JPortici
Super Member
  • Total Posts : 725
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Flash writing 2018/10/17 07:33:55 (permalink)
4 (1)
You need to tell for which part you are writing the code. There are subtle differences between families.
Did you read the relevant datasheet and reference manual chapters?
 
with flash memory you can only write from one to zero. This means that you first have to erase the location (so it's restored to all 1s) and only then you can write what you want.
If your dsPIC had ECC memory (but this is not the case i think) overwriting the memory will cause an ECC trap to be generated the moment you try to access the memory (mismatch with the ECC verification word).
 
You can't erase a single flash location but you can only erase it in pages. The size of the page varies with the device, so you have to refer to the datasheet, which means that if you only have to change a word you have to buffer the whole page before erasing it.
If the page is erased you can write to it single (or double if ECC memory is present) words, rows (a subset of a page), a whole page at a time.
Depending on the dsPIC you will have to write to the program latches before writing to the actual memory, others will be able to write the content of an array in RAM. Again, refer to datasheet and reference manual (the flash controller may be different so don't assume the REF chapter is the same for two parts, check in the document section of your controller)
#2
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/17 07:46:43 (permalink)
0
Hello JPortici,
 
First, thank you for your answer.
My 16bits PIC is the dsPIC33FJ32MC204. I read the datasheet, the section 5 of the reference manual, and the XC16 guide as well as possible.
 
What I understood is that I do not need to erase the flash before writing a signle word:
 
5.4.2.2 FLASH SINGLE WORD PROGRAMMING ALGORITHM
This algorithm is available for devices with multiple or single holding buffers.
The user-assigned application can program one word of Flash program memory (that is,
1 instruction word).
The general process is as follows:
1. Load the word (1 instruction word) from RAM into the write latch using a table write
operation.
2. Program the instruction word in Flash program memory.
a) Set up the NVMCON register to program one word of Flash program memory.
b) Disable interrupts.
c) Write the key sequence to the NVMKEY register to enable the program cycle.
d) Set the WR bit. This will start the program cycle.
e) The CPU will stall for the duration of the program cycle.
f) The WR bit is cleared by the hardware when the program cycle ends.
g) Re-enable interrupts.
 
(I didn't understand why it is necessary to erase the flash before to write a row)
 
In the same document, there is an example to do this. I compared this example to my dissambly code:
 
; Setup a pointer to data Program Memory
MOV #tblpage(PROG_ADDR),W0
MOV W0,TBLPAG
MOV #tbloffset(PROG_ADDR),W0
; Perform the TBLWT instructions to write the latches
MOV #LOW_WORD_N,W2
MOV #HIGH_BYTE_N,W3
TBLWTL W2,[W0]
TBLWTH W3,[W0++]
; Setup NVMCON for programming one word to data Program Memory
MOV #0x4003,W0
MOV W0,NVMCON
; Disable interrupts while the KEY sequence is written
PUSH SR
MOV #0x00E0,W0
IOR SR
; Write the key sequence
MOV #0x55,W0
MOV W0,NVMKEY
MOV #0xAA,W0
MOV W0,NVMKEY
; Start the write cycle
BSET NVMCON,#WR
;Re-enable interrupts, if needed
POP SR
#3
JPortici
Super Member
  • Total Posts : 725
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Flash writing 2018/10/17 08:02:21 (permalink)
5 (1)
I will assume that the prior erase is implied.
Document DS70191E - 5.4.2 Flash Programming Operations

A program or erase operation is necessary for
programming or erasing the internal Flash
program memory in RTSP mode

 
and

A row or word in Flash program memory
should not be programmed more than
twice before being erased

i find this "more than twice" unusual but that could explain why you could write to the word once: the memory location is written once by the programmer, you write for the second time...
 
(maybe, but i'm speculating here, the flash memory is 48bits wide in these parts too, with the first write you write to the upper 24bit, with the second write you write to the lower 24 bit and tell the flash controller that it has to fetch that word instead of the old one. When you erase the memory you get the whole 48 bits again so you can write it in two times. Again this is speculation and i'd love for someone to chime in to confirm or dismiss)
#4
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/17 08:14:31 (permalink)
0
That means that I have to erase a full page, even if I want to write a single word ?
That means that I have to erase 512 instructions, just to write one word ?
(by the way, I found your explanation very intersting)
#5
du00000001
Just Some Member
  • Total Posts : 3008
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: Flash writing 2018/10/17 12:22:58 (permalink)
4 (1)
@ liebart
You start getting the picture: erasing flash (whether data or program flash) resets all bits to '1'. "Programming" only can alter bits from '1' to '0' - not the other way.
Thus often special algorithms are used to reduce the number of erase cycles (that add to flash "wear": either looking for the 'last' (in whatever order) non-FF value or to devalidate values no longer valid by overwriting them with 00.
Both methods require at least one bit o indicate whether a value is/has been written: '0' in the former case, '1' (then devalidated to '0') in the latter.
In any case the address of a variable in such a data block is not constant but varying with the number of updates.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#6
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/19 00:36:53 (permalink)
0
@ du00000001
I've been heard that is it the opposite: since writting a "0" takes much longer than wrritting a "1", we erase a full row, then we write only the "1's"
 
@JPPortici
Can you tell me why we talk about a 512 instructions row for Flash Memory? I does not match with any size of page of adressing.
Also, I did not understand the "48 bit wide" ... is this a buffer or something ?
 
Thank you all
#7
du00000001
Just Some Member
  • Total Posts : 3008
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: Flash writing 2018/10/19 00:57:51 (permalink)
5 (2)
You heard wrong. There's no freedom of choice - erasing is putting everything to 1s, programming is writing 0s. That han't changed since the age of the (UV-erasable) EPROMs.
 
And the flash block size(s) are usually a power of 2 - reflecting how many address lines are used to select the block(s) and how many address lines go into the block. This has nothing to do with an eventual "page:offset" addressing scheme.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#8
JPortici
Super Member
  • Total Posts : 725
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Flash writing 2018/10/19 01:11:21 (permalink)
5 (2)
it's 512 instructions because the datasheet says so. Different flash sizes may come with different page sizes so always check the datasheet.
 
The 48 bit thing:
The flash memory is probably organized in words of 48 bit. Doesn't matter that the flash controller lets you read single bytes, the physical word width is probably 48 bit.
I base this assumption on the fact that parts with ECC memory have the ECC byte calculated for two words. In fact, in these parts the smallest amount of memory you can write is a double-word (48 bit)
From the reference manual:
DS70000613DWhen data is written to program memory, ECC generates a 7-bit Hamming code parity value for
every two (24-bit) instruction words. The data is stored in blocks of 48 data bits and 7 parity bits;

 
So, since in a memory of the flash type you can only write from 1 to 0 AND you have to erase the memory block to restore the memory to all 1s AND you can only erase in pages,
the fact that you can "write on program memory up to two times before having to erase" suggests to me that if you have a 16kByte part you actually have a 32kbyte memory, and the flash controller is masking this fact by showing the upper 24bit or the lower 24bit, depending if one or both are programmed, thus allowing you two writes on the same memory location after an erase
 
wish there was a DIE photo :(
#9
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/19 02:03:13 (permalink)
0
du00000001
 
This has nothing to do with an eventual "page:offset" addressing scheme.




Thank you, that's what I understood ... an opposite answer would have disappointed me :)
 
 
du00000001
 
And the flash block size(s) are usually a power of 2 - reflecting how many address lines are used to select the block(s) and how many address lines go into the block.


 
Can you tell me why the FLASH memory is physically organized into rows of 64 instructions ?
Also, I have the same question about the 512 instructions wide blocks.
 
Thank you
#10
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/19 02:22:15 (permalink)
0
Jack_M
it's 512 instructions because the datasheet says so. Different flash sizes may come with different page sizes so always check the datasheet.
 
The 48 bit thing:
The flash memory is probably organized in words of 48 bit. Doesn't matter that the flash controller lets you read single bytes, the physical word width is probably 48 bit.
I base this assumption on the fact that parts with ECC memory have the ECC byte calculated for two words. In fact, in these parts the smallest amount of memory you can write is a double-word (48 bit)
From the reference manual:
DS70000613DWhen data is written to program memory, ECC generates a 7-bit Hamming code parity value for
every two (24-bit) instruction words. The data is stored in blocks of 48 data bits and 7 parity bits;

 
So, since in a memory of the flash type you can only write from 1 to 0 AND you have to erase the memory block to restore the memory to all 1s AND you can only erase in pages,
the fact that you can "write on program memory up to two times before having to erase" suggests to me that if you have a 16kByte part you actually have a 32kbyte memory, and the flash controller is masking this fact by showing the upper 24bit or the lower 24bit, depending if one or both are programmed, thus allowing you two writes on the same memory location after an erase
 
wish there was a DIE photo :(



Really clear ... I do appreciate the time you spent to explain this to me
 
#11
du00000001
Just Some Member
  • Total Posts : 3008
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: Flash writing 2018/10/19 08:32:40 (permalink)
0
Flash block size is some design decision:
smaller blocks require more "infrastructure" regarding block erasing and block programming (typically 1 erase and program unit per block). Thus, larger blocks reduce this kind of "overhead" while affecting the way you can use these blocks.
Typically, program flash blocks are larger while data flash tends to present smaller, but more blocks.

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#12
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Flash writing 2018/10/19 14:30:06 (permalink)
5 (3)
liebart
@ du00000001
I've been heard that is it the opposite: since writting a "0" takes much longer than wrritting a "1", we erase a full row, then we write only the "1's"

I'd be really curious to see where this information came from, and what other "suggestions" the same source had...
 

Nearly there...
#13
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3233
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/20 07:40:40 (permalink)
0
Sounds dum, link ???

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#14
rweiser
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/09/18 21:52:47
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/25 01:19:42 (permalink)
0
Hello,
 
I need to write some values to flash and then get them back from program memory if the device losses power and is turned on again. My code is based on the example found at http://microchipdeveloper.com/16bit:flash-write
 
The code compiles and it seems to be OK, however, when I look at the variable that was modified by the write flash operation, this is still 0, so nothing has happened. I think the problem might be related to the data type of this variable.
 
Attached the code:
 
#define pagelenght 1024
#define rowlenght 128

const volatile uint16_t __attribute__((space(prog), address(0x47EC)))iParameters[pagelenght*2];

void readFlashPage(void)
{
    int offset,i;
    TBLPAG =__builtin_tblpage(&iParameters);
    offset = __builtin_tbloffset(&iParameters);
    offset &= 0x47EC;
    for(i=0;i<(pagelenght*2);i++)
    {
        RamBuffer[i++] = __builtin_tblrdl(offset);
        RamBuffer[i] = __builtin_tblrdh(offset);
        offset += 2;
    }
}

void updateRamBuffer(void)
{
    RamBuffer[1]=alarmFrequency;
    RamBuffer[3]=alarmCadence;
    RamBuffer[5]=currentTrigger;
}

void eraseFlashPage(void)
{
    int offset;
    NVMADRU = __builtin_tblpage(&iParameters);
    offset = __builtin_tbloffset(&iParameters);
    NVMADR = (offset & 0x47EC);
    NVMCONbits.WREN = 1;
    NVMCONbits.NVMOP = 0b0011;
    __builtin_disi(6);
    __builtin_write_NVM();
}

void rowFlashWrite(void)
{
    int offset, i;
    TBLPAG = 0xFA;
    offset = 0;
    for(i=0;i<rowlenght*2;i++)
    {
        __builtin_tblwtl(offset,RamBuffer[i++]);
        __builtin_tblwth(offset, RamBuffer[i]);
        offset += 2;
    }
    NVMADRU = __builtin_tblpage(&iParameters);
    offset = __builtin_tbloffset(&iParameters);
    NVMADR = (offset & 0x47EC);
    NVMCONbits.WREN = 1;
    NVMCONbits.NVMOP = 0b0010;
    __builtin_disi(6);
    __builtin_write_NVM(); 
}

void programParameters(void)
{
    updateRamBuffer();
    eraseFlashPage();
    rowFlashWrite(); 
}

 
What I am doing is:
  1. Calling readFlashPage()
  2. If RamBuffer is 0 get alarmFrequency, alarmCadence and currentTrigger otherwise assign RamBuffer first variables to the program variables
  3. Fill RamBuffer with the newly calculated parameters
  4. Call programParameters()
After executing programParameters() I only have 0's in the iParameters array, I was expecting to write the values from RamBuffer.
 
Thanks for the help
#15
du00000001
Just Some Member
  • Total Posts : 3008
  • Reward points : 0
  • Joined: 2016/05/03 13:52:42
  • Location: Germany
  • Status: online
Re: Flash writing 2018/10/25 01:47:30 (permalink)
0
@ rweiser
Start your own thread instead of capturing an existing one !

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
#16
rweiser
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/09/18 21:52:47
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/25 02:14:42 (permalink)
0
I would love to but when I try to create a new thread and click submit post I get the access denied page :/
#17
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Flash writing 2018/10/25 02:20:51 (permalink)
5 (1)
Try not putting a live URL in that first post.
It's triggering the stupid firewall that is running on this web server.
 

Nearly there...
#18
rweiser
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/09/18 21:52:47
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/25 02:33:00 (permalink)
0
@qhb Tried that but still getting the access denied
#19
liebart
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/05/27 01:38:14
  • Location: 0
  • Status: offline
Re: Flash writing 2018/10/29 02:45:50 (permalink)
0
qhb
 
I'd be really curious to see where this information came from, and what other "suggestions" the same source had...
 




Someone who looked very kind ... so I trusted him :( The next time I will double check a such information
Sorry ! (and thank you)
 
 
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5