Hi,
since a while I'm struggling with this topic.
My goal is to be able to generate the Flash signature in FW and in SW.
Here is the simple FW piece of code:
const char dummyData1[] __attribute__((aligned (0x1000))) = {
0xFF, 0x00, 0xFF, 0x11, 0xFF, 0x22, 0xFF, 0x33, 0xFF, 0x44, 0xFF, 0x55, 0xFF, 0x66, 0xFF, 0x77,
0xFF, 0x00, 0xFF, 0x11, 0x55, 0x22, 0xFF, 0x33, 0xFF, 0x44, 0xFF, 0x55, 0xFF, 0x66, 0xFF, 0x77,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};UInt32 ComputeFlashSignature(void)
{//Chip_FMC_ClearSignatureBusy();
LPC_FMC->FMSSTOP &= ~FMC_FLASHSIG_BUSY;UInt32 start = (UInt32)dummyData1;
UInt32 stop = start + 32 -1;Chip_FMC_ComputeSignature(start, stop);
while(Chip_FMC_IsSignatureBusy());
volatile UInt32 sign = Chip_FMC_GetSignature(0);
return sign;
}
Assumed that dummyData is placed at 0x1000, I'm calculating the signature from 0x1000 to 0x101F.
Since the HW block is ignoring the 4 LSBs, it results in:
This should sum up to 16B being used for the signature calculation.
The HW block seams to behave differently, if I change any of the bytes from #16 to #19 the signatures changes. It does not if I change any of the bytes after the byte #19.
So in total the HW block calculates the CRC on 20B, not 16 as some would expect.
This leads to my first question.
How is it possible to calculate the signature of the entire flash? My MCU has 256KB flash, address ranging from 0x0 to 0x3FFFF.
If I set this range it would result in:
This is not the entire range, since some bytes at the end are skipped.
If I set the range 0x0, 0x40000:
Here the mysterious bytes will be out of range/wrapped around on the first 4 bytes at address 0.
So, I'm completely misunderstanding something, or there is something which is not clear in the documentation?
Additionally, I'm trying to calculate this signature in SW, unsuccessfully. The pseudo code in the manual seams to to produce the same signature that is generated in HW.
Any hint?
Thank you in advance.
Hi Giona Imperatori ,
I'd highly recommend you to use the following function, I think it's clear to illustrate the flash signature generation.
/**
* @brief Set FLASH access time in clocks
* @param clks : Clock cycles for FLASH access (minus 1)
* @return Nothing
*/
STATIC INLINE void Chip_FMC_SetFLASHAccess(FMC_FLASHTIM_T clks)
{
uint32_t tmp = LPC_FMC->FLASHTIM & (~(0x3));
/* Don't alter upper bits */
LPC_FMC->FLASHTIM = tmp | clks;
}
/* Flash signature start and busy status bit */
#define FMC_FLASHSIG_BUSY (1UL << 17)
/**
* @brief Start computation of a signature for a FLASH memory range
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param stop : Ending FLASH address for computation, must be aligned on 16 byte boundary
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and use the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignature(uint32_t start, uint32_t stop)
{
LPC_FMC->FMSSTART = (start >> 4);
LPC_FMC->FMSSTOP = (stop >> 4) | FMC_FLASHSIG_BUSY;
}
/**
* @brief Start computation of a signature for a FLASH memory address and block count
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param blocks : Number of 16 byte blocks used for computation
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignatureBlocks(uint32_t start, uint32_t blocks)
{
Chip_FMC_ComputeSignature(start, (start + (blocks * 16)));
}
/**
* @brief Check for signature geenration completion
* @return true if the signature computation is running, false if finished
*/
STATIC INLINE bool Chip_FMC_IsSignatureBusy(void)
{
return (bool) ((LPC_FMC->FMSSTOP & FMC_FLASHSIG_BUSY) != 0);
}
/**
* @brief Returns the generated FLASH signature value
* @param index : Not used, must be 0
* @return the generated FLASH signature value
*/
STATIC INLINE uint32_t Chip_FMC_GetSignature(int index)
{
return LPC_FMC->FMSW[index];
}
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Ping, thank you for your time.
As you can see from my original question, I'm already using the code you posted.
This does not show at all how the signature has to be calculated in SW. It only shows how to generate it in HW. But this was not really the question.
One question was how to generate this signature in software (PC software, like C, C#, Python, ...).
I did implement the code which is given in the user manual (http://www.nxp.com/documents/user_manual/UM10732.pdf), page 428. But this code does not seem to generate the word which is generated in HW.
But......
The UM of the LPC11U6X advertise that this family has a 32bit generator only (Table357), and it's providing a different pseudo code.
Also the code that you posted somehow mentions that, more specifically in the comment of the function Chip_FMC_IsSignatureBusy() -> "Only the index 0 is supported".
By googling I landed by chance here (LPC Signature Generator | mbed ), and I decided to give it a try, to test the code which is presented there even though is for antoher LPC family, suppoed to have a 128bit signature generator.
Well, I was quite surprise to see that the first word of the software posted on mbed was matching the signature which I calculated in HW on my LPCXPresso mounting a LPC11U68JBD100 device, which is supposed to have a 32bit signature genreator.
Seen that, driven by my curiosity I tried to access the register FMSW1, which should not exist. And, funny enough, the register does exists and it contains the correct signature. So do also FMSW2 and FMSW3.
How cool is that? The LPC11U68 does actually have a 128bit generator, and not 32bit as you (NXP) claim.
So, to me it seams that you (NXP) don't actually know what you put in your silicon...
As a customer, what should I do? Implement my application according of what I see, with the risk that you decide to change the HW and my application will not work anymore. Or stick to what the user manual says, with the result that my application wont work at all?
Or look for another chip provider?
Dear Ping,
can you please clarify this issue?
Have a great day too!
Giona
PS: I attach a screen shot of the debugging tool, which shows the ghost registers.
Hi Giona Imperatori,
Thanks for your reply.
I'll contact with the AE team for confirming, and I will inform you ASAP if I get some replies.
Thanks for your understanding.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------