LPC1788 - Flash signature generation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1788 - Flash signature generation

2,320 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Fri Sep 02 13:42:04 MST 2011
Hello,

I'm having trouble with the "Flash signature generation" on the LPC1788.

First off the LPC178x_7x.h header file does not have the Flash signature generation structure or define macro.

I added the following to my code:

<code>
/*------------- Flash Signature Generation ----------------------*/
typedef struct
{
       uint32_t RESERVED1[8];
  __IO uint32_t FMSSTART;
  __IO uint32_t FMSSTOP;
       uint32_t RESERVED2;
  __IO uint32_t FMSW0;
  __IO uint32_t FMSW1;
  __IO uint32_t FMSW2;
  __IO uint32_t FMSW3;
       uint32_t RESERVED3[1001];
  __IO uint32_t FMSTAT;
  __IO uint32_t FMSTATCLR;
} FLASHSIG_TypeDef;


//#define LPC_FLASHSIG_BASE     (LPC_APB1_BASE + 0x04000)

#define LPC_FMC          ((FLASHSIG_TypeDef  *) 0x00200000 )

</code>

The problem I have is I get a hardfault when I access the FMSSTOP register.

Basically this is my code:

<code>
void CalcSignature()
{
    /* align flash address to refer the flash word in the array */
    uint32_t startAddr =    0x40000;
    uint32_t length =       0x3FFFF;
   
    startAddr = (startAddr >> 4) & 0x0001ffff;
    length = ((startAddr + length) >> 4) & 0x0001ffff;
    /* write start address of the flash contents to the register*/
    LPC_FMC->FMSSTART = startAddr;
   
    LPC_FMC->FMSTATCLR |= (1 << 2); // clear the SIG done
   
    /* write stop address of the flash contents to the register, start generating
    the signature*/
    length |= ( 1 << 17);
    LPC_FMC->FMSSTOP = length;   //HARD FAULT HERE!!!!!!!!!!!!!!!!!
   
   
    while((LPC_FMC->FMSTAT & (1 << 2)) == 0);
}
</code>

Anybody have any ideas or see what I'm doing wrong?


Thanks.

Marc
Labels (1)
0 Kudos
Reply
17 Replies

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Tue Jul 21 08:17:24 MST 2015
Funny, I had forgotten about this thread - after about a week, I ended up just figuring it out myself, and have been using this feature successfully since then...

The guys at NXP must be really busy, eh?  :-)

0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Mon Jul 20 20:48:13 MST 2015
Did it really take almost nine months to answer this simple question?
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mc on Mon Jul 20 20:40:39 MST 2015
Hi Dave,
It is at https://www.lpcware.com/content/nxpfile/an10918-nxp-lpc-cortex-m3-iec60335-class-b-library
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Sun Nov 02 10:24:19 MST 2014
This seems to be a dead link...

0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arw on Fri Aug 23 06:55:24 MST 2013
Hello all,
Additional information on hardware and software signature generation can be found in more detail within the IEC60335 test suite.  See app note AN10918 which is included with the source code at "http://www.nxp.com/documents/application_note/IEC60335_ClassB_CM3.zip".

Cheers,
Allen
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Mon Jul 02 14:05:58 MST 2012
Next thing I did is write a routine that would execute from internal flash... I recognize the UM states that you should execute your code from somewhere OTHER than flash, because code in flash will generate a wait state until the process is complete, but that's okay for me, since I don't have anything else running - so while the process is generating the checksum, I'd be waiting anyway... no big deal...

Here is the code I used:

<code>
   // calculate current signature
   /* 0 : CLEAR ANY PREVIOUS "DONE" FLAG */
   LPC_FMC->FMSTATCLR = (1<<2);
  
   /* 1 : SET THE START AND STOP ADDRESSES... */
   LPC_FMC->FMSSTART = (0x00000000)>>4;   // start address divided by 16
   LPC_FMC->FMSSTOP  = (0x0007FFFF)>>4;   // stop address divided by 16
  
   /* 2 : START THE SIGNATURE GENERATION... */
   LPC_FMC->FMSSTOP  |= (1<<17);          // enable start bit...
  
   /* 3 : WAIT FOR GENERATION TO COMPLETE... */
   while( !(LPC_FMC->FMSTAT & (1<<2)) );
  
   /* 4 : CLEAR "DONE" FLAG */
   LPC_FMC->FMSTATCLR = (1<<2);
  
   CurrentFlashSignagure[0] = LPC_FMC->FMSW0;
   CurrentFlashSignagure[1] = LPC_FMC->FMSW1;
   CurrentFlashSignagure[2] = LPC_FMC->FMSW2;
   CurrentFlashSignagure[3] = LPC_FMC->FMSW3;
</code>

and waddya know... the output looked like this:

<code>
FLASH SIGNATURE CHECKSUM: 0x94A71A54 E7B62D82 20239788 48B0EEBC
</code>

Now, I don't know at this stage if these values are right... I will still have to implement the algorithm in the user's manual and double check them manually (See Figure 171), but at least it's a start - no hardware faults or hang ups...

See if this helps,

0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Mon Jul 02 13:16:08 MST 2012
Hi Marc,

I've been off on other projects lately here at work, so I haven't had time to work on code for the LPC1788 in awhile...

