📄 canio.asm
字号:
; *****************************************************************************
; 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 + -