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

📄 flashcarddrive.bas

📁 用ATMEL AVR CPU开发CF CARD的程式.在BASCOM环境
💻 BAS
字号:
' This files contains the Routines


Declare Sub ReadSector(pwSRAMPointer as Word , plSectorNumber as Long , byVal pbSectorCount as Byte)
Declare Sub WriteSector(pwSRAMPointer as Word , plSectorNumber as Long , byVal pbSectorCount as Byte)
Declare Sub GetDriveIdentity(pwSRAMPointer as Word )
Declare Sub DriveInit()
Declare Sub DriveReset()
Declare Function DriveCheck() as Byte


' Register - definitions for ASM-Routines

rByteCount_Low alias r20
rByteCount_High alias r21
rCF_SectorCount alias r21
rCF_Reg alias r22
rData alias r23

nop
nop

Sub ReadSector(pwSRAMPointer as Word , plSectorNumber as Long , byVal pbSectorCount as Byte)
    ' Read Sector(s) from CF-Card to SRAM
    ' pwSRAMPointer: (Word) Variable which holds the address of SRAM to transfer Sector(s) from Card
    ' plSectorNumber: (Long) CF-Startingsector from which data should be transfered
    ' pbSectorCount: (Byte) Count of 512-Byte Sector(s) to transfer (largest Value = &H7F)
    loadadr pbSectorCount , X
    ld rCF_SectorCount, X
    loadadr pwSRAMPointer , X
    ld zl, X+
    ld zh, X+
    loadadr plSectorNumber , X
    !call _CF_Read_Sector
End Sub



Sub WriteSector(pwSRAMPointer as Word , plSectorNumber as Long , byVal pbSectorCount as Byte)
    ' Write Sector(s) from CF-Card to SRAM Byte
    ' pwSRAMPointer: (Word) Variable which holds the address of SRAM to transfer Sector(s) from Card
    ' plSectorNumber: (Long) CF-Startingsector from which data should be transfered
    ' pbSectorCount: (Byte) Count of 512-Byte Sector(s) to transfer (largest Value = &H7F)
    loadadr pbSectorCount , X
    ld rCF_SectorCount, X
    loadadr pwSRAMPointer , X
    ld zl, x+
    ld zh, x+
    loadadr plSectorNumber , X
    !call _CF_Write_Sector
End Sub



Sub GetDriveIdentity(pwSRAMPointer as Word )
    ' Read the Identity Drive from CF-Card to SRAM Byte
    ' pwSRAMPointer: (Word) Variable which holds the address of SRAM to transfer Sector(s) from Card
    ' 512 Bytes will be written
    loadadr pwSRAMPointer , X
    ld zl, x+
    ld zh, x+
    !call _CF_Read_DriveIdentity
End Sub



Sub DRIVEINIT()
    ' Setup Pins to CF-Card for Input/Output and reset CF-Card
    !Call _CF_Setup
End Sub



Sub DRIVERESET()
    ' Reset CF-Card
    !Call _CF_Reset
End Sub



Function DriveCheck() as Byte
    ' Check, if drive is ready (plugged in)
    !Call _CF_CheckCard
    loadadr DriveCheck , X
    st x, r24
End Function

nop


' =============================================================================
' ASM - Routines
' -----------------------------------------------------------------------------

' Hardware Definitions
' Port und Pin - Definitionen

' Data Port
CF_Data_Out alias PortA
CF_Data_In alias PinA
CF_Data_DDR alias DDRA

' Register - addressing
CF_ADDR_Out alias PortC
' CF_Addr_in alias PinC                ' Port C nur Output
' CF_Addr_DDR alias DDRC
' remove Comment-mark ' if bidirectional Port is used

' Control - Port
CF_Control_Out alias PortB
CF_Control_In alias PinB
CF_Control_DDR alias DDRB

' Pins at Control-Port
CF_CE1 alias 0                          ' Card enable
CF_CD1 alias 1                          ' Card detect
CF_RESET alias 2                        ' Reset-Pin
CF_OE alias 3                           ' Output enable
CF_WE alias 4                           ' Write enable
CF_RDY alias 5                          ' Card ready

' Input: CF_CD1, CF_RDY: Input
Const CF_Control_Direction = &B00011101 ' I/O Richtungen am Control-Port

Const CF_Control_Init = &B00011000      ' Setup-Ausgabe  f黵 Control-Port
Const CF_Control_Dir_Mask = &B11000000  'Maske f黵 belegte Pin's am Controlport

