; *****************************************************************************
;        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 the PIC18F252/452
;
; DESCRIPTION:
; This is an example of a bootloader routine for the PIC18FX52. The 
; PICDEM2 was used for development. A 10MHz clock was selected.
;
; INSTRUCTIONS:
; Press button RA4 and reset on the PICDEM2. Release reset. Then 
; release button RA4. Now the device is waiting for a text data stream
; to be parced and loaded into the part. 
;
; Use 'Hyperterm' to download the HEX file to be bootloaded. Set 
; the terminal for 57.6kb, 8, N, 1, and enable XON/XOFF. Use the 
; 'Send Text File' option to transfer the HEX file. The HEX file
; must be INTEL32 HEX format.
;
; RB0 will light if an error occured.
; RB1 will light if the code loaded successfully and an EOL was received.
; RB2 will toggle for each HEX line recieved.
;
;
; GENERAL INFO:
; When writing code to be bootloaded, be aware of the re-mapping of
; the reset and interrupt vectors.
;
; Memory Map
;	-----------------
;	|    0x0000	|		
;   	|		|
;	|  Boot Block 	|	(this program)
; 	|		|
;	|    0x0200	|	Re-mapped Reset Vector
;	|    0x0208	|	Re-mapped High Priority Interrupt Vector
;	|    0x0218	|	Re-mapped Low Priority Interrupt Vector
;	|		|
;	|	|	|
;	|		|
;    	|  Code Space 	|
;	|		|
;	|	|	|
;	|		|
;	|    0x7FFE     |
;	-----------------
; *****************************************************************************

 

; *****************************************************************************
	#include P18F452.INC		; Standard include
; *****************************************************************************

; *****************************************************************************

		
		__CONFIG    _CONFIG1H, _OSCS_OFF_1H & _HS_OSC_1H
		__CONFIG    _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L
		__CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
		__CONFIG    _CONFIG3H, _CCP2MX_ON_3H
		__CONFIG    _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
		__CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L 
		__CONFIG    _CONFIG5H, _CPB_ON_5H & _CPD_OFF_5H
		__CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L 
		__CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_ON_6H & _WRTD_OFF_6H
		__CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
		__CONFIG    _CONFIG7H, _EBTRB_ON_7H


#DEFINE		COMM_PIN	PORTB,7	
#DEFINE		COMM_DIR	0x12+COMM_PIN	
#DEFINE		EEADRH		0xFAA	; PIC18Fxx20-hoz (1kbájt EEPROM :)


		org 	0x000

DATACNT		res	1		; Storage area for INHX32
ADDRESS_H	res	1
ADDRESS_L	res	1
RECORD		res	1
DATA_BUFF	res	0x10

LAST_BYTE	res	1

CHKSUM		res	1		; Checksum accumulator

COUNTER		res	1		; General counter

TEMP		res	1
TEMP1		res	1		; Temp storage

RXDATA		res	1		; Receive storage area

ADDRESS_UH	res	1		; Upper word for 32-bit HEX
ADDRESS_UL	res	1


HBITTIMEH	res	1
HBITTIMEL	res	1
BITCOUNTER	res	1

; *****************************************************************************



; *****************************************************************************
	org	0x0000
	bsf	COMM_DIR		; Setup rx pin !!!!!!!!
	btfss	COMM_PIN
	bra	Setup
	bra	0x200

; *****************************************************************************



; *****************************************************************************
	org	0x0008
	bra	0x0208			; Re-map Interrupt vector

GeneralErr
	BCF	COMM_PIN	 
	BCF	COMM_DIR	;LED FOLYAMATOSAN VILÁGÍT
	BRA	$		;VÉGTELEN CIKLUS RESET GOMBIG

EndOfRecord
	MOVLW	0X06		;HÁRMAT VILLAN = SIKERES LETÖLTÉS
	RCALL	LED_BLINKING		
	bra	$
; *****************************************************************************



; *****************************************************************************
	org	0x0018
	bra	0x0218			; Re-map Interrupt vector
; *****************************************************************************



; *****************************************************************************

Setup

Wait_release
	btfss	COMM_PIN		; Wait for button release
	bra	Wait_release
	MOVLW	0X04		;A LED KETTŐT FOG
	RCALL	LED_BLINKING	;VILLANNI

;
;------------------[ BITIDŐ MÉRÉSE TMR1 MODULLAL ]-----------------
;
	RCALL	SET_DELAY	;BITIDŐ MÉRÉS
	MOVLW	B'00001011'	;COMPARE CCP1IF SET TMR1 RESET
	MOVWF	CCP1CON		;CCP1 MODUL KONFIGURÁLÁSA



; *****************************************************************************
; This section reads and parses one line of INTEL32 HEX. 
; 

