⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canio.asm

📁 带有CAN接口的PIC18系列单片机的CAN BOOTLOADER汇编程序!
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; *****************************************************************************
; This routine reads or writes the bootloader control registers.
; Then is executes any imediate command received.
_ControlReg	
	lfsr	1, _bootCtlMem
	
_ControlRegLp1
#ifdef 	ALLOW_GET_CMD
	btfsc	CAN_PG_BIT				; or copy control registers to buffer
	movff	POSTINC1, POSTINC0
	btfss	CAN_PG_BIT				; Copy the buffer to the control registers
#endif
	movff	POSTINC0, POSTINC1


	decfsz	WREG1, F
	bra		_ControlRegLp1	
	
#ifdef 	ALLOW_GET_CMD
	btfsc	CAN_PG_BIT	
	bra		_CANSendResponce		; Send responce if get
#endif
; *********************************************************

; *********************************************************	
; This is a no operation command. 
	movf	_bootSpcCmd, W			; NOP Command
	bz		_SpecialCmdJp2			; or send an acknowledge
; *********************************************************	

; *********************************************************	
; This is the reset command. 
	xorlw	CMD_RESET				; RESET Command
	btfsc	STATUS, Z
	reset
; *********************************************************	
	
; *********************************************************	
; This is the Selfcheck reset command. This routine
; resets the internal check registers, i.e. checksum and
; self verify.
	movf	_bootSpcCmd, W			; RESET_CHKSM Command
	xorlw	CMD_RST_CHKSM
	bnz		_SpecialCmdJp1
	
	clrf	_bootChksmH				; Reset chksum
	clrf	_bootChksmL
	bcf		ERR_VERIFY				; Clear the error verify flag
; *********************************************************	

; *********************************************************	
; This is the Test and Run command. The checksum is 
; verified, and the self-write verification bit is checked.
; If both pass, then the boot flag is cleared.
_SpecialCmdJp1
	movf	_bootSpcCmd, W			; RUN_CHKSM Command
	xorlw	CMD_CHK_RUN
	bnz		_SpecialCmdJp2

	movf	_bootChkL, W			; Add the control byte
	addwf	_bootChksmL, F
	bnz		_SpecialCmdJp2
	movf	_bootChkH, W
	addwfc	_bootChksmH, F
	bnz		_SpecialCmdJp2
	
	btfsc	ERR_VERIFY				; Look for verify errors
	bra		_SpecialCmdJp2
	
	setf	EEADR					; Point to last location of EEDATA
	setf	EEADRH	
	clrf	EEDATA					; and clear the data
	movlw	b'00000100'				; Setup for EEData
	rcall	_StartWrite
	
_SpecialCmdJp2	
#ifdef 	ALLOW_GET_CMD
	bra		_CANSendAck				; or send an acknowledge
#else
	bra		_CANMain
#endif					
; *****************************************************************************
	


; *****************************************************************************	
; This is a jump routine to branch to the appropriate memory 
; access function. The high byte of the 24-bit pointer is used 
; to determine which memory to access. All program memorys 
; (including Config and User IDs) are directly mapped. 
; EEDATA is remapped.
;

_DataReg

; *********************************************************								
_SetPointers
	movf	_bootAddrU, W			; Copy upper pointer
	movwf	TBLPTRU
	andlw	0xF0					; Filter
	movwf	WREG2
	
	movf	_bootAddrH, W			; Copy the high pointer
	movwf	TBLPTRH
	movwf	EEADRH	
	
	movf	_bootAddrL, W			; Copy the low pointer
	movwf	TBLPTRL
	movwf	EEADR
	
	btfss	MODE_AUTO_INC			; Adjust the pointer if auto inc is enabled
	bra		_SetPointersJp1
	
	movf	_bootCount, W			; add the count to the pointer
	addwf	_bootAddrL, F
	clrf	WREG
	addwfc	_bootAddrH, F
	addwfc	_bootAddrU, F
	
_SetPointersJp1	
; *********************************************************


; *********************************************************
_Decode
	movlw	0x30					; Program memory < 0x300000
	cpfslt	WREG2
	bra		_DecodeJp1
#ifdef 	ALLOW_GET_CMD
	btfsc	CAN_PG_BIT
	bra		_PMRead
#endif
	bra		_PMEraseWrite
	
		
_DecodeJp1	
	movf	WREG2,W					; Config memory = 0x300000
	xorlw	0x30
	bnz		_DecodeJp2
#ifdef 	ALLOW_GET_CMD
	btfsc	CAN_PG_BIT
	bra		_PMRead
#endif
	bra		_CFGWrite
	
	
_DecodeJp2	
	movf	WREG2,W					; EEPROM data = 0xF00000
	xorlw	0xF0
	bnz		_CANMain
