;********
;
; File Name :'cf.asm"
; Title :Compact Flash Common Memory Mode Driver
; Date :2004.05.12.
; Version :1.0.0
; Support telephone :+36-70-333-4034, old: +36-30-9541-658 VFX
; Support fax :
; Support Email :info@vfx.hu
; Target MCU :AVR
;
;*******
; D E S C R I P T I O N
;
; Memory Interface to a compact flash card.
; Compact flash card is used in memory mapped mode.
; Registers are located at ADR_CFC in external RAM space of Mega128
;
;
;*************
; M O D I F I C A T I O N H I S T O R Y
;
;
; rev. date who why
; ---- ---------- --- ------------------------------------
; 0.01 2004.05.12 VFX Creation
;
;************
;Hardware
;***********
;*
;* SYSCLK: f=16.000 MHz (T= 62.5 ns)
;*
;*************
;
;
;************
;* Hardware Def.
;
; CompactFlash hardware definitions
; Table 34: Memory Mapped Decoding
; -REG A10 A9-A4 A3 A2 A1 A0 Offset -OE=0 -WE=0 Notes
; 1 0 X 0 0 0 0 0 Even RD Data Even WR Data 1, 2
; 1 0 X 0 0 0 1 1 Error Features 1, 2
; 1 0 X 0 0 1 0 2 Sector Count Sector Count
; 1 0 X 0 0 1 1 3 Sector No. Sector No.
; 1 0 X 0 1 0 0 4 Cylinder Low Cylinder Low
; 1 0 X 0 1 0 1 5 Cylinder High Cylinder High
; 1 0 X 0 1 1 0 6 Select Card/Head Select Card/Head
; 1 0 X 0 1 1 1 7 Status Command
; 1 0 X 1 0 0 0 8 Dup. Even RD Data Dup. Even WR Data 2
; 1 0 X 1 0 0 1 9 Dup. Odd RD Data Dup. Odd WR Data 2
; 1 0 X 1 1 0 1 D Dup. Error Dup. Features 2
; 1 0 X 1 1 1 0 E Alt Status Device Ctl
; 1 0 X 1 1 1 1 F Drive Address Reserved
; 1 1 X X X X 0 8 Even RD Data Even WR Data 3
; 1 1 X X X X 1 9 Odd RD Data Odd WR Data 3
;Note: 1) Register 0 is accessed with -CE1 low and -CE2 low as a word register
;on the combined Odd Data Bus and Even Data Bus (D15-D0). This register may
;also be accessed by a pair of byte accesses to the offset 0 with -CE1 low and
;-CE2 high. Note that the address space of this word register overlaps
;the address space of the Error and Feature byte-wide registers that lie at
;offset 1. When accessed twice as byte register with -CE1 low, the first byte
;to be accessed is the even byte of the word and the second byte accessed
;is the odd byte of the equivalent word access.
;A byte access to address 0 with -CE1 high and -CE2 low accesses the error
;(read) or feature (write) register.
;2) Registers at offset 8, 9 and D are non-overlapping duplicates of the
;registers at offset 0 and 1. Register 8 is equivalent to register 0,
;while register 9 accesses the odd byte. Therefore, if the registers are byte
;accessed in the order 9 then 8 the data will be transferred odd byte then even
;byte. Repeated byte accesses to register 8 or 0 will access consecutive
;(even then odd) bytes from the data buffer. Repeated word accesses to register
;8, 9 or 0 will access consecutive words from the data buffer. Repeated byte
;accesses to register 9 are not supported. However, repeated alternating byte
;accesses to registers 8 then 9 will access consecutive (even then odd) bytes
;from the data buffer. Byte accesses to register 9 access only the odd byte of
;the data.
;3) Accesses to even addresses between 400h and 7FFh access register 8.
;Accesses to odd addresses between 400h and 7FFh access register 9. This
;1 Kbyte memory window to the data register is provided so that hosts can
;perform memory to memory block moves to the data register when the register
;lies in memory space.
;
;
;CF register addresses
;
.equ CF_EvenData = ADR_CFC+0x08 ;Dupl. DAta
.equ CF_OddData = ADR_CFC+0x09 ;Dupl. Data
.equ CF_Error = ADR_CFC+0x0D ;Dupl. Errors / Features
.equ CF_SECCOUNT = ADR_CFC+0x02 ;Sectorcount
.equ CF_LBA0 = ADR_CFC+0x03 ;LBA 0-7
.equ CF_LBA1 = ADR_CFC+0x04 ;LBA 8-15
.equ CF_LBA2 = ADR_CFC+0x05 ;LBA 16-23
.equ CF_LBA3 = ADR_CFC+0x06 ;LBA 24-27
.equ CF_STACOM = ADR_CFC+0x07 ;Status / Command
.equ CF_DecCont = ADR_CFC+0x0E ;
;Class 1
;Upon receipt of a Class 1 command, the CompactFlash Storage Card sets BSY
;within 400 nsec.
;Class 2
;Upon receipt of a Class 2 command, the CompactFlash Storage Card sets BSY
;within 400 nsec, sets up the sector buffer for a write operation, sets DRQ
;within 700 usec, and clears BSY within 400 nsec of setting DRQ.
;Class 3
;Upon receipt of a Class 3 command, the CompactFlash Storage Card sets BSY
;within 400 nsec, sets up the sector buffer for a write operation, sets DRQ
;within 20 msec (assuming no re-assignments), and clears BSY within 400 nsec
;of setting DRQ.
;Table 37: CF-ATA Command Set
;
;Class COMMAND Code FR SC SN CY DH LBA
;1 Check Power Mode E5h or 98h - - - - D -
;1 Execute Drive Diagnostic 90h - - - - D -
;1 Erase Sector(s) C0h - Y Y Y Y Y
;1 Flush Cache E7h - - - - D -
;2 Format Track 50h - Y - Y Y Y
;1 Identify Drive ECh - - - - D -
;1 Idle E3h or 97h - Y - - D -
;1 Idle Immediate E1h or 95h - - - - D -
;1 Initialize Drive Parameters 91h - Y - - Y -
;1 Key Management Structure Read B9 Feature 0-127 C C C C D C -
;1 Key Management Read Keying Material B9 Feature 80 C C C C D C -
;2 Key Management Change Key Management Value B9 Feature 81 C C C C D C -
;1 NOP 00h - - - - D -
;1 Read Buffer E4h - - - - D -
;1 Read Long Sector 22h or 23h - - Y Y Y Y
;1 Read Multiple C4h - Y Y Y Y Y
;1 Read Sector(s) 20h or 21h - Y Y Y Y Y
;1 Read Verify Sector(s) 40h or 41h - Y Y Y Y Y
;1 Recalibrate 1Xh - - - - D -
;1 Request Sense 03h - - - - D -
;1 Security Disable Password F6h - - - - D -
;1 Security Erase Prepare F3h - - - - D -
;1 Security Erase Unit F4h - - - - D -
;1 Security Freeze Lock F5h - - - - D -
;1 Security Set Password F1h - - - - D -
;1 Security Unlock F2h - - - - D -
;1 Seek 7Xh - - Y Y Y Y
;1 Set Features EFh Y - - - D -
;1 Set Multiple Mode C6h - Y - - D -
;1 Set Sleep Mode E6h or 99h - - - - D -
;1 Standby E2h or 96h - - - - D -
;1 Standby Immediate E0h or 94h - - - - D -
;1 Translate Sector 87h - Y Y Y Y Y
;1 Wear Level F5h - - - - Y -
;2 Write Buffer E8h - - - - D -
;2 Write Long Sector 32h or 33h - - Y Y Y Y
;3 Write Multiple C5h - Y Y Y Y Y
;3 Write Multiple w/o Erase CDh - Y Y Y Y Y
;2 Write Sector(s) 30h or 31h - Y Y Y Y Y
;2 Write Sector(s) w/o Erase 38h - Y Y Y Y Y
;3 Write Verify 3Ch - Y Y Y Y Y
;
;Definitions:
;FR = Features Register
;SC = Sector Count Register
;SN = Sector Number Register
;CY = Cylinder Registers
;DH = Card/Drive/Head Register
;LBA = Logical Block Address Mode Supported (see command descriptions for use).
;Y - The register contains a valid parameter for this command. For the Drive/Head Register Y
;means both the CompactFlash Storage Card and head parameters are used; D - only the
;CompactFlash Storage Card parameter is valid and not the head parameter; C - The register
;contains command specific data (see command descriptions for use).
;
;CF-ATA Command Set
.equ CF_CMD_READ_SEC = 0x20
.equ CF_CMD_WRITE_SEC = 0x30
.equ CF_CMD_IDENTIFY = 0xEC
.equ CFRDY = 2 ;bit 2 = 1 CF ready
.equ CFVS1 = 3 ;bit 3 = 0 CF in slot
;***************
;*** Definition of the status register bits
;***
;*** Bit7 Bit0
;*** BSY DRDY DWF DSC DRQ CORR IDX ERR
;*****************
.equ CFC_STATUS_BSY = 0x80 ;Busy flag
.equ CFC_STATUS_DRDY = 0x40 ;Drive ready
.equ CFC_STATUS_DWF = 0x20 ;Drive write fault
.equ CFC_STATUS_DSC = 0x10 ;Drive seek complete
.equ CFC_STATUS_DRQ = 0x08 ;Data request
.equ CFC_STATUS_CORR = 0x04 ;Corrected data
.equ CFC_STATUS_IDX = 0x02 ;Index
.equ CFC_STATUS_ERR = 0x01 ;Error
;
;****************
;**** VARIABLES
.DSEG
;************
.ESEG
;*************
;**** CODE SEG
;************
.CSEG
;*********
;CFRdy
;
; Wait until CF not busy
;
; Out: c= 0 no error
; 1 error
;
; Alt: R16,R17
;
CFHWRdy:
lds R16,ADR_CFST
bst R16,CFVS1 ;CF inserted?
brtc CFHWRdy0
rjmp CFDrvError
CFHWRdy0:
lds R16,ADR_CFST
bst R16,CFRDY ;CF ready?
brtc CFHWRdy
clc
ret
;**************
;CFWaitDRQ
;
; Wait until Data will available
;
; Out: c= 0 no error
; 1 error
;
; Alt: R16,R17
;
CFWaitDRQ:
rcall CFHWRdy
brcc CFWaitDRQ00
ret
CFWaitDRQ00:
lds R16,CF_STACOM
bst R16,0
brtc CFWaitDRQ0
CFWaitErr:
ldi R16,low(0xFFF0) ;Error in last command
ldi R17,high(0xFFF0) ;ide keresunk egy error kodot!!!
sec
ret
CFWaitDRQ0:
andi R16,0xF8
cpi R16,0x58
brne CFWaitDRQ
clc
ret
;***********
;CFWaitReady
;
; Wait until CF will ready
;
; Out: c= 0 no error
; 1 error
;
; Alt: R16,R17
;
CFWaitReady:
rcall CFHWRdy
brcc CFWaitRdy0
ret
CFWaitRdy0:
lds R16,CF_STACOM
bst R16,0
brts CFWaitErr
CFWaitReady01:
andi R16,0xF0
cpi R16,0x50
brne CFWaitReady
clc
ret
;**********
;CFReadSector
;
; In: R13:R12:R11:R10 - LBA sector number
; Page: Y - Pointer to Data Buffer [512 byte]
; Z - Phis. Drive Descriptor
;
; Out: c= 0 no error
; 1 error
;
CFReadSector:
ldd R0,Z+MaxSector+0
ldd R1,Z+MaxSector+1
ldd R2,Z+MaxSector+2
ldd R3,Z+MaxSector+3
cp R10,R0
cpc R11,R1
cpc R12,R2
cpc R13,R3
brcs CFReadSec00
ldi R16,low(ERROR_SECTOR_NOT_FOUND) ;Sector number too big
ldi R17,high(ERROR_SECTOR_NOT_FOUND)
sec
ret
CFReadSec00:
std Z+CurrentSector+0,R10
std Z+CurrentSector+1,R11
std Z+CurrentSector+2,R12
std Z+CurrentSector+3,R13
rcall CFWaitReady
brcc CFReadSec01
ret ;Error in last command
CFReadSec01:
ldi R16,1
sts CF_SECCOUNT,R16
nop
sts CF_LBA0,R10 ;D7..D0
nop
sts CF_LBA1,R11 ;D15..D8
nop
sts CF_LBA2,R12 ;D23..D16
ldi R16,0x0F
and R16,R13
ori R16,0xE0 ;set LBA mode
sts CF_LBA3,R16 ;D27..D24 + LBA mode + Drive0
ldi R16,CF_CMD_READ_SEC
sts CF_STACOM,R16 ;Set Read Sector Command
ldi XL,0
ldi XH,1 ;if X==0 -> X=256 word;
movw R0,YL ;save Y reg.
rcall CFWaitDrq
brcc CFReadSec02
ret ;Drive error
CFReadSec02:
lds R16,ADR_CFST
bst R16,CFVS1 ;CF inserted?
brts CFDrvError
bst R16,CFRDY ;CF ready?
brtc CFReadSec02
lds R16,CF_EvenData
st Y+,R16
lds R16,CF_OddData
st Y+,R16
sbiw XL,1
brne CFReadSec02
movw YL,R0 ;restore Y reg.
clc
ret
CFDrvError:
ldi R16,low(ERROR_BAD_UNIT)
ldi R17,high(ERROR_BAD_UNIT) ;Drive not present
sec
ret
;*********
;CFWriteSector
;
; In: R13:R12:R11:R10 - LBA sector number
; Page: Y - Pointer to Data Buffer [512 byte]
; Z - Phis. Drive Descriptor
;
; Out: c= 0 no error
; 1 error
;
CFWriteSector:
ldd R0,Z+MaxSector+0
ldd R1,Z+MaxSector+1
ldd R2,Z+MaxSector+2
ldd R3,Z+MaxSector+3
cp R10,R0
cpc R11,R1
cpc R12,R2
cpc R13,R3
brcs CFWriteSec00
ldi R16,low(ERROR_SECTOR_NOT_FOUND) ;Sector number too big
ldi R17,high(ERROR_SECTOR_NOT_FOUND)
sec
ret
CFWriteSec00:
rcall CFWaitReady
brcc CFWriteSec01
ret ;Error in last command
CFWriteSec01:
ldi R16,1
sts CF_SECCOUNT,R16
nop
sts CF_LBA0,R10 ;D7..D0
nop
sts CF_LBA1,R11 ;D15..D8
nop
sts CF_LBA2,R12 ;D23..D16
ldi R16,0x0F
and R16,R13
ori R16,0xE0 ;set LBA mode
sts CF_LBA3,R16 ;D27..D24 + LBA mode + Drive0
ldi R16,CF_CMD_WRITE_SEC
sts CF_STACOM,R16 ;Write sector command
ldi XL,0
ldi XH,1 ;if X==0 -> X=256 word;
movw R0,YL
rcall CFWaitDrq
brcc CFWriteSec02
ret ;Drive error
CFWriteSec02:
lds R16,ADR_CFST
bst R16,CFVS1 ;CF inserted?
brts CFDrvError
bst R16,CFRDY ;CF ready?
brtc CFWriteSec02
ld R16,Y+
sts CF_EvenData,R16
ld R16,Y+
sts CF_OddData,R16
sbiw XL,1
brne CFWriteSec02
movw YL,R0
clc
ret
;*************
;CFResetDevice
;
; In: -
;
; Out: c= 0 no error
; 1 error R17:R16 error code
;
CFResetDevice:
ldi R16,0b00000100 ;Force SW reset
sts ADR_CFC+0x0E,R16 ;Device Control Register
ldi R16,64
CFRes0: dec R17
brne CFRes0
dec R16
brne CFRes0
clr R16
sts ADR_CFC+0x0E,R16 ;Device Control Register
rcall CFWaitReady
ret
;********
;CFIdentify
;
; In: Z - Phis. Drive Descriptor
; Page: Y - Pointer to temporary Data Buffer [512 byte]
;
; Out: c= 0 no error
; 1 error
;
CFIdentify:
rcall CFWaitReady
brcc CFIdent01
ret ;Error code in R17:R16
CFIdent01:
ldi R16,1
sts CF_SECCOUNT,R16
clr R16
sts CF_LBA0,R16
nop
sts CF_LBA1,R16
nop
sts CF_LBA2,R16
ldi R16,0xE0
sts CF_LBA3,R16
ldi R16,CF_CMD_IDENTIFY
sts CF_STACOM,R16
ldi XL,0 ;read fixed 256 word
ldi XH,1
movw R0,YL
call CFWaitDRQ
brcc CFIdent02
ret ;Drive error
CFIdent02:
lds R16,CF_EvenData
st Y+,R16
nop
lds R16,CF_OddData
st Y+,R16
sbiw XL,1
brne CFIdent02
movw YL,R0
clr R0
ldd R16,Y+0 ;CF IDs: 848Ah
cpi R16,0x8A
brne CFIDs0
ldd R16,Y+1
cpi R16,0x84
brne CFIDs0
inc R0
CFIDs0:
std Z+MediaFlag,R0 ;Store CF ID
ldi R16,RemovableMedia
std Z+MediaType,R16
ldi R16,0x80
std Z+DiskNumber,R16 ;First HDD => HDD0
ldd R16,Y+2 ;Default tracks/cylinders
ldd R17,Y+3
std Z+Cylinders+0,R16
std Z+Cylinders+1,R17
ldd R16,Y+6 ;Default Heads
std Z+Heads,R16
ldd R16,Y+12 ;default Sectors per track
std Z+SectorsPerTrack,R16
ldd R16,Y+14 ;Number of Sectors per Card
std Z+MaxSector+2,R16 ;MSW -LSW !!!
ldd R16,Y+15
std Z+MaxSector+3,R16
ldd R16,Y+16
std Z+MaxSector+0,R16
ldd R16,Y+17
std Z+MaxSector+1,R16
clc
ret
|