?? bootload.a51
字號:
;*A**************************************************************************
; NAME: bootload.a51
;----------------------------------------------------------------------------
; REVISION: $version: $
;----------------------------------------------------------------------------
; PURPOSE: This file contains the boot loader software
;
;----------------------------------------------------------------------------
; NOTES: This boot loader is based on the T89C51CC01 V1.4
; It supports 64 Kbytes USER memory
; It supports 128 bytes page programming
; It receives hex line during programming
;
;****************************************************************************
; CHANGES:
; Updates from CC01 (RLe):
; - Supports 64k bytes FMO
; - Supports new "Custom memory plan in Read/Write mode
; - Autobaud performance improvements:
; - Check for a "real" start bit
; - Added time out detection for buggly laptops
; - Start autobaud calculation on start bit
;
;
;****************************************************************************
$TITLE (*** Boot Loader ***)
BOOTLOADER_MODULE SEGMENT CODE
BOOTLOADER_DATA SEGMENT DATA
;_____ I N C L U D E S ____________________________________________________
$include (config.inc)
$include (register.inc)
$include (hex_cmd.inc)
;_____ M A C R O S ________________________________________________________
DISPLAY_SIZE EQU 010h
;_____ D E F I N I T I O N ________________________________________________
; *** DATA RAM INTERNAL ***
RSEG BOOTLOADER_DATA
security_state: DS 1
stack: DS 40h ; This size does not overwrite HEX_DATA segment
EXTRN DATA (hex_data_size, hex_address, hex_type)
EXTRN DATA (hex_buffer)
;_____ D E C L A R A T I O N ______________________________________________
PUBLIC erase_block_8k, erase_block_16k
EXTRN CODE (fm_read_xrow, fm_program_xrow, fm_program_xrow_byte)
EXTRN CODE (fm_read_user_byte, fm_program_user, fm_program_user_byte)
EXTRN CODE (fm_read_hardware_byte)
EXTRN CODE (autobaud)
EXTRN CODE (send_char, send_cr_lf, send_point)
EXTRN CODE (send_data_byte, get_char)
EXTRN CODE (get_hex_line)
EXTRN CODE (api_program_fuse_bit)
EXTRN CODE (boot_process)
RSEG BOOTLOADER_MODULE
;*F***************************************************************************
; NAME: boot_loader
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: boot loader program
;
;*****************************************************************************
; NOTE: located at address BOOT_ENTRY
; Boot entry process:
; FCON = 00h => hardware boot => execute atmel's boot loader
; FCON = F0h => programmed boot => execute user's boot loder
; if SBV < boot base address
;*****************************************************************************
boot_loader:
acall boot_process ; software boot process
mov R0,#IDATA_SIZE-1 ; initialise the IDATA space
idata_loop:
mov @R0,#00h
djnz R0,idata_loop
mov SP,#stack-1 ; initialize stack pointer
acall autobaud ; wait 'U'
setb TI
mov A,#'U'
acall send_char ; send 'U'
setb REN ; enable reception
mov DPL,#SSB_ADDRESS
acall fm_read_xrow ; read security level
mov security_state,A
wait_hex_line:
acall get_hex_line ; wait complete hex line reception
jz hex_line_ok ; ACC= 0 if checksum ok
mov A,#'X'
acall send_char
acall send_cr_lf
ajmp wait_hex_line
hex_line_ok:
mov A,FCON
jb ACC.0,hex_line_ok ; wait flash becomes ready
mov A,hex_type
cjne A,#HEX_TYPE_PROGRAM_DATA,hex_type_01
ajmp hex_program_data
hex_type_01:
cjne A,#HEX_TYPE_END_OF_FILE,hex_type_02
ajmp hex_end_of_file
hex_type_02:
hex_type_03:
cjne A,#HEX_TYPE_WRITE_FUNCTION,hex_type_04
ajmp hex_write_function
hex_type_04:
cjne A,#HEX_TYPE_DISPLAY_FUNCTION,hex_type_05
ajmp hex_display_function
hex_type_05:
cjne A,#HEX_TYPE_READ_FUNCTION,hex_type_07
ajmp hex_read_function
hex_type_07:
$if EEPROM_ON_CHIP
cjne A,#HEX_TYPE_PROGRAM_EEPROM,hex_type_08
ajmp hex_program_eeprom
$endif ; EEPROM_ON_CHIP
hex_type_08:
$if CUSTOM_ON_CHIP
cjne A,#HEX_TYPE_PROGRAM_CUSTOM,hex_type_09
ajmp hex_program_custom
$endif ; CUSTOM_ON_CHIP
hex_type_09:
hex_type_10:
hex_type_11:
hex_type_error:
ajmp wait_hex_line
;*F***************************************************************************
; NAME: hex_program_data Type= 00h
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: program up to one page of FM0 without waiting end of programming
;
;*****************************************************************************
hex_program_data:
mov A,security_state
cjne A,#SEC_LEVEL_0,hex_security_protected
hex_program_data_security_ok:
mov DPH,hex_address ; DPTR = programming address
mov DPL,hex_address+1
mov FCON,#SEL_USER_CL ; map USER column latch in XDATA space
mov R0,#hex_buffer ; R0= read pointer
mov R1,hex_data_size ; R1= number of byte to write
hex_program_data_store_cl:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,hex_program_data_store_cl
mov FCON,#(FPL_S0 OR FMOD_USER_MSK) ; launch USER programming
mov FCON,#(FPL_S1 OR FMOD_USER_MSK)
nop ; 1.1 Rev after first Si: Busy flag too slow! :2nop added
hex_program_data_waitbusy:
mov A,FCON
jb ACC.0,hex_program_data_waitbusy
hex_program_data_end:
acall send_point
ajmp wait_hex_line
;*F***************************************************************************
; NAME: hex_end_of_file Type= 01h
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: answer 'OK' to this type of hex line
; CC03 modification : Wait end of busy flag(s) to send '.'
;*****************************************************************************
hex_end_of_file:
mov A,FCON
jb ACC.0,hex_end_of_file ;Wait flash becomes ready
$if EEPROM_ON_CHIP
hex_end_of_file_eeprom_waitbusy:
mov A,EECON
jb ACC.0,hex_end_of_file_eeprom_waitbusy ;Wait EEPROM becomes ready
$endif ; EEPROM_ON_CHIP
acall send_point
ajmp wait_hex_line
;*F***************************************************************************
; NAME: hex_program_eeprom Type= 07h
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: program up to one page of EEPROM DATA
;
;*****************************************************************************
$if EEPROM_ON_CHIP
hex_program_eeprom:
mov A,security_state
cjne A,#SEC_LEVEL_0,hex_security_protected
hex_program_eeprom_security_ok:
mov DPH,hex_address ; DPTR = programming address
mov DPL,hex_address+1
mov EECON,#SEL_EEPROM_CL ; Map EEPROM column latch in XDATA space
mov R0,#hex_buffer ; R0= read pointer
mov R1,hex_data_size ; R1= number of byte to write
hex_program_eeprom_store_cl:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,hex_program_eeprom_store_cl
mov EECON,#EEPL_S0 ; Launch EEPROM DATA programming
mov EECON,#EEPL_S1
nop ; 1.1 Rev after first Si: Busy flag too slow! :2nop added
hex_program_eeprom_waitbusy:
mov A,EECON
jb ACC.0,hex_program_eeprom_waitbusy
hex_program_eeprom_end:
acall send_point
ajmp wait_hex_line
$endif ; EEPROM_ON_CHIP
;*F***************************************************************************
; NAME: hex_write_function Type= 03h
;-----------------------------------------------------------------------------
; PARAMS: hex_buffer[0]: 01h: block erase
; hex_buffer[1]: 00h: block 0 (0000h-1FFFh)
; 20h: block 1 (2000h-3FFFh)
; 40h: block 2 (4000h-7FFFh)
; 80h: block 3 (8000h-BFFFh)
; C0h: block 4 (C000h-FFFFh)
; 03h: start application
; hex_buffer[1]: 00h: hardware Reset
; 01h: ljmp(hex_buffer[2-3])
; 04h: erase SBV & BSB
; 05h: program SSB
; hex_buffer[1]: 00h: level 1
; 01h: level 2
; 06h: program XROW
; hex_buffer[1]: 00h: BSB
; 01h: SBV
; 06h: EB
; hex_buffer[2]: data to program
; 07h: full chip erase
; 0Ah: program fuse
; hex_buffer[1]: 01h: fuse 0
; 02h: fuse 1
; 04h: fuse 2: BLJB
; 08h: fuse 3: X2
; hex_buffer[2]: 00h: program
; 01h: erase
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: write function
;
;*****************************************************************************
hex_write_function:
mov A,hex_buffer ; get function parameter
mov DPL,#00h
cjne A,#HEX_WRITE_FULL_CHIP_ERASE,hex_start_application
hex_full_chip_erase:
acall erase_full_chip
mov security_state,#SEC_LEVEL_0 ; init security variable
ajmp hex_write_function_end
hex_security_protected:
mov A,#'P'
acall send_char
acall send_cr_lf
ajmp wait_hex_line
hex_start_application:
cjne A,#HEX_WRITE_START_APPLICATION,hex_erase_sbv_bsb
mov A,hex_buffer+1
jz hex_hardware_reset
mov DPH,hex_buffer+2
mov DPL,hex_buffer+3
clr A
jmp @A + DPTR
hex_hardware_reset:
mov WDTRST,#01Eh
mov WDTRST,#0E1h
hex_wait_reset:
ajmp hex_wait_reset
hex_erase_sbv_bsb:
cjne A,#HEX_WRITE_ERASE_SBV_BSB,hex_prog_ssb
mov A,security_state ; levels 1 & 2 = write protected
cjne A,#SEC_LEVEL_0,hex_security_protected
mov A,#0FFh
mov DPL,#BSB_ADDRESS
acall fm_program_xrow_byte ; erase BSB
mov DPL,#SBV_ADDRESS
mov A,#BOOT_BASE_ADDRESS
acall fm_program_xrow_byte ; initialize SBV
ajmp hex_write_function_end
hex_prog_ssb:
cjne A,#HEX_WRITE_PROG_SSB,hex_prog_xrow
mov A,security_state ; levels 2 = write locked
cjne A,#SEC_LEVEL_2,hex_prog_ssb_ok
ajmp hex_security_protected
hex_prog_ssb_ok:
mov DPL,#SSB_ADDRESS
mov A,hex_buffer+1 ; get prog_ssb parameter
jz hex_prog_ssb_level_1
mov A,#SEC_LEVEL_2 ; level 2 can always be set
ajmp hex_prog_ssb_xrow
hex_prog_ssb_level_1:
mov A,#SEC_LEVEL_1
hex_prog_ssb_xrow:
mov security_state,A ; update security variable
acall fm_program_xrow_byte
ajmp hex_write_function_end
hex_prog_xrow:
cjne A,#HEX_WRITE_PROG_BSB_SBV,hex_prog_fuse
mov A,security_state ; levels 1 & 2 = write protected
cjne A,#SEC_LEVEL_0,hex_security_protected
hex_prog_xrow_ok:
mov A,hex_buffer+2
mov DPL,hex_buffer+1
acall fm_program_xrow_byte
ajmp hex_write_function_end
hex_prog_fuse:
cjne A,#HEX_WRITE_PROG_FUSE,hex_block_erase
mov A,security_state ; levels 1 & 2 = write protected
cjne A,#SEC_LEVEL_0,hex_security_protected
hex_prog_fuse_ok:
mov DPL,hex_buffer+1 ; get prog_fuse parameter 1
mov A,hex_buffer+2 ; get prog_fuse parameter 2
acall api_program_fuse_bit
ajmp hex_write_function_end
hex_block_erase:
cjne A,#HEX_WRITE_BLOCK_ERASE,hex_write_function_error
mov A,security_state
cjne A,#SEC_LEVEL_0,hex_security_protected
mov A,hex_buffer+1 ; get block_erase parameter
mov DPH,A
mov DPL,#00 ; init block adress
cjne A,#HEX_BLOCK0_SELECT,hex_block_erase_1
acall erase_block_8k
ajmp hex_write_function_end
hex_block_erase_1:
cjne A,#HEX_BLOCK1_SELECT,hex_block_erase_2
acall erase_block_8k
ajmp hex_write_function_end
hex_block_erase_2:
cjne A,#HEX_BLOCK2_SELECT,hex_block_erase_3
acall erase_block_16k
ajmp hex_write_function_end
hex_block_erase_3:
cjne A,#HEX_BLOCK3_SELECT,hex_block_erase_4
acall erase_block_16k
ajmp hex_write_function_end
hex_block_erase_4:
cjne A,#HEX_BLOCK4_SELECT,hex_write_function_error
acall erase_block_16k
ajmp hex_write_function_end
hex_write_function_end:
acall send_point
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -