Open source PBP bootloader


Results 1 to 40 of 41

Threaded View

  1. #21
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default Re: Open source PBP bootloader

    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.
    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)
    '
    ' ****************************************************************************
    
    ' *****************************************************************************
    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
    Attached Files Attached Files
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

Members who have read this thread : 0

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