| QUOTE |
| 198.95 ms for read a sector 206.79 ms for 3 ramdom sector take 00828822 instruction 60 cector sec/sec min 60 x .5k = 30kbit sec ramdom sector 120 sector sec/sec max 120 x 5k = 60kbit sec ramdom sector 714 consecutive sector read/sec 357kbit ses good for mp3 player :-) head seek betwen non consecutive sector sector 22,60ms mesure was taken from a seagate st946a (540mb) 2,5 laptop drive end avr cloked at 4,00 Mhz on a stk-200 board the code is not clock dependent rug good on 8mhz clock to just change value of timer1 for out of delay drive respond |
| CODE |
;***************************************************************************** ;* IDE DRIVER V1.1 * ;* * ;* * ;* * ;* Copyright(C) 1999-2000 ALPHATRONIC BY.MARC LALONDE * ;***************************************************************************** ; ------------->>>>> NOTE <<<<<------------- ; ;20/10/2000 15:50 bebug hardware interface (drive not respond to command ) ;20/10/2000 17:39 first working code (identify_device working ) ;27/10/2000 20:53 read/write sector working +adding drive command ;27/10/2000 22:41 work well on 2 quantum drive but fail on 2 segate ?? ; maby a bad timing ??im chek this now ;28/10/2000 16:35 corect a part of bug that afect segate drrive now the only ; bug on thers drive is a pinc,7 tha is alwlas 1 ?? ;29/10/2000 21:22 adding time out timer of 4 seconde if drive command crash ; ;***************************************************************************** ; ; AT90S8515Px ; SIGNAL_NAME ______ ______ SIGNAL_NAME ; . | - | . ; IDE DA0 --> (TO) PB0 --| 1 40 |-- VCC . ; IDE DA1 --> (T1) PB1 --| 2 39 |-- PA0 LCD 7 <-> IDE DD00 ; IDE DA2 --> (AIN0) PB2 --| 3 38 |-- PA1 LCD 8 <-> IDE DD01 ; IDE SC0- --> (AIN1) PB3 --| 4 37 |-- PA2 LCD 9 <-> IDE DD02 ; IDE SC1- --> (SS*) PB4 --| 5 36 |-- PA3 LCD 10 <-> IDE DD03 ; . <-- (MOSI) PB5 --| 6 35 |-- PA4 LCD 11 <-> IDE DD04 ; . --> (MISO) PB6 --| 7 34 |-- PA5 LCD 12 <-> IDE DD05 ; . <-- (SCK) PB7 --| 8 33 |-- PA6 LCD 13 <-> IDE DD06 ; . --> RESET* ->| 9 32 |-- PA7 LCD 14 <-> IDE DD07 ; . --> (RXD) PD0 --| 10 31 |-- ICP <-- . ; . <-- (TXD) PD1 --| 11 30 |-- ALE --> . ; IDE RD <-- (INT0) PD2 --| 12 29 |-- OC1B --> . ; IDE WD <-- (INT1) PD3 --| 13 28 |-- PC7 (A15) <-> IDE DD08 ; IDE RST <-- PD4 --| 14 27 |-- PC6 LCD 4 <-> IDE DD09 ; . <-- (OC1A) PD5 --| 15 26 |-- PC5 (A13) <-> IDE DD10 ; LCD 5 <-- (WR*) PD6 --| 16 25 |-- PC4 (A12) <-> IDE DD11 ; LCD 6 <-- (RD*) PD7 --| 17 24 |-- PC3 (A11) <-> IDE DD12 ; 4.0 Mhz --> XTAL1 ->| 18 23 |-- PC2 (A10) <-> IDE DD13 ; 4.0 Mhz <-- XTAL2 <-| 19 22 |-- PC1 (A9) <-> IDE DD14 ; GND --| 20 21 |-- PC0 (A8) <-> IDE DD15 ; |_____________| ; ; (DIP-40) ; ;LCD IS STK-200 STANDART PINOUT ; ;command suported end useing this label ; ;ata_rst hardware hard drive reset just call label ; ;ata_id perfor identify_device command just call label ; ;ata_idle put drive in idle state just call label ; ;ata_sleep put drive in sleep just call label ; ;lba_sel selection lba sector to do operation must load register ; sector_cnt,sector,cyl_low,cyl_hi,head before call label ; ;ata_read_sec read sector designed by lba_sel must set lba_sel first ; note: the sector content is tranfered to avr ram (block1) ; ;ata_write_sec write sector designed by lba_sel must set lba_sel first ; note: the conten of ram is copied to dirve sector (block1) ;***************************************************************************** .include "c:\atmel\inc\8515def.inc" .include "c:\atmel\project\thinkpad\2\ata_3.asm .cseg .org 0 rjmp reset reti ; External 0 interrupt Vector reti ; External 1 interrupt Vector reti ; Timer 1 Capture Vector reti ; Timer1 CompareA Vector reti ; Timer 1 CompareB Vector reti ; Timer 1 Overflow Vector reti ; Timer 0 Overflow Vector reti ; SPI Vector reti ; UART Receive Vector reti ; UDR Empty Vector reti ; UART Transmit Vector reti ; Analogue Comparator Vector RESET: ldi temp,low(RAMEND) out SPL,temp ;init Stack Pointer ldi temp,high(RAMEND) out SPH,temp ldi temp,255 out ddrb,temp out ddrd,temp sbi portd,rd sbi portd,wd ldi temp,0 out tccr1a,temp ldi temp,tck1024 ;set timer pre scaler out tccr1b,temp ldi temp,60 out ocr1ah,temp ;set timer for 4 seconde at 4mhz ldi temp,255 out ocr1al,temp ;***************************************************************************** ;* MAIN PROGRAM LOOP * ;***************************************************************************** main: rcall ata_rst ;reset of drive rcall ata_id ;get drive information ; rcall pwd_to_ram ;transfer password to ram ; rcall ata_set_pwd ;set drive whit password ; rcall ata_id ;verifi pwd set (bytes 160 in ram) ; ldi pwd_1,31 ;set passord (1 for exemple) in asci ; rcall pwd_to_ram ;transfer password to ram ; rcall ata_unlock ;unlock drive whit password ldi sector_cnt,1 ;one sector to be read ldi sector,1 ;logical bloc adress 1 (lba) ldi cyl_low,0 ;bits 8-15 of lba ldi cyl_hi,0 ;bits 16-30 of lba rcall lba_sel rcall ata_read_sec ;read sector selectioned sector ldi sector,2 ;logical bloc adress 2 rcall lba_sel rcall ata_write_sec ;write ram contain to selected adress ldi sector,2 rcall lba_sel rcall ata_read_sec ;read sector to confirm that sector ;1 is now copied in sector 2 rcall ata_sleep ;drive go sleep (head park on pellow) STOP: rjmp stop drive_error: rjmp drive_error ;if you land here you have a problem |
| CODE |
;***************************************************************************** ;* IDE DRIVER V1.1 * ;* * ;* final version 7/11/2000 * ;* * ;* Copyright(C) 1999-2000 ALPHATRONIC BY.MARC LALONDE * ;***************************************************************************** ; ------------->>>>> NOTE <<<<<------------- ; ;strobe the /DIOW and /DIOR lines. Normally these signals ;are set to 1 when not in use and to strobe the signal ;means to set the signal to 0 for at least 165ns and ;then set the signal back to 1. Also remember that the ;data and control lines must be valid for a clock cycle ;before strobing the DIOW or DIOR lines and they must be ;valid for another clock cycle after strobing DIOW/R. ;Also remember to use a clock that is slower ;than 8Mhz. If you use a clock faster than 8Mhz ;you will have to be careful with the timing requirements. ;In order to use an 8Mhz clock you need to strobe for ;2 clock cycles ; ; Drive I/O;write strobe. ; Rising edge ;clocks data from the host data bus to ;a drive register or data port ; ; Drive I/O read strobe. ;Falling edge ;enables data from a drive register or ;data port to host data bus. ; ; Don't use for ANY-THING without writen permission of alphatronic . ; ;20/10/2000 15:50 bebug hardware interface (drive not respond to command ) ;20/10/2000 17:39 first working code (identify_device working ) ;27/10/2000 20:53 read/write sector working +adding drive command ;27/10/2000 22:41 work well on 2 quantum drive but fail on 2 segate ?? ; maby a bad timing ??im chek this now ;28/10/2000 16:35 corect a part of bug that afect segate drrive now the only ; bug on thers drive is a pinc,7 tha is alwlas 1 ?? ;29/10/2000 21:22 adding time out timer of 4 seconde if drive command crash ;07/11/200 15:00 no more knot bug (final version) ;***************************************************************************** ; ; AT90S8515Px ; SIGNAL_NAME ______ ______ SIGNAL_NAME ; . | - | . ; IDE DA0 --> (TO) PB0 --| 1 40 |-- VCC . ; IDE DA1 --> (T1) PB1 --| 2 39 |-- PA0 LCD 7 <-> IDE DD00 ; IDE DA2 --> (AIN0) PB2 --| 3 38 |-- PA1 LCD 8 <-> IDE DD01 ; IDE SC0- --> (AIN1) PB3 --| 4 37 |-- PA2 LCD 9 <-> IDE DD02 ; IDE SC1- --> (SS*) PB4 --| 5 36 |-- PA3 LCD 10 <-> IDE DD03 ; . <-- (MOSI) PB5 --| 6 35 |-- PA4 LCD 11 <-> IDE DD04 ; . --> (MISO) PB6 --| 7 34 |-- PA5 LCD 12 <-> IDE DD05 ; . <-- (SCK) PB7 --| 8 33 |-- PA6 LCD 13 <-> IDE DD06 ; . --> RESET* ->| 9 32 |-- PA7 LCD 14 <-> IDE DD07 ; . --> (RXD) PD0 --| 10 31 |-- ICP <-- . ; . <-- (TXD) PD1 --| 11 30 |-- ALE --> . ; IDE RD <-- (INT0) PD2 --| 12 29 |-- OC1B --> . ; IDE WD <-- (INT1) PD3 --| 13 28 |-- PC7 (A15) <-> IDE DD08 ; IDE RST <-- PD4 --| 14 27 |-- PC6 LCD 4 <-> IDE DD09 ; . <-- (OC1A) PD5 --| 15 26 |-- PC5 (A13) <-> IDE DD10 ; LCD 5 <-- (WR*) PD6 --| 16 25 |-- PC4 (A12) <-> IDE DD11 ; LCD 6 <-- (RD*) PD7 --| 17 24 |-- PC3 (A11) <-> IDE DD12 ; 4.0 Mhz --> XTAL1 ->| 18 23 |-- PC2 (A10) <-> IDE DD13 ; 4.0 Mhz <-- XTAL2 <-| 19 22 |-- PC1 (A9) <-> IDE DD14 ; GND --| 20 21 |-- PC0 (A8) <-> IDE DD15 ; |_____________| ; ; (DIP-40) ; ;LCD IS STK-200 STANDART PINOUT ; ;command suported end useing this label ; ;ata_rst hardware hard drive reset just call label ; ;ata_id perfor identify_device command just call label ; ;ata_idle put drive in idle state just call label ; ;ata_sleep put drive in sleep just call label ; ;lba_sel selection lba sector to do operation must load register ; sector_cnt,sector,cyl_low,cyl_hi,head before call label ; ;ata_read_sec read sector designed by lba_sel must set lba_sel first ; note: the sector content is tranfered to avr ram (block1) ; ;ata_write_sec write sector designed by lba_sel must set lba_sel first ; note: the conten of ram is copied to dirve sector (block1) ; ; |<------------ t0 ------------------------>| ; __________________________________________ | ;Address Valid *1 _____/ \________ ; |<-t1->|<----------- t2 ----------->|<-t9->| | ; | |____________________________|<---t2i----->|_ ;DIOR-/DIOW- ____________/ \_____________/ ; | | | | ; | | ________|__ ->| |<-t8 ;Write Data *2 --------------------------------<___________>------------ ; | | |<--t3-->| | | ; | | ->|t4|<- | ; | | _______|___ ____ | ;Read Data *2 ---------------------------------<___________X____>------ ; ->|t7|<- | | ->|t6 |<- | | ; | | ->| tA |<- |<-t5-->|<-t6Z-->| ; | |___________________________________________| ;IOCS16- ________/ | | \____ ; | ->|tRd|<- | ; _________________|___________________|___________________ ;IORDY XXXXXXXXXXXXXXXXX____________________/ ; |<-------tB-------->| ; *1 Device Address consists of signals CS0-, CS1- and DA2-0 ; *2 Data consists of DD0-15 (16-bit) or DD0-7 (8-bit) ; ; ;t0 650ns ;t1 70 ns ;t2 165ns ;t3 60 ns ;t4 30 ns ;t5 50 ns ;t6 5 ns ;t7 90 ns ;t8 60 ns ;t9 20 ns ;***************************************************************************** ;.include "c:\atmel\inc\8515def.inc" ;diver .equ BLOCK1 =$60 ;start address of SRAM array #1 .equ security_status =$160 ;security satus bit of drive .equ model_number =$94 ;model number .equ TCK1024 =5 ;Timer/Counter runs from CK / 1024 ;ata-4 command .equ identify_device =0b11101100 ;EC HEX .equ disabel_password =0b11110110 ;F6 .equ freeze_lock =0b11110101 ;F5 .equ set_password =0b11110001 ;F1 .equ unlock =0b11110010 ;F2 .equ erase_prepare =0b11110011 ;F3 .equ erase_unit =0b11110100 ;F4 .equ check_power_mode =0b11100101 ;E5 .equ device_diagnostics =0b10010000 ;90 .equ format_track =0b01010000 ;50 .equ format_unit =0b11110111 ;F7 .equ idel =0b11100011 ;E3 .equ idel_immediate =0b11100001 ;E1 .equ initialize_device =0b10010001 ;91 .equ read_sector =0b00100000 ;20 .equ read_long =0b00100010 ;22 .equ read_long_retry =0b00100011 ;23 .equ read_multiple =0b11000100 ;C4 .equ read_verify =0b01000000 ;40 .equ read_verity_retry =0b01000001 ;41 .equ recalibrate =0b ;1x .equ seek =0b ;7x .equ set_features =0b11101111 ;EF .equ set_max_address =0b11111001 ;F9 .equ set_multiple_mode =0b11000110 ;C6 .equ sleep =0b11100110 ;E6 .equ standby =0b11100010 ;E2 .equ standby_immediate =0b11100000 ;E0 .equ write_long =0b00110010 ;32 .equ write_long_retry =0b00110011 ;33 .equ write_sectors_retry =0b00110000 ;30 .equ write_sector =0b00110001 ;31 .equ write_verity =0b00111100 ;3C ;ata-4 register bit mask of register ;command block register n\c n\c n\c SC1- SC0- DA2 DA1 DA0 .equ feature =0b00010001 .equ sector_cont =0b00010010 .equ sector_number =0b00010011 .equ cylinder_low =0b00010100 .equ cylinder_high =0b00010101 .equ device_head =0b00010110 .equ command =0b00010111 ;write .equ status =0b00010111 ;read .equ data =0b00010000 .equ error =0b00010001 ;control block registers .equ alternate_status =0b00010110 .equ device control =0b00010110 .equ master =0b11100000 .equ slave =0b10100000 .equ user_pwd =0b00000000 .equ master_pwd =0b00000001 ;pin direct .equ rd = 5 .equ wd = 4 .equ rst = 3 ;***** Main Program Register variables .def chr_1 = r2 ;pasword character 1 in asci .def chr_2 = r3 .def chr_3 = r4 .def chr_4 = r5 ; to .def chr_5 = r6 .def chr_6 = r7 .def chr_7 = r8 ;password character 7 .def delay = r17 .def Counter = r16 ;used as character counter .def temp = r17 .def drv_status = r18 .def sector = r19 ;in LBA =bits 0 - 7 .def cyl_low = r20 ;in LBA =bits 8 - 15 .def cyl_hi = r21 ;in LBA =bits 16 - 23 .def head = r22 ;in LBA =bits 23 - 30 .def ata_command = r23 .def sector_cnt = r24 ;***************************************************************************** ;* ATA COMMAND LIST * ;***************************************************************************** .org 100 ata_rst: rcall delay4ms ;whait voltage stab cbi portd,rst ;put drive in reset rcall delay4ms ;whait voltage stab sbi portd,rst ;put drive in working mode rcall ata_stat ata_pio: ldi temp,255 ;put data bus as ouput out ddra,temp ldi temp,feature ;select registe out portb,temp cbi portd,wd ;selection pio mode ldi temp,0b00000011 out porta,temp ;select master drive sbi portd,wd ldi temp,sector_cont ;select registe out portb,temp cbi portd,wd ;write data to resister of drive ldi temp,0b00000001 out porta,temp ;pio mode = 0 sbi portd,wd ldi temp,device_head ;select registe out portb,temp cbi portd,wd ldi temp,master out porta,temp ;select master drive sbi portd,wd ldi temp,command ;select register out portB,temp cbi portD,wd ;write comend ldi temp,set_features out porta,temp sbi portd,wd rcall ata_stat ret ata_id: ldi ata_command,identify_device rcall set_command rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall read_buffer rcall ata_stat ret ata_disable_pwd: ldi ata_command,disabel_password rcall set_command rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall write_buffer rcall ata_stat ret ata_unlock: ldi ata_command,unlock rcall set_command rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall write_buffer rcall ata_stat ret ata_set_pwd: ldi ata_command,set_password rcall set_command rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall write_buffer rcall ata_stat ret ata_idle: ldi ata_command,idel_immediate rcall set_command rcall ata_stat ret ata_sleep: ldi ata_command,sleep rcall set_command rcall ata_stat ret lba_sel: ldi temp,255 ;put data bus as ouput out ddra,temp ldi temp,device_head ;select registe out portb,temp cbi portd,wd ;write data to resister of drive ldi temp,master out porta,temp ;select master drive sbi portd,wd ldi temp,sector_cont ;write sector count out portb,temp cbi portd,wd out porta,sector_cnt sbi portd,wd ldi temp,sector_number ;write sector no. out portb,temp cbi portd,wd out porta,sector sbi portd,wd ldi temp,cylinder_low ;write cyl_low out portb,temp cbi portd,wd out porta,cyl_low sbi portd,wd ldi temp,cylinder_high ;write cyl_hi out portb,temp cbi portd,wd out porta,cyl_hi sbi portd,wd ldi temp,command ;select register out portB,temp ret ata_read_sec: cbi portD,wd ;write comend ldi temp,read_sector out porta,temp sbi portd,wd rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall read_buffer rcall ata_stat ret ata_write_sec: cbi portD,wd ;write comend ldi temp,write_sector out porta,temp sbi portd,wd rcall ata_stat2 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) rcall write_buffer rcall ata_stat ret pwd_to_ram: ldi YH,high(BLOCK1) ;init Y-pointer to start of sram ldi YL,low(BLOCK1) ldi temp,user_pwd ;chose betwen user or master pwd st Y+,temp st y+,chr_1 ;write pasword in ram (7 chr asci) st y+,chr_2 st y+,chr_3 st y+,chr_4 st y+,chr_5 st y+,chr_6 st y+,chr_7 ldi counter,247 fill: ldi temp,0 ;fill the rest or ram of 0 st y+,temp dec counter ;conter - 1 brne fill ret ;***************************************************************************** ;* IDE ROUTINE * ;***************************************************************************** ata_stat2: ldi temp,0 ;clear timer conter out tcnt1h,temp out tcnt1l,temp ldi temp,255 ;clear interup flag just in case out tifr,temp r_stat2: in temp,tifr sbrc temp,6 ;if drive is still in error after rjmp drive_error ;4 sec falg set en go drive error ldi temp,0 out porta,temp out ddra,temp ldi temp,status ;read status regist for see if error out portB,temp cbi portD,rd ;strobe read pin rcall delay100us ;let drive time to respond in drv_status,pina ;store status in registe drv_status nop ;small delay sbi portD,rd ;rising edge of read pin sbrs drv_status,7 ;drive busy (bsy) sbrc drv_status,0 ;drive error (err) rjmp r_stat2 drq: in temp,tifr ;if drive is still in error after sbrc temp,6 ;4 sec falg set en go drive error rjmp drive_error sbrc drv_status,3 ;loop until drive set drq bit ret cbi portd,rd rcall delay40us in drv_status,pina nop sbi portd,rd rjmp drq ata_stat: ldi temp,0 ;clear timer conter out tcnt1h,temp out tcnt1l,temp ldi temp,255 ;clear interup flag just in case out tifr,temp r_stat: in temp,tifr ;if drive is still in error after sbrc temp,6 ;4 sec falg set en go drive error rjmp drive_error ldi temp,0 out porta,temp out ddra,temp ldi temp,status ;read status regist for see if error out portB,temp cbi portD,rd ;strobe read pin rcall delay100us ;let drive time to respond in drv_status,pina ;store status in registe drv_status nop ;small delay sbi portD,rd ;rising edge of read pin sbrs drv_status,7 ;drive busy (bsy) sbrc drv_status,0 ;drive error (err) rjmp r_stat sbrs drv_status,6 ;device redy (drdy) rjmp r_stat ret set_command: ldi temp,255 ;put data bus as ouput out ddra,temp ldi temp,device_head ;select registe out portb,temp cbi portd,wd ;write data to resister of drive ldi temp,master out porta,temp ;select master drive sbi portd,wd ldi temp,command ;select register out portB,temp cbi portD,wd ;write comend out porta,ata_command sbi portd,wd ret read_buffer: ldi temp,0 ;put portA as a input out ddra,temp out ddrc,temp ldi temp,0 ;clear bit in portA out portA,temp out portc,temp ldi counter,250 ;buffer size (fifo) first 250 bytes ldi temp,data ;select data registe on port d out portB,temp lp3: sbi portb,5 ;set pinb,5 hi for test sbi ddrb,5 cbi portD,rd nop in temp,pina st Y+,temp in temp,pinc st Y+,temp; nop sbi portd,rd dec counter ;conter - 1 brne lp3 ldi counter,6 last6: cbi portb,5 ;clr pinb,5 hi for test cbi ddrb,5 ;read last 128 bytes of ram cbi portD,rd ;but dont in ram to prevent nop ;stak pointer coruption sbi portD,rd dec counter brne last6 ret write_buffer: ldi temp,255 ;put portA as a ouput out ddra,temp out ddrc,temp ldi temp,0 ;clear bit in portA out portA,temp out portc,temp ldi counter,250 ;buffer size (fifo) first 250 bytes ldi temp,data ;select data registe on port d out portB,temp lp4: cbi portd,wd nop ld temp,y+ out porta,temp ld temp,y+ out portc,temp nop sbi portd,wd dec counter ;buffer - 1 brne lp4 ldi counter,6 last6_2: ;read last 128 bytes of ram cbi portD,wd ;but dont in ram to prevent nop ;stak pointer coruption sbi portD,wd dec counter brne last6_2 ret ;**************************************************************************** ;* 3 different delay routines used by IDE * ;**************************************************************************** Delay40us: ldi r21,$40 Loop3: dec r21 brne loop3 ret Delay100us: ldi r21,$88 Loop: dec r21 brne loop ret Delay4ms: ldi r22,$1c Loop1: ldi r21,$00 Loop2: dec r21 brne loop2 dec r22 brne loop1 ret |
| CODE |
AVRASM ver. 1.30 C:\Atmel\project\thinkpad\2\main.asm Wed Nov 08 13:47:27 2000 ;***************************************************************************** ;* IDE DRIVER V1.1 * ;* * ;* * ;* * ;* Copyright(C) 1999-2000 ALPHATRONIC BY.MARC LALONDE * ;***************************************************************************** ; ------------->>>>> NOTE <<<<<------------- ; ;20/10/2000 15:50 bebug hardware interface (drive not respond to command ) ;20/10/2000 17:39 first working code (identify_device working ) ;27/10/2000 20:53 read/write sector working +adding drive command ;27/10/2000 22:41 work well on 2 quantum drive but fail on 2 segate ?? ; maby a bad timing ??im chek this now ;28/10/2000 16:35 corect a part of bug that afect segate drrive now the only ; bug on thers drive is a pinc,7 tha is alwlas 1 ?? ;29/10/2000 21:22 adding time out timer of 4 seconde if drive command crash ; ;***************************************************************************** ; ; AT90S8515Px ; SIGNAL_NAME ______ ______ SIGNAL_NAME ; . | - | . ; IDE DA0 --> (TO) PB0 --| 1 40 |-- VCC . ; IDE DA1 --> (T1) PB1 --| 2 39 |-- PA0 LCD 7 <-> IDE DD00 ; IDE DA2 --> (AIN0) PB2 --| 3 38 |-- PA1 LCD 8 <-> IDE DD01 ; IDE SC0- --> (AIN1) PB3 --| 4 37 |-- PA2 LCD 9 <-> IDE DD02 ; IDE SC1- --> (SS*) PB4 --| 5 36 |-- PA3 LCD 10 <-> IDE DD03 ; . <-- (MOSI) PB5 --| 6 35 |-- PA4 LCD 11 <-> IDE DD04 ; . --> (MISO) PB6 --| 7 34 |-- PA5 LCD 12 <-> IDE DD05 ; . <-- (SCK) PB7 --| 8 33 |-- PA6 LCD 13 <-> IDE DD06 ; . --> RESET* ->| 9 32 |-- PA7 LCD 14 <-> IDE DD07 ; . --> (RXD) PD0 --| 10 31 |-- ICP <-- . ; . <-- (TXD) PD1 --| 11 30 |-- ALE --> . ; IDE RD <-- (INT0) PD2 --| 12 29 |-- OC1B --> . ; IDE WD <-- (INT1) PD3 --| 13 28 |-- PC7 (A15) <-> IDE DD08 ; IDE RST <-- PD4 --| 14 27 |-- PC6 LCD 4 <-> IDE DD09 ; . <-- (OC1A) PD5 --| 15 26 |-- PC5 (A13) <-> IDE DD10 ; LCD 5 <-- (WR*) PD6 --| 16 25 |-- PC4 (A12) <-> IDE DD11 ; LCD 6 <-- (RD*) PD7 --| 17 24 |-- PC3 (A11) <-> IDE DD12 ; 4.0 Mhz --> XTAL1 ->| 18 23 |-- PC2 (A10) <-> IDE DD13 ; 4.0 Mhz <-- XTAL2 <-| 19 22 |-- PC1 (A9) <-> IDE DD14 ; GND --| 20 21 |-- PC0 (A8) <-> IDE DD15 ; |_____________| ; ; (DIP-40) ; ;LCD IS STK-200 STANDART PINOUT ; ;command suported end useing this label ; ;ata_rst hardware hard drive reset just call label ; ;ata_id perfor identify_device command just call label ; ;ata_idle put drive in idle state just call label ; ;ata_sleep put drive in sleep just call label ; ;lba_sel selection lba sector to do operation must load register ; sector_cnt,sector,cyl_low,cyl_hi,head before call label ; ;ata_read_sec read sector designed by lba_sel must set lba_sel first ; note: the sector content is tranfered to avr ram (block1) ; ;ata_write_sec write sector designed by lba_sel must set lba_sel first ; note: the conten of ram is copied to dirve sector (block1) ;***************************************************************************** .include "c:\atmel\inc\8515def.inc" ;*************************************************************************** ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number :AVR000 ;* File Name :"8515def.inc" ;* Title :Register/Bit Definitions for the AT90S8515 ;* Date :99.01.28 ;* Version :1.30 ;* Support telephone :+47 72 88 43 88 (ATMEL Norway) ;* Support fax :+47 72 88 43 99 (ATMEL Norway) ;* Support E-mail :avr@atmel.com ;* Target MCU :AT90S8515 ;* ;* DESCRIPTION ;* When including this file in the assembly program file, all I/O register ;* names and I/O register bit names appearing in the data book can be used. ;* In addition, the six registers forming the three data pointers X, Y and ;* Z have been assigned names XL - ZH. Highest RAM address for Internal ;* SRAM is also defined ;* ;* The Register names are represented by their hexadecimal address. ;* ;* The Register Bit names are represented by their bit number (0-7). ;* ;* Please observe the difference in using the bit names with instructions ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" ;* (skip if bit in register set/cleared). The following example illustrates ;* this: ;* ;* in r16,PORTB ;read PORTB latch ;* sbr r16,(1<<PB6)+(1<<PB5);set PB6 and PB5 (use masks, not bit#) ;* out PORTB,r16 ;output to PORTB ;* ;* in r16,TIFR ;read the Timer Interrupt Flag Register ;* sbrc r16,TOV0 ;test the overflow flag (use bit#) ;* rjmp TOV0_is_set ;jump if set ;* ... ;otherwise do something else ;*************************************************************************** ;***** Specify Device .device AT90S8515 ;***** I/O Register Definitions .equ SREG =$3f .equ SPH =$3e .equ SPL =$3d .equ GIMSK =$3b .equ GIFR =$3a .equ TIMSK =$39 .equ TIFR =$38 .equ MCUCR =$35 .equ TCCR0 =$33 .equ TCNT0 =$32 .equ OCR0 =$31 .equ TCCR1A =$2f .equ TCCR1B =$2e .equ TCNT1H =$2d .equ TCNT1L =$2c .equ OCR1AH =$2b .equ OCR1AL =$2a .equ OCR1BH =$29 .equ OCR1BL =$28 .equ ICR1H =$25 .equ ICR1L =$24 .equ WDTCR =$21 .equ EEARH =$1f .equ EEARL =$1e .equ EEDR =$1d .equ EECR =$1c .equ PORTA =$1b .equ DDRA =$1a .equ PINA =$19 .equ PORTB =$18 .equ DDRB =$17 .equ PINB =$16 .equ PORTC =$15 .equ DDRC =$14 .equ PINC =$13 .equ PORTD =$12 .equ DDRD =$11 .equ PIND =$10 .equ SPDR =$0f .equ SPSR =$0e .equ SPCR =$0d .equ UDR =$0c .equ USR =$0b .equ UCR =$0a .equ UBRR =$09 .equ ACSR =$08 ;***** Bit Definitions .equ INT1 =7 .equ INT0 =6 .equ INTF1 =7 .equ INTF0 =6 .equ TOIE1 =7 .equ OCIE1A =6 .equ OCIE1B =5 .equ TICIE1 =3 .equ TOIE0 =1 .equ TOV1 =7 .equ OCF1A =6 .equ OCF1B =5 .equ ICF1 =3 .equ TOV0 =1 .equ SRE =7 .equ SRW =6 .equ SE =5 .equ SM =4 .equ ISC11 =3 .equ ISC10 =2 .equ ISC01 =1 .equ ISC00 =0 .equ CS02 =2 .equ CS01 =1 .equ CS00 =0 .equ COM1A1 =7 .equ COM1A0 =6 .equ COM1B1 =5 .equ COM1B0 =4 .equ PWM11 =1 .equ PWM10 =0 .equ ICNC1 =7 .equ ICES1 =6 .equ CTC1 =3 .equ CS12 =2 .equ CS11 =1 .equ CS10 =0 .equ WDDE =4 .equ WDE =3 .equ WDP2 =2 .equ WDP1 =1 .equ WDP0 =0 .equ EEMWE =2 .equ EEWE =1 .equ EERE =0 .equ PA7 =7 .equ PA6 =6 .equ PA5 =5 .equ PA4 =4 .equ PA3 =3 .equ PA2 =2 .equ PA1 =1 .equ PA0 =0 .equ DDA7 =7 .equ DDA6 =6 .equ DDA5 =5 .equ DDA4 =4 .equ DDA3 =3 .equ DDA2 =2 .equ DDA1 =1 .equ DDA0 =0 .equ PINA7 =7 .equ PINA6 =6 .equ PINA5 =5 .equ PINA4 =4 .equ PINA3 =3 .equ PINA2 =2 .equ PINA1 =1 .equ PINA0 =0 .equ PB7 =7 .equ PB6 =6 .equ PB5 =5 .equ PB4 =4 .equ PB3 =3 .equ PB2 =2 .equ PB1 =1 .equ PB0 =0 .equ DDB7 =7 .equ DDB6 =6 .equ DDB5 =5 .equ DDB4 =4 .equ DDB3 =3 .equ DDB2 =2 .equ DDB1 =1 .equ DDB0 =0 .equ PINB7 =7 .equ PINB6 =6 .equ PINB5 =5 .equ PINB4 =4 .equ PINB3 =3 .equ PINB2 =2 .equ PINB1 =1 .equ PINB0 =0 .equ PC7 =7 .equ PC6 =6 .equ PC5 =5 .equ PC4 =4 .equ PC3 =3 .equ PC2 =2 .equ PC1 =1 .equ PC0 =0 .equ DDC7 =7 .equ DDC6 =6 .equ DDC5 =5 .equ DDC4 =4 .equ DDC3 =3 .equ DDC2 =2 .equ DDC1 =1 .equ DDC0 =0 .equ PINC7 =7 .equ PINC6 =6 .equ PINC5 =5 .equ PINC4 =4 .equ PINC3 =3 .equ PINC2 =2 .equ PINC1 =1 .equ PINC0 =0 .equ PD7 =7 .equ PD6 =6 .equ PD5 =5 .equ PD4 =4 .equ PD3 =3 .equ PD2 =2 .equ PD1 =1 .equ PD0 =0 .equ DDD7 =7 .equ DDD6 =6 .equ DDD5 =5 .equ DDD4 =4 .equ DDD3 =3 .equ DDD2 =2 .equ DDD1 =1 .equ DDD0 =0 .equ PIND7 =7 .equ PIND6 =6 .equ PIND5 =5 .equ PIND4 =4 .equ PIND3 =3 .equ PIND2 =2 .equ PIND1 =1 .equ PIND0 =0 .equ SPIE =7 .equ SPE =6 .equ DORD =5 .equ MSTR =4 .equ CPOL =3 .equ CPHA =2 .equ SPR1 =1 .equ SPR0 =0 .equ SPIF =7 .equ WCOL =6 .equ RXC =7 .equ TXC =6 .equ UDRE =5 .equ FE =4 .equ OR =3 .equ RXCIE =7 .equ TXCIE =6 .equ UDRIE =5 .equ RXEN =4 .equ TXEN =3 .equ CHR9 =2 .equ RXB8 =1 .equ TXB8 =0 .equ ACD =7 .equ ACO =5 .equ ACI =4 .equ ACIE =3 .equ ACIC =2 .equ ACIS1 =1 .equ ACIS0 =0 .def XL =r26 .def XH =r27 .def YL =r28 .def YH =r29 .def ZL =r30 .def ZH =r31 .equ RAMEND =$25F;Last On-Chip SRAM Location .equ XRAMEND =$FFFF .equ E2END =$1FF .equ FLASHEND=$FFF .equ INT0addr=$001;External Interrupt0 Vector Address .equ INT1addr=$002;External Interrupt1 Vector Address .equ ICP1addr=$003;Input Capture1 Interrupt Vector Address .equ OC1Aaddr=$004;Output Compare1A Interrupt Vector Address .equ OC1Baddr=$005;Output Compare1B Interrupt Vector Address .equ OVF1addr=$006;Overflow1 Interrupt Vector Address .equ OVF0addr=$007;Overflow0 Interrupt Vector Address .equ SPIaddr =$008;SPI Interrupt Vector Address .equ URXCaddr=$009;UART Receive Complete Interrupt Vector Address .equ UDREaddr=$00a;UART Data Register Empty Interrupt Vector Address .equ UTXCaddr=$00b;UART Transmit Complete Interrupt Vector Address .equ ACIaddr =$00c;Analog Comparator Interrupt Vector Address .include "c:\atmel\project\thinkpad\2\ata_3.asm ;***************************************************************************** ;* IDE DRIVER V1.1 * ;* * ;* * ;* * ;* Copyright(C) 1999-2000 ALPHATRONIC BY.MARC LALONDE * ;***************************************************************************** ; ------------->>>>> NOTE <<<<<------------- ; ;strobe the /DIOW and /DIOR lines. Normally these signals ;are set to 1 when not in use and to strobe the signal ;means to set the signal to 0 for at least 165ns and ;then set the signal back to 1. Also remember that the ;data and control lines must be valid for a clock cycle ;before strobing the DIOW or DIOR lines and they must be ;valid for another clock cycle after strobing DIOW/R. ;Also remember to use a clock that is slower ;than 8Mhz. If you use a clock faster than 8Mhz ;you will have to be careful with the timing requirements. ;In order to use an 8Mhz clock you need to strobe for ;2 clock cycles ; ; Drive I/O;write strobe. ; Rising edge ;clocks data from the host data bus to ;a drive register or data port ; ; Drive I/O read strobe. ;Falling edge ;enables data from a drive register or ;data port to host data bus. ; ; Don't use for ANY-THING without writen permission of alphatronic . ; ;20/10/2000 15:50 bebug hardware interface (drive not respond to command ) ;20/10/2000 17:39 first working code (identify_device working ) ;27/10/2000 20:53 read/write sector working +adding drive command ;27/10/2000 22:41 work well on 2 quantum drive but fail on 2 segate ?? ; maby a bad timing ??im chek this now ;28/10/2000 16:35 corect a part of bug that afect segate drrive now the only ; bug on thers drive is a pinc,7 tha is alwlas 1 ?? ;29/10/2000 21:22 adding time out timer of 4 seconde if drive command crash ; ;***************************************************************************** ; ; AT90S8515Px ; SIGNAL_NAME ______ ______ SIGNAL_NAME ; . | - | . ; IDE DA0 --> (TO) PB0 --| 1 40 |-- VCC . ; IDE DA1 --> (T1) PB1 --| 2 39 |-- PA0 LCD 7 <-> IDE DD00 ; IDE DA2 --> (AIN0) PB2 --| 3 38 |-- PA1 LCD 8 <-> IDE DD01 ; IDE SC0- --> (AIN1) PB3 --| 4 37 |-- PA2 LCD 9 <-> IDE DD02 ; IDE SC1- --> (SS*) PB4 --| 5 36 |-- PA3 LCD 10 <-> IDE DD03 ; . <-- (MOSI) PB5 --| 6 35 |-- PA4 LCD 11 <-> IDE DD04 ; . --> (MISO) PB6 --| 7 34 |-- PA5 LCD 12 <-> IDE DD05 ; . <-- (SCK) PB7 --| 8 33 |-- PA6 LCD 13 <-> IDE DD06 ; . --> RESET* ->| 9 32 |-- PA7 LCD 14 <-> IDE DD07 ; . --> (RXD) PD0 --| 10 31 |-- ICP <-- . ; . <-- (TXD) PD1 --| 11 30 |-- ALE --> . ; IDE RD <-- (INT0) PD2 --| 12 29 |-- OC1B --> . ; IDE WD <-- (INT1) PD3 --| 13 28 |-- PC7 (A15) <-> IDE DD08 ; IDE RST <-- PD4 --| 14 27 |-- PC6 LCD 4 <-> IDE DD09 ; . <-- (OC1A) PD5 --| 15 26 |-- PC5 (A13) <-> IDE DD10 ; LCD 5 <-- (WR*) PD6 --| 16 25 |-- PC4 (A12) <-> IDE DD11 ; LCD 6 <-- (RD*) PD7 --| 17 24 |-- PC3 (A11) <-> IDE DD12 ; 4.0 Mhz --> XTAL1 ->| 18 23 |-- PC2 (A10) <-> IDE DD13 ; 4.0 Mhz <-- XTAL2 <-| 19 22 |-- PC1 (A9) <-> IDE DD14 ; GND --| 20 21 |-- PC0 (A8) <-> IDE DD15 ; |_____________| ; ; (DIP-40) ; ;LCD IS STK-200 STANDART PINOUT ; ;command suported end useing this label ; ;ata_rst hardware hard drive reset just call label ; ;ata_id perfor identify_device command just call label ; ;ata_idle put drive in idle state just call label ; ;ata_sleep put drive in sleep just call label ; ;lba_sel selection lba sector to do operation must load register ; sector_cnt,sector,cyl_low,cyl_hi,head before call label ; ;ata_read_sec read sector designed by lba_sel must set lba_sel first ; note: the sector content is tranfered to avr ram (block1) ; ;ata_write_sec write sector designed by lba_sel must set lba_sel first ; note: the conten of ram is copied to dirve sector (block1) ; ; |<------------ t0 ------------------------>| ; __________________________________________ | ;Address Valid *1 _____/ \________ ; |<-t1->|<----------- t2 ----------->|<-t9->| | ; | |____________________________|<---t2i----->|_ ;DIOR-/DIOW- ____________/ \_____________/ ; | | | | ; | | ________|__ ->| |<-t8 ;Write Data *2 --------------------------------<___________>------------ ; | | |<--t3-->| | | ; | | ->|t4|<- | ; | | _______|___ ____ | ;Read Data *2 ---------------------------------<___________X____>------ ; ->|t7|<- | | ->|t6 |<- | | ; | | ->| tA |<- |<-t5-->|<-t6Z-->| ; | |___________________________________________| ;IOCS16- ________/ | | \____ ; | ->|tRd|<- | ; _________________|___________________|___________________ ;IORDY XXXXXXXXXXXXXXXXX____________________/ ; |<-------tB-------->| ; *1 Device Address consists of signals CS0-, CS1- and DA2-0 ; *2 Data consists of DD0-15 (16-bit) or DD0-7 (8-bit) ; ; ;t0 650ns ;t1 70 ns ;t2 165ns ;t3 60 ns ;t4 30 ns ;t5 50 ns ;t6 5 ns ;t7 90 ns ;t8 60 ns ;t9 20 ns ;***************************************************************************** ;.include "c:\atmel\inc\8515def.inc" ;diver .equ BLOCK1 =$60 ;start address of SRAM array #1 .equ security_status =$160 ;security satus bit of drive .equ model_number =$94 ;model number .equ TCK1024 =5 ;Timer/Counter runs from CK / 1024 ;ata-4 command .equ identify_device =0b11101100 ;EC HEX .equ disabel_password =0b11110110 ;F6 .equ freeze_lock =0b11110101 ;F5 .equ set_password =0b11110001 ;F1 .equ unlock =0b11110010 ;F2 .equ erase_prepare =0b11110011 ;F3 .equ erase_unit =0b11110100 ;F4 .equ check_power_mode =0b11100101 ;E5 .equ device_diagnostics =0b10010000 ;90 .equ format_track =0b01010000 ;50 .equ format_unit =0b11110111 ;F7 .equ idel =0b11100011 ;E3 .equ idel_immediate =0b11100001 ;E1 .equ initialize_device =0b10010001 ;91 .equ read_sector =0b00100000 ;20 .equ read_long =0b00100010 ;22 .equ read_long_retry =0b00100011 ;23 .equ read_multiple =0b11000100 ;C4 .equ read_verify =0b01000000 ;40 .equ read_verity_retry =0b01000001 ;41 .equ recalibrate =0b ;1x .equ seek =0b ;7x .equ set_features =0b11101111 ;EF .equ set_max_address =0b11111001 ;F9 .equ set_multiple_mode =0b11000110 ;C6 .equ sleep =0b11100110 ;E6 .equ standby =0b11100010 ;E2 .equ standby_immediate =0b11100000 ;E0 .equ write_long =0b00110010 ;32 .equ write_long_retry =0b00110011 ;33 .equ write_sectors_retry =0b00110000 ;30 .equ write_sector =0b00110001 ;31 .equ write_verity =0b00111100 ;3C ;ata-4 register bit mask of register ;command block register n\c n\c n\c SC1- SC0- DA2 DA1 DA0 .equ feature =0b00010001 .equ sector_cont =0b00010010 .equ sector_number =0b00010011 .equ cylinder_low =0b00010100 .equ cylinder_high =0b00010101 .equ device_head =0b00010110 .equ command =0b00010111 ;write .equ status =0b00010111 ;read .equ data =0b00010000 .equ error =0b00010001 ;control block registers .equ alternate_status =0b00010110 .equ device control =0b00010110 .equ master =0b11100000 .equ slave =0b10100000 .equ user_pwd =0b00000000 .equ master_pwd =0b00000001 ;pin direct .equ rd = 5 .equ wd = 4 .equ rst = 3 ;***** Main Program Register variables .def chr_1 = r2 ;pasword character 1 in asci .def chr_2 = r3 .def chr_3 = r4 .def chr_4 = r5 ; to .def chr_5 = r6 .def chr_6 = r7 .def chr_7 = r8 ;password character 7 .def delay = r17 .def Counter = r16 ;used as character counter .def temp = r17 .def drv_status = r18 .def sector = r19 ;in LBA =bits 0 - 7 .def cyl_low = r20 ;in LBA =bits 8 - 15 .def cyl_hi = r21 ;in LBA =bits 16 - 23 .def head = r22 ;in LBA =bits 23 - 30 .def ata_command = r23 .def sector_cnt = r24 ;***************************************************************************** ;* ATA COMMAND LIST * ;***************************************************************************** .org 100 ata_rst: 000064 d10e rcall delay4ms ;whait voltage stab 000065 9893 cbi portd,rst ;put drive in reset 000066 d10c rcall delay4ms ;whait voltage stab 000067 9a93 sbi portd,rst ;put drive in working mode 000068 d0a8 rcall ata_stat ata_pio: 000069 ef1f ldi temp,255 ;put data bus as ouput 00006a bb1a out ddra,temp 00006b e111 ldi temp,feature ;select registe 00006c bb18 out portb,temp 00006d 9894 cbi portd,wd ;selection pio mode 00006e e013 ldi temp,0b00000011 00006f bb1b out porta,temp ;select master drive 000070 9a94 sbi portd,wd 000071 e112 ldi temp,sector_cont ;select registe 000072 bb18 out portb,temp 000073 9894 cbi portd,wd ;write data to resister of drive 000074 e011 ldi temp,0b00000001 000075 bb1b out porta,temp ;pio mode = 0 000076 9a94 sbi portd,wd 000077 e116 ldi temp,device_head ;select registe 000078 bb18 out portb,temp 000079 9894 cbi portd,wd 00007a ee10 ldi temp,master 00007b bb1b out porta,temp ;select master drive 00007c 9a94 sbi portd,wd 00007d e117 ldi temp,command ;select register 00007e bb18 out portB,temp 00007f 9894 cbi portD,wd ;write comend 000080 ee1f ldi temp,set_features 000081 bb1b out porta,temp 000082 9a94 sbi portd,wd 000083 d08d rcall ata_stat 000084 9508 ret ata_id: 000085 ee7c ldi ata_command,identify_device 000086 d0a2 rcall set_command 000087 d069 rcall ata_stat2 000088 e0d0 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram 000089 e6c0 ldi YL,low(BLOCK1) 00008a d0ac rcall read_buffer 00008b d085 rcall ata_stat 00008c 9508 ret ata_disable_pwd: 00008d ef76 ldi ata_command,disabel_password 00008e d09a rcall set_command 00008f d061 rcall ata_stat2 000090 e0d0 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram 000091 e6c0 ldi YL,low(BLOCK1) 000092 d0be rcall write_buffer 000093 d07d rcall ata_stat 000094 9508 ret ata_unlock: 000095 ef72 ldi ata_command,unlock 000096 d092 rcall set_command 000097 d059 rcall ata_stat2 000098 e0d0 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram 000099 e6c0 ldi YL,low(BLOCK1) 00009a d0b6 rcall write_buffer 00009b d075 rcall ata_stat 00009c 9508 ret ata_set_pwd: 00009d ef71 ldi ata_command,set_password 00009e d08a rcall set_command 00009f d051 rcall ata_stat2 0000a0 e0d0 ldi YH,high(BLOCK1) ;init Y-pointer to start of sram 0000a1 e6c0 ldi YL,low(BLOCK1) 0000a2 d0ae rcall write_buffer 0000a3 d06d rcall ata_stat 0000a4 9508 ret ata_idle: Build your own community today with the largest message board hosting company. |