The first thing I'm working on is this issue, so I revisited your thread here to get started.

My first job was to generate an FMC structure as you did...

That's when I noticed your address mapping.

Check the user's manual - I think you'll see that your FMSTATCLR member is mapped to the wrong address...

Here's my structure definition:
<code>
typedef struct
   {
        uint32_t RESERVED1[8];      // 0xXXXX0000
   __IO uint32_t FMSSTART;          // 0xXXXX0020
   __IO uint32_t FMSSTOP;           // 0xXXXX0024
        uint32_t RESERVED2;         // 0xXXXX0028
   __IO uint32_t FMSW0;             // 0xXXXX002C
   __IO uint32_t FMSW1;             // 0xXXXX0030
   __IO uint32_t FMSW2;             // 0xXXXX0034
   __IO uint32_t FMSW3;             // 0xXXXX0038
        uint32_t RESERVED3[1001];   // 0xXXXX003C
   __IO uint32_t FMSTAT;            // 0xXXXX0FE0
        uint32_t RESERVED4;         // 0xXXXX0FE4
   __IO uint32_t FMSTATCLR;         // 0xXXXX0FE8
   } FLASHSIG_TypeDef;
</code>
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Wed Jun 20 09:09:21 MST 2012
Anyboby?
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by cherry_typer on Tue Nov 01 09:34:26 MST 2011
I have the same problem.
For me it is just suspicious that the EEPROM_BASE address is within the FMC register addresses.

FMSTART 0x20 0020
...
LPC_EEPROM_BASE 0x20 0080

FMSTAT 0x20 0FE8

Maybe addresses of FMC in the user manual are wrong. I have tried the addresses of different LPC models and
all resulted in a hard fault when writing to FMSSTOP
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Sun Oct 30 00:12:33 MST 2011
Sorry Marc, I've been busy designing my board, so my software development has been at a stand still lately...  I should be able to revisit this issue in a couple more weeks...

-Dave
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Fri Oct 28 08:29:40 MST 2011
Anyboby get anywhere on this yet?  I still haven't been successful.
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Mon Oct 03 10:41:50 MST 2011
Anybody have any success using this feature?

Anybody from NXP, has this been tested? Do you have any test code you could share?
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Wed Sep 07 05:52:27 MST 2011
Hi wmues,

Thanks for this but this is not the feature I'm referring too.  This is the checksum for valid user code, I'm referring to the flash signature generating module.


Does anyone have working code for this module on the LPC1788?

Thanks


Marc
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Tue Sep 06 08:49:42 MST 2011
From what I can tell, the only requirement is executing from "not the flash"...  ;-)

The user's manual states the following: (Section 37.10 Flash signature generation)

"While signature generation is in progress, the flash memory cannot be accessed for other
purposes, and an attempted read will cause a wait state to be asserted until signature
generation is complete. Code outside of the flash (e.g. internal RAM) can be executed
during signature generation. This can include interrupt services, if the interrupt vector
table is re-mapped to memory other than the flash memory. The code that initiates
signature generation should also be placed outside of the flash memory."

This sounds like you're fine executing your code from RAM...

-Dave
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Tue Sep 06 05:20:53 MST 2011
Hi Dave,

No I'm not executing from external memory. I am executing the code above from internal RAM.  Is executing from external memory a requirement? Or did you just mean executing from not the flash...

Thanks.

Marc
0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Tue Sep 06 03:50:04 MST 2011
I have done it in the following way:

a) in the linker script:
<code>
  /* Calculate NXP Cortex-M3 valid user code checksum. This is 0-(sum of first 7 entries in vector table),
   * Note that we must add 1 to each code space vector (LSB = marker for thumb code).
   */
  __valid_user_code_checksum = 0 - (__cs3_stack + __cs3_reset + 1 + NMI_Handler + 1 + HardFault_Handler + 1 + MemManage_Handler + 1 + BusFault_Handler + 1 + UsageFault_Handler + 1);
</code>
Attention: these statements must be outside any output section, because linker variables inside output sections are relative to the start of the section.

b) in the startup code:
<code>
__cs3_interrupt_vector_cortex_m:
    .long   __cs3_stack                 /* Top of Stack                 */
    .long   __cs3_reset                 /* Reset Handler                */
    .long   NMI_Handler                 /* NMI Handler                  */
    .long   HardFault_Handler           /* Hard Fault Handler           */
    .long   MemManage_Handler           /* MPU Fault Handler            */
    .long   BusFault_Handler            /* Bus Fault Handler            */
    .long   UsageFault_Handler          /* Usage Fault Handler          */
    .long   __valid_user_code_checksum  /* Valid User Code Checksum     */
</code>

or if you want it to code in C:
<code>
extern int  __valid_user_code_checksum;
#define USER_CODE_CHECKSUM (uint32_t) (&__valid_user_code_checksum)
</code>

...and insert this constant into the vector table struct.

So the linker is doing the calculation for you. No problem.




0 Kudos
Reply

2,069 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Dave on Fri Sep 02 20:26:01 MST 2011
Hi Marc,

I've not implemented this yet, but I started reading the UM to get a feel for how to do it.

My first question is:  Are you executing this code from external memory?

-Dave
0 Kudos
Reply