PDA

View Full Version : Open source PBP bootloader



cncmachineguy
- 26th February 2011, 17:08
Ok guys, I read lots of stuff about how to change this or that with xyz bootloader. It seems to me this should not be a hard thing for us folks to create. So anybody up for this? Heck Walter even posted 1 in another thread, written in ASM. Now I suppose I could just reverse engineer it, but wheres the fun in that.

I am thinking about something well commented with places pointed out clearly for things like "I want to use UART 2, not 1" or "I want to use I2C"

What say you?

ardhuru
- 27th February 2011, 12:46
I am thinking about something well commented with places pointed out clearly for things like "I want to use UART 2, not 1" or "I want to use I2C"


Reminds me of the first bootloader I used: Tony Nixon's ROMZAP. Besides a snazzy interface, it had options to use ANY pins, not just the UART, with or without inversion (could save you a MAX chip!), user-configurable speeds and more.

Unfortunately Tony stopped development a long time ago, so its pretty much of no use today. A pity!

Anand Dhuru

cncmachineguy
- 27th February 2011, 22:57
It does sould like exactly what I think we all need in our "tool box" So we have a very vauge goal now. What a shame he quit on it. any idea why he stopped?

cncmachineguy
- 28th February 2011, 03:26
Ok, just got done reading AN851. This doesn't seem too hard to implement in PBP. Is anyone intrested? If so, what do you think of this as a starting point?

PJALM
- 28th February 2011, 10:28
I was planning on making a PBP Serial/USB/I2C/SD/Ethernet Bootloader but never got around to starting it yet. I guess now is a good time :)

cncmachineguy
- 28th February 2011, 14:34
PJALM, That sounds pretty awesome, and aggressive! :)

After doing some googling, There is at least 1 open source python interface out there to talk to AN851 BL. I like that approach, Python I mean, then we have multiplatform available.

Ok, we have 2 responses so far. I have no idea how to tend to the logistics of this - meaning making it a group effort- or if we just contribuite code until we get something working. Baring any other suggestions, I will start to port AN851 to PBP.

We will also need TESTERS!!! :)

cncmachineguy
- 2nd March 2011, 05:52
This is where I am so far. I am sure there are some errors, but what are friends for? :)


' ************************************************** ***************************
' Software License Agreement
'
' The software supplied herewith by PBP forum members
' (the “Company”) for Microchip's PICmicro® Microcontroller's 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.
'
'
' This software has been ported from Microchip's AN851 bootloader
' Changes have been made and will be made as the company sees fit.
' This version is for 16F's, there is another version for 18F's
'
'
' 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><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)
'
' ************************************************** **************************

' ************************************************** ***************************
CHKSUM VAR BYTE ' Checksum accumulator
COUNTER VAR BYTE ' General counter
ABTIME VAR BYTE
RXDATA VAR BYTE
TXDATA VAR BYTE
TEMP VAR BYTE

PCLATH_TEMP VAR BYTE ' Interrupt context
STATUS_TEMP VAR BYTE ' save/restore registers
W_TEMP VAR BYTE

' Frame Format
'
' <STX><STX>[<COMMAND><DATALEN><ADDRL><ADDRH><ADDRU><...DATA...>]<CHKSUM><ETX>

DATA_BUFF VAR BYTE ' Start of receive buffer SAME ADDRESS AS COMMAND

COMMAND VAR BYTE ' Data mapped in receive buffer SAME ADDRESS AS DATA_BYTE
DATA_COUNT VAR BYTE
ADDRESS_L VAR BYTE
ADDRESS_H VAR BYTE
ADDRESS_U VAR BYTE
PACKET_DATA VAR BYTE 'THIS SHOULD BE AN ARRAY I THINK**************
' ************************************************** ***************************


' This is the remapping section, note the interrupt also saves context
' ************************************************** ***************************
@ ORG 0x0000 ' Re-map Reset vector **Not sure how to set the address to start at
VReset:
PCLATH = 0
goto Setup

@ ORG 0x0004 'standard interrupt vector **again not sure of the PBP equal for ORG
VInt:
W_TEMP = W 'I am assuming this will be the "W" register
STATUS_TEMP = STATUS 'We may have trouble here. ASM uses SWAP so as not to affect the status
STATUS = 0
PCLATH_TEMP = PCLATH
PCLATH = 0
goto RVInt ' Re-map Interrupt vector

; ************************************************** ***************************
************************************************** ***************************
; Setup the appropriate registers.
Setup:
clrwdt
READ $ff,temp 'get the value of last EEPROM location
IF temp = $ff then goto SRX 'BL startup
goto RVReset ' If not 0xFF then normal reset

SRX:
RCSTA = b'10000000' ' Setup rx and tx, CREN disabled
TRISC.6 = 0 ' Setup tx pin
TXSTA = b'00100110'
STATUS.IRP = 1
; ************************************************** ***************************



Well it formats much better in notepad++. well I tried to attach the code, but had some issues there. but for now, the code is as I wrote it, just the comments are messed up.

ScaleRobotics
- 2nd March 2011, 09:54
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.



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:


; ************************************************** ***************************
; 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>

cncmachineguy
- 2nd March 2011, 12:28
Thanks Walter, any help is great!

Question is does data_packet want to be 5 bytes with data being it's own array, or do we want to keep it 1 big array (261 bytes)?

cncmachineguy
- 2nd March 2011, 14:15
Now that I am at work, I have read my PBP bible. I see we are limited to 96 bytes for an array in 16F devices, maybe less depending on the device. So I need some help here. How do we deal with this limitation?

The most elegant thing that comes to mind is if at compile time we can determine the array size for the device we want to use, store this as a constant in the BL, then the PC side can query this value and adjust the packets accordingly.

Short of that, I guess we either limit the max size to the biggest available in the smallest package, or have many BL's for the different PIC's. Now this is not an issue for the 18f's. Then how do we change the packet size in the GUI? - walter does this fall within the limited changes you can make?

I assume the array size will only somewhat alter our overall loading speed. I don't feel like this will be a big issue, after all, we have to transmit ALL of the data at some point. A smaller array will just have us checking the packet header more often. - Will we really care? Must we be able to D/L the program in under 1 sec instead of 2?

