Open source PBP bootloader


Results 1 to 40 of 41

Threaded View

  1. #6
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: Open source PBP bootloader

    This is pretty small help. I'll try to do better later..... I notice the GUI that Microchip includes includes the Visual Basic 6.0 source code. So in that case I may be able to do some simple stuff for the interface. I know this doesn't help our linux crowd though.

    Code:
    DATA_BUFF   VAR BYTE[6]        ' Start of receive buffer SAME ADDRESS AS COMMAND
        
    COMMAND     VAR DATA_BUFF[0]    ' Data mapped in receive buffer SAME ADDRESS AS DATA_BYTE
    DATA_COUNT1 VAR DATA_BUFF[1]    
    ADDRESS_L   VAR DATA_BUFF[2]
    ADDRESS_H   VAR DATA_BUFF[3]
    ADDRESS_U   VAR DATA_BUFF[4]
    PACKET_DATA VAR DATA_BUFF[5]    'THIS SHOULD BE AN ARRAY I THINK**************
    ' *****************************************************************************
    I may be off base on Packet_Data ; DATA - General data up to 255 bytes

    ASM source:
    Code:
    ; *****************************************************************************
    ;        Software License Agreement                    
    ;                                     
    ; The software supplied herewith by Microchip Technology         
    ; Incorporated (the “Company”) for its PICmicro® Microcontroller is 
    ; intended and supplied to you, the Company’s customer, for use     
    ; solely and exclusively on Microchip PICmicro Microcontroller        
    ; products. The software is owned by the Company and/or its         
    ; supplier, and is protected under applicable copyright laws. All   
    ; rights are reserved. Any use in violation of the foregoing          
    ; restrictions may subject the user to criminal sanctions under        
    ; applicable laws, as well as to civil liability for the breach of  
    ; the terms and conditions of this license.                
    ;                                    
    ; THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES, 
    ; WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 
    ; TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A         
    ; PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, 
    ; IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR         
    ; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.            
    ;                                    
    ;                                     
    ; Bootloader for PIC16F by Rodger Richey
    ; Adapted from PIC18F bootloader developed by Ross Fosler
    ; 03/18/2002    ... First full implementation
    ; 03/25/2002    Modified receive & parse engine to vector to autobaud on a checksum 
    ;        error since a checksum error could likely be a communications problem.
    ;         Modified the protocol to incorporate the autobaud as part of the 
    ;        first received <stx>. Doing this improves robustness by allowing
    ;        re-sync under any condition. Previously it was possible to enter a 
    ;        state where only a hard reset would allow re-syncing.
    ; 04/09/2002    Fixed bugs: 1) clear carry before shifting ABTIME in Autobaud
    ;                    2) Increment address in program memory write
    ;                    3) Increment address in program memory read
    ; 06/07/2002    Fixed bug in read, byte counter in code is word counter.  Needed
    ;               to multiply by 2 to get bytes.
    ;
    ; Memory Map
    ;    -----------------
    ;    |    0x0000    |    Reset vector
    ;    |            |
    ;       |    0x0004    |    Interrupt vector
    ;    |            |    
    ;    |        |
    ;    |  Boot Block     |    (this program)
    ;     |        |
    ;    |    0x0200    |    Re-mapped Reset Vector
    ;    |    0x0204    |    Re-mapped High Priority Interrupt Vector
    ;    |        |
    ;    |    |    |
    ;    |        |
    ;        |  Code Space     |    User program space
    ;    |        |
    ;    |    |    |
    ;    |        |
    ;    |    0x3FFF     |
    ;    -----------------
    ;
    ;
    ; Incomming data format:
    ;
    ;    <stx><stx><data><chksum><etx>
    ;          /    \
    ;     ________/      \____________________________
    ;    /                                         \
    ;    <command></command><dlen><addrl><addrh><addru><data>...
    ;
    ; Definitions:
    ;
    ;     STX    -    Start of packet indicator
    ;    ETX    -    End of packet indicator
    ;     LEN     -    Length of incomming packet
    ;     DATA    -    General data up to 255 bytes
    ;     CHKSUM     -     The 8-bit two's compliment sum of LEN & DATA
    ;     COMMAND -     Base command
    ;     DLEN    -    Length of data associated to the command
    ;     ADDR    -    Address up to 24 bits
    ;     DATA     -    Data (if any)
    ;
    ;
    ; Commands:
    ;
    ;     RD_VER        0x00    Read Version Information
    ;     RD_MEM        0x01    Read Program Memory
    ;     WR_MEM        0x02    Write Program Memory
    ;     ER_MEM        0x03    Erase Program Memory (NOT supported by PIC16)
    ;     RD_EE        0x04    Read EEDATA Memory 
    ;     WR_EE        0x05    Write EEDATA Memory 
    ;     RD_CONFIG    0x06    Read Config Memory (NOT supported by PIC16)
    ;     WT_CONFIG    0x07    Write Config Memory (NOT supported by PIC16)
    ;
    ; *****************************************************************************
    
     
    
    ; *****************************************************************************
        #include P16F877A.INC        ; Standard include
    ; *****************************************************************************
    
        errorlevel -302            ; Do not show any banking warnings
    
    ; *****************************************************************************
    #define    MINOR_VERSION    0x03        ; Version
    #define    MAJOR_VERSION    0x00
    
    #define    RC_DLE        0x01
    #define    RC_STX        0x02
    
    #define    STX        0x0F
    #define    ETX        0x04
    #define    DLE        0x05
    
    ;#define DEBUGGING            ; Debugging enabled with ICD
    ; *****************************************************************************
    
    
    
    ; *****************************************************************************
    CHKSUM        equ    0x71        ; Checksum accumulator
    COUNTER        equ    0x72        ; General counter
    ABTIME        equ    0x73
    RXDATA        equ    0x74
    TXDATA        equ    0x75
    TEMP        equ    0x76
    
    PCLATH_TEMP    equ    0x7D        ; Interrupt context
    STATUS_TEMP    equ    0x7E        ; save/restore registers
    W_TEMP        equ    0x7F
    
    ; Frame Format
    ;
    ;  <stx><stx>[<command></command><datalen><addrl><addrh><addru><...DATA...>]<chksum><etx>
    
    DATA_BUFF    equ    0x10        ; Start of receive buffer
        
    COMMAND        equ    0x10        ; Data mapped in receive buffer
    DATA_COUNT    equ    0x11    
    ADDRESS_L    equ    0x12
    ADDRESS_H    equ    0x13
    ADDRESS_U    equ    0x14
    PACKET_DATA    equ    0x15    
    ; *****************************************************************************
    
    
     
    ; *****************************************************************************
        ORG    0x0000            ; Re-map Reset vector
    VReset
        bcf    STATUS,RP0                            ; B0/B2
        bsf    STATUS,RP1                            ; B2
        clrf    PCLATH                                ; B2
        goto    Setup                                ; B2
    
        ORG    0x0004
    VInt
        movwf    W_TEMP                                ; ?
        swapf    STATUS,W                            ; ?
        movwf    STATUS_TEMP                            ; ?
        clrf    STATUS                                ; B0
        movf    PCLATH,W                            ; B0
        movwf    PCLATH_TEMP                            ; B0
        clrf    PCLATH                                ; B0
        goto    RVInt            ; Re-map Interrupt vector        ; B0
    
    ; *****************************************************************************
    
    
    
    ; *****************************************************************************
    ; Setup the appropriate registers.
    Setup    clrwdt
        movlw    0xFF                                ; B2
        movwf    EEADR            ; Point to last location        ; B2
        bsf    STATUS,RP0                            ; B3
        clrf    EECON1                                ; B3
        bsf    EECON1,RD        ; Read the control code            ; B3
        bcf    STATUS,RP0                            ; B2
        incf    EEDATA,W                            ; B2
        btfsc    STATUS,Z                            ; B2
        goto    SRX                                ; B2
    
        bcf    STATUS,RP1                            ; B0
        goto    RVReset            ; If not 0xFF then normal reset        ; B0
    
    SRX    bcf    STATUS,RP1                            ; B0
        movlw    b'10000000'        ; Setup rx and tx, CREN disabled    ; B0
        movwf    RCSTA                                ; B0
        bsf    STATUS,RP0                            ; B1
        bcf    TRISC,6            ; Setup tx pin                ; B1
        movlw    b'00100110'                            ; B1
        movwf    TXSTA                                ; B1
        bsf    STATUS,IRP                            ; B1
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    Autobaud
    ;
    ; ___     __________            ________
    ;    \__/       \__________/
    ;       |                     |
    ;       |-------- p ----------|
    ;
    ;    p = The number of instructions between the first and last
    ;           rising edge of the RS232 control sequence 0x0F. Other 
    ;        possible control sequences are 0x01, 0x03, 0x07, 0x1F, 
    ;         0x3F, 0x7F.
    ;
    ;    SPBRG = (p / 32) - 1      BRGH = 1
                                            ; B0/B1/B2
        bcf    STATUS,RP1                            ; B0/B1
        bsf    STATUS,RP0                            ; B1
        movlw    b'00000011'                            ; B1
        movwf    OPTION_REG                            ; B1
        bcf    STATUS,RP0                            ; B0
        bcf    RCSTA,CREN                            ; B0
    
        call    WaitForRise                            ; B0
     
        clrf    TMR0            ; Start counting            ; B0
    
        call    WaitForRise                            ; B0
    
        movf    TMR0,W            ; Read the timer            ; B0
        movwf    ABTIME                                ; B0
    
        bcf    STATUS,C
        rrf    ABTIME,W                            ; B0
        btfss    STATUS,C        ; Rounding                ; B0
        addlw    0xFF                                ; B0
    
        bsf    STATUS,RP0                            ; B1
        movwf    SPBRG                                ; B1
        bcf    STATUS,RP0                            ; B0
        bsf    RCSTA,CREN        ; Enable receive            ; B0
    
        movf    RCREG,W                                ; B0
        movf    RCREG,W                                ; B0
    
        bsf    STATUS,RP0                            ; B1
        movlw    b'11111111'                            ; B1
        movwf    OPTION_REG                            ; B1
    ; *****************************************************************************
    
    
    
    ; *****************************************************************************
    ; Read and parse the data.
    StartOfLine                                    ; B1/B2/B0
        bcf    STATUS,RP0                            ; B0/B2
        bcf    STATUS,RP1                            ; B0
        call    RdRS232            ; Look for a start of line        ; B0
        xorlw    STX            ; <stx><stx>                ; B0
        btfss    STATUS,Z                            ; B0
        goto    Autobaud        ;was StartOfline            ; B0
    
        movlw    DATA_BUFF        ; Point to the buffer            ; B0
        movwf    FSR                                ; B0
    
        clrf    CHKSUM            ; Reset checksum            ; B0
            
    GetNextDat                
        call    RdRS232            ; Get the data                ; B0
        xorlw    STX            ; Check for a STX            ; B0
        btfsc    STATUS,Z                            ; B0
        goto    StartOfLine        ; Yes, start over            ; B0
    
    NoSTX    movf    RXDATA,W                            ; B0
        xorlw    ETX            ; Check for a ETX            ; B0
        btfsc    STATUS,Z                            ; B0
        goto    CheckSum        ; Yes, examine checksum            ; B0
    
    NoETX    movf    RXDATA,W                            ; B0
        xorlw    DLE            ; Check for a DLE            ; B0
        btfss    STATUS,Z                            ; B0
        goto    NoDLE            ; Check for a DLE            ; B0
    
        call    RdRS232            ; Yes, Get the next byte        ; B0
        
    NoDLE    movf    RXDATA,W                            ; B0
        movwf    INDF            ; Store the data            ; B0
        addwf    CHKSUM,F        ; Get sum                ; B0
        incf    FSR,F                                ; B0
    
        goto    GetNextDat                            ; B0
    
    CheckSum    
        movf    CHKSUM,F        ; Checksum test                ; B0
        btfss    STATUS,Z                            ; B0
        goto    Autobaud                            ; B0
    ; ***********************************************
    
    
    
    ; ***********************************************
    ; Pre-setup, common to all commands.                        ; B0
        bsf    STATUS,RP1                            ; B2
        movf    ADDRESS_L,W        ; Set all possible pointers        ; B2
        movwf    EEADR                                ; B2
        movf    ADDRESS_H,W                            ; B2
        movwf    EEADRH                                ; B2
    
        movlw    PACKET_DATA                            ; B2
        movwf    FSR                                ; B2
    
        movf    DATA_COUNT,W         ; Setup counter                ; B2
        movwf    COUNTER                                ; B2
        btfsc    STATUS,Z                            ; B2
        goto    VReset            ; Non valid count (Special Command)    ; B2
    ; ***********************************************
    
     
    
    ; ***********************************************
    ; Test the command field and sub-command.                    ; B2
    CheckCommand
        movf    COMMAND,W        ; Test for a valid command        ; B2
        sublw    d'7'                                ; B2
        btfss    STATUS,C                            ; B2
        goto    Autobaud                            ; B2
    
        movf    COMMAND,W        ; Perform calculated jump        ; B2
        addwf    PCL,F                                ; B2
        
        goto    ReadVersion        ; 0                    ; B2
        goto    ReadProgMem        ; 1                    ; B2
        goto    WriteProgMem        ; 2                    ; B2
        goto    StartOfLine        ; 3                    ; B2
        goto    ReadEE            ; 4                    ; B2
        goto    WriteEE            ; 5                    ; B2
        goto    StartOfLine        ; 6                    ; B2
        goto    StartOfLine        ; 7                    ; B2
    ;maybe add jump to reset vector in this table
    ; ***********************************************
    
    
    
    ; ***********************************************
    ; Commands
    ; 
    ; In:    <stx><stx>[<0x00><0x02>]<0xFF><etx>
    ; OUT:    <stx><stx>[<0x00><verl><verh>]<chksum><etx>
    ReadVersion                                    ; B2
        movlw    MINOR_VERSION                            ; B2
        movwf    DATA_BUFF + 2                            ; B2
        movlw    MAJOR_VERSION                            ; B2
        movwf    DATA_BUFF + 3                            ; B2
    
        movlw    0x04                                ; B2
        goto    WritePacket                            ; B2
    
    
    ; In:    <stx><stx>[<0x01><dlen><addrl><addrh><addru>]<chksum><etx>
    ; OUT:    <stx><stx>[<0x01><dlen><addrl><addrh><addru><data>...]<chksum><etx>
    ReadProgMem                                    ; B2
    RPM1    bsf    STATUS,RP0                            ; B3
        bsf    EECON1,EEPGD                            ; B3
        bsf    EECON1,RD                            ; B3
        nop                                    ; B3
        nop                                    ; B3
        bcf    STATUS,RP0                            ; B2
        movf    EEDATA,W                            ; B2
        movwf    INDF                                ; B2
        incf    FSR,F                                ; B2
        movf    EEDATH,W                            ; B2
        movwf    INDF                                ; B2
        incf    FSR,F                                ; B2
    
        incf    EEADR,F                                ; B2
        btfsc    STATUS,Z                            ; B2
        incf    EEADRH,F                            ; B2
    
        decfsz    COUNTER,F                            ; B2
        goto    RPM1            ; Not finished then repeat        ; B2
    
        rlf    DATA_COUNT,W        ; Setup packet length            ; B2
        addlw    0x05                                ; B2
                    
        goto    WritePacket                            ; B2
    
    
    ; In:    <stx><stx>[<0x02><dlenblock><addrl><addrh><addru><data>...]<chksum><etx>
    ; OUT:    <stx><stx>[<0x02>]<chksum><etx>
    WriteProgMem                                    ; B2
        bsf    STATUS,RP0                            ; B3
        movlw    b'10000100'        ; Setup writes                ; B3
        movwf    EECON1                                ; B3
        bcf    STATUS,RP0                            ; B2
        movlw    b'11111100'        ; Force a boundry            ; B2
        andwf    EEADR,F                                ; B2
     
        movlw    0x04                                ; B2
        movwf    TEMP                                ; B2
    
    Lp1    
        movf    INDF,W                                ; B2
        movwf    EEDATA                                ; B2
        incf    FSR,F                                ; B2
        movf    INDF,W                                ; B2
        movwf    EEDATH                                ; B2
        incf    FSR,F                                ; B2
        call    StartWrite                            ; B2
    
        incf    EEADR,F                                ; B2
        btfsc    STATUS,Z                            ; B2
        incf    EEADRH,F                            ; B2
    
        decfsz    TEMP,F                                ; B2
        goto    Lp1                                ; B2
    
        decfsz    COUNTER,F                            ; B2
        goto    WriteProgMem        ; Not finished then repeat        ; B2
    
        goto    SendAcknowledge        ; Send acknowledge            ; B2
    
    
    ; In:    <stx><stx>[<0x04><dlen><addrl><addrh><0x00>]<chksum><etx>
    ; OUT:    <stx><stx>[<0x04><dlen><addrl><addrh><0x00><data>...]<chksum><etx>
    ReadEE                                        ; B2
        bsf    STATUS,RP0                            ; B3
        clrf    EECON1                                 ; B3
    
        bsf    EECON1,RD        ; Read the data                ; B3
        bcf    STATUS,RP0                            ; B2
        movf    EEDATA,W                            ; B2
        movwf    INDF                                ; B2
        incf    FSR,F                                ; B2
        
        incf    EEADR,F            ; Adjust EEDATA pointer            ; B2
    
        decfsz    COUNTER,F                            ; B2
        goto    ReadEE            ; Not finished then repeat        ; B2
    
        movf    DATA_COUNT,W        ; Setup packet length            ; B2
        addlw    0x05                                ; B2
                    
        goto    WritePacket                            ; B2
    
    
    ; In:    <stx><stx>[<0x05><dlen><addrl><addrh><0x00><data>...]<chksum><etx>
    ; OUT:    <stx><stx>[<0x05>]<chksum><etx>
    WriteEE                                        ; B2
        movf    INDF,W                                ; B2
        movwf    EEDATA                                ; B2
        incf    FSR,F                                ; B2
        call    WriteWaitEEData        ; Write data                ; B2
    
        incf    EEADR,F            ; Adjust EEDATA pointer            ; B2
    
        decfsz    COUNTER,F                            ; B2
        goto    WriteEE            ; Not finished then repeat        ; B2
    
        goto    SendAcknowledge        ; Send acknowledge            ; B2
    ; ***********************************************
    
    
    
    ; ***********************************************
    ; Send the data buffer back.
    ;
    ; <stx><stx>[<data>...]<chksum><etx>
    
    SendAcknowledge                                    ; B2
        movlw    0x01            ; Send acknowledge            ; B2
                                            ; B2
    WritePacket
        movwf    COUNTER                                ; B2
    
        movlw    STX            ; Send start condition            ; B2
        call    WrRS232                                ; B2
        call    WrRS232                                ; B0
    
        clrf    CHKSUM            ; Reset checksum            ; B0
    
        movlw    DATA_BUFF        ; Setup pointer to buffer area        ; B0
        movwf    FSR                                ; B0
        
    SendNext                ; Send DATA
        movf    INDF,W                                ; B0
        addwf    CHKSUM,F                            ; B0
        incf    FSR,F                                ; B0
        call    WrData                                ; B0
        decfsz    COUNTER,F                            ; B0
        goto    SendNext                            ; B0
    
        comf    CHKSUM,W        ; Send checksum                ; B0
        addlw    0x01                                ; B0
        call    WrData                                ; B0
    
        movlw    ETX            ; Send stop condition            ; B0
        call    WrRS232                                ; B0
    
        goto    Autobaud                            ; B0
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    ; Write a byte to the serial port.
    
    WrData                                        ; B0
        movwf    TXDATA            ; Save the data                ; B0
    
        xorlw    STX            ; Check for a STX            ; B0
        btfsc    STATUS,Z                            ; B0
        goto    WrDLE            ; No, continue WrNext            ; B0
    
        movf    TXDATA,W                            ; B0
        xorlw    ETX            ; Check for a ETX            ; B0
        btfsc    STATUS,Z                            ; B0
        goto    WrDLE            ; No, continue WrNext            ; B0
    
        movf    TXDATA,W                            ; B0
        xorlw    DLE            ; Check for a DLE            ; B0
        btfss    STATUS,Z                            ; B0
        goto    WrNext            ; No, continue WrNext            ; B0
    
    WrDLE
        movlw    DLE            ; Yes, send DLE first            ; B0
        call    WrRS232                                ; B0
    
    WrNext
        movf    TXDATA,W        ; Then send STX                ; DC
    
    WrRS232                                        ; B2/B0
        clrwdt                                    ; B2
        bcf    STATUS,RP1                            ; B0
        btfss    PIR1,TXIF        ; Write only if TXREG is ready        ; B0
        goto    $ - 1                                ; B0
        
        movwf    TXREG            ; Start sending                ; B0
    
        return                                    ; B0
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    RdRS232                                        ; B0
        clrwdt                                    ; B0
    
        btfsc    RCSTA,OERR        ; Reset on overun            ; B0
        goto    VReset                                ; B0
    
        btfss    PIR1,RCIF        ; Wait for data from RS232        ; B0
        goto    $ - 1                                ; B0
    
        movf    RCREG,W            ; Save the data                ; B0
        movwf    RXDATA                                ; B0
     
        return                                    ; B0
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    WaitForRise                                    ; B0
        btfsc    PORTC,7            ; Wait for a falling edge        ; B0
        goto    WaitForRise                            ; B0
        clrwdt                ;;; Do we need this?            ; B0
    WtSR    btfss    PORTC,7            ; Wait for starting edge        ; B0
        goto    WtSR                                ; B0
        return                                    ; B0
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    ; Unlock and start the write or erase sequence.
    
    StartWrite                                    ; B3
        clrwdt                                    ; B2
        bsf    STATUS,RP0                            ; B3
        movlw    0x55            ; Unlock                ; B3
        movwf    EECON2                                ; B3
        movlw    0xAA                                ; B3
        movwf    EECON2                                ; B3
        bsf    EECON1,WR        ; Start the write            ; B3
        nop                                    ; B3
        nop                                    ; B3
        bcf    STATUS,RP0                            ; B2
        return                                    ; B2
    ; *****************************************************************************
    
    
    
    
    ; *****************************************************************************
    WriteWaitEEData                                    ; B2
        bsf    STATUS,RP0                            ; B3
        movlw    b'00000100'        ; Setup for EEData            ; B3
        movwf    EECON1                                ; B3
        call    StartWrite                            ; B3
        btfsc    EECON1,WR        ; Write and wait            ; B3
        goto    $ - 1                                ; B3
        bcf    STATUS,RP0                            ; B2
        return                                    ; B2
    ; *****************************************************************************
    
    
    ; *****************************************************************************
        ORG    0x100
    RVReset                    
    
        ORG    0x104
    RVInt
    
    ; *****************************************************************************
    
    
        END
    </etx></chksum></data></stx></stx></etx></chksum></stx></stx></etx></chksum></data></addrh></addrl></dlen></stx></stx></etx></chksum></data></addrh></addrl></dlen></stx></stx></etx></chksum></addrh></addrl></dlen></stx></stx></etx></chksum></stx></stx></etx></chksum></data></addru></addrh></addrl></dlenblock></stx></stx></etx></chksum></data></addru></addrh></addrl></dlen></stx></stx></etx></chksum></addru></addrh></addrl></dlen></stx></stx></etx></chksum></verh></verl></stx></stx></etx></stx></stx></stx></stx></etx></chksum></addru></addrh></addrl></datalen></stx></stx></data></addru></addrh></addrl></dlen></etx></chksum></data></stx></stx></stx>
    Last edited by ScaleRobotics; - 2nd March 2011 at 09:25.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts