ds30 bootloader ds30loader.asm

Ook hier een 18F25K20 met interne oscillator op 8Mhz

Bij lijn nr. 233 vindt je het vak “User specific entry code go here”

Hier kun je diverse register instellingen kwijt die nodig zijn om de communicatie poorten op de juiste manier in te stellen.

Om de interne oscillator van de 18F25K20 op 8Mhz te krijgen moet je het OSCCON register instellen (zie datasheet)
Zonder ingesteld register werkt de oscillator op 1 Mhz.
Zie bij lijn 255 hoe je dit doet.

Een andere vaak voorkomende instelling die je moet doen is het van analoog naar digitaal zetten van de voor communicatie bedoelde poorten.
Bij alle PIC’s is het zo dat poorten die een analoge functie kunnen hebben, bij het opstarten als analoog (input) op komen, je kunt er op dat moment dus niet mee communiceren.(ontvangen)
Bij de 18F25K20 is dit niet nodig omdat C7 (RX) geen analoge functie heeft.
Bij de 18F25K22 moet dit wel!

De error lijn (lijn 240) die in werking treed zodra er sprake is van een device met een ADCON1 register (betekend dat de PIC analoge functies heeft) komt op, ongeacht of dat die functies op de communicatie poorten zitten.
Na controle of verdere acties nodig zijn moet deze lijn uitgecommentarieerd worden (; ervoor) zodat de uiteindelijke hex file gemaakt kan worden (build).
Met een error melding erin gaat dit niet.


;------------------------------------------------------------------------------
;
; Title:			ds30 Loader for PIC18F
;
; File description:	Main firmwarefile
;
; Copyright: 		Copyright � 09-11, Mikael Gustafsson
;
; Version:			3.0.0 April 2011
;
; Webpage: 			http://mrmackey.no-ip.org/elektronik/ds30loader/
;
; Thanks to:		Claudio Chiculita, this code is based on the Tiny PIC bootloader
;					Fabien Pieraldi for writing the CAN part
;
; History:			3.0.0 New feature: compatible with ds30 Secure Loader
;						  New feature: auto baud rate detection
;					      Bugifx: bootloader protection was calculate wrong on PIC18F devices with 64 byte pagesize					      
;					      Bugfix: receiving non hello command on start-up caused long delay
;					      Improvement: merged PIC18FJ firmware
;		 				  Improvement: increased range of timeout values
;					2.0.5 Bugfix: devices with pagesize != 32 words
;					2.0.4 Bugfix: uart 1 rx interupt flag was checked also for uart 2
;					      New feature: 16-bit brg
;					2.0.3 Bugfix: In some case, CAN engine won't start (bad state on RB2)
;						  Bugfix: goto protection not working for some devices
;						  Improvement: renamed fosc to oscf for compatibility with some devices
;					2.0.2 Change: node ID configuration moved in settings.inc
;						  New feature: goto protection
;						  New feature: bl protection
;						  Change: size is 7 pages
;						  Bugfix: compatible with devices that has no eeprom (2450, 4450 and more)
;					2.0.1 New feature: adjustable non hello discard, HELLORETRIES setting					  
;					      Improvement: compatible with include files containing both TXSTA and TXSTA1 definitions
;						  Improvement: 5 or 7 (see section Init) more instructions free to use (CAN)
;					2.0.0 CAN support
;					1.0.2 Replaced old baudrate calculator	
;					1.0.1 Erase is now made just before write to increase reliability
;					1.0.0 Separated boot timeout and receive timeout
;						  Added range check of times and brg
;					0.9.2 Changed bootloader size to 5 pages (to make room for more user init code)
;						  Added tx enable support
;					0.9.1 1 more instruction free to use
;						  Added watchdog clear
;						  Fixed baudrate error check
;					 	  Correct buffer size
;					0.9.0 Initial release                                                                            
;------------------------------------------------------------------------------