#ifdef 	ALLOW_GET_CMD
	btfsc	CAN_PG_BIT
	bra		_EERead
#endif
	bra		_EEWrite
; *****************************************************************************
	
	
	
; *****************************************************************************
; Function: 	VOID _PMRead()
;				VOID _PMEraseWrite()
;
; PreCondition:	WREG1 and FSR0 must be loaded with the count and address of
;				the source data.
;
; Input:    	None.
;                               
; Output:   	None. 
;
; Side 
; Effects: 		N/A. 
;
; Stack 
; Requirements: N/A
;
; Overview: 	These routines are technically not functions since they will not 
;				return when called. They have been written in a linear form to 
;				save space.	Thus 'call' and 'return' instructions are not 
;				included, but rather they are implied.	
;
; 				These are the program memory read/write functions. Erase is
; 				available through control flags. An automatic erase option
; 				is also available. A write lock indicator is in place to 
; 				insure intentional write operations.
;
; 				Note: write operations must be on 8-byte boundries and 
; 				must be 8 bytes long. Also erase operations can only
; 				occur on 64-byte boundries.
; *****************************************************************************
#ifdef 	ALLOW_GET_CMD
_PMRead:
	tblrd	*+						; Fill the buffer
	movff	TABLAT, POSTINC0
	decfsz	WREG1, F		
	bra		_PMRead					; Not finished then repeat
	
	bra		_CANSendResponce
#endif
; *********************************************************

; *********************************************************
_PMEraseWrite:
	btfss	MODE_AUTO_ERASE			; Erase if auto erase is requested
	bra		_PMWrite

_PMErase:
	movf	TBLPTRL, W				; Check for a valid 64 byte border
	andlw	b'00111111'
	bnz		_PMWrite

_PMEraseJp1
	movlw	b'10010100'				; Setup erase
	rcall	_StartWrite				; Erase the row

_PMWrite:
	btfsc	MODE_ERASE_ONLY			; Don't write if erase only is requested
#ifdef 	ALLOW_GET_CMD
	bra		_CANSendAck
#else
	bra		_CANMain
#endif

	movf	TBLPTRL, W				; Check for a valid 8 byte border
	andlw	b'00000111'
	bnz		_CANMain	
 	
	movlw	0x08
	movwf	WREG1

_PMWriteLp1
	movf	POSTINC0, W 			; Load the holding registers
	movwf	TABLAT
	
	rcall	_UpdateChksum			; Adjust the checksum

	tblwt	*+					
	
	decfsz	WREG1, F
	bra		_PMWriteLp1
 
#ifdef 	MODE_SELF_VERIFY 
 	movlw	0x08
 	movwf	WREG1
_PMWriteLp2
	tblrd	*-						; Point back into the block
	movf	POSTDEC0, W
	decfsz	WREG1, F
	bra		_PMWriteLp2

	movlw	b'10000100'				; Setup writes
	rcall	_StartWrite				; Write the data

	movlw	0x08
	movwf	WREG1

_PMReadBackLp1
	tblrd	*+						; Test the data
	movf	TABLAT, W
	xorwf	POSTINC0, W
	btfss	STATUS, Z
	bsf		ERR_VERIFY
	
	decfsz	WREG1, F		
	bra		_PMReadBackLp1			; Not finished then repeat

#else
	tblrd	*-						; Point back into the block

	movlw	b'10000100'				; Setup writes
	rcall	_StartWrite				; Write the data

	tblrd	*+						; Return the pointer position	
#endif

#ifdef 	ALLOW_GET_CMD
	bra		_CANSendAck
#else
	bra		_CANMain
#endif
; *****************************************************************************



	
; *****************************************************************************
; Function: 	VOID _CFGWrite()
;				VOID _CFGRead()
;
; PreCondition:	WREG1 and FSR0 must be loaded with the count and address of
;				the source data.
;
; Input:    	None.
;                               
; Output:   	None. 
;
; Side 
; Effects: 		N/A. 
;
; Stack 
; Requirements: N/A
;
; Overview: 	These routines are technically not functions since they will not 
;				return when called. They have been written in a linear form to 
;				save space.	Thus 'call' and 'return' instructions are not 
;				included, but rather they are implied.	
;
; 				This is the Config memory read/write functions. Read is 
; 				actually the same for standard program memory, so any read
;				request is passed directly to _PMRead.
; *****************************************************************************
_CFGWrite:		
#ifdef MODE_SELF_VERIFY				; Write to config area
	movf	INDF0, W				; Load data
#else
	movf	POSTINC0, W