StartOfLine

WaitForStart
	rcall	GetChar			; Look for a start of line
	xorlw	':'
	bnz	WaitForStart		; Go back for another character


	rcall	GetByte			; Get the data count
	movwf	CHKSUM			
	movwf	DATACNT			; Set the data counter
	addlw	0x03
	movwf	COUNTER		
	

	lfsr	0, ADDRESS_H	
GetNextDat				; Get the data
	rcall	GetByte
	addwf	CHKSUM, F
	movwf	POSTINC0
	decfsz	COUNTER, F
	bra	GetNextDat

	rcall	GetByte			; Get the checksum
	movwf	LAST_BYTE

; *****************************************************************************



; *****************************************************************************
; This tests, writes, and verifies the line of HEX data.
;
; Notes:
; The HEX data is assumed to be padded to fill a 16 byte 
; INHX32 line.
;
; Programming is limited to program memory space only.
;
; Not all record types are decoded.

TestChkSum				; Examine the checksum
	movf	LAST_BYTE, W
	negf	CHKSUM
	xorwf	CHKSUM, W
	bnz	GeneralErr		; Stop if an error is detected


TestRecordType				; Check the record type
	movlw	0x00			
	xorwf	RECORD, W
	bz	NormalDataRecord	; If a normal record then process
	movlw	0x01
	xorwf	RECORD, W
	bz	EndOfRecord		; IF EOF then finish
	movlw	0x04
	xorwf	RECORD, W
	bz	ExtendedRecord		; If extended then adjust
	bra	StartOfLine		; Otherwise, undefined record type...


ExtendedRecord				; Read in upper word of 32-bit address
	movff	DATA_BUFF, ADDRESS_UH	
	movff	DATA_BUFF + 1, ADDRESS_UL	

	bra	StartOfLine


NormalDataRecord			; Normal data record

	movf	ADDRESS_UH		; Get the next line if too high
	bnz	StartOfLine

	movlw	0x20			; Write ID locations?
	xorwf	ADDRESS_UL, W
	bz	WriteIDLocations
	movlw	0x30			; Write Config locations?
	xorwf	ADDRESS_UL, W
	bz	WriteConfig
	movlw	0xF0			; Write Data EEPROM?
	xorwf	ADDRESS_UL, W
	bz	WriteEEPROM
	
;	btfsc	ADDRESS_H, 7		; Get the next line if too high
;	bra	StartOfLine

	movf	ADDRESS_UL,w
	andlw	b'11100000'		; 2 Megabájtig lehet írni...
	bnz	StartOfLine
	movf	ADDRESS_UL		; a lefelső 5 bites címrész 0?
	bnz	TestForBlankMem			
	movlw	0x02			; Prevent writing to boot area
	subwf	ADDRESS_H, W
	bnc	GeneralErr		; Ha a boot területet akarja írni hiba!!!


TestForBlankMem				; Do not write unless blank
	rcall	SetPointers
TestNext
	tblrd	*+			; Read 
	comf	TABLAT			; Test for blank (0xFF)
	bnz	EraseRow
	decfsz	COUNTER
	bra	TestNext
	bra	Write2Blocks

EraseRow				; Erase row if pointing to first byte in row
	rcall	SetPointers
;	movf	ADDRESS_L, W		; Check for row allignment
;	andlw	b'00111111'
;	bnz	TestForBlankMem
	movlw	b'10010100'		; Setup erase
	movwf	EECON1
	rcall	StartWrite		; Erase the row	

Write2Blocks				; Program one HEX line (2 blocks)
	rcall	SetPointers
	rcall	WriteBlock		; Write 2 blocks (16 bytes)
	movlw	0x09			; csak akkor írjon két blokkot, ha 8 bájtnál több!!!
	subwf	DATACNT,w
	bnc	VerifyWrite
	rcall	WriteBlock


VerifyWrite				; Verify the data		
	rcall	SetPointers
VerifyNext				; Compare
	tblrd	*+
	movf	POSTINC2, W
	xorwf	TABLAT
	bnz	GeneralErr		; Stop if bad verify
	decfsz	COUNTER
	bra	VerifyNext

	bra	StartOfLine		; Go get the next line of data
; *****************************************************************************



; *****************************************************************************
WriteIDLocations
;	movff	ADDRESS_UL, TBLPTRU
	rcall	SetPointers
	movlw	b'10010100'		; törlés...
	movwf	EECON1
	rcall	StartWrite
	rcall	WriteBlock
	bra	StartOfLine
; *****************************************************************************



; *****************************************************************************
WriteConfig
	movlw	b'11000100'		; Setup to write fuses
	movwf	EECON1


	rcall	SetPointers
