-- Title: Hard disk library for communicating with parallel ata hard drives -- with a 40 pin ide connector. -- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved. -- Adapted-by: -- Compiler: >=2.4n -- -- This file is part of jallib (http://jallib.googlecode.com) -- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php) -- -- Description: this library provides example usage for pata/ide hard disk drives. -- includes examples for : spin up / spin down drive -- : read sectors -- : identify drive -- : write sectors -- -- Sources: -- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt -- IDE hardware reference & information document by alex t. ivopol -- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf -- include 16f877a -- target PICmicro -- -- This program assumes that a 20 MHz resonator or crystal -- is connected to pins OSC1 and OSC2. pragma target clock 20_000_000 -- oscillator frequency -- configuration memory settings (fuses) pragma target OSC HS -- HS crystal or resonator pragma target WDT disabled -- no watchdog pragma target LVP disabled -- no Low Voltage Programming -- enable_digital_io() -- disable all analog pins if any _usec_delay (100_000) -- wait for power to stablilize include delay -- setup uart for communication const serial_hw_baudrate = 115200 -- set the baudrate include serial_hardware serial_hw_init() -- some aliases so it is easy to change from serial hw to serial sw. alias serial_write is serial_hw_write alias serial_read is serial_hw_read alias serial_data is serial_hw_data alias serial_data_available is serial_hw_data_available include print -- setup hard disk library const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins -- pin assignments alias pata_hd_data_low is portb -- data port (low bits) alias pata_hd_data_low_direction is portb_direction alias pata_hd_data_high is portd -- data port (high bits) alias pata_hd_data_high_direction is portd_direction alias pata_hd_a0 is pin_a3 alias pata_hd_a0_direction is pin_a3_direction alias pata_hd_a1 is pin_a1 alias pata_hd_a1_direction is pin_a1_direction alias pata_hd_a2 is pin_a0 alias pata_hd_a2_direction is pin_a0_direction alias pata_hd_iowr is pin_e0 alias pata_hd_iowr_direction is pin_e0_direction alias pata_hd_iord is pin_a4 alias pata_hd_iord_direction is pin_a4_direction ;alias pata_hd_cs1 is pin_a3 ;alias pata_hd_cs1_direction is pin_a3_direction ;alias pata_hd_cs0 is pin_a4 ;alias pata_hd_cs0_direction is pin_a4_direction pata_hd_a0_direction = output -- register select pin pata_hd_a1_direction = output -- register select pin pata_hd_a2_direction = output -- register select pin pata_hd_iowr_direction = output -- used for write pulse pata_hd_iord_direction = output -- used for read pulse ;pata_hd_cs1_direction = output -- register select pin ;pata_hd_cs0_direction = output -- register select pin include pata_hard_disk -- include the parallel ata ide hard disk library pata_hd_init() -- initialize startup settings ------------------------------------------------------------ -- START of PROGRAM ------------------------------------------------------------ -- procedure for sending 80 "-----------------" via serial port procedure separator() is serial_hw_data = 13 serial_hw_data = 10 const byte str3[] = "--------------------------------------------------------------------------------" print_string(serial_hw_data, str3) print_crlf(serial_hw_data) end procedure -- Send something to the serial port separator() -- send "----" via serial port var byte start_string[] = "HARD DISK SAMPLE STARTED" print_string(serial_hw_data,start_string) -- variables for the sample var word step1 var byte data separator() -- seperate the examples with "----" -------------------------------------------------------------------------------- -- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time -------------------------------------------------------------------------------- pata_hd_start_read(0) -- get sd card ready for read at sector 0 for 512 * 2 loop -- read 2 sectors (512 * 2 bytes) data = pata_hd_data_byte -- read 1 bytes of data serial_hw_write(data) -- send byte via serial port end loop pata_hd_stop_read() -- tell sd card you are done reading separator() -- seperate the examples with "----" _usec_delay(500_000) -- a small delay -------------------------------------------------------------------------------- -- EXAMPLE #2 - write to a sector 1 byte at a time -------------------------------------------------------------------------------- pata_hd_start_write(20) -- get sd card ready for write at sector 20 for 512 + 256 loop -- loop 1 sector + 1 half sector (512 + 256 bytes) pata_hd_data_byte = "A" -- write 1 bytes of data end loop pata_hd_stop_write() -- tell sd card you are done reading -- -- read the data back pata_hd_start_read(20) -- get sd card ready for read at sector 20 for 512 + 256 loop -- loop 1 sector + 1 half sector (512 + 256 bytes) data = pata_hd_data_byte -- read 1 bytes of data serial_hw_write(data) -- send byte via serial port end loop pata_hd_stop_read() -- tell sd card you are done reading separator() -- seperate the examples with "----" _usec_delay(500_000) -- a small delay ; -------------------------------------------------------------------------------- ; -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address ; -- user friendly and fastest. ; -------------------------------------------------------------------------------- ; -- fill the sector buffer with data ; for 512 using step1 loop -- loop till the end of the sector buffer ; pata_hd_sector_buffer[step1] = "B" -- set each byte of data ; end loop ; -- write the sector buffer to sector 20 ; pata_hd_write_sector_address(20) ; for 512 using step1 loop -- loop till the end of the sector buffer ; pata_hd_sector_buffer[step1] = "C" -- set each byte of data ; end loop ; -- write the sector buffer to sector 21 ; pata_hd_write_sector_address(21) ; -- ; -- read back the same sectors ; -- read sector 20 into the sector buffer ; pata_hd_read_sector_address(20) ; -- now send it to the serial port ; for 512 using step1 loop -- loop till the end of the sector buffer ; serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port ; end loop ; -- read sector 21 into the sector buffer ; pata_hd_read_sector_address(21) ; -- now send it to the serial port ; for 512 using step1 loop -- loop till the end of the sector buffer ; serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port ; end loop ; ; separator() -- seperate the examples with "----" ; _usec_delay(500_000) -- a small delay ; -------------------------------------------------------------------------------- ; -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as ; -- example 3. ; -------------------------------------------------------------------------------- ; -- get sd card ready for write at sector 20 ; pata_hd_start_write(20) ; -- fill the sector buffer with data ; for 512 using step1 loop -- loop till the end of the sector buffer ; pata_hd_sector_buffer[step1] = "D" -- set each byte of data ; end loop ; -- write the sector buffer to the sd card ; pata_hd_write_sector() ; -- fill the sector buffer with new data ; for 512 using step1 loop -- loop till the end of the sector buffer ; pata_hd_sector_buffer[step1] = "E" -- set each byte of data ; end loop ; -- write the sector buffer to the sd card ; pata_hd_write_sector() -- write the buffer to the sd card ; -- tell sd card you are done writing ; pata_hd_stop_write() ; -- ; -- read back both of the same sectors ; -- get sd card ready for read at sector 20 ; pata_hd_start_read(20) ; -- read the sector into the sector buffer ; pata_hd_read_sector() ; -- now send it to the serial port ; for 512 using step1 loop -- loop till the end of the sector buffer ; serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port ; end loop ; -- read the next sector into the sector buffer ; pata_hd_read_sector() ; -- now send it to the serial port ; for 512 using step1 loop -- loop till the end of the sector buffer ; serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port ; end loop ; pata_hd_stop_read() -- tell sd card you are done reading ; ; ; separator() -- seperate the examples with "----" ; _usec_delay(500_000) -- a small delay -- ---------------------------------------------------------------------------- -- EXAMPLE #5 - spin up & spin down drive command -- ---------------------------------------------------------------------------- for 2 loop pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN) -- turn off motor _usec_delay(5_000_000) -- 5 sec delay pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP) -- turn on motor _usec_delay(5_000_000) -- 5 sec delay end loop separator() -- seperate the examples with "----" _usec_delay(500_000) -- a small delay -- ---------------------------------------------------------------------------- -- Example #6 - identify drive command (Read drive information) -- size of drive, make, model, serial number, etc. -- ---------------------------------------------------------------------------- -- send the identify drive command pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE) -- check if drive is ready reading and set data ports as inputs -- this MUST be used before reading since we did not use pata_hd_start_read pata_hd_data_request(PATA_HD_WAIT_READ) -- Read 512 bytes for 512 loop -- 256 words, 512 bytes per sector data = pata_hd_data_byte serial_hw_data = data end loop -- drive info high/low bytes are in reverse order -------THE END!--------