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

CALLR does not return control (ASM for bootloader)

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.

  • Hello,

    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