| ??? 02/19/09 15:04 Read: times |
#162569 - Function "Program Double Clock" never returns in IAP mode |
Hi everyone,
it seems to me that function "Program Security Bit, Double Clock" (see [1] on page 27) of P89V51RD2's bootloader v7 contains a bug: it never returns when called via IAP interface. Other functions, such as "Read ID" and "Set ISP Entry Mode" (see [2]) works fine for me. Has anyone else experienced the same problem? The values I use for the interface registers are:
More precisely, my code looks like:
//--- implemented IAP functions -----------------------------------------------
// common functions R1 DPH DPL ACC
#define IAP_GET_DEVICE_ID_1 0x00,0x00,0x01,0x00 ///< request device id #1
#define IAP_GET_MANUFACTURER_ID 0x00,0x00,0x00,0x00 ///< request manufacturer id
// for device 89C51 only R1 DPH DPL ACC
[...]
// for device 89V51 only R1 DPH DPL ACC
#define IAP_V51_GET_BOOT_CODE_VERSION
0x00,0x00,0x02,0x00 ///< read id - boot code ver
#define IAP_V51_SET_DOUBLE_CLOCK
0x05,0x00,0x05,0x00 ///< program double clock
#define IAP_V51_SET_ISP_ENTRY_MODE_ALWAYS
0x04,0x00,0x03,0x00 ///< run ISP after reset
#define IAP_V51_SET_ISP_ENTRY_MODE_PIN_LOW(pinl)
0x04,pinl,0x01,0x00 ///< user code if pin high
void init_iap (void)
{
BSEL = 1; // select bank 0 for reading (89V51 only)
SWR = 0; // make bank 1 (boot code) accessible (89V51 only)
switch (call_iap(IAP_GET_MANUFACTURER_ID)) {
case 0x15: // Philips
[...]
break;
case 0xBF: // NXP (?)
switch (call_iap(IAP_GET_DEVICE_ID_1)) {
case 0x91: // P89V51Rx2xx
iap.device = IAP_DEVICE_89V51;
if (call_iap(IAP_V51_GET_BOOT_CODE_VERSION) == 0x07)
return;
upgrade_p89v51_iap();
call_iap(IAP_V51_SET_DOUBLE_CLOCK);
call_iap(IAP_V51_SET_ISP_ENTRY_MODE_PIN_LOW(0x90 + 0));
// port P1 + pin 0
iap_reboot();
}
} // switch
fatal_error(E_IAP_UNKNOWN_DEVICE_TYPE);
}
/// call IAP routine
/**
* This function is a wrapper around real IAP routine placed in
* bootcode area.
*
* @warning
* The function code relies on the fact that current compiler passes
* function parameters via registers @c R1, @c R2, @c R3, and @c R4,
* in this order.
*
* @return IAP function exit code or value
*/
#pragma location="IAP_SAFE_CODE" // code segment start >= 0x2000
#pragma optimize=no_inline
static char call_iap (const char R1, ///< 1st parameter passed via R1
const char R2, ///< 2nd parameter passed via R2
const char R3, ///< 3rd parameter passed via R3
const char R4) ///< 4th parameter passed via R4
{
asm("PUSH 0xA8/*IEN0*/ ");
asm("CLR 0xA8.7/*EA*/ ");// disable interrupts
asm("ANL 0xB1/*FCF*/,#~0x01 ");// enable 89V51's bootcode bank
asm("ANL ?DPS,#~0x01 ");// select DPTR 0
asm("MOV DPH,R2 ");
asm("MOV DPL,R3 ");
asm("MOV A,R4 ");
asm("CALL iap_routine ");// call 89V51's IAP routine (0x1FF0)
asm("ORL 0xB1/*FCF*/,#0x01 ");// disable 89V51's bootcode bank
asm("POP 0xA8/*IEN0*/ ");
return ACC;
}
By inspecting the bootloader's disassembled code, I noticed (see line in bold below) that there is a loop which waits for serial transmit interrupt flag (SCON.1). Because I am in IAP mode, not ISP mode, and I have no transmission pending, the loop never ends.
04BFh MOV A,FST
04C1h JB ACC.3,0502h
04C4h JNB SCON.1,04C4h
04C7h ORL FCF,#40h
04CAh MOV B4h,#55h
04CDh MOV B5h,#AAh
04D0h MOV B2h,#08h
[...]
0502h CLR A
0503h RET
I think I have only two choices:
I would go for option 1. What would you guys do? [1] - P89V51RB2/RC2/RD2 - 8-bit 80C51 5V low power 16/32/64 kB Flash microcontroller with 1 kB RAM (rev. 03 - 02 December 2004) [2] - 89V/LV51Rx2 Bootcode Enanchements (part of ZIP archive available at P89V51Rx2 Bootloader Update) |
| Topic | Author | Date |
| Function "Program Double Clock" never returns in IAP mode | 01/01/70 00:00 | |
| You should check carefully | 01/01/70 00:00 | |
| I feel safe | 01/01/70 00:00 | |
| bootloader v6 is affected, too | 01/01/70 00:00 | |
| it's the same in v4 and v5, too | 01/01/70 00:00 | |
| TI=1 workaround | 01/01/70 00:00 | |
| 3-rd party programming and thebootloader | 01/01/70 00:00 | |
| bootloader self-upgraded to v7 | 01/01/70 00:00 | |
IAP ? | 01/01/70 00:00 |



