📄 sfcon.src
字号:
;*************************************************************************
;* Copyright (C) 2002, HITACHI LTD. All Rights Reserved
;*
;* FILE NAME : SFCon.asm
;* DATE CREATED : Apr 2002
;*
;* DESCRIPTION : low level driver for Samsung K95608 series flash memory
;*
;* Remark : flash memory is accessed by bus controller + I/O
;*
;**************************************************************************
.CPU 2000A
;**** Export functions
.EXPORT _fread_id ; read product ID
.EXPORT _fread_status ; read device status
.EXPORT _freset ; write reset command
.EXPORT _ferase_blk ; erase 1 blk (2048 + 64)
.EXPORT _ferase_blk_nowait ; erase 1 blk (2048 + 64) no status return
.EXPORT _fread_data ; read data with length and page location
.EXPORT _fwrite_data ; write data with length and page location
.EXPORT _fread_sector ; read sector/block data
.EXPORT _fwrite_sector ; write sector/block data
.EXPORT _fcopy_back ; copy a page to another page
.EXPORT _fread_sector_no_ecc
;**** Import variables
.IMPORT _flash_rw ; flash read/write parameters
;.IMPORT _asm_genEccS ; ECC generation
;***************************************************************************
; Flash Memory I/O Definiation
;***************************************************************************
;
;**** I/O port register
porte .EQU H'FFFFB0 ; port E0 and E1 for flash memory select
portbdr .EQU H'FFFF0A ; portB data register
pgddr .EQU H'FFFE3F ; port G data direction register
CS1_BUS .EQU H'ff ; CS1 control by bus controller
CS1_IO .EQU H'f7 ; CS1 is input (external pull low)
cle_h .EQU B'01000000
cle_l .EQU B'00000000
ale_h .EQU B'10000000
ale_l .EQU B'00000000
f_io_ce0 .EQU 0
f_io_ce1 .EQU 1
f_io_busy .EQU 7
;**** Flash momory Command code
fcmd_read10 .EQU H'00
fcmd_read11 .EQU H'01
fcmd_read2 .EQU H'50
fcmd_read_id .EQU H'90
fcmd_read_status .EQU H'70
fcmd_wr1 .EQU H'80
fcmd_wr2 .EQU H'10
fcmd_cpback1 .EQU H'00
fcmd_cpback2 .EQU H'8A
fcmd_erase_blk .EQU H'60
fcmd_erase_blk1 .EQU H'D0
fcmd_reset .EQU H'FF
error .EQU 1
;**** Flash momory Addressing
addr_fcmd .EQU H'207FFF
addr_faddr .EQU H'208000
addr_fdata .EQU H'200000
;***************************************************************************
; Program
;***************************************************************************
.SECTION P,CODE,ALIGN=2
;********************************************************
;** Read Product ID
;********************************************************
;** - return maker and device code (R0)
;********************************************************
_fread_id:
;*** write command
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_read_id,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'90 (read cmd) to flash memory
MOV.B #ale_h,R0H
MOV.B R0H,@portbdr
MOV.B #H'0,R0L
MOV.B R0L,@ER1 ; write H'00 (addr 00)
MOV.B #ale_l,R0H
MOV.B R0H,@portbdr
MOV.L #addr_fdata,ER1 ; data address
MOV.B @ER1,R0H ; store Maker Code
MOV.B @ER1,R0L ; store device Code
RTS
;********************************************************
;** Read Device Status
;********************************************************
;** - return device status (R0L)
;********************************************************
_fread_status:
;*** write command
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_read_status,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'70 (read cmd) to flash memory
MOV.B #cle_l,R0H
MOV.B R0H,@portbdr
MOV.L #addr_fdata,ER1 ; data address
MOV.B @ER1,R0L ; store status
RTS
;********************************************************
;** Send Reset Command
;********************************************************
_freset:
;*** write command
MOV.L #addr_fcmd,ER1 ; cmd address 207fff
MOV.B #fcmd_reset,R0L; fcmd_reset 0xff
MOV.B #cle_h,R0H;cle_h high
MOV.B R0H,@portbdr; portb
MOV.B R0L,@ER1 ; write H'FF (reset cmd) to flash memory
MOV.B #cle_l,R0H
MOV.B R0H,@portbdr
NOP
NOP
reset_busy_wait:
BLD #f_io_busy,@porte
NOP
BCC reset_busy_wait
RTS
;****************************************************
;** BLOCK ERASE (16K + 512 bytes)
;****************************************************
;** - R0 is Block address
;** - return status register (R0L)
;****************************************************
_ferase_blk:
;*** write command
MOV.W R0,E0
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_erase_blk,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'60 (erase blk cmd) to flash memory
MOV.B #ale_h,R0H
MOV.B R0H,@portbdr
MOV.W E0,R0
MOV.B R0L,@ER1 ; block address
MOV.B R0H,@ER1
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_erase_blk1,R0L
MOV.B R0L,@ER1 ; write H'D0 (erase blk1 cmd) to flash memory
MOV.B #cle_l,R0H
MOV.B R0H,@portbdr
NOP
NOP
erase_busy_wait: ; busy wait
BLD #f_io_busy,@porte
NOP
BCC erase_busy_wait
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B #fcmd_read_status,R0L
MOV.B R0L,@ER1 ; read status
MOV.B #cle_l,R0H
MOV.B R0H,@portbdr
NOP
MOV.B @ER1,R0L ; store status in R0L
AND.B #H'01,R0L ; Mask out unwanted bit, non-zero error
RTS
;*** no wait busy
_ferase_blk_nowait:
;*** write command
MOV.W R0,E0
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_erase_blk,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'60 (erase blk cmd) to flash memory
MOV.B #ale_h,R0H
MOV.B R0H,@portbdr
MOV.W E0,R0
MOV.B R0L,@ER1 ; block address
MOV.B R0H,@ER1
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_erase_blk1,R0L
MOV.B R0L,@ER1 ; write H'D0 (erase blk1 cmd) to flash memory
MOV.B #cle_l,R0H
MOV.B R0H,@portbdr
RTS
;****************************************************
;** READ data with length and page location
;****************************************************
;** - R0 location
;****************************************************
_fread_data:
PUSH.L ER2
MOV.W R0,E1 ; location is E1
fread_data_wait0:
MOV.B @porte,R1L
BPL fread_data_wait0
;*** write command
MOV.B #fcmd_read10,R1L
CMP.W #255,E1
BLS write_cmd
MOV.B #fcmd_read11,R1L
SUB.W #256,E1
CMP.W #255,E1
BLS write_cmd
MOV.B #fcmd_read2,R1L
SUB.W #256,E1
write_cmd:
MOV.B #cle_h,R1H
MOV.B R1H,@portbdr
MOV.L #addr_fcmd,ER0 ; cmd address
MOV.B R1L,@ER0 ; write H'50 (read2 cmd) to flash memory
MOV.B #ale_h,R1H
MOV.B R1H,@portbdr
MOV.W E1,R1 ; already sub., alway <256
MOV.B R1L,@ER0 ; write location
MOV.W @_flash_rw+2,R1
MOV.B R1L,@ER0 ; write page address
MOV.B R1H,@ER0 ; write page address
MOV.B #ale_l,R0H
MOV.B R0H,@portbdr
;**** perpare Read data from Flash memory to buffer
MOV.L #addr_fdata,ER0 ; Source buffer
MOV.L @_flash_rw+6,ER1 ; Target buffer
MOV.W @_flash_rw+4,E2 ; Number of byte
;**** wait busy signal
fread_spare_wait1:
MOV.B @porte,R2L
BPL fread_spare_wait1
;**** perform data read
fread_spare_loop:
MOV.B @ER0,R2L
MOV.B R2L,@ER1
INC.L #1,ER1
DEC.W #1,E2
BNE fread_spare_loop
POP.L ER2
RTS
;********************************************************
;** READ SECTOR NO ECC CODE
;********************************************************
;** - read information stored in struct "_flash_rw"
;** - Fixed transfer 512 bytes
;** -
;********************************************************
;** - read_sector (512 + 16 = 528 bytes OR by length)
;** - flash_rw stored information to read
;********************************************************
;** flash_rw 0~3 - sector address
;** flash_rw 4~5 - length (max. 65536 bytes)
;** flash_rw 6~9 - target buffer location
;********************************************************
_fread_sector_no_ecc:
fread_sector_wait0_no_ecc:
BLD #f_io_busy,@porte
BCC fread_sector_wait0_no_ecc
PUSH.W R2 ; push register R2
;*** write command
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_read10,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'00 (read cmd) to flash memory
MOV.B #ale_h,R0H
MOV.B R0H,@portbdr
MOV.B #0,R0L ; lower address
MOV.B R0L,@ER1
MOV.W @_flash_rw+2:16,R0 ; upper 16bit address
MOV.B R0L,@ER1
MOV.B R0H,@ER1
MOV.B #ale_l,R0H
MOV.B R0H,@portbdr
;**** perpare Read data from Flash memory to buffer
MOV.W @_flash_rw+4,R2 ; get length
MOV.L #addr_fdata,ER0 ; Source buffer
MOV.L @_flash_rw+6,ER1 ; Target buffer
;**** wait busy signal and perform data read
JSR @DMA_read ; including wait loop & read 512 bytes only
POP.W R2
RTS
;********************************************************
;** READ SECTOR
;********************************************************
;** - read information stored in struct "_flash_rw"
;** - cannot more than 2048 bytes
;** - length must in module of 512
;********************************************************
;** - read_sector (512 + 16 = 528 bytes OR by length)
;** - flash_rw stored information to read
;********************************************************
;** flash_rw 0~3 - sector address
;** flash_rw 4~5 - length (max. 65536 bytes)
;** flash_rw 6~9 - target buffer location
;** flash_rw 10~13 - ECC buffer location
;********************************************************
_fread_sector:
fread_sector_wait0:
BLD #f_io_busy,@porte
BCC fread_sector_wait0
PUSH.W R2 ; push register R2
;*** write command
MOV.L #addr_fcmd,ER1 ; cmd address
MOV.B #fcmd_read10,R0L
MOV.B #cle_h,R0H
MOV.B R0H,@portbdr
MOV.B R0L,@ER1 ; write H'00 (read cmd) to flash memory
MOV.B #ale_h,R0H
MOV.B R0H,@portbdr
MOV.B #0,R0L ; lower address
MOV.B R0L,@ER1
MOV.W @_flash_rw+2:16,R0 ; upper 16bit address
MOV.B R0L,@ER1
MOV.B R0H,@ER1
MOV.B #ale_l,R0H
MOV.B R0H,@portbdr
;**** perpare Read data from Flash memory to buffer
MOV.W @_flash_rw+4,R2 ; get length
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -