EmbeddedRelated.com
Forums
Memfault Beyond the Launch

IAP command problems

Started by koerner_stefan September 27, 2004
Could anyone help me to run the IAP commands on KEIL MCB2100
(LPC2129)?

I am working with the ARM RVDS tools (& RV ICE) and tried to run a
small sample calling the IAP commands (program runs from iRAM).

Most time I get a "memory access violation" several seconds after
calling the IAP commands.
Sometimes the first IAP command (code 50) runs ok but I did never saw
a guilty write command. I tried it also with cclk = 12MHz. Do I have
to do additional initialisation?
I have reserved 16 bytes on top of Stack.

best regards
Stefan

This is my source

static void PLL_Init(void)
{
// Fosc = 12.000.000 MHz

PLLCON = 1; // enable PLL
PLLCFG = 0x24; // M=5 and P=2 -> Cclk = 60.000.000 MHz
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

while (!(PLLSTAT & 0x400)); // wait for the PLL to be locked

PLLCON = 3; // enable and connect PLL
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

VPBDIV = 0; // Pclk = 15.000.000 MHz

}

static void PLL_Off(void)
{
// Fosc = 12.000.000 MHz

PLLCON = 0; // disable PLL cclk = Fosc
VPBDIV = 1; // Pclk = cclk

} void savesetup(struct SETUP *setup){
typedef void (*IAP)(unsigned int [],unsigned int[]);
unsigned int command[5];
unsigned int result[2];
IAP iap_entry;
// PLL_Off();
//__ARMLIB_disableIRQ();
iap_entry=(IAP) IAP_LOCATION;
// prepare to erase
command[0]P;
command[1]; /* start sector */
command[2]; /* end sector */
iap_entry(command, result);
if (result[0] != 0) goto error;
// erase
command[0]R;
command[1]; /* start sector */
command[2]; /* end sector */
command[3]`000; /* System Clock cclk in KHz */
sendstr ("\nnow erase");
iap_entry(command, result); /* erase the block */
if (result[0] != 0) goto error;
// prepare to program
iap_entry=(IAP) IAP_LOCATION;
command[0]P;
command[1]; /* start sector */
command[2]; /* stop sector */
sendstr ("\nnow prepair to program");
iap_entry(command, result);
if (result[0] != 0) goto error;
// program
command[0]Q;
command[1]=0x1C000; /* destination address */
command[2]=(int)setup; /* source RAM adress */
command[3]Q2; /* number of Bytes*/
command[4]`000; /* system clock cclk in KHz */
sendstr ("\nnow program");
iap_entry(command, result);
if (result[0] != 0) goto error;
//__ARMLIB_enableIRQ();
return;
error:
sendstr ("\nFlash Access error");
//__ARMLIB_enableIRQ();
} int main (void) {

unsigned int ui_cnt;

struct SETUP setup;
struct SETUP * nonvolatile;
nonvolatile= (struct SETUP*) 0x1C000; /* Points to page 14 in Flash
(LPC2106)*/

PLL_Init();
// PLL_Off();

/* Init General Purpose I/O GPIO */
IOCLR1 = 0xFFFFFFFF;
IODIR1 = 0x00FF0000; /* Port 1[23..16] is Output LEDs */

init_serial(); /* Initialize Serial Interface */
sendstr ("\nIAP Test");
while (1) { /* Loop forever */

setup=*nonvolatile; /* read ROM to RAM */

sendstr ("\nsetup.ui_CH_ZS_Value = 0x");
sendhex((setup.ui_CH_ZS_Value[0] >> 28) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 24) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 20) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 16) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 12) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 8) & 0x0F);
sendhex((setup.ui_CH_ZS_Value[0] >> 4) & 0x0F);
sendhex(setup.ui_CH_ZS_Value[0] & 0x0F);

setup.ui_CH_ZS_Value[0]++; /*modify for test */
setup.ui_CH_FS_Value[0]++;

savesetup (&setup);

}



An Engineer's Guide to the LPC2100 Series