Also, I don't think it makes a lot of difference if DATA_PACKET is part of the DATA array.



; {STX}{STX}{DATA}{CHKSUM}{ETX}
; / \
; _______/ \________________________
; / \
; {COMMAND}{DLEN}{ADDRL}{ADDRH}{ADDRU}{DATA}...

ScaleRobotics
- 2nd March 2011, 16:21
Assembly normally confuses me, but I am more confused than normal. I do not see anywhere that they are changing the size of the array in the Microchip code.

In the Tiny Bootloader assembly code, I see:


cblock 0x20
buffer:80
endc


And that looks like an array of 80 to me. Where does Microchip set the array size for the data?

cncmachineguy
- 2nd March 2011, 16:34
They don't. Microchip assumes 255 bytes of ram will be available to store the data in. They start at address 0x10 (command byte) then if you look at No_DLE they store the data (this all happens after comparing the byte to STX,ETX,COMMAND, and DLE. (doing this from memory, so if I left any out, sry) The MOVLF INDF command stores the byte at 0x10 + FSR. at the end of the No_DLE routine, they have INCF FSR. this is how they are incrementing the ram address. They are using indirect addressing for all of this.

I am not sure if we have a simiular thing in PBP. Lookup does it, but that finds stuff, not store it.

ScaleRobotics
- 2nd March 2011, 19:08
Thanks Bert, that clears it up. I will check the GUI and see how they handle the data, and try to see if I can figure out what would need to be changed, if this data array is made small enough for PBP to handle easily.

I know this is for 16F, but if we made the buffer about 50 bytes, it could be made to bootload to a 8 pin 12F1822, which would be pretty cute. I don't think it would take too much longer to program, as it would just need a quick checksum and response from the PC.

Walter

cncmachineguy
- 2nd March 2011, 19:09
I have run into a snag in my brain. Here is the ASM:


rrf ABTIME,W ; B0
btfss STATUS,C ; Rounding ; B0
addlw 0xFF

Now I understand what it is doing, but I don't get why. The first line shifts ABTIME right 1 bit. This also clears bit 7. Because RRF rotates through the carry bit, ABTIME.0 gets put into the carry flag. So what is happening is this:
Shift right 1 bit
If the original (before shift) ABTIME.0=0 then add $FF to ABTIME. this seems to just clear the new ABTIME.0

So why not just do this:


tempflag = ABTIME.0
ABTIME = ABTIME >>1
IF TEMPFLAG THEN ABTIME.0 = 0


I guess my problem is did I evaluate what they are doing correctly?

cncmachineguy
- 2nd March 2011, 19:13
Walter, I am happy to make the data array any size we want. If smaller makes it more portable, then by all means I feel like thats the thing to do. I already think 96 is too big, just cuz PBP will want some bank 0 ram, and on the '887, I think thats the only bank big enough for 96 bytes. So we would prolly have compile errors right off!

The question I can't answer is so far I don't see where they are switching banks to get the next block of ram. But it may be built into the inderect addressing. I have never used it before.

cncmachineguy
- 3rd March 2011, 01:05
I need to edit post 14 but can't. I have my logic reversed. If ABTIME.0=0 then add $FF.

cncmachineguy
- 3rd March 2011, 12:09
Made a little more progress, also fixed some thing in what I already had. Any questions, comments, or suggestions ask away!



' ************************************************** ***************************
' Software License Agreement
'
' The software supplied herewith by PBP forum members
' (the “Company”) for Microchip's PICmicro® Microcontroller's 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.
'
'
' This software has been ported from Microchip's AN851 bootloader
' Changes have been made and will be made as the company sees fit.
' This version is for 16F's, there is another version for 18F's
'
'
' 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}{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 00 Read Version Information
' RD_MEM 01 Read Program Memory
' WR_MEM 02 Write Program Memory
' ER_MEM 03 Erase Program Memory (NOT supported by PIC16)
' RD_EE 04 Read EEDATA Memory
' WR_EE 05 Write EEDATA Memory
' RD_CONFIG 06 Read Config Memory (NOT supported by PIC16)
' WT_CONFIG 07 Write Config Memory (NOT supported by PIC16)
'
' ************************************************** **************************

' ************************************************** ***************************
CHKSUM VAR BYTE ' Checksum accumulator
COUNTER VAR BYTE ' General counter
ABTIME VAR BYTE
RXDATA VAR BYTE
TXDATA VAR BYTE
TEMP VAR BYTE
ARRAYPOINTER VAR BYTE

TEMPFLAG VAR BIT

PCLATH_TEMP VAR BYTE ' Interrupt context
STATUS_TEMP VAR BYTE ' save/restore registers
W_TEMP VAR BYTE

' Frame Format
'
' {STX}{STX}[{COMMAND}{DATALEN}{ADDRL}{ADDRH}{ADDRU}{...DATA... }]{CHKSUM}{ETX}

DATA_BUFF VAR BYTE[50] ' Start of receive buffer SAME ADDRESS AS COMMAND

COMMAND VAR DATA_BUFF[0] ' Data mapped in receive buffer SAME ADDRESS AS DATA_BYTE
DATA_COUNT 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-49] 'Maybe we don't need this line?**************
' ************************************************** ***************************


' This is the remapping section, note the interrupt also saves context
' ************************************************** ***************************
@ ORG 0x0000 ' Re-map Reset vector **Not sure how to set the address to start at
VReset:
PCLATH = 0
goto Setup

@ ORG 0x0004 'standard interrupt vector **again not sure of the PBP equal for ORG
VInt:
W_TEMP = W 'I am assuming this will be the "W" register
STATUS_TEMP = STATUS 'We may have trouble here. ASM uses SWAP so as not to affect the status
STATUS = 0
PCLATH_TEMP = PCLATH
PCLATH = 0
goto RVInt ' Re-map Interrupt vector

' ************************************************** ***************************
************************************************** ***************************
' Setup the appropriate registers.
Setup:
clrwdt
READ $ff,temp 'get the value of last EEPROM location
IF temp = $ff then goto SRX 'BL startup
goto RVReset ' If not 0xFF then normal reset