;	movff	ADDRESS_UL, TBLPTRU
;	movff	DATACNT, COUNTER	; a setpointers-ben már ezt megtette :)

WriteNextConfig
	
	movf	POSTINC2, W
	movwf	TABLAT
	tblwt	*
	rcall	StartWrite		; Initiate a write
	
	tblrd 	*+
	decfsz	COUNTER, F
	bra	WriteNextConfig

	bra	StartOfLine
; *****************************************************************************



; *****************************************************************************
WriteEEPROM
	movlw	b'00000100'		; Setup to write DataEE
	movwf	EECON1

;	rrcf	ADDRESS_H, W
;	rrcf	ADDRESS_L, W
;	movwf	EEADR

	movff	ADDRESS_H,EEADRH
	movff	ADDRESS_L,EEADR

	rcall	SetPointers
;	movlw	0x08			; a setpointers-ben már beállítja a valós értéket :)
;	movwf	COUNTER
	
WriteNextEE
	movff	POSTINC2, EEDATA	; Load the data
;	movf	POSTINC2, W		; nem kell mert bájtosan tárolja

	rcall	StartWrite		; Initiate a write

	btfsc	EECON1, WR		; Wait for the write to finish
	bra	$ - 2

	infsnz	EEADR, F
	incf	EEADRH,F

	decfsz	COUNTER, F
	bra	WriteNextEE

	bra	StartOfLine
; *****************************************************************************

					

; *****************************************************************************
; Reset pointers to program mem and data mem.

SetPointers
	movff	ADDRESS_UL,TBLPTRU	; Ez kell a PIC18Fx720-hoz!!! (128 kbájt)
	movff	ADDRESS_H, TBLPTRH	; Reset pointer
	movff	ADDRESS_L, TBLPTRL
		
	lfsr	2, DATA_BUFF

;	movlw	0x10
;	movwf	COUNTER
	movff	DATACNT,COUNTER		; a valós bájtok számát töltsük a COUNTER-be

	return
; *****************************************************************************



; *****************************************************************************
; Get a byte of data from the serial port.

GetByte
	rcall	GetChar			; Get a character
	rcall	Ascii2Hex		; Convert to hexdecimal
	swapf	RXDATA, W
	movwf	TEMP1

	rcall	GetChar			; Get the next character
	rcall	Ascii2Hex		; Convert to hexdecimal
	movf	TEMP1, W

	iorwf	RXDATA, W		; Assemble the two nibbles
	
	return
; *****************************************************************************



; *****************************************************************************
; Convert ASCII to HEX.

Ascii2Hex				; Convert ASCII to Hexdecimal
	movlw	'0'
	subwf	RXDATA
	movlw	0xF0
	andwf	RXDATA, W
	bz	A2HDone			; If no upper nibble then number only
	movlw	'A'-'0'-0x0A		; else get the letter
	subwf	RXDATA, F
A2HDone	return
; *****************************************************************************



; *****************************************************************************
; Write a block of data to program memory.


WriteBlock
	movlw	0x08

Lp1	movff	POSTINC2, TABLAT	; Load the holding registers
	tblwt	*+
	decfsz	WREG, F
	bra	Lp1

	tblrd	*-			; Point back into the block

	movlw	b'10000100'		; Setup writes
	movwf	EECON1

	rcall	StartWrite		; Write the data

	tblrd	*+			; Point to the beginning of the next block

	return
; *****************************************************************************	



; *****************************************************************************
; Unlock and start the write or erase sequence.

StartWrite
	movlw	0x55			; Unlock
	movwf	EECON2
	movlw	0xAA
	movwf	EECON2
	bsf	EECON1, WR		; Start the write
	nop

	return
; *****************************************************************************





; *****************************************************************************
; Automatic block aligning function with padding
;WriteBlock
;	call	FlushBuffer
;
;	movlw	0x07			; Determine how much of the block to write
;	andwf	TBLPTRL, W
;
;	comf	WREG, F		
;	andlw	0x07
;	incf	WREG, F
;
;Lp1	movff	POSTINC2, TABLAT	; Load the holding registers
;	tblwt	*+
;	decfsz	WREG, F
;	bra	Lp1
;
;	tblrd	*-			; Point back into the block
;
;	rcall	StartWrite		; Write the data
;
;	tblrd	*+			; Point to the beginning of the next block
;
;	return
;
; *****************************************************************************	



; *****************************************************************************
;FlushBuffer				; Clear any data in the holding registers
;
;	movff	TBLPTRL, PRODL		; Copy the LSB of the pointer
;
;	clrf	TBLPTRL
;	setf	TABLAT
;	movlw	0x08			; Clear the buffer
;Lp2	tblwt	*+
;	decfsz	WREG, F
;	bra	Lp2
;
;	movff	PRODL, TBLPTRL		; Restore the LSB of the pointer
;
;	return
; *****************************************************************************