--- In , "koerner_stefan" <koerner.stefan@a...>
wrote:
> Could anyone help me to run the IAP commands on KEIL MCB2100
> (LPC2129)?
>
> I am working with the ARM RVDS tools (& RV ICE) and tried to run a
> small sample calling the IAP commands (program runs from iRAM).
>
> Most time I get a "memory access violation" several seconds after
> calling the IAP commands.
> Sometimes the first IAP command (code 50) runs ok but I did never saw
> a guilty write command. I tried it also with cclk = 12MHz. Do I have
> to do additional initialisation?
> I have reserved 16 bytes on top of Stack.
>
> best regards
> Stefan
>
> This is my source
>
> ...

I have some problems with the IAP as well.
After upgrading to version 1.63 bootloader (one is a LPC 2124 the
other a LPC 2129) the behavior is predictable but not what should happen.
I do 4 steps: 1. prepare 2. erase 3. prepare 4. coppy RAM to flash.
Steps 1. to 3. show as Status Code CMD_SUCCESS but definetly erase
does not work. Step 4. gives back 9
SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION.

Any help would be appreciated.

Thanks

Helmut Bitter

Part of my source follows:

static void
flash_schreiben (unsigned int *puffer)
{
iap_entry=(iap) iap_location;

/* Stop A/D Wandler */
ADCR = 0x01;

/* Disable Interrupts */
__ARMLIB_disableIRQ();

/* Disable FIQ */
__ARMLIB_disableFIQ();

PLLCON = 0; // disable PLL, cclk = Fosc
PLLFEED=0xaa;
PLLFEED=0x55;
while ((PLLSTAT & 0x300) ==0x300 ); // warten bis PLL nicht mehr
Clock Source

/* Stopp MAM */
MAMCR = 0;

command[0]U; // Boot Code Version
iap_entry (command,result);

/* zuerst Sector lchen */
/* ein "Prepare" Kommando ausfren */
command[0]P; // Prepare Sector
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
/* "Erase" Kommando geben */
command[0]R; // Erase
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
command[3]000; // Takt Frequenz in KHz
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
for (i=2;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}

/* nun Copy RAM to Flash */
/* dazu zuerst ein "Prepare" Kommando ausfren */
command[0]P; // Prepare Sector
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
for (i=3;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}

/* jetzt das "Copy RAM to Flash" Kommando ausfren */
command[0]Q; // Copy RAM to Flash
command[1]=sector_adr; // Destination Flash address
command[2]=(int)puffer; // Source RAM address
command[3]Q2; // Anzahl Bytes, die ins Flash geschrieben
werden sollen
command[4]000; // Taktfrequenz in KHz
iap_entry (command,result);
/* Fehlerauswertung nach dem Flashen */
if (result[0]!=0)
{
// Fehlermeldung
for (i=4;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}
else
{
/* flashen war erfolgreich, deshalb 1x Summer und gre LED an-
und ausschalten */
delay (434000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (434000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
delay (434000);
}

/* PLL wieder als Clock Source */
PLLCON = 1; // enable PLL
PLLCFG = 0x25; // M=6 and P=2 -> Cclk = 60 MHz bei 10 MHz Quarz
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

while (!(PLLSTAT & 0x400)); // wait for the PLL to be locked

PLLCON = 3; // enable and connect PLL
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

/* MAM wieder freigeben */
MAMCR = 0;
MAMTIM = 0x03;
MAMCR = 2; /* Enable Interrupts */
__ARMLIB_enableIRQ();

/* Enable FIQ */
__ARMLIB_enableFIQ();

/* Start A/D-Wandlung von ain0 ... ain3 im Burst Mode */
ADCR = 0x00210D0F;
}



Make sure you are in thumb mode before calling any IAP code (as it is
implemented in thumb). Hugh @ http://www.ashling.com/support/lpc2000/

-----Original Message-----
From: helmutbitter [mailto:]
Sent: 04 October 2004 11:54
To:
Subject: [lpc2000] Re: IAP command problems
--- In , "koerner_stefan" <koerner.stefan@a...>
wrote:
> Could anyone help me to run the IAP commands on KEIL MCB2100
> (LPC2129)?
>
> I am working with the ARM RVDS tools (& RV ICE) and tried to run a
> small sample calling the IAP commands (program runs from iRAM).
>
> Most time I get a "memory access violation" several seconds after
> calling the IAP commands.
> Sometimes the first IAP command (code 50) runs ok but I did never saw
> a guilty write command. I tried it also with cclk = 12MHz. Do I have
> to do additional initialisation?
> I have reserved 16 bytes on top of Stack.
>
> best regards
> Stefan
>
> This is my source
>
> ...

I have some problems with the IAP as well.
After upgrading to version 1.63 bootloader (one is a LPC 2124 the
other a LPC 2129) the behavior is predictable but not what should happen.
I do 4 steps: 1. prepare 2. erase 3. prepare 4. coppy RAM to flash.
Steps 1. to 3. show as Status Code CMD_SUCCESS but definetly erase
does not work. Step 4. gives back 9
SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION.

Any help would be appreciated.

Thanks

Helmut Bitter

Part of my source follows:

static void
flash_schreiben (unsigned int *puffer)
{
iap_entry=(iap) iap_location;

/* Stop A/D Wandler */
ADCR = 0x01;

/* Disable Interrupts */
__ARMLIB_disableIRQ();

/* Disable FIQ */
__ARMLIB_disableFIQ();

PLLCON = 0; // disable PLL, cclk = Fosc
PLLFEED=0xaa;
PLLFEED=0x55;
while ((PLLSTAT & 0x300) ==0x300 ); // warten bis PLL nicht mehr
Clock Source

/* Stopp MAM */
MAMCR = 0;

command[0]U; // Boot Code Version
iap_entry (command,result);

/* zuerst Sector lchen */
/* ein "Prepare" Kommando ausfren */
command[0]P; // Prepare Sector
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
/* "Erase" Kommando geben */
command[0]R; // Erase
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
command[3]000; // Takt Frequenz in KHz
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
for (i=2;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}

/* nun Copy RAM to Flash */
/* dazu zuerst ein "Prepare" Kommando ausfren */
command[0]P; // Prepare Sector
command[1]=sector; // Start Sector
command[2]=sector; // End Sector
iap_entry (command,result);
if (result[0]!=0)
{
// Fehlermeldung
for (i=3;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}

/* jetzt das "Copy RAM to Flash" Kommando ausfren */
command[0]Q; // Copy RAM to Flash
command[1]=sector_adr; // Destination Flash address
command[2]=(int)puffer; // Source RAM address
command[3]Q2; // Anzahl Bytes, die ins Flash geschrieben
werden sollen
command[4]000; // Taktfrequenz in KHz
iap_entry (command,result);
/* Fehlerauswertung nach dem Flashen */
if (result[0]!=0)
{
// Fehlermeldung
for (i=4;i;--i)
{
delay (117000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (117000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
}
}
else
{
/* flashen war erfolgreich, deshalb 1x Summer und gre LED an-
und ausschalten */
delay (434000);
IO1SET=0x00010000;
IOSET=0x02000000;
delay (434000);
IO1CLR=0x00010000;
IOCLR=0x02000000;
delay (434000);
}

/* PLL wieder als Clock Source */
PLLCON = 1; // enable PLL
PLLCFG = 0x25; // M=6 and P=2 -> Cclk = 60 MHz bei 10 MHz Quarz
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

while (!(PLLSTAT & 0x400)); // wait for the PLL to be locked

PLLCON = 3; // enable and connect PLL
PLLFEED = 0xAA; // PLL Feed Sequence
PLLFEED = 0x55; // PLL Feed Sequence

/* MAM wieder freigeben */
MAMCR = 0;
MAMTIM = 0x03;
MAMCR = 2; /* Enable Interrupts */
__ARMLIB_enableIRQ();

/* Enable FIQ */
__ARMLIB_enableFIQ();

/* Start A/D-Wandlung von ain0 ... ain3 im Burst Mode */
ADCR = 0x00210D0F;
}
<http://us.ard.yahoo.com/SIG9r9j7q4/M)5196.4901138.6071305.3001176/D=gr
oups/S06554205:HM/EXP96973635/A!28215/R=0/SIGse96mf6/*http://comp
anion.yahoo.com> click here

<http://us.adserver.yahoo.com/l?M)5196.4901138.6071305.3001176/D=groups/S=
:HM/A!28215/randR7304916 _____

> .



> Date: Mon, 04 Oct 2004 10:53:43 -0000
> From: "helmutbitter" <>
> Subject: Re: IAP command problems

1) The code below is what we use to call IAP from ARM code.

2) It is solid providing that you have upgraded to the
v1.52/1.63 bootloader.

3) it works fine from Flash or from RAM.

4) The pointer to cmd in on the R12/psp stack, and the pointer
to res is in R10/tos. The return stack is R13/rsp.

Stephen l: ^IAP
IAPentry 1 or , \ entry address, Thumb
mode

code IAP \ *cmd *res --
\ *G The primitive to call the IAP routines. Interrupts are
\ ** disabled for the duration of the IAP call.
str link, [ rsp, # -4 ] ! \ save return address

\ Disable interrupts
mrs r0, cpsr \ save interrupt status
str r0, [ rsp, # -4 ] !
orr r0, r0, # $C0 \ disable interrupts
msr cpsr, _c r0

\ Set up parameters and call the IAP Thumb routine
ldr r0, [ psp ], # 4 \ R0 = *cmd
mov r1, tos \ R1 = *res
stmfd rsp ! { r9-r12 } \ preserve regs
ldr r12, ^IAP \ get entry address
mov link, pc \ link set to after BX
bx r12 \ jump to Thumb code
mov r0, r0 \ probably unnecessary
mov r0, r0
mov r0, r0
mov r0, r0
ldmfd rsp ! { r9-r12 } \ restore regs

\ restore interrupts
ldr r0, [ rsp ], # 4
msr cpsr, _c r0

ldr tos, [ psp ], # 4 \ restore TOS
ldr pc, [ rsp ], # 4 \ return
end-code

--
Stephen Pelc,
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 23 80 631441, fax: +44 23 80 339691
web: http://www.mpeltd.demon.co.uk - free VFX Forth downloads




--- In , "helmutbitter" <helmut.bitter@t...> wrote:
>
> --- In , "koerner_stefan" <koerner.stefan@a...>
> wrote:
> > Could anyone help me to run the IAP commands on KEIL MCB2100
> > (LPC2129)?
> >
> > I am working with the ARM RVDS tools (& RV ICE) and tried to run a
> > small sample calling the IAP commands (program runs from iRAM).
> >
> > Most time I get a "memory access violation" several seconds after
> > calling the IAP commands.
> > Sometimes the first IAP command (code 50) runs ok but I did never saw
> > a guilty write command. I tried it also with cclk = 12MHz. Do I have
> > to do additional initialisation?
> > I have reserved 16 bytes on top of Stack.
> >
> > best regards
> > Stefan
> >
> > This is my source
> >
> > ...
>
> I have some problems with the IAP as well.
> After upgrading to version 1.63 bootloader (one is a LPC 2124 the
> other a LPC 2129) the behavior is predictable but not what should
happen.
> I do 4 steps: 1. prepare 2. erase 3. prepare 4. coppy RAM to flash.
> Steps 1. to 3. show as Status Code CMD_SUCCESS but definetly erase
> does not work. Step 4. gives back 9
> SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION.
>
> Any help would be appreciated.
>
> Thanks
>
> Helmut Bitter

Sometimes it is simpler as you thing!!

To philips_apps:
There is an error in the LPC2114/2124/2212/2214 USER MANUAL(date
2004-05-03)
- On page 33 figure 2 it shows the LPC 2124 in the block of devices
with 128 kB flash!! It has 256 kB.

In my example Sector 14 and address 0x1C000 didn't fit for the LPC
2124 doing IAP and resulted in Status Code 9
SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION. Helmut



Memfault Beyond the Launch