' CF-Card Register
' addresses uses 3 LSB Bit x x x x x A2 A1 A0

' Register addresses
Const Data_Reg = &H00
Const Error_Reg = &H01
Const Feature_Reg = &H01
Const Sec_Cnt_Reg = &H02
Const Sec_Num_Reg = &H03
Const Cyl_Lo_Reg = &H04
Const Cyl_Hi_Reg = &H05
Const Head_Reg = &H06
Const Status_Reg = &H07
Const Command_Reg = &H07

' Commands for Compact Flash Card

Const CF_Identify = &HEC
Const CF_Write_Sec = &H30
Const CF_Read_Sec = &H20

'------------------------------------------------------------------------------
' Read Identity Info from the CF-Card
_CF_Read_DriveIdentity:
   ldi rCF_SectorCount, 1               ' 512 Bytes = 1 Sector to read
   ldi rData, CF_Identify               ' Command for Card identity
   rcall _CF_Write_CommandReg           ' send to card
   rjmp _CF_Read_Sector_LBASet          ' Read Info to SRAM (mit return)


'------------------------------------------------------------------------------
' Pin CF_Rdy is Low at Ready
_CF_Check_Ready:
   sbis CF_Control_In, CF_Rdy           ' no timeout!!!
   rjmp _CF_Check_Ready
   Ret

'------------------------------------------------------------------------------
' give a pulse to WE to force Compactflash Card to read Data
' Registeraddress (A0-A2) and Data (D0-D7) must be set
_CF_Write:
   rcall _CF_Check_ready
   cbi CF_Control_Out, CF_WE            ' WE Line to Low
   nop                                  ' 600 ns at 3.3 V VCC is enough
   nop
   sbi CF_Control_Out, CF_WE            ' WE Line to High
   ret

'------------------------------------------------------------------------------
' Read 1 Byte from the CF
' Register address must be set.
_CF_Read:
   rcall _CF_Check_Ready
   ldi _temp1, &H00                     ' change data-port to Input
   !out Cf_Data_DDR , _temp1
   cbi CF_Control_out, CF_OE            ' OE Line to Low
   nop
   nop
   nop
   in rData,CF_Data_in                  ' Read Byte
   sbi CF_Control_Out, CF_OE            ' OE - Line to High
   ldi _temp1, &HFF                     ' change Data-port back to OUTPUT
   !out CF_Data_DDR, _temp1
   ret

'------------------------------------------------------------------------------
' Set register address, and leave pins 3 - 7 unchanged
' two entry-points to routine
' 1: CF_Set_RegAddr: Register address must passed in rCF_Reg
' 2: CF_Set_RegAddrData: register address is Data
_CF_Set_RegAddrData:
   ldi rCF_Reg, Data_Reg
_CF_Set_RegAddr:
   in _temp1, CF_Addr_Out               ' get current output at Port
   andi _temp1, &B11111000              ' CF-Address-bits masked out
   or _temp1, rCF_Reg                   ' add CF-Address with OR
   !out CF_Addr_Out, _temp1
   ret


' -----------------------------------------------------------------------------
' Read Sector(s) from CF-Card to SRAM
' Entry with following parameters set:
' Register rCF_SectorCount: Count of Sector(s) to transfer
' Register X: Pointer to Sectornumber (LONG)
' Register Z: SRAM-Address, where the data to transfer
_CF_Read_Sector:
   rcall _CF_Set_CntLBA                 ' LBA-Sector to CF
   ldi rData, CF_Read_Sec               ' read command
   rcall _CF_Write_CommandReg           ' to Compactflash
_CF_Read_Sector_LBASet:
   rcall _CF_Set_RegAddrData            ' turn register-address to data
   clr rByteCount_Low                   ' Low-Byte of Byte-Count always zero
   lsl rByteCount_High                  ' Change Sector-Count to HighByte of Transferlenght
_CF_Read_Sector1:
   rcall _CF_Read                       ' read 1 Byte
   st z+, rData
   dec rByteCount_Low
   brne  _CF_READ_SECTOR1
   dec rByteCount_High
   brne  _CF_READ_SECTOR1               ' all bytes read?
   Ret


' -----------------------------------------------------------------------------
' write Sector(s) to CF-Card
' Entry with following parameter set:
' Register rCF_SectorCount: Count of sector(s) to transfer
' Register X: Pointer to Sectornumber (LONG)
' Register Z: SRAM-Address, at which Data to transfer starts
_CF_Write_Sector:
   rcall _CF_Set_CntLBA                 ' LBA-Sector to CF
   ldi rData, CF_Write_Sec              ' write command
   rcall _CF_Write_CommandReg           ' to compactflash