;------------------[ LED-ET VILLOGTATÓ RUTIN ]----------------------
;W-BEN VAN, HOGY HÁNYAT VILLANJON 
LED_BLINKING:	
	MOVWF	BITCOUNTER	;VILLANÁSOK SZÁMA
	BSF	COMM_PIN	;KIMENETI TÁROLÓ=1
	BCF	COMM_DIR	;A LÁB KIMENET LESZ
BLINKING_LOOP:
	RCALL	PAUSE		;SW IDŐZITÉS
	RCALL	PAUSE		;VÁR
	BTG	COMM_PIN	;VÁLT
	DECFSZ	BITCOUNTER
	BRA	BLINKING_LOOP	;
	BSF	COMM_DIR	;LÁB BEMENET LESZ ISMÉT
	RETURN
;---------------------[ SW KÉSLELTETÉS ]--------------------------
PAUSE:	CLRF	TEMP
	CLRF	TEMP1
LOOP1:	NOP		;65536 CIKLUS
	NOP
	NOP
	DCFSNZ	TEMP1
	DECFSZ	TEMP
	BRA	LOOP1
	RETURN

;--------------------[ BITIDŐ MEGHATÁROZÁSA ]------------------- 
;KARAKTER: 0000111111 = START(0)-00011111-STOP(1)
;A NYOLC NULLA IDOTARTAMÁT MÉRJÜK 
SET_DELAY:
	CLRF	T1CON			
	CLRF	TMR1L
	CLRF	TMR1H
WAIT_LLEVEL:
	BTFSC	COMM_PIN	;MAGAS SZINT?
	BRA	WAIT_LLEVEL	;IGEN	
	BSF	T1CON,TMR1ON	;NEM, MÉRÉS INDUL
WAIT_HLEVEL:
	BTFSS	COMM_PIN	;MÉRÉS MÍG ALACSONY
	BRA	WAIT_HLEVEL
	BCF	T1CON,TMR1ON	;MÉRÉS ÁLLJ
	BCF	STATUS,C
	RRCF	TMR1H,F		;NULLIDŐ/2
	RRCF	TMR1L,F
	BCF	STATUS,C
	RRCF	TMR1H,W
	MOVWF	CCPR1H		;NULLIDŐ/4=BITIDŐ
	RRCF	TMR1L,W
	MOVWF	CCPR1L		;BITIDO CCP-BE
	BCF	STATUS,C		
	RRCF	CCPR1H,W		
	MOVWF	HBITTIMEH	;NULLIDO/8=FÉL BITIDŐ
	COMF	HBITTIMEH,F	;KOMPLEMENS KÉPZÉS
	RRCF	CCPR1L,W
	MOVWF	HBITTIMEL
	COMF	HBITTIMEL,W	;FÉL BITIDO KOMPLEMENSE
	ADDLW	0X06		;KETTES KOMLEMENS +5 IDOZITESKORREKCIO
	MOVWF	HBITTIMEL
	BTFSC	STATUS,C
	INCF	HBITTIMEH	
	RETURN
;-----------------[ BÁJT VÉTELE SOROS VONALON ] -------------------
GetChar:
	BCF	T1CON,TMR1ON
	MOVLW	0X08
	MOVWF	BITCOUNTER
	MOVFF	HBITTIMEL,TMR1L	;TIMER FELTOLTESE
	MOVFF	HBITTIMEH,TMR1H
WAIT_SILENCE:
	BTFSS	COMM_PIN	;VÁRAKOZÁS HA ALACSONY
	BRA	WAIT_SILENCE
WAIT_STARTBIT:
	BTFSC	COMM_PIN	;VÁRAKOZÁS HA MAGAS
	BRA	WAIT_STARTBIT
	BSF	T1CON,TMR1ON	;STARTBIT JÖTT TIMER INDUL
NEXT_BIT:			;
	RCALL	DELAY		;ELŐSZÖR MÁSFÉL BITIDŐNYI KÉSLEL!
	BCF	STATUS,C
	BTFSC	COMM_PIN
	BSF	STATUS,C
	RRCF	RXDATA
	DECFSZ	BITCOUNTER
	BRA	NEXT_BIT

	bcf	RXDATA,7
	movf	RXDATA,w

	RETURN
;--------------------[ BITIDŐNYI KÉSLELTETÉS ]---------------------
DELAY:
	BCF	PIR1,CCP1IF
WAIT_CCP:	
	BTFSS	PIR1,CCP1IF
	BRA	WAIT_CCP
	RETURN


;--------------------[ FELHASZNÁLÓI PROGRAM ]---------------------	
	org	0x200
	bra	$

	END
