⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootldr3.asm

📁 pic bootloader 用于PIC单片机的主程序下载
💻 ASM
📖 第 1 页 / 共 2 页
字号:
        goto    CheckLineDone   ;check for rollover
        incf    AddressH,F      ;if so then increment high address byte

CheckLineDone:
        decfsz  Counter,F       ;check if all words have been programmed
        goto    CheckAddress    ;if not then go program next word

;-----------------------------------------------------------------------------
;Done programming line of file

LineDone:
        movlw   '.'             ; line has been programmed so
        call    SerialTransmit  ; transmit progress indicator back
        call    SerialReceive   ; eat the trailing CR (hopefully!)
        goto    GetNewLine      ; go get next line hex file


;
;  Control reaches this point after loading a file.  Change the
;  status indicator to show that a legal file has been loaded,
;  then issue the success indicator and return to the top for
;  the next command.
;

FileDone:
File1:
        call    SerialReceive   ; need to eat checksum for file record
        xorlw   0x0d            ; hit the CR yet?
        btfsc   STATUS,Z
        goto    File2           ; got the CR, finish the report
        xorlw   0x0d            ; need to echo, restore the char
        call    SerialTransmit  ; do the echo
        goto    File1           ; loop until CR

File2:
        call    LoadStatusAddr  ;load address of CodeStatus word
        clrf    EEDATH          ;load data to indicate program exists
        clrf    EEDATA          ;load data to indicate program exists
        call    FlashWrite

        call    SendCRLF
        movlw   'O'             ; show success
        call    SerialTransmit
        movlw   'K'
        call    SerialTransmit

        goto    GetNewLine


;
;  An error occurred in the file download.  Send an error
;  indicator, then return to the top for another command.
;

ErrorMessage:
        call    SendCRLF
        movlw   '!'                     ; show failure
        call    SerialTransmit
        call    SerialTransmit
        goto    GetNewLine


;
;  Control reaches this point to process the GO command.  Check for
;  a valid file (CodeStatus).  If OK, jump to user program, otherwise,
;  send an error code.  Note that this code is copied from the code at
;  Main that runs on power-up in user mode.
;
;  There are two forms of this command:
;
;  G <CR>       code status must be good before jump to user code.
;  G! <CR>      jumps to user code WITHOUT checking code status  
;
;  Note that the G! form forces the CodeStatus word to 0 before jumping
;  to the user code.  This means subsequent resets with the bootloader
;  select line high will also jump to user code.  There had better be
;  something there!
;

DoGoCmd:
        call    SerialReceive           ; get next char
        xorlw   0x0d                    ; check it
        btfss   STATUS,Z
        goto    GoCmd1                  ; no CR, might be !
        call    SendCRLF                ; echo CR and LF
        call    LoadStatusAddr          ; load address of CodeStatus word
        call    FlashRead               ; read data at CodeStatus location
        Bank2                           ; change from bank3 to bank2
        movf    EEDATA,F                ; set Z flag if data is zero
        Bank0                           ; change from bank2 to bank0
        btfsc   STATUS,Z                ; skip if code status is bad
        goto    StartUserCode           ; run the user program

        call    SendCRLF                ; make it pretty
        movlw   'N'                     ; get the failure marker
        call    SerialTransmit          ; send it
        movlw   'O'                     ; get rest of marker
        call    SerialTransmit          ; send it
        goto    GetNewLine              ; back to the top

GoCmd1:
        xorlw   0x0d                    ; restore char
        xorlw   '!'                     ; force char?
        btfss   STATUS,Z
        goto    EatLine                 ; not !, must be trash...
        movlw   '!'                     ; need to echo
        call    SerialTransmit          ;
        call    SerialReceive           ; get next char
        xorlw   0x0d                    ; better be CR
        btfss   STATUS,Z
        goto    EatLine                 ; no CR, ignore it
        call    SendCRLF                ; echo CR and LF
        call    LoadStatusAddr          ;load address of CodeStatus word
        clrf    EEDATH                  ;load data to indicate program exists
        clrf    EEDATA                  ;load data to indicate program exists
        call    FlashWrite
        goto    StartUserCode           ; run the user program (hopefully)

        

;
;  SendCRLF      send a CR/LF sequence
;

SendCRLF:
        movlw   0x0d                    ; CR
        call    SerialTransmit
        movlw   0x0a                    ; LF
        call    SerialTransmit
        return


;
;  SendByte      send a byte as two hex characters
;

SendByte:
        movwf   Temp                    ; save a copy
        swapf   Temp,w                  ; move top nybble to w
        call    outnyb                  ; send it
        movf    Temp,w                  ; move low nybble to w
        call    outnyb                  ; send and return
        return

;
;  outnyb      send low nybble of w as hex to serial port
;

outnyb:
        andlw   0x0f            ; leave only low 4 bits
        addlw   -.10            ; test against 9
        btfsc   STATUS,C        ; skip if value was <= 9
        addlw   7               ; 10 or more, adjust to hex
        addlw   .10             ; restore value
        addlw   '0'             ; make it ascii
        call    SerialTransmit  ; and send it
        return