_CF_Write_Sector_LBASet:
   rcall _CF_Set_RegAddrData            ' turn register-address to data
   clr rByteCount_Low                   ' Low-Byte of Byte-Count alwas zero
   lsl rByteCount_High                  ' Change Sector-Count to HighByte of Transferlenght
_CF_Write_Sector1:
   ld rData, z+
   !out CF_Data_out, rData              ' Byte to data port
   rcall _CF_Write                      ' force CF to read byte
   dec rByteCount_low
   brne  _CF_Write_SECTOR1
   dec rByteCount_High
   brne  _CF_Write_SECTOR1              ' last byte written?
   Ret

'------------------------------------------------------------------------------
' write a value to a specified register address, value is passed in rData
' two different entry points
' 1: CF_Write_CommandReg: write value to command-register (default)
' 2: CF_Write_Reg: Register passed in rCF_Reg
_CF_Write_CommandReg:
   ldi rCF_Reg, Command_Reg             ' Default register: Command
_CF_Write_Reg:
   !out CF_Data_out, rData              ' set data to data port
   rcall _CF_Set_RegAddr                ' set register address
   rjmp _CF_Write                       ' force CF to accept register and data

' -----------------------------------------------------------------------------
' Write count of sector(s) (read or write) and Sectornumber (LBA) to CF-Card
' following parameter must be set:
' Register CF_SectorCount: Count of Sector(s) (max &7F)
' Register X: Pointer to sectornumber
'
_CF_Set_CntLBA:
   ldi rCF_Reg, Sec_Cnt_Reg             ' Start with Sector-Count Register in CF (2)
   mov rData, rCF_SectorCount           ' prepare for output
   rjmp _CF_Set_LBA2
_CF_Set_LBA1:
   ld rData, X+                         ' load next byte of sectornumber
_CF_Set_LBA2:
   rcall _CF_Write_Reg                  ' set register-address
   inc rCF_Reg                          ' set to next register address
   cpi rCF_Reg, 6
   brmi  _CF_Set_LBA1                   ' Reg. 6 reached? (LBA/Disk/Header)
   ld rData, X+                         ' need special handling
   andi rData, &B00001111               ' mask upper nibble (LBA-Sign and drive)
   ori rData, &HE0                      ' set to LBA
   rjmp _CF_Write_Reg                   ' write to CF; incl Ret

' -----------------------------------------------------------------------------
' Setup the pins needed for the CF-Card
_CF_Setup:
   ' Data port to OUTPUT
   ldi _temp1, &H00                     ' all Data pins to low
   !out CF_Data_Out, _temp1

   ldi _temp1, &HFF
   !Out CF_Data_DDR , _temp1            ' Data pins to output

   ' Controlport: prepare 6 pins, leave other two unchanged
   in _temp1, CF_Control_Out            '
   andi _temp1, CF_Control_Dir_Mask     '
   ori _temp1, CF_Control_Init
   !Out CF_Control_Out, _temp1

   in _temp1, CF_Control_DDR            ' read direction of pins at control port
   andi _temp1, CF_Control_Dir_Mask     ' mask out used pins
   ori _temp1, CF_Control_Direction     ' set direction in and Out
   !Out CF_Control_DDR, _temp1          ' set new direction configuration

   ' Address port: attention: adjust if not on Port C at ATMega103
   ' ATMega103 Port C have only output, so here no configuration is necessary
   'in _temp1, CF_ADDR_DDR
   'ori _temp1, &B00000111
   '!Out CF_Addr_DDR, _temp1
   waitms 1
   rjmp _CF_Reset

'------------------------------------------------------------------------------
' force CF-Card to a Hardware-reset
_CF_Reset:
   sbi CF_Control_Out, CF_Reset
   waitms 1
   cbi CF_Control_Out, CF_Reset
   waitms 500
   ret

'------------------------------------------------------------------------------
' Checks, whether Card is plugged in: Pin CD1 is LOW
' if OK r24 = 1; otherwise 0
_CF_CheckCard:
   ldi r24, 1
   sbic CF_Control_In, CF_CD1           ' flashcard plugged in?
   ldi r24, 0
   ret

nop
nop
nop   

⌨️ 快捷键说明

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