SRX:
RCSTA = %10000000 ' Setup rx and tx, CREN disabled
TRISC.6 = 0 ' Setup tx pin
TXSTA = %00100110
STATUS.IRP = 1
' ************************************************** ***************************


' ************************************************** ***************************
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


OPTION_REG = %00000011 'sets tmr0 to 1:16 prescale
STATUS.RP0 = 0
RCSTA.CREN = 0

gosub WaitForRise

TMR0 = 0 ' Start counting

gosub WaitForRise

ABTIME = TMR0 ' Read the timer
TEMPFLAG = ABTIME.0
ABTIME = ABTIME >>1
IF !TEMPFLAG THEN ABTIME.0 = 0 'Rounding
SPBRG = ABTIME
RCSTA.CREN = 1 ' Enable receive

TEMP = RCREG ' To clear the Rx buffer
TEMP = RCREG ' Both of them

OPTION_REG = %11111111 'Return Option Reg to reset state

' ************************************************** ***************************


' ************************************************** ***************************
' Read and parse the data.
StartOfLine:
GOSUB RdRS232 ' Look for a start of line
IF RXDATA != STX THEN Autobaud '{STX}{STX}

ARRAYPOINTER = 0 ' Point to the beginning of Array

CHKSUM = 0 ' Reset checksum

GetNextDat:
GOSUB RdRS232 ' Get the data
IF RXDATA = STX THEN StartOfLine ' Check for a STX
' Yes, start over

NoSTX:
IF RXDATA = ETX THEN CheckSum ' Check for a ETX
' Yes, examine checksum

NoETX:
IF RXDATA = DLE THEN GOSUB RdRS232 ' Check for a DLE
' Yes, Get the next byte

NoDLE:
DATA_BUFF[ARRAYPOINTER] = RXDATA ' Store the data
CHKSUM = CHKSUM + RXDATA ' Get sum
ARRAYPOINTER = ARRAYPOINTER + 1

goto GetNextDat

CheckSum:
IF CHKSUM = 0 THEN Autobaud ' Checksum test
' ***********************************************

cncmachineguy
- 3rd March 2011, 14:11
Just wanted to say, I am sorry this is taking me so long to convert. It is a simple matter to just change the ASM to PBP, but I am making sure I understand everything as I convert. That way when it doesn't work, I can at least have half a chance to find the problem. Also this will make it easier when we try to start making this do different things like I2C, or have it pass the program to another uP.

ScaleRobotics
- 3rd March 2011, 15:12
Learned a little more about the Microchip bootloader GUI. It reads a P1618qp.ini file which contains information about each chip. The dropdown menu is built from this ini file. So you can add chips if you enter the right information. I tried adding a chip, and was successful in seeing it appear int the dropdown menu of the GUI.

They have two subroutines for reading and two for writing to the code space, depending on whether it is a 16 or an 18 chip.

Here are a couple pic definition samples of the .ini file:


[PIC18F67J11]
writeblock=8
readblock=1
eraseblock=64
devicetype=1
maxpacketsize=128
bytesperaddr=1
pmrangelow="000400"
pmrangehigh="01FBFF"
eerangelow="000000"
eerangehigh="000000"
usrrangelow="200000"
usrrangehigh="20000F"
cfgrangelow="300000"
cfgrangehigh="30000F"
300001="CONFIG1H"
300002="CONFIG2L"
300003="CONFIG2H"
300005="CONFIG3H"
300006="CONFIG4L"
300008="CONFIG5L"
300009="CONFIG5H"
30000A="CONFIG6L"
30000B="CONFIG6H"
30000C="CONFIG7L"
30000D="CONFIG7H"



[PIC16F877]
writeblock=8
readblock=2
devicetype=0
maxpacketsize=32
bytesperaddr=2
pmrangelow="000200"
pmrangehigh="001FFF"
eerangelow="000000"
eerangehigh="0000FF"
And for the 18F devices, they have a menu that lets you configure the fuses. But it looks like you have to enter the value for them. Would be nice to make it read from the device file C:\Program Files\Microchip\MPLAB IDE\Device and populate the dropdown list. But that would definitely be down the road, because now I am having trouble seeing where they size the data field!

I do see a:


'limit the packet size
If (AddrH + 1) - BootAddr > PicBootS.MaxPacketSize Then
picA.BootDatLen = PicBootS.MaxPacketSize
Else
picA.BootDatLen = (AddrH + 1) - BootAddr
End If
But I am having trouble figuring out where they use it. Might take a couple cups of coffee ... or more.

cncmachineguy
- 3rd March 2011, 15:25
So if I understand this, for the 16f877 it says MAXPACKETSIZE=32. So thats how big the arreay should be for DATA_BUFF? I put in 50 for now, but can clearly make that 32. I think as a down the road desire, this value should be a variable that will get set at compile time or maybe the GUI can tell the PIC.

Good stuff Walter!! :)

ScaleRobotics
- 3rd March 2011, 16:20
Might be too early to say this, but it looks like it already does pull it from the ini file, and "tell" the pic. (I just don't see where it tells it yet) One of the parts that confuses me is that all I see is 32 as the maxdatasize for pic16, and 128 for what I think are all PIC18's. So where does 255 come in?

I have a lot more work to do.

cncmachineguy
- 3rd March 2011, 16:31
Don't quote me on this just yet, but I think the 18's use a word for the data, so then it would make sense. Also for the ASM program they can get away with just letting it be whatever size because the compiler doesn't care if its too big. No such luck with PBP. :(

ScaleRobotics
- 3rd March 2011, 17:45
Don't quote me on this just yet, but I think the 18's use a word for the data, so then it would make sense.

Oops, just quoted you .....:D

If that is true, then we should be good with the standard 32 bytes (if it is in bytes for 16F's) of data, then adding the 5 bytes for:



DATA_BUFF VAR BYTE[37] ' 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-36] 'THIS SHOULD BE AN ARRAY I THINK**************
would be 37 bytes for 12F and 16F devices, leaving more room for variables in case we want more PBP bells and whistles later. Then for the 18F's, they all use the 128 words (maybe).

cncmachineguy
- 3rd March 2011, 18:19
Newest update, includes Walter's last post regarding Array size. I have to stop here to think about what I am doing. I DON'T like the Read Program Memory at the end. I think it will work as is, but it really looks like ASM to me. I think I need to utilize the READCODE command, just not sure yet how to deal with the address and data. I assume maybe the address needs to be a word, comprised of EEADRH,EEADR. Then I guess the data is also a word. then I guess I just add 2 to the ARRAYPOINTER?

IF anyone wants to chime in on this, now is a good time :)

As a side note, IF anyone wants to help with this conversion, clearly I am working from the top down. If someone were to work from the bottom up, It would be easy for me to add it to what I have. Then when we meet in the middle, we will be done. :) No Biggie either way.

ANY testers out there? Still looking for some. I will be able to test compile, but don't feel comfy trying to test the code as I have never used a bootloader so I won't know if problems are with my setup or the code.



' ************************************************** ***************************
' Software License Agreement
'
' The software supplied herewith by PBP forum members
' (the “Company”) for Microchip's PICmicro® Microcontroller's 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.
'
'
' This software has been ported from Microchip's AN851 bootloader
' Changes have been made and will be made as the company sees fit.
' This version is for 16F's, there is another version for 18F's
'
'
' 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}{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 00 Read Version Information
' RD_MEM 01 Read Program Memory
' WR_MEM 02 Write Program Memory
' ER_MEM 03 Erase Program Memory (NOT supported by PIC16)
' RD_EE 04 Read EEDATA Memory
' WR_EE 05 Write EEDATA Memory
' RD_CONFIG 06 Read Config Memory (NOT supported by PIC16)
' WT_CONFIG 07 Write Config Memory (NOT supported by PIC16)
'
' ************************************************** **************************

' ************************************************** ***************************
CHKSUM VAR BYTE ' Checksum accumulator
COUNTER VAR BYTE ' General counter
ABTIME VAR BYTE
RXDATA VAR BYTE
TXDATA VAR BYTE
TEMP VAR BYTE
ARRAYPOINTER VAR BYTE
FAKEW VAR BYTE

TEMPFLAG VAR BIT

PCLATH_TEMP VAR BYTE ' Interrupt context
STATUS_TEMP VAR BYTE ' save/restore registers
W_TEMP VAR BYTE

' Frame Format
'
' {STX}{STX}[{COMMAND}{DATALEN}{ADDRL}{ADDRH}{ADDRU}{...DATA... }]{CHKSUM}{ETX}

DATA_BUFF VAR BYTE[37] ' Start of receive buffer SAME ADDRESS AS COMMAND

COMMAND VAR DATA_BUFF[0] ' Data mapped in receive buffer SAME ADDRESS AS DATA_BYTE
DATA_COUNT 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] 'Is this Valid? It is now!
' ************************************************** ***************************


' This is the remapping section, note the interrupt also saves context
' ************************************************** ***************************
@ ORG 0x0000 ' Re-map Reset vector **Not sure how to set the address to start at
VReset:
PCLATH = 0
goto Setup

@ ORG 0x0004 'standard interrupt vector **again not sure of the PBP equal for ORG
VInt:
W_TEMP = W 'I am assuming this will be the "W" register
STATUS_TEMP = STATUS 'We may have trouble here. ASM uses SWAP so as not to affect the status
STATUS = 0
PCLATH_TEMP = PCLATH
PCLATH = 0
goto RVInt ' Re-map Interrupt vector

' ************************************************** ***************************
************************************************** ***************************
' Setup the appropriate registers.
Setup:
clrwdt
READ $ff,temp 'get the value of last EEPROM location
IF temp = $ff then goto SRX 'BL startup
goto RVReset ' If not 0xFF then normal reset

SRX:
RCSTA = %10000000 ' Setup rx and tx, CREN disabled
TRISC.6 = 0 ' Setup tx pin
TXSTA = %00100110
STATUS.IRP = 1
' ************************************************** ***************************


' ************************************************** ***************************
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


OPTION_REG = %00000011 'sets tmr0 to 1:16 prescale
STATUS.RP0 = 0
RCSTA.CREN = 0

gosub WaitForRise

TMR0 = 0 ' Start counting

gosub WaitForRise

ABTIME = TMR0 ' Read the timer
TEMPFLAG = ABTIME.0
ABTIME = ABTIME }}1
IF !TEMPFLAG THEN ABTIME.0 = 0 'Rounding
SPBRG = ABTIME
RCSTA.CREN = 1 ' Enable receive

TEMP = RCREG ' To clear the Rx buffer
TEMP = RCREG ' Both of them

OPTION_REG = %11111111 'Return Option Reg to reset state

' ************************************************** ***************************


' ************************************************** ***************************
' Read and parse the data.
StartOfLine:
GOSUB RdRS232 ' Look for a start of line
IF RXDATA != STX THEN Autobaud '{STX}{STX}

ARRAYPOINTER = 0 ' Point to the beginning of Array

CHKSUM = 0 ' Reset checksum

GetNextDat:
GOSUB RdRS232 ' Get the data
IF RXDATA = STX THEN StartOfLine ' Check for a STX
' Yes, start over

NoSTX:
IF RXDATA = ETX THEN CheckSum ' Check for a ETX
' Yes, examine checksum

NoETX:
IF RXDATA = DLE THEN GOSUB RdRS232 ' Check for a DLE
' Yes, Get the next byte

NoDLE:
DATA_BUFF[ARRAYPOINTER] = RXDATA ' Store the data
CHKSUM = CHKSUM + RXDATA ' Get sum
ARRAYPOINTER = ARRAYPOINTER + 1

goto GetNextDat

CheckSum:
IF CHKSUM = 0 THEN Autobaud ' Checksum test
' ***********************************************


' ***********************************************
' Pre-setup, common to all commands.
EEADR = ADDRESS_L 'Set all possible pointers
EEADRH = ADDRESS_H

ARRAYPOINTER = 5 'start of data in array