#endif 				
	movwf	TABLAT
	
	rcall	_UpdateChksum			; Adjust the checksum
	
	tblwt	*						; Write the data

	movlw	b'11000100'
	rcall	_StartWrite				

	tblrd	*+						; Move the pointers and verify
	
#ifdef MODE_SELF_VERIFY
	movf	TABLAT, W
	xorwf	POSTINC0, W
	btfss	STATUS, Z
	bsf		ERR_VERIFY
#endif

	decfsz	WREG1, F
	bra		_CFGWrite				; Not finished then repeat
	
#ifdef 	ALLOW_GET_CMD
	bra		_CANSendAck
#else
	bra		_CANMain
#endif
; *****************************************************************************




; *****************************************************************************
; Function: 	VOID _EERead()
;				VOID _EEWrite()
;
; PreCondition:	WREG1 and FSR0 must be loaded with the count and address of
;				the source data.
;
; Input:    	None.
;                               
; Output:   	None. 
;
; Side 
; Effects: 		N/A. 
;
; Stack 
; Requirements: N/A
;
; Overview: 	These routines are technically not functions since they will not 
;				return when called. They have been written in a linear form to 
;				save space.	Thus 'call' and 'return' instructions are not 
;				included, but rather they are implied.	
;
; 				This is the EEDATA memory read/write functions.
; *****************************************************************************
#ifdef 	ALLOW_GET_CMD
_EERead:
	clrf	EECON1 

	bsf		EECON1, RD				; Read the data
	movff	EEDATA, POSTINC0
	
	infsnz	EEADR, F				; Adjust EEDATA pointer
	incf	EEADRH, F

	decfsz	WREG1, F
	bra		_EERead					; Not finished then repeat

	bra		_CANSendResponce
#endif
; *********************************************************
	
; *********************************************************
_EEWrite:
#ifdef MODE_SELF_VERIFY
	movf	INDF0, W				; Load data
#else
	movf	POSTINC0, W
#endif
	movwf	EEDATA
	
	rcall	_UpdateChksum			; Adjust the checksum

	movlw	b'00000100'				; Setup for EEData
	rcall	_StartWrite				; and write
	
#ifdef MODE_SELF_VERIFY
	clrf	EECON1 					; Read back the data
	bsf		EECON1, RD				; verify the data
	movf	EEDATA, W				; and adjust pointer
	xorwf	POSTINC0, W				
	btfss	STATUS, Z
	bsf		ERR_VERIFY
#endif
	
	infsnz	EEADR, F				; Adjust EEDATA pointer
	incf	EEADRH, F

	decfsz	WREG1, F		
	bra		_EEWrite				; Not finished then repeat

#ifdef 	ALLOW_GET_CMD
#else
	bra		_CANMain
#endif
; *****************************************************************************





; *****************************************************************************
; Function: 	VOID _CANSendAck()
;				VOID _CANSendResponce()
;
; PreCondition:	TXB0 must be preloaded with the data.
;
; Input:    	None.
;                               
; Output:   	None. 
;
; Side 
; Effects: 		N/A. 
;
; Stack 
; Requirements: N/A
;
; Overview: 	These routines are technically not functions since they will not 
;				return when called. They have been written in a linear form to 
;				save space.	Thus 'call' and 'return' instructions are not 
;				included, but rather they are implied.	
;
; 				These routines are used for 'talking back' to the source. The 
;				_CANSendAck routine sends an empty message to indicate 
;				acknowledgement of a memory write operation. The 
;				_CANSendResponce is used to send data back to the source.
; *****************************************************************************
#ifdef 	ALLOW_GET_CMD
_CANSendAck:
	btfss	MODE_ACK
	bra		_CANMain
	clrf	TXB0DLC					; Setup for a 0 byte transmission
	bra		_CANSendMessage
#endif
; *********************************************************

; *********************************************************
#ifdef 	ALLOW_GET_CMD
_CANSendResponce:
	movlw	0x08					; Setup for 8 byte transmission
	movwf	TXB0DLC

_CANSendMessage
	btfsc	TXB0CON,TXREQ			; Wait for the buffer to empty
	bra		$ - 2

	movlw	CAN_TXB0SIDH			; Set ID
	movwf	TXB0SIDH
	movlw	CAN_TXB0SIDL
	movwf	TXB0SIDL
	movlw	CAN_TXB0EIDH
	movwf	TXB0EIDH
	movlw	CAN_TXB0EIDL
	movwf	TXB0EIDL
	
	bsf		CANTX_CD_BIT			; Setup the command bit
	btfss	CAN_CD_BIT
	bcf		CANTX_CD_BIT
			
	bsf		TXB0CON, TXREQ			; Start the transmission
	
	bra		_CANMain
#endif
; *****************************************************************************	






	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -