This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

IAP + philips firmware call & C51 debugger

Trying to use the code shown in the following

http://www.keil.com/support/docs/2045.htm

Basically, shows you how to do In Application programming on a philips device.

I have set my target device to a p89c662 which supports this, but when I call the code inside the debugger (uVision pretending to be the device) it gets to the

CALL 0FFF0H ; call philips firmware line

and chokes with the error:

*** error 65: access violation at C:0xFF00 : no 'execute/read' permission

I'd like to test it before I go anywhere near the device itself, am I missing something or can the C51 enironment not replicate that particular function?

  • Robert,
    The code sample omits the setting/resetting of the ENBOOT bit. The call to PGM_MTP(0FFF0H) should be preceded by MOV AUXR1,#20H to set the ENBOOT bit. After the call, use a MOV AUXR1,#NOT 020H to reset the bit.

    Robert

  • Thank you(!) Robert for the help :)

    Greatly appreciated.

    Robert

  • Spoke to soon.

    Added the lines you suggested and get the error:

    src\iap.asm(12): error A45: UNDEFINED SYMBOL (PASS-2)

    It doesn't like the AUXR1 symbol :(

    I created a seperate file (iap.asm) for the assembly code, do I somehow have to add the include file (reg66x.h) or do I have to put the code in my .c file?

    (Apologies for the newbie question but I haven't had to do assembly thus far in my working life)

  • I created a seperate file (iap.asm) for the assembly code, do I somehow have to add the include file (reg66x.h)
    yes, unless as below
    or do I have to put the code in my .c file?
    I always generate my own include files to enable global searches. If you, as normal, work both on the SFR and on the bit it becomes a nightmare to find "that little glitch". Thus EA in my lingo is SB_IE_EA for the bit and SM_IE_EA for sfr access. That way a global search on IE will give every place that sfr is accessed and a global search on EA will give all places that bit is accessed whether as a bit (re)set or as part of a SFR write.

    Erik

  • I actually change the include to the appropriate CPU header file -- in this case <REG66x.H>, and update all SFR and SBIT references accordingly (SCON to S0CON, etc.).

    Also, instead of using MOV to update the AUXR1, use ORL AUXR1,#020H and ANL AUXR1,#NOT 020H instead. This will avoid clobbering any other important bits in AUXR1...

    Cheers!

    Robert

  • Okay, tried that. still no success.

    Does the simulator support this function? Or is this only possible using a real p89c662 chip?

    Presently calling PGM_MTP (0xFFF0) doesn't work. There is a NOP there, which is what is making me wonder if the simulator supports this.

    All of the rest of the registers / sfr's contain the correct values (auxr1, a, dptr, r0, r1).

    Stumpted :(

  • Sorry, cannot help you there -- I use this code on a real P89C664.

    Robert

  • Thanks for trying though!

    I'll have a real p89c662 in a couple of days when the control board we are using is built and delievered. (my company was a bit to cheap to get a development board *grrr*)

    I was just trying to complete / test as much of the code as possible before it arrives :)

    Rob

  • Just a thought, but I wouldn't think the emulator would provide support for the firmware included in the Boot ROM -- but I could be mistaken.

    Your best bet is to use an #ifdef/#else clause to assemble a non-Flash version of the _ProgramDataByte function when using the emulator.

    Robert

  • Hi again Robert, quick question for you.

    Now got my control board and can write to the flash. But it appears that if I try to write to the same location, the write function appears to carry out an && function.

    for instance

    //main.c
    
    extern unsigned char ProgramDataByte (unsigned int addr, unsigned char v);
    
    void main (void)  {
    	ProgramDataByte (0x4000, 0x55);
    	ProgramDataByte (0x4000, 0x66);
    }
    
    // assembly
    
    #define AUXR1	0xA2
    XTAL_MHZ        EQU     12            ; Chip runs at 12MHz
    ?PR?_ProgramDataByte?ISA  SEGMENT CODE
    RSEG ?PR?_ProgramDataByte?ISA
    PUBLIC _ProgramDataByte         ; Entry Point for C Compiler
    ; unsigned char ProgramDataByte (unsigned int addr, unsigned char v);
    ; The C51 compiler passes addr in R6/R7 and v in R5
    _ProgramDataByte:       MOV   AUXR1, #20H
    			MOV   DPH,R6
                            MOV   DPL,R7
                            MOV   A,R5
                            MOV   R0,#XTAL_MHZ
                            MOV   R1,#02H        ; function code
                            CALL  0FFF0H         ; Call Philips firmware
                            MOV   R7,A           ; C51 expects return in R7
    			MOV   AUXR1, #NOT 20H
                            RET
                            END
    

    If I then look at the memory location I find I have 0x44, rather than 0x66 which I was expecting.

    I basically want to reprogram the byte without having to erase all the bytes in the block. Is that possible? (thought I'd ask give you said you worked with the 664)

    Many thanks

    Rob

  • When you write to flash, what you actually do is set some bits to 0. "Erasing" flash actually sets all bits to 1s. If you program the same byte twice without erasing in between, the first write will set some bits to zero, and then the second write will come along and set possibly some other bits to zero. The only way to set a flash bit to 1 is to erase the block.

    Hence, your observed "&& operation". 0x55 & 0x66 == 0x44. The write of 0x55 sets bit 1 to 0; the write of 0x66 can't get it back to a 1. The write of 0x66 sets bit 0 to 0. Both writes have bit 2 == 1, so it remains set after both writes.