COUNTER = DATA_COUNT 'Setup counter
IF COUNTER = 0 THEN VReset 'Non valid count (Special Command)
' ***********************************************

' ***********************************************
' Test the command field and sub-command.
CheckCommand
IF COMMAND } 7 THEN Autobaud ' Test for a valid command
SELECT CASE COMMAND ' Perform calculated jump
CASE 0
goto ReadVersion ' 0
CASE 1
goto ReadProgMem ' 1
CASE 2
goto WriteProgMem ' 2
CASE 3
goto StartOfLine ' 3
CASE 4
goto ReadEE ' 4
CASE 5
goto WriteEE ' 5
CASE 6
goto StartOfLine ' 6
CASE 7
goto StartOfLine ' 7
'maybe add jump to reset vector in this table
'***********************************************



' ***********************************************
' Commands
' ************* Read Version
' In: {STX}{STX}[{0x00}{0x02}]{0xFF}{ETX}
' OUT: {STX}{STX}[{0x00}{VERL}{VERH}]{CHKSUM}{ETX}
ReadVersion:
DATA_BUFF[2] = MINOR_VERSION
DATA_BUFF[3] = MAJOR_VERSION

FAKEW = 4
goto WritePacket

'*************Read Program Memory

' In: {STX}{STX}[{0x01}{DLEN}{ADDRL}{ADDRH}{ADDRU}]{CHKSUM}{ETX}
' OUT: {STX}{STX}[{0x01}{DLEN}{ADDRL}{ADDRH}{ADDRU}{DATA}...]{CHKSUM}{ETX}
ReadProgMem:
RPM1:
EECON1.EEPGD = 1
EECON1.RD = 1
@nop 'not sure how to convert this to PBP
@nop
DATA_BUFF[ARRAYPOINTER] = EEDATA
ARRAYPOINTER = ARRAYPOINTER + 1
DATA_BUFF[ARRAYPOINTER] = EEDATH
ARRAYPOINTER = ARRAYPOINTER + 1
EEADR = EEADR + 1
IF EEADR = 0 then
EEADRH = EEADRH + 1
ENDIF
COUNTER = COUNTER - 1
IF COUNTER > 0 THEN RPM1 ' Not finished then repeat

DATA_COUNT = (DATA_COUNT << 1) + 5 ' Setup packet length

goto WritePacket

'************* Write Program Memory

ScaleRobotics
- 4th March 2011, 18:20
Sorry my earlier post won't work that way, PBP takes 5-36 as subtraction. Probably the closest to the assembly example like this. Then you could specify the address in assembly if need be in a similar PACKET_DATA + x manner. I took the liberty of editing your previous post with that one change. [5-36] to [5]



DATA_BUFF VAR BYTE[37] ' 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] ' DATA_BUFF[5] through DATA_BUFF[36] (32 bytes)

cncmachineguy
- 5th March 2011, 18:20
Here is the final installment. I feel like there must be MANY errors, but maybe not. I have not tried to compile yet, I thought maybe you kind folks might give it a look over for glaring errors.


' ************************************************** ***************************
' Software License Agreement
'
' The software supplied herewith by PBP forum members
' (the “Company”) for Microchip's PICmicro® Microcontroller's 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.
'
'
' This software has been ported from Microchip's AN851 bootloader
' Changes have been made and will be made as the company sees fit.
' This version is for 16F's, there is another version for 18F's
'
'
' 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}{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 00 Read Version Information
' RD_MEM 01 Read Program Memory
' WR_MEM 02 Write Program Memory
' ER_MEM 03 Erase Program Memory (NOT supported by PIC16)
' RD_EE 04 Read EEDATA Memory
' WR_EE 05 Write EEDATA Memory
' RD_CONFIG 06 Read Config Memory (NOT supported by PIC16)
' WT_CONFIG 07 Write Config Memory (NOT supported by PIC16)
'
' ************************************************** **************************

' ************************************************** ***************************
PRGADD VAR WORD
DATAWORD VAR WORD

PRGADDL VAR PRGADD.LOWBYTE
PRGADDH VAR PRGADD.HIGHBYTE
DATAWORDL VAR DATAWORD.LOWBYTE
DATAWORDH VAR DATAWORD.HIGHBYTE

CHKSUM VAR BYTE ' Checksum accumulator
COUNTER VAR BYTE ' General counter
ABTIME VAR BYTE
RXDATA VAR BYTE
TXDATA VAR BYTE
TEMP VAR BYTE
ARRAYPOINTER VAR BYTE
FAKEW VAR BYTE
BIGLOOP VAR BYTE
TEMPFLAG VAR BIT

PCLATH_TEMP VAR BYTE ' Interrupt context
STATUS_TEMP VAR BYTE ' save/restore registers
W_TEMP VAR BYTE

' Frame Format
'
' {STX}{STX}[{COMMAND}{DATALEN}{ADDRL}{ADDRH}{ADDRU}{...DATA... }]{CHKSUM}{ETX}

DATA_BUFF VAR BYTE[37] ' Start of receive buffer SAME ADDRESS AS COMMAND

COMMAND VAR DATA_BUFF[0] ' Data mapped in receive buffer SAME ADDRESS AS DATA_BYTE
DATA_COUNT 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 is the remapping section, note the interrupt also saves context
' ************************************************** ***************************
@ ORG 0x0000 ' Re-map Reset vector **Not sure how to set the address to start at
VReset:
PCLATH = 0
goto Setup

@ ORG 0x0004 'standard interrupt vector **again not sure of the PBP equal for ORG
VInt:
W_TEMP = W 'I am assuming this will be the "W" register
STATUS_TEMP = STATUS 'We may have trouble here. ASM uses SWAP so as not to affect the status
STATUS = 0
PCLATH_TEMP = PCLATH
PCLATH = 0
goto RVInt ' Re-map Interrupt vector

' ************************************************** ***************************
************************************************** ***************************
' Setup the appropriate registers.
Setup:
clrwdt
READ $ff,temp 'get the value of last EEPROM location
IF temp = $ff then goto SRX 'BL startup
goto RVReset ' If not 0xFF then normal reset

