AVR与CF卡(IDE)接口
2012-12-23
标签: AVR CF卡

;***************************************************************************

;

; 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 NH I S T O R Y

;

;

;rev.datewhowhy

; ---- -------------------------------------------------

; 0.01 2004.05.12VFXCreation

;

;***************************************************************************

;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=0Notes

;10X00000Even RD DataEven WR Data1, 2

;10X00011ErrorFeatures1, 2

;10X00102Sector CountSector Count

;10X00113Sector No.Sector No.

;10X01004Cylinder LowCylinder Low

;10X01015Cylinder HighCylinder High

;10X01106Select Card/HeadSelect Card/Head

;10X01117StatusCommand

;10X10008Dup. Even RD DataDup. Even WR Data2

;10X10019Dup. Odd RD DataDup. Odd WR Data2

;10X1101DDup. Error Dup.Features2

;10X1110EAlt StatusDevice Ctl

;10X1111FDrive AddressReserved

;11XXXX08Even RD DataEven WR Data3

;11XXXX19Odd RD DataOdd WR Data3

;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

;***

;*** Bit7Bit0

;*** BSYDRDYDWFDSCDRQCORRIDXERR

;***************************************************************************************

.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

brneCFIDs0

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

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号