;-----------------------------------------------------------------------------
;    This file is part of ds30 Loader.
;
;    ds30 Loader is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation.
;
;    ds30 Loader is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with ds30 Loader. If not, see .
;------------------------------------------------------------------------------


;------------------------------------------------------------------------------
; Includes
;------------------------------------------------------------------------------ 
		#include "settings.inc"
		
		
;------------------------------------------------------------------------------
; Defines
;------------------------------------------------------------------------------	
		#define	VERENC				0
		#define	VERMAC				0
		
		#define	VERMAJ				3			;firmware version major
		#define	VERMIN				0			;firmware version minor
		#define	VERREV				0			;firmware version revision
		
		#define HELLO 				0xC1
		#define OK 				'K'			;erase/write ok
		#define CHECKSUMERR			'N'			;checksum error
		#define	VERFAIL				'V'			;verification failed
		#define	BLPROT				'P'        		;bl protection tripped
		#define	UCMD     			'U'         		;unknown command		
		
		#define	PWOK				0xFE	

		
		#if BLINIT < 2500
        	#define	TMRBASE	10
        #else
        	#define	TMRBASE 30
        #endif
        #define	DELBASE		( (TMRBASE * OSCF) / (3+(4000 * 255 * 6)) )			;delay
        #define	BLSTART		( BLINIT / TMRBASE )						;count for boot receive delay
        #define	BLDELAY		( BLTIME / TMRBASE )						;count for receive delay
        
        ifndef USE_BRG16
        	#define	UBRG	( (((OSCF / BAUDRATE) / 8) - 1) / 2 )				;baudrate
        else
        	#define	UBRG	( (((OSCF / BAUDRATE) / 2) - 1) / 2 )				;baudrate
        endif
		
		#define	PAGESIZER	(PAGESIZEW/ROWSIZEW)					;pagesize [rows]
		#define	ROWSIZEB	(ROWSIZEW*2)						;rowsize [bytes]
		#define STARTADDR	( MAX_FLASH - BLPLP * PAGESIZER * ROWSIZEW * 2 )	;bootloader placement
		
		ifdef	IS_PIC18F
			#define	ERASE_CODE	b'10010100'
			#define	WRITE_CODE	b'10000100'
		else
			#define	ERASE_CODE	b'00010100'
			#define	WRITE_CODE	b'00000100'
		endif
		
		; Debug output
		;messg	STARTADDR_IS 		#v(STARTADDR)
		;messg	UBRG_IS			#v(UBRG)
		;messg	delbaesis 		#v(DELBASE)	
		;messg	blstartis 		#v(BLSTART)	
		;messg	bldelayis 		#v(BLDELAY)
		

		
		#ifdef USE_UART1
			#define	USE_UART	1
		#endif		
		#ifdef USE_UART2
			#define	USE_UART	1	   	
		#endif	

				
;------------------------------------------------------------------------------
; Range check
;------------------------------------------------------------------------------
		if DELBASE > 255
			error overflow in delay calculation
		endif
		if BLSTART > 255
			error BLSTART_ is out of range
		endif
		if BLSTART == 0
			error BLSTART might be out of range
		endif			
		
		if BLDELAY > 255
			error BLDELAY_ is out of range
		endif			
		if BLDELAY == 0
			error BLDELAY_ might be out of range
		endif
		
		
;------------------------------------------------------------------------------
; Variables
;------------------------------------------------------------------------------		
			#define BUFFERSIZE (ROWSIZEB + 1 ) ;row + checksum
			cblock 0x0
				buffer 		: 	BUFFERSIZE
				crc			: 	1	;receive checksum
				dcnt		: 	1	;datacount
				dcnt2		: 	1	;datacount
				cnt1		: 	1	;receive timeout timer
				cnt2		: 	1	;receive timeout timer
				cnt3		: 	1	;receive timeout timer
				cntHello	: 	1	;
				rowcnt		: 	1	;row iterator
				rowcnt2		: 	1	;
				cmd			: 	1	;command
				doerase		: 	1	;do erase before next write
				ttblptru	: 	1
				ttblptrh	: 	1
				ttblptrl	: 	1				
			endc
				
		
