📄 isp_test.asm
字号:
;LPC9xx family boot program for IN-SYSTEM PROGRAMMING
;
;copyright Philips Semiconductors 2003, 2004
;FILENAME: LPC2_ISP_8K_V04.TXT
;CODE TYPE: ISP
;VERSION: 04
;RELEASE DATE: 30 Jul 04
;CODE MEMORY SIZE: 8KB
;CODE ADDRESS RANGE: 1E00h - 1FFFh
;BOOT VECTOR: 1F00h
;USES IAP VERSION: 04
;USES IAP ENTRY: FF03h
;Author: Bill Houghton
;
;Features:
;
;Version 4:
;
;- Fixes bug: CCP command was assigned the same value as the write sec 2 security byte.
;
;Version 3:
;
;- Support added for hardware code corruption (BOOTSTAT.7:5) - valid key needed for write operations
;- Fixes bug in direct load of UART baud rate command.
;- Fixes Port 0 init to only program P1 modes for TxD & RxD pins.
;
;Version 2:
;- Modifieds WDL and WDCON to select longest WDT timeout & provides periodic feeding.
;- Program user code page has option to use either IDATA or XDATA (if available on chip).
;- Software code corruption protection - valid key needed for write operations
;- Code traps (software reset) added to start of ISP & IAP sections
;
;Version 1:
;- Includes standard features originally released with LPC932.
;********************************************************************************
;************************* SET DEVICE CODE MEMORY SIZE HERE *********************
;********************************************************************************
;This program is used to create source code for devices with different code memory
;sizes. To set the size of the device, "comment-out" the two devices sizes that do
;not match leaving only the appropriate device size.
MEM_TOP EQU 2000H ;use for 8KB code memory devices
;MEM_TOP EQU 1000H ;use for 4KB code memory devices
;MEM_TOP EQU 800H ;use for 2KB code memory devices
;code memory space for LPC2
;
;block 0, 1KB, 0000h - 03FFh
;block 1, 1KB, 0400h - 07FFh
;block 2, 1KB, 0800h - 0BFFh
;block 3, 1KB, 0C00h - 0FFFh
;block 4, 1KB, 1000h - 13FFh
;block 5, 1KB, 1400h - 17FFh
;block 6, 1KB, 1800h - 1BFFh
;block 7, 1KB, 1C00h - 1FFFh
;Bootrom, 240 bytes , FF00h - FFEF
PGMU EQU 00
VRD EQU 01
MWR EQU 02
MRD EQU 03
ERS EQU 04
SCRC EQU 05
GCRC EQU 06
RUSR EQU 07
F1 EQU 0D1H
WDL EQU 0C1H
WDCON EQU 0A7H
WFEED1 EQU 0C2H
WFEED2 EQU 0C3H
FMCON EQU 0E4H
FMDATA EQU 0E5H
PGM_MTP EQU 0FF03H
;byte variables definition
DSEG AT 30H
ADR0: DS 1 ;low byte of address
ADR1: DS 1 ;high byte of address
CHKSUM: DS 1 ;record checksum
NBYTES: DS 1 ;number of bytes in record
RTYPE: DS 1 ;record type
TMP3: DS 1 ;temporary storage
UCFG1: DS 1 ;User configuration register 1
UCFG2: DS 1 ;User configuration register 2
BOOTV: DS 1 ;Boot Vector
STATBY: DS 1 ;Status Byte
FCFG1: DS 1 ;Factory config 1, read only
FCFG2: DS 1 ;Factory config 2, read only
DERIV: DS 1 ;Derivative
TMEB_v: DS 1 ;TMEB
SEC0: DS 1 ;Security byte 0
SEC1: DS 1 ;Security byte 1
SEC2: DS 1 ;Security byte 2
SEC3: DS 1 ;Security byte 3
SEC4: DS 1 ;Security byte 4
SEC5: DS 1 ;Security byte 5
SEC6: DS 1 ;Security byte 6
SEC7: DS 1 ;Security byte 7
MF_ID: DS 1 ;Signature byte 0 (mfg id)
ID_1: DS 1 ;Signature byte 1 (device id)
ID_2: DS 1 ;Signature byte 2 (derivative id)
CRC0: DS 1 ;CRC data
CRC1: DS 1 ;CRC data
CRC2: DS 1 ;CRC data
CRC3: DS 1 ;CRC data
;ISEG AT 0FFH
;KEY: DS 1 ;IAP request key
KEY data 0xFF
;*************** equates list ************************
CONFB EQU UCFG1 ;start of CONF register space
RXDn EQU P1.1 ;RxD pin
ISP_VER EQU 04H ;ISP version id = 4
AUXR EQU 08EH ;auxr register
AUXR1 EQU 0A2H ;auxr 1 register
SRST EQU 8H ;OR mask for software reset bit
TAMOD EQU 8FH ;timer aux mode register
P1M1 EQU 91H
P1M2 EQU 92H
BRGR0 EQU 0BEH
BRGR1 EQU 0BFH
BRGCON EQU 0BDH
OI EQU ACC.0 ;operation aborted by interrupt
SV EQU ACC.1 ;security violation
HVE EQU ACC.2 ;high voltage error
SBVAL EQU 0FFH ;status byte default value
BVVAL EQU 0FCH ;boot vector default value
DBYTES EQU 80H ;start of RAM buffer for hex string
KEYVAL EQU 96H ;IAP request key value
SET_WE EQU 08H ;enable writing
CSEG AT MEM_TOP-512 ;Should be 1E00h
RESET:
ORL AUXR1,#SRST ;set the software reset bit
;*********************************************************
;
; START OF PROGRAM
;
;*********************************************************
; First, we need to measure the baud rate of
;the host in terms of our own clock speed. This
;measurement can be made on a start bit provided
;the first data bit is a logical one. A capital "U"
;is a good choice since it has alternating 1s and 0s .
; Our measurement uses T1 which is clocked at
;fosc/2, which is the same as when T1 is used as
;a baud rate generator. The UART uses 16x sampling
;so we need to divide the T1 count by 16. Even
;though the timer will be used in the 8-bit
;auto-reload mode for baud rate generation, non-reload
;16-bit mode is used for the measurement to give
;more clock counts for slower baud rates. This number
;will be divided by 16. This method allows the timer
;to count up to 4096 counts (16 x 256). The timer
;counts up towards zero thus counts loaded into the
;timer counter need to be negative numbers. A two's
;complement of the adjusted count produces this result.
INIT:
ACALL I_WDT ;
ANL 91H,#0FCH ;RxD = quasi-bi
ORL 92H,#01H ;TxD = push-pull
MOV P1,#0FFH ;
MOV TMOD,#20H ;8-bit auto-reload mode
ANL 0BAH,#0FAH
CLR A
MOV 0BDH,A
MOV SCON,#50H ;init UART 8-bit variable, TI=0 RI=0
MOV 0BEH,#0F0H
MOV 0BFH,#02H
MOV 0BDH,#03H
QRZ:
ACALL ECHO ;wait until character is rcv'd & get it
CJNE A,#'U',QRZ ;check to see if uppercase "U"
W1: ACALL CO
LCMD:
MOV R5,#0 ;begin record... zero checksum
ACALL ECHO ;get first char and echo
CJNE A,#':',W1 ;record starts with ':' char
ACALL GET2 ;get the number of bytes in record
MOV 33H,35H ;and save
ACALL GET2 ;get MSB of load address
MOV 31H,35H ;and save
ACALL GET2 ;get LSB of load address
MOV 30H,35H ;and save it
ACALL GET2 ;get record type
MOV 34H,35H ;and save it
MOV A,33H ;else, more than
MOV R2,A
JZ EOR ;zero data bytes ?
MOV R1,#80H ;pointer for data bytes
LDATA: ACALL GET2 ;get data byte
MOV @R1,35H ;store it
INC R1 ;and bump up the pointer
DJNZ R2,LDATA ;repeat if more bytes in record
EOR:
MOV A,R5 ;
MOV R4,A ;save calculated checksum
ACALL GET2 ;get the checksum byte
MOV A,R4 ;and compare with calculated checksum byte
CJNE A,35H,CHKERR ;recv'd & calc'd chksums match ?
MOV R1,#80H ;pointer for data
AJMP PROCESS ;YES, process command
CHKERR:
; MOV A,#'X'
AJMP RSPND1
GET2: ACALL ECHO ;get first char of length
ACALL A2HEX ;convert to hex
SWAP A ;set in high nibble
MOV 35H,A ;store in NBYTES
ACALL ECHO ;get second char of length
ACALL A2HEX ;convert to hex
ORL 35H,A ;add into NBYTES
MOV A,R5 ;get checksum
CLR C ;subtract NBYTES
SUBB A,35H ;from checksum and
MOV R5,A ;store as new checksum
RET
;***** console output routine *****
;
;Outputs character in the ACC to
;the serial output line.
CO: ACALL FD_WDT ;feed the WDT
; JNB TI,CO ;wait till xmtr ready
; CLR TI ;reset xmtr flag
MOV SBUF,A ;output char to SIO
JNB TI,$ ;wait till xmtr ready
CLR TI ;reset xmtr flag
RET ;and done
;***** console input routine *****
;
;Waits until character has been received
;and then returns char in ACC.
CI: ACALL FD_WDT ;feed the WDT
JNB RI,CI ;wait till char
CLR RI ;reset rcvr flag
MOV A,SBUF ;read the char
RET ;and done
;***** character echo routine *****
;
;waits until a character is received from
;the console input and echos this character
;to the console output. The received char
;is also passed to the caller in the ACC.
ECHO: ACALL CI ;get char from console
; ACALL CO ;print the character
JNB ACC.6,EXECHO ;exit if not 4x,5x, or 6x Hex
CLR ACC.5 ;convert to upper case
EXECHO:
RET ;and done
;***** ASCII to HEX routine *****
;
;This routine accepts an ASCII char in the ACC
;and converts it into the corresponding hex digit.
;The routine checks to see if the char is in the
;range of '0' through '9' or in the range of 'A'
;through 'F'. If not in either range then the ASCII
;char is not a valid hex entry from the operator
;and an error flag is returned true along with the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -