Hello,
I am writing bootloader for XC2287M. The very first 32 bytes load next stage (#2) codes into PSRAM, then this loaded code starts. The compiled test code - the listing is here - does work sending out A1h byte on UART which I can see using the oscilloscope. But as soon as I place CALLR to a subroutine - in shown listing this is ASubRoutine - the microcontroller does not work anymore.
What is wrong with initialization? - Would appreciate any idea.
; ; By BKL, Jul-2010. Infineon XC2287M bootstrapping module #2; Standard UART BSL mode ; $SEGMENTED $CASE $MODV2 ; Define C166v2 core mode $INCLUDE (XC2xxx.INC) BOOTSTRAP2 SECTION CODE AT 0E00200H ; E0'0000H - Program SRAM ; ; Bootstrapping stage #2 - this code is loaded by 32-byte 1st stage bootloader ; _BLSTAGE2 PROC FAR diswdt mov STKOV, #0A000h ; Data SRAM for system stack mov STKUN, #0A200h mov SP, #0A200h mov SPSEG, #0 mov CP, #0FC00h ; Context @ Dualport RAM (DRAM) einit ; ; While in bootstrapping mode, ; XC2xxxM automatically has this spesific state - see "XC2000M Family User Manual V2.0 2009, 12-26" ; ; Item Value Comments ; ; DPP1 0081H Points to USIC0 base address ; R0 4044H Pointer to U0C0_PSR - Protocol Status Register ; R1 4048H Pointer to U0C0_PSCR - Protocol Status Clear Register ; R2 405CH Pointer to U0C0_RBUF - RX Buffer ; R3 4000H Mask to clear RIF ; ; Devices in 144/100-pin package: ; P7_IOCR03 00B0H P7.3 is push/pull output (TxD) ; P7_IOCR04 0020H P7.4 is input with pull-up (RxD) ; mov r4, #4080h ; U0C0_TBUF00 - Transmit Buffer Input Location 00 mov r7, #6000h ; mask to clear both Rx/Tx flags mov [r1], r7 ; clear PSCR _MAIN_LOOP: nop callr ASubRoutine ; (!) firmware does not work if this line is uncommented ; i.e. callr does not return control mov r7, #0A1H ; test byte we expect to see on the scope movb [r4], rl7 ; send out the test byte _wait_tx: mov r7, [r0] ; read PSR jnb r7.13, _wait_tx ; check TBIF flag mov r7, #2000h ; mask for Tx flag mov [r1], r7 ; clear PSCR jmpr cc_UC, _MAIN_LOOP ; ---------------------------------------------------------------- ASubRoutine: nop nop ret ; ---------------------------------------------------------------- _BLSTAGE2 ENDP BOOTSTRAP2 ENDS ; SECTION END END
Linker data is here:
".\obj\blstage2.obj" TO ".\obj\blstage2" PRINT(".\obj\blstage2.m66") CLASSES (NDATA (0xE00000-0xE03FFF), NDATA0 (0xE00000-0xE03FFF), SDATA (0xF600-0xFDFF), SDATA0 (0xF600-0xFDFF), IDATA (0xF600-0xFDFF), IDATA0 (0xF600-0xFDFF), FDATA (0xE00000-0xE07FFF), FDATA0 (0xE00000-0xE07FFF), HDATA (0xE00000-0xE07FFF), HDATA0 (0xE00000-0xE07FFF), XDATA (0xE00000-0xE07FFF), XDATA0 (0xE00000-0xE07FFF))
The generated map:
MEMORY MAP OF MODULE: .\obj\blstage2 (BLSTAGE2) START STOP LENGTH TYPE RTYP ALIGN TGR GRP COMB CLASS SECTION NAME ===================================================================================== E00200H E00243H 000044H CODE ABS AT.. --- --- PRIV --- BOOTSTRAP2 ... ... E00200H BLOCK LVL=0 0044H --- _BLSTAGE2 E0023EH SYMBOL LABEL --- --- ASubRoutine E00230H SYMBOL LABEL --- --- _wait_tx E00226H SYMBOL LABEL --- --- _MAIN_LOOP ... Program Size: data=0(near=0) const=0(near=0) code=68 L166 RUN COMPLETE. 0 WARNING(S), 0 ERROR(S)
Regards, Nikolay.
I found the reason: when calling subroutine explicit inter-segment ASM instructions CALLS/RETS must be used:
... calls #SEG ASubRoutine, #SOF ASubRoutine ; this heals the problem, otherwise stack underflow trap is generated ... ASubRoutine: ... rets
Note the bootloader is located in E0'0000 address space.
Regards, Nikolay