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

📄 smc_dtc_upload.fsm

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 FSM
字号:
;===================================================================
;
;                    SMART MEDIA CARD
;
;===================================================================

;------------
; smc_dtc_up
;------------

;------------------------------------------------------------------
;		START ADDRESS FOR read data to USB
;	ST7: Give a 3 or 4 bytes address, number of pages
;	0x1632 - 0x1635 = The address, big endien (0x00E2-0x00E5)
;	0x163F = Number of pages (counter), it should be 0 on exit
;	On return: Counter = 0 means no error
;		   Counter !=0 means ECC error on that page
;------------------------------------------------------------------
:init_command_address
      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	MSB 0
      LD	LSB 15
      LD	DDR_PARALLEL	; PA3-0 as output, PA4 as input
      LD	OR_PARALLEL	; PA3=/RD, PA2=ALE, PA1=/WE, PA0=CLE
				; PA4=R/B

      LD	MSB 15
      LD	MASK		; MASK = 0xFF

      XOR			; A = 0
      LD	ADR_BUFFER01	; clear the high byte of ADR0
      LD	DATA_FLASH	; command Read(1), sequential read

      LD	LSB 1
      LD	X		; X = 1
      LD	ADR_BUFFER11

;;; Output the sequential read command (0x00)
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0
      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
      LD	LSB 10
      LD	DR_PARALLEL	; WE = 1, CLE = 0

;--------------------------------------------------
;             START ADDRESS FOR address_latch_cycle
;--------------------------------------------------
      LD	MSB 14
      LD	LSB 06
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x00E6
      LD	A DATA_BUFFER0
      LD	Y		; Y = number of address bytes
      DECY
      LD	LSB 12
      LD	CMP01		; CMP01 = 12, for send address toggling lines
      LD	LSB 14
      LD	DR_PARALLEL	; ALE = 1, WE = 1

      LD	A ADR_BUFFER01	; clear A as the first byte, it is always 0
      LD	ADR_BUFFER10	; clear low byte of ADR1
      LD	CMP10		; clear low byte of CMP1
      LD	BUFFER_MNGT	; clear SEGment offset for using Y on ECC check

:loop_send_address
;-----------------

      SUB16	ADR_BUFFER0	; send address from high byte to low byte

      LD	DATA_FLASH	; Output the address bytes
      LD	A CMP01
      LD	DR_PARALLEL	; ALE = 1, WE = 0
      LD	LSB 14
      LD	DR_PARALLEL	; ALE = 1, WE = 1

      LD	A DATA_BUFFER0

      DECY
      JP :loop_send_address

      LD	MSB 0
      LD	LSB 10
      LD	DR_PARALLEL	; ALE = 0, WE = 1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;	Start to read one page
;; 1. Test the READY/BUSY line is ready
;; 2. Wait one of the buffer is free
;; 3. Read the page data
;; 4. Check the ECC
;; 5. Submit the buffer to send the page data
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:Wait_SMC_Ready
;--------------
      LD	A ADR_BUFFER01
      LD	CMP01
      LD	LSB 2
      LD	CMP00		; CMP0 = 0x0002, will use for RD toggling
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x0002

;;; Reset the ECC calculation machine
;     LD	MSB 0		; data_flash port = intput   
      LD	LSB 9		; DATA_FLASH Port driven by FCI 
      LD	CTRL_FCI	; PARALLEL Port driven by FCI 
      LD	MSB 2		; ECC Mode & Reset TMP Reg
      LD	CTRL_FCI	; PARALLEL Port driven by FCI

:wait_ready_line
;---------------
      ADDER16	ADR_BUFFER0
      CP	ADR_BUFFER0=>CMP0
      JP :test_busy_line
				; the waiting loop is timeout
      STATUS STOP ERROR		; return with error
:test_busy_line
;--------------
      LD	A DR_PARALLEL
      EXCHANGE
      BCLR1
      JP :wait_ready_line