;------------------------------------------------------------------------------
; Globals & externals
;------------------------------------------------------------------------------
		
		
;------------------------------------------------------------------------------
; Macros
;------------------------------------------------------------------------------ 	
SendL 	macro sbyte
			movlw 	sbyte
			rcall	Send
		endm
		

	
;------------------------------------------------------------------------------
; Reset vector
;------------------------------------------------------------------------------ 
		org     0x0000
		goto    blstart


;------------------------------------------------------------------------------
; GOTO user application
;------------------------------------------------------------------------------ 	
		org 	STARTADDR - 4	;space to deposit goto to user application
loadusr	nop
		nop
	
	
;------------------------------------------------------------------------------
; Start of bootloader code
;------------------------------------------------------------------------------ 	
		org 	STARTADDR
blstart

		
;------------------------------------------------------------------------------
; Trouble shooting tools
;------------------------------------------------------------------------------		
		;bra dev_ftest
		
		; Toggle pin, frequency on pin = PIC frequency / 16
		if 0
			bcf	TRISx, TRISxx
tsfloop		bsf LATx, LATxx
			bcf LATx, LATxx
			bra tsfloop
		endif
		
		
;------------------------------------------------------------------------------
; User specific entry code go here
;------------------------------------------------------------------------------				
		
		;----------------------------------------------------------------------
		; Make uart pins digital
		;----------------------------------------------------------------------
		ifdef	ADCON1
				;error Do you need to configura uart pins to be digital? If not, remove this line
		endif
		;movlw 	b'01100000'		;xxx disable 
		;movwf 	ADCON1			;xxx analog on tx/rx
 
                 ;Set Port C naar digitaal voor de 18F25K22 (kijk in de datasheet, dit is niet voor alle PIC's hetzelfde)		
		; banksel   ANSELC      ; you need this as ANSELC is at banked address.   
                ; bcf       ANSELC,7
  		

                 ;--------------------------------------------------------------------------------
                 ; Set internal Oscilator frequenty 
                 ;--------------------------------------------------------------------------------

                 ; Set internal oscillator to 8 MHz, (default for 18F25K20 = 1Mhz)	       xxx
		movlw b'01100000'							;xxx
		movwf OSCCON								;xxx
                   
                 ;18F25K20/22
                 ; 01110000 = 16Mhz
                 ; 01100000 = 8 Mhz
                 ; 01010000 = 4 Mhz 
                 ; 01000000 = 2 Mhz
                 ; 00110000 = 1 Mhz (default on reset)
                 ; 00100000 = 500Khz
                 ; 00010000 = 250Khz
                 ; 00000000 = 31,25Khz
                 ; ander type's starten vaak met 8Mhz op 01110000 en hebben zo over de hele range andere freqenties (zie datasheet)

		;----------------------------------------------------------------------
		; UART/CAN pps config
		;----------------------------------------------------------------------
		ifdef	HAS_PPS
			ifdef USE_UART2
					error You need to configure PPS
					
					; This template maps U2Rx to RP4
					bcf		RPINR16, RX2DT2R0		;xxx
					bcf		RPINR16, RX2DT2R1		;xxx
					bsf		RPINR16, RX2DT2R2		;xxx
					bcf		RPINR16, RX2DT2R3		;xxx
					bcf		RPINR16, RX2DT2R4		;xxx
					
					; This template maps RP3 to U2Tx
					bsf		RPOR3,	RP3R0			;xxx
					bcf		RPOR3,	RP3R1			;xxx
					bsf		RPOR3,	RP3R2			;xxx
					bcf		RPOR3,	RP3R3			;xxx
					bcf		RPOR3,	RP3R4			;xxx
			endif
		endif
		
		
;------------------------------------------------------------------------------
; Init
;------------------------------------------------------------------------------	
		clrf	doerase
		rcall	CommInit
		
		
;----------------------------------------------------------------------
; Wait for computer
;----------------------------------------------------------------------
		clrf	cntHello
rhello	movlw	BLSTART
		rcall 	RcvIni
		sublw 	HELLO
		bz 	    rhellook		
		; Not hello received
		incf	cntHello
		movf	cntHello, w
		sublw	HELLOTRIES
		bz		exit
		bra		rhello		
rhellook

		
;----------------------------------------------------------------------
; Send device id and firmware version
;----------------------------------------------------------------------		
sendid	SendL 	( DEVICEID & 0xff )
		SendL	( ((DEVICEID&0x100)>>1) + VERMAC + VERENC + VERMAJ )
		SendL	( ((DEVICEID&0x200)>>2) + (VERMIN<<4) + VERREV )
		
		
;----------------------------------------------------------------------
; Main loop
;----------------------------------------------------------------------			
Main	SendL 	OK				;last command was successfull, waiting for next
mainl	clrf 	crc
		

		;----------------------------------------------------------------------
		; Receive address
		;----------------------------------------------------------------------			
		;Upper byte
		rcall 	Receive			
		movwf 	TBLPTRU
		; High byte
		rcall 	Receive
		movwf 	TBLPTRH
		#ifdef	BIGEE
			movwf	EEADRH		;for eeprom
		endif		
		; Low byte
		rcall 	Receive
		movwf 	TBLPTRL
		#ifdef	EEADR
			movwf 	EEADR		;for eeprom
		endif

					
		;----------------------------------------------------------------------
		; Receive command
		;----------------------------------------------------------------------			
		rcall 	Receive	
		movwf 	cmd	
		
		
		;----------------------------------------------------------------------
		; Receive nr of data bytes that will follow
		;----------------------------------------------------------------------			
		rcall 	Receive	
		movwf 	dcnt	
		movwf	dcnt2	


		
		
		;----------------------------------------------------------------------
		; Receive data
		;----------------------------------------------------------------------	
		lfsr 	FSR0, buffer	;load buffer pointer to fsr0
rcvoct	rcall 	Receive
		movwf 	POSTINC0
		decfsz 	dcnt
		bra 	rcvoct
				
		
		;----------------------------------------------------------------------
		; Check checksum
		;----------------------------------------------------------------------			
		tstfsz 	crc				
		bra 	crcfail			
chksumok
		
		
	

					
				
		;----------------------------------------------------------------------
		; 0x00 goto protection
		;----------------------------------------------------------------------	
		ifdef	PROT_GOTO
			; Only for write row command
			btfss 	cmd, 1			
			bra 	protgotook		
			; Check for row 0
			tstfsz	TBLPTRU
			bra		protgotook
			tstfsz	TBLPTRH
			bra		protgotook
			tstfsz	TBLPTRL
			bra		protgotook						
			; Init buffer pointer
			lfsr 	FSR0, buffer	;load buffer pointer to fsr0
			; 1st word low byte = low address byte 
			movlw 	((STARTADDR>>1)&0xff)
			movwf	POSTINC0
			; 1st word high byte = goto instruction
			movlw	0xef
			movwf	POSTINC0
			; 2nd word low byte = upper address byte
			movlw 	(((STARTADDR>>1)&0xff00)>>8)
			movwf	POSTINC0
			; 2nd word high byte = uppder address nibble + goto instruction			
			movlw 	(0xf0 + (((STARTADDR>>1)&0xf0000)>>16))
			movwf	POSTINC0
protgotook
		endif
		
		
		;----------------------------------------------------------------------
		; Init buffer pointer
		;----------------------------------------------------------------------			
		lfsr 	FSR0, buffer	;load buffer pointer to fsr0
		
		
		;----------------------------------------------------------------------
		; Check command
		;----------------------------------------------------------------------
		
		; Erase page, set do erase status flag
		btfss	cmd, 0
		bra		cmdrow
		setf	doerase
		bra		Main
		; Write row
cmdrow	btfsc 	cmd, 1			
		bra 	blprot
		; Write eeprom word
		ifdef	EEDATA			
			btfsc 	cmd, 2			
			bra 	eeprom
		endif
		; Write config
		btfsc 	cmd, 3
		bra 	cfg	
		; Else, unknown command
		SendL   UCMD		
		bra     mainl
		
		
		
		
		
				
		
				
		;------------------------------------------------------------------------------
		; Exit, placed here so it can be branched to from all code, max +-127
		;------------------------------------------------------------------------------				
exit
		rcall	CommExit
		bra 	loadusr		
		
							
		;----------------------------------------------------------------------
		; Bootloader protection
		;----------------------------------------------------------------------
blprot	nop
		ifdef PROT_BL
			if PAGESIZEW == 16
				#define	ROTROUNDS	5
			endif
			if PAGESIZEW == 32			;most PIC18F
				#define	ROTROUNDS	6
			endif
			if PAGESIZEW == 64			;some PIC18F
				#define	ROTROUNDS	7
			endif
			if PAGESIZEW == 128
				#define	ROTROUNDS	8
			endif
			if PAGESIZEW == 256
				#define	ROTROUNDS	9
			endif
			if PAGESIZEW == 512			;PIC18FJ
				#define	ROTROUNDS	10
			endif
			; Make a copy of address
			movff	TBLPTRU, ttblptru
			movff	TBLPTRH, ttblptrh
			movff	TBLPTRL, ttblptrl
			; Calculate page number of received address
			movlw	ROTROUNDS		;2^6=64=pagesize[bytes]
			#undefine	ROTROUNDS
			movwf	cnt1
			bcf		STATUS, C	;clear carry bit
calcpage	rrcf	ttblptru, 1
			rrcf	ttblptrh, 1
			rrcf	ttblptrl, 1
			decfsz	cnt1
			bra		calcpage			
			; Received page high < bl start page = OK
			movlw	((STARTADDR/(PAGESIZEW*2))>>8)
			subwf	ttblptrh, 0
			bn		blprotok
			; Received page = bl start page
			movlw	((STARTADDR/(PAGESIZEW*2))>>8)
			subwf	ttblptrh, 0
			bnz		chkgt	
			; Received page low < bl start page low = OK		
			movlw	((STARTADDR/(PAGESIZEW*2))&0xff)
			subwf	ttblptrl, 0
			bn		blprotok
			; Received page high > bl end page = OK
chkgt		movlw	(((STARTADDR/(PAGESIZEW*2))+BLSIZEP-1)>>8)
			subwf	ttblptrh, 0
			bz		chkgt2
			bn		chkgt2
			bra		blprotok
			; Received page = bl end page
chkgt2		movlw	(((STARTADDR/(PAGESIZEW*2))+BLSIZEP-1)>>8)
			subwf	ttblptrh, 0
			bnz		proterr	
			; Received page low > bl end page low = OK		
			movlw	(((STARTADDR/(PAGESIZEW*2))+BLSIZEP-1)&0xff)
			subwf	ttblptrl, 0
			bz		proterr
			bn		proterr
			bra		blprotok
			; Protection tripped
proterr		SendL   BLPROT		
		    bra     mainl
		endif
		
		
		;----------------------------------------------------------------------
		; Erase page
		;----------------------------------------------------------------------					
blprotok
erase	btfss 	doerase, 0
        bra     wrloop
		movlw	ERASE_CODE		;setup erase
		rcall 	Write
		clrf	doerase
		
		
		;----------------------------------------------------------------------
		; Write row
		;----------------------------------------------------------------------			
wrloop	movlw 	ROWSIZEB
		movwf 	rowcnt	
		movwf	rowcnt2	
		; Load latches
wrbyte	movff 	POSTINC0, TABLAT
		tblwt	*+
		decfsz 	rowcnt
		bra 	wrbyte		
		; Write
		tblrd	*-				;point back into row
		movlw	WRITE_CODE		
		rcall 	Write
		
		
		;----------------------------------------------------------------------
		; Verify row
		;----------------------------------------------------------------------	
		lfsr 	FSR0, (buffer+(ROWSIZEB-1))	;load buffer pointer to fsr0
		; Read
verbyte	tblrd	*-		
		movf 	POSTDEC0, w
		; Compare
		cpfseq	TABLAT
		bra		verfail
		; Loop?
		decfsz 	rowcnt2
		bra 	verbyte		
		; Verify succesfull
		bra 	Main
			
		
		;----------------------------------------------------------------------
		; Erase, write & verify eeprom word
		;----------------------------------------------------------------------			
		ifdef	EEADR
			; Load latch
eeprom		movff	INDF0, EEDATA
			; Write
			movlw 	b'00000100'
			rcall 	Write
			; Verify, read byte
			movlw 	b'00000001'
			bsf		EECON1, RD
			movf	INDF0, w
			; Compare
			cpfseq	EEDATA
			bra		verfail
			; Verify succesfull
			bra 	Main
		endif
		
				
		;----------------------------------------------------------------------
		; Write config byte
		;----------------------------------------------------------------------					
		; Load latch
cfg		movff 	INDF0, TABLAT
		tblwt	*
		; Write
		movlw 	b'11000100'
		rcall 	Write
		; Write finished
		bra		Main
		
				
		;----------------------------------------------------------------------
		; Verify fail
		;----------------------------------------------------------------------
verfail	SendL 	VERFAIL
		bra 	mainl
		
				
		;----------------------------------------------------------------------
		; Checksum error
		;----------------------------------------------------------------------
crcfail	SendL 	CHECKSUMERR
		bra 	mainl
		
		
;------------------------------------------------------------------------------
; Write()
;------------------------------------------------------------------------------		
Write	movwf 	EECON1
		movlw 	0x55
		movwf 	EECON2
		movlw 	0xAA
		movwf 	EECON2
		bsf 	EECON1, WR
		; Wait for write to finish, only needed for eeprom
waitwre	btfsc 	EECON1, WR
		bra 	waitwre
		bcf 	EECON1,WREN		;disable writes
		return		
		

;------------------------------------------------------------------------------
; Functions
;------------------------------------------------------------------------------	
		ifdef USE_UART
			#include "uart.inc"
		endif


;------------------------------------------------------------------------------
; End of code
;
; After reset
; Do not expect the memory to be zero,
; Do not expect registers to be initialised as described in datasheet.
;------------------------------------------------------------------------------			
		end


Voor de 18F25K22 wordt het:

;------------------------------------------------------------------------------
; User specific entry code go here
;------------------------------------------------------------------------------				
		
		;----------------------------------------------------------------------
		; Make uart pins digital
		;----------------------------------------------------------------------
		ifdef	ADCON1
				;error Do you need to configura uart pins to be digital? If not, remove this line
		endif
		;movlw 	b'01100000'		;xxx disable 
		;movwf 	ADCON1			;xxx analog on tx/rx
 
                ;Set Port C naar digitaal voor de 18F25K22 (kijk in de datasheet, banksel is niet voor alle PIC's hetzelfde)		
		 banksel   ANSELC      ; you need this as ANSELC is at banked address.   
                 bcf       ANSELC,7


                 ;--------------------------------------------------------------------------------
                 ; Set internal Oscilator frequenty 

Bij dit type is de communicatie poort C7 (RX) in eerste instantie analoog en moeten die in het ANSELC (analoog select poort C) eerst op digitaal gezet worden.




Hit Counter by Digits