SRX:
RCSTA = %10000000 ' Setup rx and tx, CREN disabled
TRISC.6 = 0 ' Setup tx pin
TXSTA = %00100110
STATUS.IRP = 1
' ************************************************** ***************************


' ************************************************** ***************************
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


OPTION_REG = %00000011 'sets tmr0 to 1:16 prescale
STATUS.RP0 = 0
RCSTA.CREN = 0

gosub WaitForRise

TMR0 = 0 ' Start counting

gosub WaitForRise

ABTIME = TMR0 ' Read the timer
TEMPFLAG = ABTIME.0
ABTIME = ABTIME >> 1
IF !TEMPFLAG THEN ABTIME.0 = 0 'Rounding
SPBRG = ABTIME
RCSTA.CREN = 1 ' Enable receive

TEMP = RCREG ' To clear the Rx buffer
TEMP = RCREG ' Both of them

OPTION_REG = %11111111 'Return Option Reg to reset state

' ************************************************** ***************************


' ************************************************** ***************************
' Read and parse the data.
StartOfLine:
GOSUB RdRS232 ' Look for a start of line
IF RXDATA != STX THEN Autobaud '{STX}{STX}

ARRAYPOINTER = 0 ' Point to the beginning of Array

CHKSUM = 0 ' Reset checksum

GetNextDat:
GOSUB RdRS232 ' Get the data
IF RXDATA = STX THEN StartOfLine ' Check for a STX
' Yes, start over

NoSTX:
IF RXDATA = ETX THEN CheckSum ' Check for a ETX
' Yes, examine checksum

NoETX:
IF RXDATA = DLE THEN GOSUB RdRS232 ' Check for a DLE
' Yes, Get the next byte

NoDLE:
DATA_BUFF[ARRAYPOINTER] = RXDATA ' Store the data
CHKSUM = CHKSUM + RXDATA ' Get sum
ARRAYPOINTER = ARRAYPOINTER + 1

goto GetNextDat

CheckSum:
IF CHKSUM = 0 THEN Autobaud ' Checksum test
' ***********************************************


' ***********************************************
' Pre-setup, common to all commands.
PRGADDL = ADDRESS_L 'Set all possible pointers
PRGADDH = ADDRESS_H

ARRAYPOINTER = 5 'start of data in array

COUNTER = DATA_COUNT 'Setup counter
IF COUNTER = 0 THEN VReset 'Non valid count (Special Command)
' ***********************************************

' ***********************************************
' Test the command field and sub-command.
CheckCommand
IF COMMAND } 7 THEN Autobaud ' Test for a valid command
SELECT CASE COMMAND ' Perform calculated jump
CASE 0
goto ReadVersion ' 0
CASE 1
goto ReadProgMem ' 1
CASE 2
goto WriteProgMem ' 2
CASE 3
goto StartOfLine ' 3
CASE 4
goto ReadEE ' 4
CASE 5
goto WriteEE ' 5
CASE 6
goto StartOfLine ' 6
CASE 7
goto StartOfLine ' 7
'maybe add jump to reset vector in this table
'***********************************************



' ***********************************************
' Commands
' ************* Read Version
' In: {STX}{STX}[{0x00}{0x02}]{0xFF}{ETX}
' OUT: {STX}{STX}[{0x00}{VERL}{VERH}]{CHKSUM}{ETX}
ReadVersion:
DATA_BUFF[2] = MINOR_VERSION
DATA_BUFF[3] = MAJOR_VERSION

FAKEW = 4
goto WritePacket

'*************Read Program Memory

' In: {STX}{STX}[{0x01}{DLEN}{ADDRL}{ADDRH}{ADDRU}]{CHKSUM}{ETX}
' OUT: {STX}{STX}[{0x01}{DLEN}{ADDRL}{ADDRH}{ADDRU}{DATA}...]{CHKSUM}{ETX}
ReadProgMem:
RPM1:
READCODE PRGADD,DATAWORD

DATA_BUFF[ARRAYPOINTER] = DATAWORDL
DATA_BUFF[ARRAYPOINTER + 1] = DATAWORDH
ARRAYPOINTER = ARRAYPOINTER + 2
PRGADD = PRGADD + 1

COUNTER = COUNTER - 1
IF COUNTER } 0 THEN RPM1 ' Not finished then repeat

DATA_COUNT = (DATA_COUNT << 1) + 5 ' Setup packet length

goto WritePacket

'************* Write Program Memory


' In: {STX}{STX}[{0x02}{DLENBLOCK}{ADDRL}{ADDRH}{ADDRU}{DATA}...]{CHKSUM}{ETX}
' OUT: {STX}{STX}[{0x02}]{CHKSUM}{ETX}
WriteProgMem:
FOR BIGLOOP = COUNTER TO 0 STEP -1
EECON1 = %10000100 ' Setup writes
EEADR = EEADR & %11111100 ' Force a boundry ' B2
FOR TEMP = 1 TO 4
WRITECODE PRGADD,DATAWORD[ARRAYPOINTER]
ARRAYPOINTER = ARRAYPOINTER + 2
NEXT

NEXT
goto SendAcknowledge ' Send acknowledge

'************** Read EE


' In: {STX}{STX}[{0x04}{DLEN}{ADDRL}{ADDRH}{0x00}]{CHKSUM}{ETX}
' OUT: {STX}{STX}[{0x04}{DLEN}{ADDRL}{ADDRH}{0x00}{DATA}...]{CHKSUM}{ETX}
ReadEE:
FOR BIGLOOP = COUNTER TO 0 STEP -1
READ PRGADD,DATA_BUFF[ARRAYPOINTER]
ARRAYPOINTER = ARRAYPOINTER + 1
PRGADD = PRGADD + 1
NEXT

FAKEW = DATA_COUNT + 5
GOTO WritePacket


' In: <STX><STX>[<0x05><DLEN><ADDRL><ADDRH><0x00><DATA>...]<CHKSUM><ETX>
' OUT: <STX><STX>[<0x05>]<CHKSUM><ETX>
WriteEE:
FOR BIGLOOP = 0 TO COUNTER
WRITE PRGADD + BIGLOOP,DATA_BUFF[ARRAYPOINTER+BIGLOOP]
NEXT
goto SendAcknowledge ; Send acknowledge