:Init_Page_Reading
;-----------------		; Initialize ADR0 for read ECC
      LD	A ADR_BUFFER10
      LD	ADR_BUFFER01	; clear high byte of pointer 0
      LD	MSB 15
      LD	LSB 8
      LD	ADR_BUFFER00	; ADR0 = 0x00F8, points the ECC memory

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Test and wait one of the buffer is full
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      LD	A ADR_BUFFER11
      BSET2
      JP :wait_buffer1_full

      LD	LSB 1
      LD	ADR_BUFFER11	; buffer pointer 1 = 0x0100

:wait_buffer0_full
;-----------------
      LD	A BUFFER_MNGT
      BSET3
      JP :wait_buffer0_full
      JP :read_one_page

:wait_buffer1_full
;-----------------
      LD	A, BUFFER_MNGT
      BSET4
      JP :wait_buffer1_full

:read_one_page
;-------------
      LD	A ADR_BUFFER10
      LD	Y		; Clear Y

:read_256_bytes
;--------------
      LD	LSB 2
      LD	DR_PARALLEL	; RD = 0; WE = 1; ALE=CLE=0
      LD	LSB 10
      LD	DR_PARALLEL	; RD = 1; WE = 1; ALE=CLE=0

      LD	A DATA_FLASH	; Get the reading data byte
      LD	DATA_BUFFER1	; Save it in the buffer
      LD	ECC_CRC		; Load to ECC_CRC REG

      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 
  
      ADDER16	ADR_BUFFER1
      INCY
      JP :read_256_bytes

;-------------------
; Save the calculated ECC to 0xF8, 0xF9, 0xFA -- 0xFB, 0xFC, 0xFD
;-------------------
:read_ecc_calcul
      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
      ADDER16	ADR_BUFFER0

      LD	A ADR_BUFFER11	; The value can be 0010, 0011, 0100, 0101
      BCLR1
      JP :read_256_bytes

;---------------------------------------------
; Read 16 bytes of redundant area from the SMC
; They will be saved in 0xE7-0xF6
;---------------------------------------------
:init_read_spare
      LD	LSB 15
      LD	Y		; Y = 15
      LD	MSB 14
      LD	LSB 06
      LD	ADR_BUFFER00	; ADR0 = 0x00E6,
				; points to one byte before spare area
:read_spare
;----------
      ADDER16	ADR_BUFFER0

      LD	LSB 2
      LD	DR_PARALLEL	; RD = 0; WE = 1; ALE=CLE=0
      LD	LSB 10
      LD	DR_PARALLEL	; RD = 1; WE = 1; ALE=CLE=0

      LD	A DATA_FLASH	; Save one byte of redundant area
      LD	DATA_BUFFER0

      DECY
      JP :read_spare

;------------------------------------------------------
; Check the calculated ECC againest with redundant area
;------------------------------------------------------
:init_ecc2_check
;---------------
      LD	MSB 15
      LD	LSB 10
      LD	Y		; Y = 0xFA, points to ECC2[2]
      LD	LSB 4
      LD	CMP00		; CMP0 = 0x00F4

:ecc2_check
;----------
      LD	A DATA_BUFFER0	; ADR0 = spare area = 0x00F6, 0x00F5, 0x00F4
      LD	MASK
      LD	A <Y>		; Y = 0xFA, 0xF9, 0xF8
      XOR
      CP	A=>X
      JP :ecc_error

      SUB16	ADR_BUFFER0
      DECY
      CP	ADR_BUFFER0=>CMP0
      JP :ecc2_check

:init_ecc1_check
;---------------
      LD	MSB 15
      LD	LSB 13
      LD	Y		; Y = 0xFD, points to ECC1[2]
      LD	LSB 0
      LD	CMP00		; CMP0 = 0x00F0
      SUB16	ADR_BUFFER0	; buffer pointer 0 = 0x00F2

