C51: In-Application Programming (IAP) on Philips LPC9XX
Information in this article applies to:
QUESTION
I'm using a Philips P89LPC932 that provides
In-system Application Programming (IAP) with an entry address at
0xFF00.
Is there a clever way to access the IAP functions directly from C
without the need to write assembler interface routines?
Some Philips LPC900 variants require to set a key value
in the idata memory at address 0xFF.
Is it possible to set this key from the C-level?
ANSWER
Yes, there is a clever way. Just add the following code to your
application. For devices that require a key value, include
the key assignment in your code.
#include // SFR header file
#include // Absolute memory address macros
#define IAP_key DBYTE[0xFF] // access macro for key value
unsigned char IAP_ProgramUserCodePage (
char idata * ptr, // Pointer to data buffer in RAM
unsigned short addr, // Page address
unsigned char nb) { // number of bytes to program
ptr = ptr; // avoid warnings
addr = addr;
nb = nb;
IAP_key = 0x96; // write key value
ACC = 0; // MOV A,#00H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned char IAP_ReadVersionId (void) {
ACC = 1; // MOV A,#01H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned char IAP_MiscWrite (unsigned char regaddr, unsigned char value) {
regaddr = regaddr; // avoid warnings
value = value;
IAP_key = 0x96; // write key value
ACC = 2; // MOV A,#02H
return ((unsigned char (code *)(void)) 0xFF00) ); // LJMP 0FF00H
}
unsigned char IAP_MiscRead (unsigned char regaddr) {
regaddr = regaddr; // avoid warnings
ACC = 3; // MOV A,#03H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned char IAP_EraseSector (unsigned char mode, unsigned short addr) {
mode = mode; // avoid warnings
addr = addr;
IAP_key = 0x96; // write key value
ACC = 4; // MOV A,#04H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned long IAP_ReadSectorCRC (unsigned char sector) {
sector = sector; // avoid warnings
ACC = 5; // MOV A,#05H
return ((unsigned long (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
long unsigned IAP_ReadGlobalCRC (void) {
ACC = 6; // MOV A,#06H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned char IAP_ReadUserCode_ (char dummy, unsigned short addr) {
dummy = dummy; // avoid warnings
addr = addr;
ACC = 7; // MOV A,#07H
return ((unsigned char (code *)(void)) 0xFF00)(); // LJMP 0FF00H
}
unsigned char IAP_ReadUserCode (unsigned short addr) {
return IAP_ReadUserCode_ (0, addr); // move addr to R4|R5
}
Depending on the CY flag, the return value of these IAP functions
is a status or memory value. You can query the CY flag immediately
after the IAP function call as follows:
:
// program the 'buf' content to address 0x1200
status = IAP_ProgramUserCodePage (buf, 0x1200, sizeof (buf));
if (CY) return (status); // error occured
:
- Philips P89LPC9xx User's Manuals
SEE ALSO
Last Reviewed: Thursday, February 25, 2021