The datasheet for the MK10DX256VLH7 states that the Program LongWord command will program FCCOB4 to FCCOB7 to addresses n to n+3, but when I check it, the word written has the bytes swapped.
It means I have to program:
enum { FTFL_ProgramLongWord = 0x06};
void programWord( int address, uint32_t value)
{
FTFL_BASE_PTR->FCCOB0 = FTFL_ProgramLongWord;
FTFL_BASE_PTR->FCCOB1 = address >> 16;
FTFL_BASE_PTR->FCCOB2 = address >> 8;
FTFL_BASE_PTR->FCCOB3 = address >> 0;
FTFL_BASE_PTR->FCCOB4 = value >> 24;
FTFL_BASE_PTR->FCCOB5 = value >> 16;
FTFL_BASE_PTR->FCCOB6 = value >> 8;
FTFL_BASE_PTR->FCCOB7 = value >> 0;
// start command and wait for completion
...
}
Digging deeper, I noticed as well the definition in KM10D7.h, which has a byte swapped ordered FCCOB declaration, contradicting the order described in the datasheet.
typedef struct FTFL_MemMap {
uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */
uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */
uint8_t FSEC; /**< Flash Security Register, offset: 0x2 */
uint8_t FOPT; /**< Flash Option Register, offset: 0x3 */
uint8_t FCCOB3; /**< Flash Common Command Object Registers, offset: 0x4 */
uint8_t FCCOB2; /**< Flash Common Command Object Registers, offset: 0x5 */
uint8_t FCCOB1; /**< Flash Common Command Object Registers, offset: 0x6 */
uint8_t FCCOB0; /**< Flash Common Command Object Registers, offset: 0x7 */
uint8_t FCCOB7; /**< Flash Common Command Object Registers, offset: 0x8 */
uint8_t FCCOB6; /**< Flash Common Command Object Registers, offset: 0x9 */
uint8_t FCCOB5; /**< Flash Common Command Object Registers, offset: 0xA */
uint8_t FCCOB4; /**< Flash Common Command Object Registers, offset: 0xB */
uint8_t FCCOBB; /**< Flash Common Command Object Registers, offset: 0xC */
uint8_t FCCOBA; /**< Flash Common Command Object Registers, offset: 0xD */
uint8_t FCCOB9; /**< Flash Common Command Object Registers, offset: 0xE */
uint8_t FCCOB8; /**< Flash Common Command Object Registers, offset: 0xF */
uint8_t FPROT3; /**< Program Flash Protection Registers, offset: 0x10 */
uint8_t FPROT2; /**< Program Flash Protection Registers, offset: 0x11 */
uint8_t FPROT1; /**< Program Flash Protection Registers, offset: 0x12 */
uint8_t FPROT0; /**< Program Flash Protection Registers, offset: 0x13 */
uint8_t RESERVED_0[2];
uint8_t FEPROT; /**< EEPROM Protection Register, offset: 0x16 */
uint8_t FDPROT; /**< Data Flash Protection Register, offset: 0x17 */
} volatile *FTFL_MemMapPtr;
Which means that one could do the programming of a long word as follows:
typedef struct FTFL_WordMap {
int :32;
uint32_t FCCOB_3_0;
uint32_t FCCOB_7_4;
uint32_t FCCOB_B_8;
int :32;
int :32;
} volatile *FTFL_WordMapPtr;
enum { FTFL_ProgramLongWord = 0x06};
void programWord( int address, uint32_t value)
{
FTFL_WordMapPtr* pWordBase = (FTFL_WordMapPtr) FTFL_BASE_PTR;
pWordBase->FCCOB_3_0 = FTFL_ProgramLongWord << 24 | ( address & ( ( 1<<24) - 1));
pWordBase->FCCOB_7_4 = value;
...
}
Do these issues extend to all Kinetis processors utilizing the FTFL or FTFE flash module?
Hi,
The old version (vBeta033) FTFL Programlongword driver with below info, which according to Kinetis product Endianness select FCCOB[4~7] data.
Please check below code:
/* check for error return code */ | |
if(FTFx_OK == returnCode) | |
{ | |
while(size > 0) | |
{ | |
/* preparing passing parameter to program the flash block */ | |
pCommandArray[0] = FTFx_PROGRAM_LONGWORD; | |
pCommandArray[1] = (UINT8)(destination >> 16); | |
pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); | |
pCommandArray[3] = (UINT8)(destination & 0xFF); | |
#if (ENDIANNESS == BIG_ENDIAN) /* Big Endian */
pCommandArray[4] = READ8(source); | |
pCommandArray[5] = READ8(source + 1); | |
pCommandArray[6] = READ8(source + 2); | |
pCommandArray[7] = READ8(source + 3); |
#else /* Little Endian */
pCommandArray[4] = READ8(source + 3); | |
pCommandArray[5] = READ8(source + 2); | |
pCommandArray[6] = READ8(source + 1); | |
pCommandArray[7] = READ8(source); |
#endif
I also attached the whole FTFL Programlongword driver for your reference.
Wish it help.
best regards,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
This may be correct but also confusing. The FCCOB register bytes are implemented in little-endian storage which then swaps it around again. On the other hand it may also be wrong and it should state that it uses a little-endian addressing convention(?).
In any case the flash controllers in all parts is the same in this respect, so it is always possible to write a long word directly when addressing the FCCOB registers as long words (like FTFL_FCCOB7_4) as you have done.
Regards
Mark