Code:
	; CF-Register addresses
.equ Data_Reg = &H00
.equ Error_Reg = &H01
.equ Feature_Reg = &H01
.equ Sec_Cnt_Reg = &H02
.equ Sec_Num_Reg = &H03
.equ Cyl_Lo_Reg = &H04
.equ Cyl_Hi_Reg = &H05
.equ Head_Reg = &H06
.equ Status_Reg = &H07
.equ Command_Reg = &H07
; Commands for Compact Flash Card
.equ CF_Identify = &HEC
.equ CF_Write_Sec = &H30
.equ CF_Read_Sec = &H20
;------------------------------------------------------------------------------
[_DriveGetIdentity]
$EXTERNAL _CF_Write_Reg
; Read Identity Info from the CF-Card
_DriveGetIdentity:
   ldi r21, 1         ; 512 Bytes = 1 Sector to read
   ldi r23, CF_Identify         ; Command for Card identity
   rcall _CF_Write_CommandReg       ; send to card
   rjmp _CF_Read_Sector_LBASet      ; Read Info to SRAM (mit return)
[End]
[_CF_Check_Ready]
; Pin CF_Rdy is Low at Ready
_CF_Check_Ready:
 * sbis CF_Control_In , CF_Rdy ; no timeout check
   rjmp _CF_Check_Ready
   Ret
[END]
[_CF_Write]
$EXTERNAL _CF_Check_Ready
; 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
   ; Pulse is for Crystal 16 MHz, Approximitly 1 NOP for 2 MHz
   ; and can be reduced for slower CPU
   nop
   nop
   nop
 * #IF _XTAL > 6000000
   nop
   nop
   nop
 * #ENDIF
 * #IF _XTAL > 12000000
   nop
   nop
 * #ENDIF
 * sbi CF_Control_Out , CF_WE ; WE Line to High
   ret
[END]
[_CF_Read]
$EXTERNAL _CF_Check_Ready
; 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
 * #IF _XTAL > 6000000
   nop
   nop
   nop
 * #ENDIF
 * #IF _XTAL > 12000000
   nop
   nop
 * #ENDIF
 * in r23 , 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
[END]
[_CF_Set_RegAddr]
; Set register address, and leave pins 3 - 7 unchanged
; two entry-points to routine
; 1: CF_Set_RegAddr: Register address must passed in r22
; 2: CF_Set_RegAddr23: register address is Data
_CF_Set_RegAddr23:
   ldi r22, 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, r22            ; add CF-Address with OR
 * out CF_Addr_Out , _temp1
   ret
[End]
[_DriveReadSector]
$EXTERNAL _CF_Set_CntLBA , _CF_Write_Reg , _CF_Read
; Read Sector(s) from CF-Card to SRAM
; Entry with following parameters set:
; Register r21: Count of Sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, where the data to transfer
_DriveReadSector:
   ldi r21, 1         ; fixed to 1 sector to read
   rcall _CF_Set_CntLBA          ; LBA-Sector to CF
   ldi r23, CF_Read_Sec         ; read command
   rcall _CF_Write_CommandReg       ; to Compactflash
_CF_Read_Sector_LBASet:
   rcall _CF_Set_RegAddr23       ; turn register-address to data
   clr r20            ; Low-Byte of Byte-Count always zero
   lsl r21           ; Change Sector-Count to HighByte of Transferlenght
_CF_Read_Sector1:
   rcall _CF_Read              ; read 1 Byte
   st z+, r23
   dec r20
   brne  _CF_READ_SECTOR1
   dec r21
   brne  _CF_READ_SECTOR1         ; all bytes read?
   clr r25                          ; set default no error
   clc
   Ret
[END]
[_DriveWriteSector]
$EXTERNAL _CF_Set_CntLBA , _CF_Write_Reg
; write Sector(s) to CF-Card
; Entry with following parameter set:
; Register r21: Count of sector(s) to transfer
; Register X: Pointer to Sectornumber (LONG)
; Register Z: SRAM-Address, at which Data to transfer starts
_DriveWriteSector:
   ldi r21, 1         ; fixed to 1 sector to write
   rcall _CF_Set_CntLBA          ; LBA-Sector to CF
   ldi r23, CF_Write_Sec         ; write command
   rcall _CF_Write_CommandReg       ; to compactflash
_CF_Write_Sector_LBASet:
   rcall _CF_Set_RegAddr23       ; turn register-address to data
   clr r20            ; Low-Byte of Byte-Count alwas zero
   lsl r21           ; Change Sector-Count to HighByte of Transferlenght
_CF_Write_Sector1:
   ld r23, z+
 * out CF_Data_out , r23 ; Byte to data port
   rcall _CF_Write             ; force CF to read byte
   dec r20
   brne  _CF_Write_SECTOR1
   dec r21
   brne  _CF_Write_SECTOR1         ; last byte written?
   clr r25                           ; set default no error
   clc
   Ret
[END]
[_CF_Write_Reg]
$EXTERNAL _CF_Set_RegAddr , _CF_Write
;------------------------------------------------------------------------------
; write a value to a specified register address, value is passed in r23
; two different entry points
; 1: CF_Write_CommandReg: write value to command-register (default)
; 2: CF_Write_Reg: Register passed in r22
_CF_Write_CommandReg:
   ldi r22, Command_Reg        ; Default register: Command
_CF_Write_Reg:
 * out CF_Data_out , r23 ; set data to data port
   rcall _CF_Set_RegAddr         ; set register address
   rjmp _CF_Write              ; force CF to accept register and data
[End]
[_CF_Set_CntLBA]
$EXTERNAL _CF_Write_Reg
; 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 r22, Sec_Cnt_Reg        ; Start with Sector-Count Register in CF (2)
   mov r23, r21       ; prepare for output
   rjmp _CF_Set_LBA2
_CF_Set_LBA1:
   ld r23, X+               ; load next byte of sectornumber
_CF_Set_LBA2:
   rcall _CF_Write_Reg           ; set register-address
   inc r22               ; set to next register address
   cpi r22, 6
   brmi  _CF_Set_LBA1            ; Reg. 6 reached? (LBA/Disk/Header)
   ld r23, X+               ; need special handling
   andi r23, &B00001111         ; mask upper nibble (LBA-Sign and drive)
   ori r23, &HE0             ; set to LBA
   rjmp _CF_Write_Reg            ; write to CF; incl Ret
[END]
[_DriveInit]
$EXTERNAL _DriveReset
; Setup the pins needed for the CF-Card
_DriveInit:
   ; 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
*BASIC:WAITMS 1
;   ldi r24, 1
;   clr r25
;   call _Waitms ; 1 ms delay
   rjmp _DriveReset
[End]
[_DriveReset]
;------------------------------------------------------------------------------
; force CF-Card to a Hardware-reset
_DriveReset:
 * sbi CF_Control_Out , CF_Reset
   ; waitms 1
   ldi r24, 1
   clr r25
   call _waitms ; 1 ms delay
 * cbi CF_Control_Out , CF_Reset
   ;  waitms 500
   clr r24
   ldi r25, 2
   call _waitms ; 512 ms delay
   clr r25                      ; set default no error
   clc
   ret
[End]
[_DriveCheck]
;------------------------------------------------------------------------------
; Checks, whether Card is plugged in: Pin CD1 is LOW
; if OK r24 = 1; otherwise 0
_DriveCheck:
   clr r25
   clc
 * sbis CF_Control_In , CF_CD1 ; flashcard plugged in
   ret
 * ldi r25 , cpErrDriveNotPresent
   sec
   ret
[END]
 
						
Lesezeichen