;
;  LoadStatusAddr      load address of CodeStatus word to flash addr regs
;
;  This routine returns in bank2.
;

LoadStatusAddr:
        Bank2                   ;change from bank0 to bank2
        movlw   high CodeStatus ;load high addr of CodeStatus location
        movwf   EEADRH
        movlw   low CodeStatus  ;load low addr of CodeStatus location
        movwf   EEADR
        return


;
;  GetHexByte      get two ASCII digits, convert to a byte
;
;  This routine reads and echoes two characters from the USART
;  and converts them to a single byte, returned in W.  No check
;  is made for legality.  The byte is added to the checksum.
;  This routine returns in bank0.

GetHexByte:
        call    SerialReceive   ;get new byte from serial port
        call    SerialTransmit  ;echo the character
        addlw   0xbf            ;add -'A' to Ascii high byte
        btfss   STATUS,C        ;check if positive
        addlw   0x07            ;if not, add 17 ('0' to '9')
        addlw   0x0a            ;else add 10 ('A' to 'F') 
        movwf   HexByte         ;save nibble
        swapf   HexByte,F       ;move nibble to high position

        call    SerialReceive   ;get new byte from serial port
        call    SerialTransmit  ;echo the character
        addlw   0xbf            ;add -'A' to Ascii low byte
        btfss   STATUS,C        ;check if positive
        addlw   0x07            ;if not, add 17 ('0' to '9')
        addlw   0x0a            ;else add 10 ('A' to 'F') 
        iorwf   HexByte,F       ;add low nibble to high nibble
        movf    HexByte,W       ;put result in W reg
        addwf   Checksum,F      ;add to cumulative checksum
        return

;
;  SerialSetup      initialize the USART
;
;  Configure the USART for transmit and receive at the default
;  baud rate.
;
;  Note that this routine returns with the banking registers set
;  for bank0.
;

SerialSetup:
        Bank1
        movlw   BAUD_DEFAULT    ;set baud rate 
        movwf   SPBRG
        bsf     TXSTA,BRGH      ;baud rate high speed option
        bsf     TXSTA,TXEN      ;enable transmission
        Bank0                   ;change from bank1 to bank0
        bsf     RCSTA,CREN      ;enable reception
        bsf     RCSTA,SPEN      ;enable serial port
        return


;
;  SerialReceive      read a byte from USART, return it in W
;
;  Note that this routine returns with the banking registers set
;  for bank0.
;

SerialReceive:
        Bank0                   ;change from unknown bank to bank0
        btfss   PIR1,RCIF       ;check if data received
        goto    $-1             ;wait until new data
        movf    RCREG,W         ;get received data into W
        return


;
;  SerialTransmit      transmit byte in W register from USART
;
;  Note that this routine returns with the banking registers set
;  for bank0.
;

SerialTransmit:
        Bank0                   ;change from unknown bank to bank0
        btfss   PIR1,TXIF       ;check that buffer is empty
        goto    $-1
        movwf   TXREG           ;transmit byte
        return


;
;  FlashWrite      write to a location in the flash program memory.
;
;  The calling routine should write the address of interest in EEADRH
;  and EEADR, and the data in EEDATH and EEDATA.
;
;  Note that this routine returns with the banking registers set
;  for bank3.
;

FlashWrite:
                Bank3                   ;change from bank2 to bank3
                movlw   0x84            ;enable writes to program flash
                movwf   EECON1

                movlw   0x55            ;do timed access writes
                movwf   EECON2
                movlw   0xaa
                movwf   EECON2
                bsf     EECON1,WR       ;begin writing to flash

                nop                     ;processor halts here while writing
                nop
                return

;-----------------------------------------------------------------------------
;
;  FlashRead      read from a location in the flash program memory
;
;  Address is in EEADRH and EEADR, data returned in EEDATH and EEDATA
;  This routine returns in bank3.
;

FlashRead:
                Bank2                   ; get it right
                movlw   0x1f            ; keep address within range
                andwf   EEADRH,F

                Bank3                   ; change from bank2 to bank3
                movlw   0x80            ; enable reads from program flash
                movwf   EECON1
                bsf     EECON1,RD       ; read from flash
                nop                     ; processor waits while reading
                nop
                return


;
;  The following instructions act as vectors to permit other programs
;  access to routines within the monitor.  Programs should execute
;  a CALL to one of these addresses, rather than a CALL directly to
;  the target routine, as the target routine might move in future
;  versions of this program!
;
;  Pay close attention to the banking when these routines exit, as
;  they often change the current register bank.
;
;  Note that entry to the Loader at $xxff should be via a GOTO, not
;  a CALL.
;

        org     StartOfBoot+0x1f8

        return                          ; $1ff8
        return                          ; $1ff9
        return                          ; $1ffa
        return                          ; $1ffb
        goto    SerialSetup             ; $1ffc
        goto    FlashRead               ; $1ffd
        goto    FlashWrite              ; $1ffe
        goto    Loader                  ; $1fff
        
;-----------------------------------------------------------------------------

                END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -