Hi to everyone:
I have a question about MPC5554 flash.
In section 13.4.2.3 Flash Programming of MPC5553_4_Reference_Manual,_Rev_31,
" 2. Write the first address to be programmed in the Flash module with the program data. This write is referred to as a program data interlock write. An interlock write may be either be an aligned word
or double-word."
In order to realize this function, I wrote the following code
void FlashWrite(uint32 address_u32,uint32 data_u32)
{
*(uint32*)address_u32 = data_u32;
}
But it didn't work when debugging and the number in the address is still FF.
So,how to write data to mpc5554 through C code?
Best regards.
Solved! Go to Solution.
Hi,
you need to follow whole procedure described in section "13.4.2.3 Flash Programming". Not just one step.
I found this piece of test code in my repository:
/* Unlock block L0 at 0x0000_0000 */
FLASH.LMLR.R = 0xA1A11111;
FLASH.LMLR.R = 0xFFFFFFFE;
FLASH.SLMLR.R = 0xC3C33333;
FLASH.SLMLR.R = 0xFFFFFFFE;
/* Erase L0 block */
FLASH.MCR.B.ERS = 1;
FLASH.LMSR.R = 1;
*(unsigned int *)0x0 = 0xFFFFFFFF;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.ERS = 0;
/* Program the block with some data */
for(i=0;i<0x4000; i=i+8)
{
FLASH.MCR.B.PGM = 1;
*(unsigned int *)i = 0xAABBCCDD;
*(unsigned int *)(i+4) = 0x11223344;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.PGM = 0;
}
Notes:
- Read-While-Write (RWW) is supported only between partitions. See "Table 13-4. Flash Partitions" in the reference manual. When a partition is being programmed or erased, the code must run from another partition or from RAM.
- It is important to program only a doubleword which is fully erased:
"Whenever a program operation occurs, ECC bits are programmed. ECC is handled on a 64-bit boundary.
Thus, if only one word in any given 64-bit ECC segment is programmed, the adjoining word (in that
segment) should not be programmed because ECC calculation has already completed for that 64-bit
segment. Attempts to program the adjoining word will probably result in an operation failure. It is
recommended that all programming operations be from 64 bits to 256 bits, and be 64-bit aligned. The
programming operation should completely fill selected ECC segments within the page."
Regards,
Lukas
Hi,
you need to follow whole procedure described in section "13.4.2.3 Flash Programming". Not just one step.
I found this piece of test code in my repository:
/* Unlock block L0 at 0x0000_0000 */
FLASH.LMLR.R = 0xA1A11111;
FLASH.LMLR.R = 0xFFFFFFFE;
FLASH.SLMLR.R = 0xC3C33333;
FLASH.SLMLR.R = 0xFFFFFFFE;
/* Erase L0 block */
FLASH.MCR.B.ERS = 1;
FLASH.LMSR.R = 1;
*(unsigned int *)0x0 = 0xFFFFFFFF;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.ERS = 0;
/* Program the block with some data */
for(i=0;i<0x4000; i=i+8)
{
FLASH.MCR.B.PGM = 1;
*(unsigned int *)i = 0xAABBCCDD;
*(unsigned int *)(i+4) = 0x11223344;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.PGM = 0;
}
Notes:
- Read-While-Write (RWW) is supported only between partitions. See "Table 13-4. Flash Partitions" in the reference manual. When a partition is being programmed or erased, the code must run from another partition or from RAM.
- It is important to program only a doubleword which is fully erased:
"Whenever a program operation occurs, ECC bits are programmed. ECC is handled on a 64-bit boundary.
Thus, if only one word in any given 64-bit ECC segment is programmed, the adjoining word (in that
segment) should not be programmed because ECC calculation has already completed for that 64-bit
segment. Attempts to program the adjoining word will probably result in an operation failure. It is
recommended that all programming operations be from 64 bits to 256 bits, and be 64-bit aligned. The
programming operation should completely fill selected ECC segments within the page."
Regards,
Lukas
Dear Lukas:
Thank you very much for your help. According to the code you gave me, I wrote the relevant program again, but there was a new problem.Here is my code
/* Program the block with some data */
FLASH.MCR.B.PGM = 1;
*(unsigned int *)(0x00030010)= 0x12341234;
*(unsigned int *)(0x00030014) = 0x27582758;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.PGM = 0;
During debugging, I found that in the memory window of CodeWarrior, 0x00030010-0x00030019 is XX and 0x00030020 is 27 58 27 58 %x%x — —。
When I power up again and run the erase program:
FLASH.MCR.B.ERS = 1;
FLASH.LMSR.R = 1;
*(unsigned int *)0x0 = 0xFFFFFFFF;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.ERS = 0;
The situation in the memory window of CodeWarrior is still the same as above.
Excuse me, why does this happen and how to solve it?
Best regards.
韦恩
Hi,
'XX' is caused by overprogramming, most likely. As I already mentioned, make sure that the double word si fully erased before programming.
If the content of flash is still the same after programming, it's caused by cache. It's necessary to invalidate the cache after erase operation (see attached example). Or you can disable the cache or configure certain areas as cache inhibited by MMU.
Regards,
Lukas
Dear Lukas:
Thank you very much for your answer. I wonder if you mind if I ask two more questions:
1、 I ran the last code and found a new problem,Code 1 runs normally. When I run code 2, the program is abnormal and falls into an endless loop. I don't know where the problem is and how to solve it, so I ask for your help. Here is my code:
/* Unlock block L0 at 0x0000_0000 */
FLASH.LMLR.R = 0xA1A11111;
FLASH.LMLR.R = 0xFFFFFFFE;
FLASH.SLMLR.R = 0xC3C33333;
FLASH.SLMLR.R = 0xFFFFFFFE;
/* Erase L0 block */
FLASH.MCR.B.ERS = 1;
FLASH.LMSR.R = 1;
*(unsigned int *)0x0 = 0xFFFFFFFF;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.ERS = 0;
/* Program the block with some data */
FLASH.MCR.B.PGM = 1;
//code1
*(unsigned int *)0x00000000 = 0xAABBCCDD;
*(unsigned int *)0x00000004= 0x11223344;
//code2
//*(unsigned int *)0x00000F0F = 0xAABBCCDD;
//*(unsigned int *)0x00000F13= 0x11223344;
FLASH.MCR.B.EHV = 1;
while(FLASH.MCR.B.DONE == 0){};
if(FLASH.MCR.B.PEG == 0)
while(1){};
FLASH.MCR.B.EHV = 0;
FLASH.MCR.B.PGM = 0;
2、In section 13.3.2.2 Low/Mid Address Space Block Locking Register (FLASH_LMLR) and
13.3.2.5 Low/Mid Address Space Block Select Register (FLASH_LMSR) of Flash Programming of MPC5553_4_Reference_Manual,_Rev_31,
In this regard, I have two different understandings, and I do not know which one is right.I list two understandings. Please point out that the right or the two are incorrect.
Regards,
Lukas
Hi,
1. The address must be always aligned to 8 bytes when programming a doubleword.
If you program single word only, the address must be aligned to 4 bytes. But in this case, whole aligned doubleword must be in erased state and then you are not allowed to program second word in this doubleword because it's not in erased state anymore.
2. The bit mapping is very simple, see attached picture.
Regards,
Lukas
Dear Lukas:
Thank you very much for your answers.
Best wishes to you.
Yours 韦恩