' ***********************************************

' ***********************************************
' Send the data buffer back.
'
' {STX}{STX}[{DATA}...]{CHKSUM}{ETX}

SendAcknowledge:
FAKEW = 1 ' Send acknowledge

WritePacket:
COUNTER = FAKEW

FAKEW = STX ' Send start condition
GOSUB WrRS232
GOSUB WrRS232

CHKSUM = 0 ' Reset checksum
ARRAYPOINTER = 0

SendNext: ' Send DATA
FOR BIGLOOP = 1 TO COUNTER
FAKEW = DATA_BUFF[ARRAYPOINTER]
CHKSUM = CHKSUM + FAKEW
GOSUB WrData
NEXT

'********************************************
comf CHKSUM,W ' Send checksum
addlw 0x01 ' NEEDS CONVERTING!!!!!
'***********************************************
GOSUB WrData

FAKEW = ETX ' Send stop condition
GOSUB WrRS232

goto Autobaud
' ************************************************** ***************************

' ************************************************** ***************************
' Write a byte to the serial port.

WrData:
TXDATA = FAKEW ' Save the data
IF FAKEW = STX THEN WrDLE
IF FAKEW = ETX THEN WrDLE
IF FAKEW != DLE THEN WrNext

WrDLE:
GOSUB WrRS232 'Send DLE

WrNext:
FAKEW = TXDATA ' Then send DATA

WrRS232:
clrwdt
WHILE !PIR1.TXIF WEND ' Write only if TXREG is ready

TXREG = FAKEW ' Start sending

return
' ************************************************** ***************************



' ************************************************** ***************************
RdRS232:
clrwdt

IF RCSTA.OERR THEN VReset ' Reset on overun

WHILE !PIR1.RCIF WEND ' Wait for data from RS232


RXDATA = RCREG ' Save the data
return
' ************************************************** ***************************




' ************************************************** ***************************
WaitForRise:
WHILE PORTC.7 WEND ' Wait for a falling edge
clrwdt ' Do we need this?
WHILE !PORTC.7 WEND ' Wait for starting edge
return
' ************************************************** ***************************

' I DON'T THINK WE NEED THE NEXT 2 SECTIONS
' CAN ANYBODY TELL ME?


' ************************************************** ***************************
' 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
; ************************************************** ***************************


; ************************************************** ***************************
RVReset:
@ORG 0x100

RVInt:
@ORG 0x104


; ************************************************** ***************************


END

cncmachineguy
- 5th March 2011, 23:53
This one compiles up to MPASM part, then PLENTY of overwrite errors.


BTW, is it odd we can't attach .PBP files?

mister_e
- 6th March 2011, 22:07
Hint: ASM ORG & PBP (see mostcompilers) are poor bedfellows when you don't know why and how they interract.

Plausible solution, compile without ORG, use the HEX to get the ASM code, then add some ORG & GOTO, recompile the asm and try to make it work ;)

Still Plausible: Hack a .LIB and or .INC to use Labels in your Bootloader code instead of ORG.

Lots of possibilities, my favourites being 100% pure ASM.

cncmachineguy
- 7th March 2011, 02:25
Hint: ASM ORG & PBP (see mostcompilers) are poor bedfellows when you don't know why and how they interract.

Well I must admit not knowing. I know it makes no sense to use it in this way, I know PBP won't be paying attention to it, therefore probable conflicts will arrise.


Plausible solution, compile without ORG, use the HEX to get the ASM code, then add some ORG & GOTO, recompile the asm and try to make it work ;)

This sounds like a quick fix not in line with the intention of this project.


Still Plausible: Hack a .LIB and or .INC to use Labels in your Bootloader code instead of ORG.

If we can have the hack as part of the "package" maybe. Right now it seems more then too much to ask folks to rem out config lines



Lots of possibilities, my favourites being 100% pure ASM.

we already have that. The purpose here is to try and make a PBP bootloader, for all to use and abuse.

Thanks for pointing in the direction of the first of many (maybe) problems. I feel like I saw something in the PBP bible about defining code locations, but it is at work :(

mister_e
- 7th March 2011, 04:50
Well, there's an easy alternative. Compile your bootloader without ORG, see how much code space it needs. Once you know it, add an ORG at the END of your bootloader + Label. Your bootloader must jump to this Label when it exit.



'bootloader code here
Goto GetOutOfHere

@ ORG WhateverYouDecide
GetOutOfHere:
Now when you want to use the bootloader, in your application code you need to use DEFINE RESET_ORG... and Period.



DEFINE RESET_ORG WhateverYouDecide
' and your application code goes there
Now go figure how interrupt will work and how to integrate it, have fun!
http://www.picbasic.co.uk/forum/showthread.php?t=5590&p=31662#post31662

Readme.txt:

ORG Define

It may sometimes be useful to move the start of the generated code to a
location other than 0. This can be used to move the program code beyond
a boot loader, for example. A Define has been added to the compiler to
allow a different reset address to be specified for the 14-bit core PIC
MCUs and the PIC18 parts.

Define RESET_ORG 100h

This Define moves the starting location of the program, the reset vector,
to the specified address. The interrupt vector(s) follow at their usual
offset, followed by the library and program code.

For 14-bit core devices with more than 2K of code space, only interrupts
in assembler may be used. On Interrupt will not work properly if the
device has more than 2K of code space and RESET_ORG is not 0. For
assembler interrupts in a device with more than 2K of code space and
RESET_ORG something other than 0, the values of W, STATUS and PCLATH must
be saved by whatever program now resides at the PIC MCU's fixed vector
locations before the jump to the new vector location. In general, the
save locations are named wsave, ssave and psave. The information on these
save locations should be provided with the boot loader or whatever program
requires the altered origination so that the register values may be restored
at the end of interrupt processing.

For 14-bit enhanced core devices with more than 2K of code space,
On Interrupt may be used but the values of W, STATUS and PCLATH must not be
changed to get to the interrupt vector as they will not be restored upon
return from the interrupt. This usually means bra will be used to jump to
the new interrupt vector location. Interrupts in assembler do not require
any special treatment.

Either 14-bit core PBP library must fit into the first 2K of code space.
The PIC18 PBP library must fit into the first 32K of code space. It is best
for RESET_ORG to start on an even 256 word boundary.

PJALM
- 7th March 2011, 13:17
Are you just converting the exsisting serial bootloader over to PBP? I had thought you were going to make a new bootloader from scratch in pure PBP.

cncmachineguy
- 7th March 2011, 13:30
The goal is a new one using pure PBP. To get me started, I am attempting to convert the existing Microchip serial one, AN851. For me this does 2 things, it has shown me just how the guts of the BL work, and I thought by starting there, we are able to test the GUI with it.

To that end, I do have a much better feel for how they work, at least this one. So we can make this work and build onto it, or start over with a completly new one. No matter to me :)

