📄 smc_dtc_download2562k.fsm
字号:
;============================================================================
;
; SMC DOWNLOAD Plugin
;
;============================================================================
;;
;; For Download:
;; 0xE6: Number of address bytes; 3 or 4
;; 0xE5-0xE2: CA0-7, PA0-7, PA8-15, [PA16-23]
;; 0xE0: Page counter. Number of pages to be download
;; 0xF0-0xFF: For the redundant area
;;
;; For Erase one block
;; 0xE6: Number of address bytes; 2 or 3
;; 0xE5-0xE3: PA0-7, PA8-15, [PA16-23]
;;
;============================================================================
;------------- <<<<<< Entry point for download from buffer0
LD LSB 1
:Init_Download
;-------------
LD MSB 0
LD ADR_BUFFER11
LD MSB 8
CP ALWAYS
JP :Init_Registers
;------------- <<<<<< Entry point for download from buffer1
LD LSB 3
CP ALWAYS
JP :Init_Download
;------------- <<<<<< Entry point for block erase
LD MSB 0
LD LSB 0
LD ADR_BUFFER11
LD MSB 6
:Init_Registers
;--------------
LD LSB 0
LD CMP11
; LD MSB 1 ; data_flash port = output,removed for 256mb
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
LD MSB 0
LD LSB 15
LD DDR_PARALLEL ; PA3-0 as output, PA7-4 as input
LD OR_PARALLEL ; PA3=/RD, PA2=ALE, PA1=/WE, PA0=CLE
; PA4=R/B
LD MSB 15
LD MASK
XOR
LD ADR_BUFFER01 ; clear the high byte of ADR0
LD ADR_BUFFER10 ; clear the low byte of ADR1
LD CMP01
LD BUFFER_MNGT ; Clear segment pointer for calculate PARITY
LD LSB 1
LD X ; X = 1
LD CMP00 ; Set CMP0=0x0001 for timeout control on busy
LD LSB 10
LD DR_PARALLEL ; RD = 1; ALE = 0; WE = 1; CLE = 0
;============================================================================
;; The buffer flag is in ADR_BUFFER11
;; 0x01: write to buf0
;; 0x03: write to buf1
;; 0x00: erase operation
;============================================================================
;commented for 256mb
LD A ADR_BUFFER11
BCLR1 ; Skip send "Sequential Read" CMD on Erasing
LD LSB 0 ; A=0; This is "Sequential Read" command
JP :Loop_Write_Pages
;end of 256mb
;============================================================================
;;; Output the sequential read command (0x00)
; LD DATA_FLASH ; Send "Sequential Read" command,for 256mb
;;; Preset the "Reserved Field", "Data Status Field" & "Block Status Byte"
LD MSB 15
LD ADR_BUFFER00 ; ADR0 points to spare area
LD LSB 10
LD Y ; Used to count 6 time of ADR0 pointer
LD A MASK
:Preset_0xFF
;-----------
LD DATA_BUFFER0
ADDER16 ADR_BUFFER0
INCY
JR :Preset_0xFF
LD MSB 15
LD LSB 12
LD Y ; Y points to low byte of Address Field-2
;;; Calculate the parity bit of the address fields
;;; Since ST7 is too slow to do this job, let DTC do it!!
LD A DATA_BUFFER0
ADDER16 ADR_BUFFER0
SEC
XOR
LD A DATA_BUFFER0
XOR
CP CARRY
; JP :Set_Parity_Done ;for 256mb
JP :Loop_Write_Pages
XOR
BSET1 ; Set the parity bit
LD DATA_BUFFER0 ; Update parity bit of Address-Field 1
LD <Y> ; Update parity bit of Address-Field 2
:Set_Parity_Done
;---------------
;commented for 256mb
; LD LSB 11
; LD DR_PARALLEL ; WE = 1, CLE = 1
; LD LSB 9
; LD DR_PARALLEL ; WE = 0, CLE = 1
; NOP
:Loop_Write_Pages
;----------------
LD LSB 11
LD DR_PARALLEL ; WE = 1, CLE = 1, ALE = 0, RD = 1
;; LD LSB 10
;; LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 0, RD = 1
;; Keep CLE as high to output "Data Input" or "Block Erase" command
;============================================================================
LD MSB 1 ; data_flash port = output
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
LD A CMP11 ; Load "Data Input" or "Block Erase" cmd
LD DATA_FLASH ; Send the first command. It is 0x80 or 0x60
LD LSB 9
LD DR_PARALLEL ; WE = 0, CLE = 1
LD LSB 11
LD DR_PARALLEL ; WE = 1, CLE = 1
;============================================================================
;; Finish output a command, set CLE low.
;; Going to output the address, set ALE high
LD LSB 14
LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 1, RD = 1
; LD A CMP01
; LD ADR_BUFFER01
LD MSB 14
LD LSB 6
LD ADR_BUFFER00 ; ADR0 = 0x00E6; points to "Num of address"
LD A DATA_BUFFER0
LD Y ; Load number of addres bytes
SUB16 ADR_BUFFER0
DECY
;; Send one byte less if this is an erase operation
LD A ADR_BUFFER11
; BCLR1 ;changed for 256mb
BSET1
JP :Send_Address_Bytes
DECY ;added for 256mb
DECY
:Send_Address_Bytes
;------------------
LD A DATA_BUFFER0
SUB16 ADR_BUFFER0
LD DATA_FLASH ; Send the address byte
LD LSB 12
LD DR_PARALLEL ; WE = 0, ALE = 1
LD LSB 14
LD DR_PARALLEL ; WE = 1, ALE = 1
:Next_Address_Byte
;-----------------
DECY
JP :Send_Address_Bytes
LD LSB 10
LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 0, RD = 1
;============================================================================
;:write_next_col
;--------------
LD A ADR_BUFFER11 ; Load the operation flag
BCLR1 ; It is 0001 or 0011 or 0000
LD MSB 12
LD LSB 6 ;commented for debug
; LD LSB 13
BRANCH :Send_Erase_CMD
;============================================================================
; INCY ; Now Y=0
:write_next_col
;----------------
; LD A CMP01 ;for 256mb
; LD Y
;-------------- ; Reset the ECC machine first
LD MSB 3 ; Reset ECC machine, DATA_FLASH port = output
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
LD A CMP01
LD Y
LD MSB 15
LD LSB 13
LD ADR_BUFFER00 ; Load pointer of ECC1 (0x00FD)
;============================================================================
;; Wait on one of the buffer full
;commented for debug
LD A ADR_BUFFER11
BSET2
JP :Wait_Buffer1_Full
;debug end
:Wait_Buffer0_Full
;-----------------
LD A BUFFER_MNGT
BCLR3
JP :Wait_Buffer0_Full
JP :Write_256_Bytes
;debug
;-------
:Wait_Buffer1_Full
;-----------------
LD A BUFFER_MNGT
BCLR4
JP :Wait_Buffer1_Full
;debug end
;============================================================================
:Write_256_Bytes
;---------------
LD A DATA_BUFFER1
LD DATA_FLASH
LD ECC_CRC
LD A ECC_CRC ; AUTO UPDATE OF Line PARITY 1
LD A ECC_CRC ; AUTO UPDATE OF Line PARITY 2
LD A ECC_CRC ; AUTO UPDATE OF column PARITY
LD LSB 8
LD DR_PARALLEL ; WE = 0
LD LSB 10
LD DR_PARALLEL ; WE = 1
ADDER16 ADR_BUFFER1
INCY
JP :Write_256_Bytes
; Save the ECC code
;------------------
LD A TMP_ECC ; first read (Line parity 1)
LD DATA_BUFFER0
LD A ECC_CRC ; -- INCR CRC_ECC_STATE --
ADDER16 ADR_BUFFER0
LD A TMP_ECC ; second read (Line parity 2)
LD DATA_BUFFER0
LD A ECC_CRC ; -- INCR CRC_ECC_STATE --
ADDER16 ADR_BUFFER0
LD A TMP_ECC ; third read ( column parity)
LD DATA_BUFFER0
LD MSB 15
LD LSB 8
LD ADR_BUFFER00 ; Load pointer of ECC2 (0x00F8)
LD A ADR_BUFFER11 ; Write buf0: 0001=>0010, =>0011
; Write buf1: 0011=>0100, =>0101
BCLR1
JP :Write_256_Bytes
;============================================================================
;; Write 16 bytes of the redundant area
LD MSB 15
LD LSB 0
LD Y ; Y = 0xF0; pointer of redundant area (0x00F0)
:Write_Spare_Area
;----------------
LD A <Y>
LD DATA_FLASH
LD LSB 8
LD DR_PARALLEL ; WE = 0
LD LSB 10
LD DR_PARALLEL ; WE = 1
INCY
JP :Write_Spare_Area
;-----------------------------------------------------------------
;testing
;----------------------------------------------------------------
:Release_Buffer
;--------------
LD A ADR_BUFFER11 ; Buf0: 0001=>0010=>0011
; Buf1: 0011=>0100=>0101
BCLR3 ; Wrap the segment pointer
LD ADR_BUFFER11 ; Reload for the next page writing
JP :Free_Buffer0
LD LSB 2
JP :Free_Buffer
:Free_Buffer0
;------------
LD LSB 1
:Free_Buffer
;-----------
LD BUFFER_MNGT
LD LSB 0
LD BUFFER_MNGT
;-----------------end testing-------------------------------------
;-------------
;For 256MB
;-------------
LD MSB 14
LD LSB 0
LD ADR_BUFFER00 ;point to 0xe0
LD A DATA_BUFFER0
CLC
SUB8 X
LD DATA_BUFFER0
CP A<X
JP :pgm_page
LD MSB 14
LD LSB 4
LD ADR_BUFFER00
LD MSB 0
LD LSB 2
LD Y
LD A DATA_BUFFER0
CLC
ADDER8 Y
BCLR4
LD DATA_BUFFER0
; BCLR4
LD MSB 6
LD LSB 9
BRANCH :write_next_col
LD A ADR_BUFFER01
; LD DATA_BUFFER0
ADDER16 ADR_BUFFER0 ;Reload both 0xe5 and 0xe4 for nxt page
LD DATA_BUFFER0
;============================================================================
:pgm_page
;----------
LD MSB 1 ; Send the "Page Program" command - 0x10
JP :Send_CMD2
:Send_Erase_CMD
;--------------
LD MSB 13 ; Send the "Block Erase" command - 0xD0
:Send_CMD2
;---------
LD LSB 0
LD DATA_FLASH
LD LSB 11
LD DR_PARALLEL ; WE = 1, CLE = 1
LD LSB 9
LD DR_PARALLEL ; WE = 0, CLE = 1
LD LSB 11
LD DR_PARALLEL ; WE = 1, CLE = 1, ALE = 0, RD = 1
;============================================================================
;; Wait on busy line
;============================================================================
:Wait_On_Busy
;------------
; ADDER16 ADR_BUFFER0
; CP ADR_BUFFER0=>CMP0
; JP :No_Timeout
; STATUS ERROR STOP ; timeout of 19ms
NOP
NOP
NOP
;:No_Timeout
;----------
LD A DR_PARALLEL
EXCHANGE
BCLR1 ; Test R/-B line
JP :Wait_On_Busy
;============================================================================
;; Read the status byte
LD MSB 7
LD LSB 0
LD DATA_FLASH ; Send "Status Read" command
LD LSB 9
LD DR_PARALLEL ; WE = 0, CLE = 1
LD LSB 11
LD DR_PARALLEL ; WE = 1, CLE = 1, ALE = 0, RD = 1
LD LSB 10
LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 0, RD = 1
LD MSB 0 ; DATA_FLASH port = input
LD LSB 9 ; DATA_FLASH Port driven by FCI
LD CTRL_FCI ; PARALLEL Port driven by FCI
LD LSB 2
LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 0, RD = 0
LD LSB 10
LD DR_PARALLEL ; WE = 1, CLE = 0, ALE = 0, RD = 1
LD A DATA_FLASH ; Get the status byte
BCLR1
JP :Status_Good
;;; Status "FAIL" Stop the DTC
STATUS ERROR STOP
;============================================================================
:Status_Good
;-----------
LD A ADR_BUFFER11 ; Buf0: 0001=>0010=>0011
; Buf1: 0011=>0100=>0101
BSET1
; JP :Release_Buffer
JP :increment_page
STATUS STOP ; Return if it is a BLOCK_ERASE
;:Release_Buffer
;--------------
; BCLR3 ; Wrap the segment pointer
; LD ADR_BUFFER11 ; Reload for the next page writing
; JP :Free_Buffer0
; LD LSB 2
; JP :Free_Buffer
;:Free_Buffer0
;------------
; LD LSB 1
:Free_Buffer
;-----------
; LD BUFFER_MNGT
; LD LSB 0
; LD BUFFER_MNGT
;============================================================================
:increment_page
;---------------
;; Decrease the page number and increase the page address
LD A CMP01
LD ADR_BUFFER01
LD MSB 14
LD LSB 3
LD ADR_BUFFER00 ;0xe5 = 1st col. byte
; LD MSB 1
; LD LSB 0
; LD Y
; LD A DATA_BUFFER0
; CLC
; ADDER8 Y
; LD DATA_BUFFER0
; SUB16 ADR_BUFFER0 ;0xe4 = 2nd col byte
; LD MSB 0
; LD LSB 2
; LD Y
; LD A DATA_BUFFER0
; CLC
; ADDER8 Y
; BCLR4
; LD DATA_BUFFER0
; JP :dec_page
; ADDER16 ADR_BUFFER0 ; 1st col = 0 at page change
; LD A ADR_BUFFER01
; LD DATA_BUFFER0
; SUB16 ADR_BUFFER0
; SUB16 ADR_BUFFER0 ; 0xe3 = 1st row byte
:next_page
;------------
; LD A <Y>
LD A DATA_BUFFER0
CLC
ADDER8 X
; LD <Y> ; Increase the page address and save it back
LD DATA_BUFFER0
;For 256mb
:dec_page
LD MSB 14
LD LSB 0
LD Y
LD A <Y>
; CLC
; SUB8 X
; LD <Y> ;new
CP A=>X
LD MSB 3
LD LSB 13
BRANCH :Loop_Write_Pages
STATUS STOP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -