??? 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 |