cncmachineguy
- 8th March 2011, 13:24
If you want to get the code to compile, rem the first 2 @org's. change the last to to 800 and 808. These need to be changed anyway as I think they were not far enough in memory.

I have been digesting what Steve has pointed to. My understanding is this: I need to let PBP take care of memory!! The first @ORG is un-needed as PBP will place the code at 00 anyway. So that just needs to be deleted. I think the for the interrupt redirect, we just need a


DEFINE INTHAND NewIntLocation

then in our application code:



DEFINE RESET_ORG 800
GOTO Start ' or whatever you favorite label is
NewIntLocation:
Do your Interrupt thing

Start:
Code till your hearts content, (or MEM is full)


So if I am correct, the only thing left is context saving in the real interrupt vector before jumping.

Now as for the rest of the code, I need some help here. I have a crazy mix of PBP commands and direct register addressing. I want to get rid of the direct addressing. This is really bad in the comm part. Do we want to use HSERIN/OUT or SERIN/OUT. I think using SER would be nicer in the aspect we can then use any pins to do this, and have control over true vs inverted signals. It will also be a trivial matter to use I2C instead of SER using the bit-bang approach.

Let me just throw in my opinion here, speed is NOT the issue. This is a bootloader, It will not be used often once your app is done.

pedja089
- 3rd March 2014, 15:26
I need to create bootloader for PIC18F that program flash from external I2C memory, eg 24lc512.
I'll probably write bootloader in pbp and asm.

If I understand correctly how bootloader works, there is 2 ways to implement bootloader.
-One is to make bootloader that sits on beginning of flash, then on address 4 and 8, need to be GOTO to new int vector. That will add one more GOTO before executing int, PBP already add one. I don't like that GOTO's.
-Other option is that first instruction in flash is GOTO Bootloader, and to put bootloader on end of flash. Then there is no need to remap interrupt. When bootloader finish job, then GOTO 1
In main program only need to remap reset vector to 1.
Am I understand how it works?

For now I'll create LED blink program, that use bootloader with reset vector at 1.
And then try to make bootloader that will program that hex to flash. For start hex will be in LOOKUP2, until I get flesh erase and write to work, then comunication...

Probably I should start with analyzing syntax of hex file.

Is there anyone interested and willing to help?

pedja089
- 3rd March 2014, 15:53
Edit timeout...
Address for int are 8 and 24, and GOTO takes 2 program word so, reset org should be 4.

pedja089
- 7th March 2014, 10:35
Is there way to move RESET_ORG to other address, without moving interrupt vector?
DEFINE RESET_ORG 004h also move vectors. In .LST file interrupt vector are defined as RESET_ORG+8h or 18h.
DEFINE LOADER_USED 1 doesn't do anything. I'm looking in disassembled hex file...
This is test code:


DEFINE NO_CLRWDT 1
DEFINE LOADER_USED 1
DEFINE INTHAND myint ' Define interrupt handler
DEFINE INTLHAND myint ' Define interrupt handler

Start:
PORTD.6=1
PORTD.6=0
GOTO Start

@myint bcf PORTB,1
7267

Also I noticed that with or without NO_CLRWDT 1, there is no CLRWDT in hex file.

Demon
- 10th March 2014, 23:18
I have VERY limitted knowledge in this area, but can't you set config fuses from the programmer?

(NO_CLRWDT is a config fuse right?)

If input to the programmer is the hex file, wouldn't that mean that fuses are handled separately than the hex file?

Robert

pedja089
- 11th March 2014, 00:44
PBP should put CLRWDT if there is no defined NO_CLRWDT 1. DEFINE NO_CLRWDT 1 isn't config, it is PBP's define.

pedja089
- 22nd March 2014, 01:00
http://www.youtube.com/watch?v=jbLy6kE-Szg
This is exactly what I'm trying to do.

Heckler
- 22nd March 2014, 15:32
wayneandlayne.com have a pretty neat solution for a bootloader, it uses two LED's as light detectors to receive the code that is "flashed" or "blinked" to your PC's monitor screen. One LED light sensor is for clocking and one LED light sensor is for the data.


I'm not sure if this is actually a boot loader... or more of just a way of changing the message that this little kit displays...
but I would think it could be modified to act as a boot loader.

It may even work from a smart phones browser (it does play from a phones browser)


http://youtu.be/IorVBVML7nE

Here is their actual programming web page where you can scroll down and click on the "GO" button and see it in action.
http://www.wayneandlayne.com/blinky_programmer/


and a description of their bootloader...
http://www.wayneandlayne.com/projects/blinky/design/#questions

Their project is open source but I'm not sure if the programming web page code is available.

pedja089
- 22nd March 2014, 19:34
Nice idea... But that isn't what I need. Devices already have communication with PC or internet, so transferring data to device isn't problem.
I want to create one bootloader that will flash device from I2C EEPROM. Reason for that is that I2c is simple communication, so it won't take lot of space.
Code for communication is already in main app. So there is no need to have 10-20Kof code to get file from server. Download hex in main app, then goto bootloader, and write that data to FLASH.
For now I have working ERASECODE and WRITECODE to erase, and then write new code. And it's working... But still don't understand how to write config.
I need to understand how to parse hex file, and extract FLESH and EEPROM data... There is bootloader application from microchip written in VB6, so that shouldn't be problem.