Unable to get IAP working with LPC1853

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

Unable to get IAP working with LPC1853

1,132 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fcarlo on Tue Nov 20 09:04:28 MST 2012
Hi,
I am struggling to get IAP working with a custom made board that mount a LPC1853 part. I can program this part using ISP DFU and the application provided from NXP. I am working with IAR 6.40.5 compiler and Segger JLINK debugger.

I have started from here:
http://www.lpcware.com/content/blog/application-programming-iap-code-example

The .ICF (linker file) is set properly to reserve top 32 bytes of RAM as follow:

// Top 32 bytes are reserved for IAP variables
define symbol LOCAL_SRAM_start__    = 0x10080000;
define symbol LOCAL_SRAM_end__      = 0x10089FDF;
define region LOCAL_SRAM_region    = mem:[from LOCAL_SRAM_start__  to  LOCAL_SRAM_end__];

Command parameter table and command result table are placed at a fixed address:

static unsigned int iapCommands[6] @ 0x10080000;
static unsigned int iapResults[4]  @ 0x10080018;

The IAP invoke call is located in the jump table as follows:

#define IAP_LOCATION 0x10400100
typedef void (__thumb *IAP)(unsigned int[], unsigned int[]);
const static IAP iap_entry = (IAP)IAP_LOCATION;

To keep thing as simple as possibile, I am only trying to send an "IAP_INIT (49)" command and looking for a CMD_SUCCESS response.

__disable_interrupt();
iapCommands[0] = (unsigned int)IAP_INIT;
iap_entry(iapCommands, iapResults);
ret = iapResults[0];
__enable_interrupt();

if (ret != CMD_SUCCESS) {
  /*Cmd failed*/
  return((uint32_t)-1);
}

When IAP is called, I can see from via JTAG that the registers are properly set:
R0: 0x10080000 //&iapCommands[0]
R1: 0x10080018 //&iapResults[0]
R2: 0x10400100 //IAP ROM driver table

From the disassembly listing I can see the jump command to the address:
BLX R2

After that some assembly instructions are done and at some point the processor goes to the Hardware Fault ISR before reaching the instruction:
ret = iapResults[0];

Is there someone that could tell me if I made something wrong or misunderstood something from the User Manual?
Thank you
Labels (1)
0 Kudos
Reply
5 Replies

890 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nxp21346 on Wed Nov 28 17:57:00 MST 2012
Also... make sure to have enough stack space available, especially if you plan to call Set active boot flash bank. That command requires 2208 bytes of stack.

-Dave @ NXP
0 Kudos
Reply

890 Views
hiephuynh
Contributor III

Hi Dave, how would one reserve 2208 bytes for this "Set Active boot flash bank" command?  Thank you

0 Kudos
Reply

890 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fcarlo on Thu Nov 22 01:35:39 MST 2012
Thank you for pointing this out.
Now is working properly.
Greetings
0 Kudos
Reply

890 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Wed Nov 21 11:11:32 MST 2012
0x10400100 is not the IAP entry point. Rather this word location holds the <i>pointer</i> to the IAP entry point!

<code>
iap_entry = *((IAP *)0x10400100);
iap_entry(...);  /* Jumps to 0x10408580 */
</code>
0 Kudos
Reply

890 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fcarlo on Wed Nov 21 03:59:06 MST 2012
I have replaced the default HardFault handler with this one:

void HardFault_Handler(void) {
   __ASM("TST LR, #4");
   __ASM("ITE EQ");
   __ASM("MRSEQ R0, MSP");
   __ASM("MRSNE R0, PSP");
   __ASM("B hard_fault_handler_c");
}

// From Joseph Yiu, minor edits by fcarlo
// hard fault handler in C,
// with stack frame location as input parameter
// called from HardFault_Handler in file xxx.s
void hard_fault_handler_c(unsigned int * hardfault_args) {
  unsigned int stacked_r0;
  unsigned int stacked_r1;
  unsigned int stacked_r2;
  unsigned int stacked_r3;
  unsigned int stacked_r12;
  unsigned int stacked_lr;
  unsigned int stacked_pc;
  unsigned int stacked_psr;
 
  unsigned int stacked_bfar;
  unsigned int stacked_cfsr;
  unsigned int stacked_hfsr;
  unsigned int stacked_dfsr;
  unsigned int stacked_afsr;
  unsigned int stacked_scb_shcsr;

  stacked_r0 = ((unsigned long) hardfault_args[0]);
  stacked_r1 = ((unsigned long) hardfault_args[1]);
  stacked_r2 = ((unsigned long) hardfault_args[2]);
  stacked_r3 = ((unsigned long) hardfault_args[3]);

  stacked_r12 = ((unsigned long) hardfault_args[4]);
  stacked_lr = ((unsigned long) hardfault_args[5]);
  stacked_pc = ((unsigned long) hardfault_args[6]);
  stacked_psr = ((unsigned long) hardfault_args[7]);
 
  stacked_bfar = (*((volatile unsigned long *)(0xE000ED38)));
  stacked_cfsr = (*((volatile unsigned long *)(0xE000ED28)));
  stacked_hfsr = (*((volatile unsigned long *)(0xE000ED2C)));
  stacked_dfsr = (*((volatile unsigned long *)(0xE000ED30)));
  stacked_afsr = (*((volatile unsigned long *)(0xE000ED3C)));
  stacked_scb_shcsr = SCB->SHCSR;

  printf ("\n\n[Hard fault handler - all numbers in hex]\n");
  printf ("R0 = %x\n", stacked_r0);
  printf ("R1 = %x\n", stacked_r1);
  printf ("R2 = %x\n", stacked_r2);
  printf ("R3 = %x\n", stacked_r3);
  printf ("R12 = %x\n", stacked_r12);
  printf ("LR [R14] = %x  subroutine call return address\n", stacked_lr);
  printf ("PC [R15] = %x  program counter\n", stacked_pc);
  printf ("PSR = %x\n", stacked_psr);
  printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
  printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
  printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
  printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
  printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
  printf ("SCB_SHCSR = %x\n", SCB->SHCSR);

  while (1);
}

And this is the output:

R0        = 0
R1        = 0x100826FB
R2        = 0x10400100
R3        = 0x40050004
R12       = 0x40050044
LR [R14]  = 0x1A001E3F
PC [R15]  = 0x1040012A
PSR       = 0x41000000
BFAR      = 0xE000ED38
CFSR      = 0x00000400
HFSR      = 0x40000000
DFSR      = 1
AFSR      = 0
SCB_SHCSR = 0


I can't do step-by-step debugging with Segger J-link after the jump to the ROM API address (0x10400100) so I can't understand exactly what could be the problem.
I forgot to mention that I am currently using an external oscillator and PLL1 is enabled to run at 60 MHz.
0 Kudos
Reply