:ecc1_check
;----------
      SUB16	ADR_BUFFER0
      LD	A DATA_BUFFER0	; buffer pointer 0 = 0x00F1, 0x00F0, 0x00EF
      LD	MASK
      LD	A <Y>		; Y = 0xFD, 0xFC, 0xFB
      XOR
      CP	A<X
      JP :no_ecc_error

:ecc_error
;---------
      STATUS STATUS STOP

:no_ecc_error
;------------
      DECY
      CP	ADR_BUFFER0=>CMP0
      JP :ecc1_check

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; After the ECC check is verified. Submit the buffer read
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      LD	A ADR_BUFFER11	; The value is either 0011 or 0101
      BSET3
      JP :Set_buffer1_full

:Set_buffer0_full
;----------------
      LD	LSB 1
      JP :Set_Buffer_Full

:Set_buffer1_full
;----------------
      LD	LSB 2
:Set_Buffer_Full
;---------------
      LD	BUFFER_MNGT
      LD	LSB 0
      LD	BUFFER_MNGT

:next_page
;---------
      LD	MSB 15
      LD	LSB 15
      LD	MASK
      LD	ADR_BUFFER00	; buffer pointer 0 = 0x00FF, points the counter
      LD	A DATA_BUFFER0
      CLC
      SUB8	X
      LD	DATA_BUFFER0	; update the page counter
      CP	A=>X
      LD	MSB 3
      LD	LSB 3
      BRANCH	:Wait_SMC_Ready

:all_pages_read
;--------------
; ** LD	A BUFFER_MNGT	; wait for 2 buffers are free
; ** BSET3
; ** JP :all_pages_read
; ** BSET4
; ** JP :all_pages_read

      STATUS	STOP		; FINISH SUCCESSFULLY!


;------------------------------------------------------------------
;		START ADDRESS FOR read data FF to USB
;	ST7: Give number of pages
;	0x163F = Number of pages (counter), it should be 0 on exit
;	On return: Counter = 0 means no error
;		   Counter !=0 means ECC error on that page
;------------------------------------------------------------------

      LD	MSB 0
      LD	LSB 0
      LD	ADR_BUFFER10	; low byte of pointer 1
      LD	ADR_BUFFER01	; high byte of pointer 0
      LD	CMP10
      LD	LSB 1
      LD	ADR_BUFFER11	; ADR1 = 0x0100
      LD	X		; X = 1
      LD	LSB 5
      LD	CMP11		; CMP1 = 0x0500

      LD	MSB 15
      LD	LSB 15
      LD	ADR_BUFFER00	; ADR00 = 0x00FF

:fill_buffer_with_FF
      LD	DATA_BUFFER1
      ADDER16	ADR_BUFFER1
      CP	ADR_BUFFER1<CMP1
      JP :fill_buffer_with_FF

      LD	A DATA_BUFFER0
      LD	Y		; load the page counter

:FFsend_2_pages
;--------------
      DECY
      JP :FFwait_for_buffer_0
      JP :FF_finish

:FFwait_for_buffer_0
;-----------------
      LD	A BUFFER_MNGT
      BSET3
      JP :FFwait_for_buffer_0

      LD	LSB 1
      LD	BUFFER_MNGT	; mark buffer0 full
      LD	LSB 0
      LD	BUFFER_MNGT	; mark buffer0 full

      DECY
      JP :FFwait_for_buffer_1

:FF_finish
      INCY
      LD	A Y
      LD	DATA_BUFFER0	; clear the page counter
      STATUS	STOP

:FFwait_for_buffer_1
;-----------------
      LD	A BUFFER_MNGT
      BSET4
      JP :FFwait_for_buffer_1

      LD	LSB 2
      LD	BUFFER_MNGT	; mark buffer1 full
      LD	LSB 0
      LD	BUFFER_MNGT	; mark buffer1 full

      JP :FFsend_2_pages

⌨️ 快捷键说明

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