Author: sebastien.lelong
Date: Fri Jul 10 07:32:57 2009
New Revision: 1101
Added:
trunk/include/external/storage/
trunk/include/external/storage/harddisk/
trunk/include/external/storage/harddisk/pata_hard_disk.jal
trunk/sample/16f877_pata_hard_disk.jal
Modified:
trunk/TORELEASE
Log:
include HD lib + sample
Modified: trunk/TORELEASE
==============================================================================
--- trunk/TORELEASE (original)
+++ trunk/TORELEASE Fri Jul 10 07:32:57 2009
@@ -145,6 +145,7 @@
include/device/18lf13k50.jal
include/device/18lf14k50.jal
include/device/chipdef_jallib.jal
+
# Externals
include/external/co2/co2_t6603.jal
include/external/humidity/humidity_sht.jal
@@ -154,6 +155,7 @@
include/external/lcd/lcd_hd44780_common.jal
include/external/lcd/lcd_hd44780_serial_sw.jal
include/external/ranger/ir/ir_ranger_gp2d02.jal
+include/external/storage/harddisk/pata_hard_disk.jal
include/external/temperature/temperature_tc77.jal
# Jal extension
@@ -304,6 +306,7 @@
sample/16f876a_t6603.jal
sample/16f876a_tc77.jal
sample/16f877_blink.jal
+sample/16f877_pata_hard_disk.jal
sample/16f877a_blink.jal
sample/16f877a_co2_t6603.jal
sample/16f877a_i2c_hw_l1.jal
Added: trunk/include/external/storage/harddisk/pata_hard_disk.jal
==============================================================================
--- (empty file)
+++ trunk/include/external/storage/harddisk/pata_hard_disk.jal Fri Jul 10
07:32:57 2009
@@ -0,0 +1,462 @@
+-- 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.4k
+--
+-- This file is part of jallib (http://jallib.googlecode.com)
+-- Released under the ZLIB license
(http://www.opensource.org/licenses/zlib-license.html)
+--
+-- Description: this library provides functions for pata/ide hard disk
drives.
+--
+-- 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
+--
+-- Notes: If you are not using Alternate Status, Digital Output or Drive
Address registers
+-- pins cs1 & cs0 can be saved by connecting these ide pins to cs0-high,
cs1-low
+--
+-- Variable descriptions:
+-- pata_hd_word_count - counts words read from disk, 256 words in a sector.
+-- You should read full sectors and MUST write full sectors.
+--
+-- Functions descriptions:
+-- pata_hd_init - initialize startup settings
+-- pata_hd_register_write - Select a register and give it a command
+-- or data.
+-- pata_hd_register_read - Select a register and get data from it.
+-- pata_hd_write_pulse - Send a number of write pulses to data
register,
+-- sending 0's as data.
+-- - Used to get to the end of a sector or to get
to a
+-- certain location in a sector.
+-- - Increments pata_hd_word_count.
+-- pata_hd_read_pulse - Send a number of read pulses to data register
+-- without getting any data.
+-- - Used to get to the end of a sector or to get
to a certain
+-- location in a sector.
+-- - Increments pata_hd_word_count.
+-- pata_hd_go_to_sector - Go to a specific sector.
+-- - Set sector count value (number of sectors to
read)
+-- pata_hd_set_address - Select lba/chs mode and master/slave drive.
+-- - set drive sector address
+-- - Set sector count value (number of sectors to
read)
+-- pata_hd_data_request - Wait for drive to be ready for a data
transfer.
+-- - Sets data pins as inputs or outputs for
read/write.
+-- THIS FUNCTION MUST BE USED BEFORE
READING/WRITING SECTORS.
+-- pata_hd_read_data - Read two bytes from disk.
+-- - must use
pata_hd_data_request(PATA_HD_WAIT_READ)
+-- before each 256 reads (before reading each
sector).
+-- - There are 512 bytes in a sector
+-- pata_hd_write_data - Write two bytes to disk
+-- - must use
pata_hd_data_request(PATA_HD_WAIT_WRITE)
+-- before each 256 writes (before writing each
sector).
+-- Data will not be written unless 256 writes
are sent.
+-- - There are 512 bytes in a sector
+--
+-- Pin-outs - PATA IDE 40 pin connector
+-- Power connector - black ground, red +5v, yellow +12v
+-- - 2.5" laptop drives do not need 12v
+-- 2,19,22,24,26,30,40 - connect direct to ground
+-- 1 - /reset, connect to switch (high 5v for normal operation, low resets
drive)
+-- 28 - ALE, connect to -> 1k resistor -> 5v
+-- 39 - ACT, connect to -> LED -> 1k resistor -> 5v
+-- 21,27,20,29,31,32,34, leave not connected
+-- 3,5,7,9,11,13,15,17 - D0-D7, connect direct to pata_hd_data_low pins
+-- 18,16,14,12,10,8,6,4 - D8-D15, connect direct to pata_hd_data_high pins
+-- 23 - /IOW, connect direct to iowr -- see "const bit
PATA_HD_NO_INVERTER"
+-- 25 - /IOR, connect direct to pata_hd_iord -- see "const bit
PATA_HD_NO_INVERTER"
+-- 38 - /cs0, connect direct to pata_hd_cs0 -- see "const bit
PATA_HD_NO_INVERTER"
+-- 37 - /cs1, connect direct to pata_hd_cs1 -- see "const bit
PATA_HD_NO_INVERTER"
+-- 36 - A2, connect direct to pata_hd_a2
+-- 33 - A1, connect direct to pata_hd_a1
+-- 35 - A0, connect direct to pata_hd_a0
+-- Watch for open drain pins on your pic, use pull-up resistors.
+--
+-- Declare the following pin assignments and variables:
+-- var volatile byte pata_hd_data_low is portb -- data
port (low bits)
+-- var volatile byte pata_hd_data_low_direction is portb_direction
+-- var volatile byte pata_hd_data_high is portd -- data
port (high bits)
+-- var volatile byte pata_hd_data_high_direction is portd_direction
+-- var volatile bit pata_hd_a0 is pin_a0
+-- var volatile bit pata_hd_a0_direction is pin_a0_direction
+-- var volatile bit pata_hd_a1 is pin_a1
+-- var volatile bit pata_hd_a1_direction is pin_a1_direction
+-- var volatile bit pata_hd_a2 is pin_a2
+-- var volatile bit pata_hd_a2_direction is pin_a2_direction
+-- var volatile bit pata_hd_cs1 is pin_a3
+-- var volatile bit pata_hd_cs1_direction is pin_a3_direction
+-- var volatile bit pata_hd_cs0 is pin_a4
+-- var volatile bit pata_hd_cs0_direction is pin_a4_direction
+-- var volatile bit pata_hd_iowr is pin_c2
+-- var volatile bit pata_hd_iowr_direction is pin_c2_direction
+-- var volatile bit pata_hd_iord is pin_c1
+-- var volatile bit pata_hd_iord_direction is pin_c1_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_cs1_direction = output -- register select pin
+-- pata_hd_cs0_direction = output -- register select pin
+-- pata_hd_iowr_direction = output -- used for write pulse
+-- pata_hd_iord_direction = output -- used for read pulse
+--
+-- var byte pata_hd_word_count = 0 -- counts words read so you know
where you are in a sector, 256 words per sector.
+-- const bit PATA_HD_NO_INVERTER = true -- if true, an external inverter
chip is not needed for /iowr, /iord, /cs0, /cs1 pins.
+--
+-- include pata_hard_disk -- include the parallel ata ide hard disk
library
+-- pata_hd_init() -- initialize startup settings
+--
+--
+
+
+-- readable/writeable registers
+const PATA_HD_DATA_REG = 8 -- data register
+const PATA_HD_SEC_COUNT_REG = 10 -- sector count
+const PATA_HD_SEC_NUM_REG = 11 -- sector number
+const PATA_HD_CYL_LOW_REG = 12 -- cylinder low
+const PATA_HD_CYL_HIGH_REG = 13 -- cylinder high
+const PATA_HD_SDH_REG = 14 -- sector/drive/head register
+
+-- readable registers
+const PATA_HD_ERROR_REG = 9 -- error register
+const PATA_HD_STATUS_REG = 15 -- status register
+const PATA_HD_ALT_STATUS_REG = 16 -- alternate status
+const PATA_HD_ADDRESS_REG = 17 -- drive address
+
+-- writeable registers
+const PATA_HD_PRECOMP_REG = 9 -- write precomp reg
+const PATA_HD_COMMAND_REG = 15 -- command register
+const PATA_HD_DODC_REG = 16 -- digital output / device control
+
+-- common commands for command register:
+const PATA_HD_RECALIBRATE = 0x10 -- sends drive heads to cyl 0, SC,
SN, and SDH are not changed
+const PATA_HD_READ_SECTOR = 0x20 -- reads data from sector(s)
+const PATA_HD_WRITE_SECTOR = 0x30 -- write data to sector(s)
+const PATA_HD_IDENTIFY_DRIVE = 0xEC -- read drive info such as
make/modem/sn/drive size
+const PATA_HD_SPIN_DOWN = 0xE0 -- turn off the drive's motor
+const PATA_HD_SPIN_UP = 0xE1 -- turn on the drive's motor
+
+-- other constants
+-- used for pata_hd_data_request()
+const BIT PATA_HD_WAIT_READ = 0 -- wait for sector buffer to fill it's
contents with data from disk platters
+const BIT PATA_HD_WAIT_WRITE = 1 -- wait for sector buffer to empty it's
contents to disk platters
+
+-- from "connecting ide drives by tilmann reh" -
http://www.gaby.de/gide/ide-tcj.txt
+-- List of commands and required parameters:
+-- --------------------------------------------------------------------
+-- command type 7 6 5 4 3 2 1 0 hex parameters
+-- --------------------------------------------------------------------
+-- recalibrate * 0 0 0 1 (rate) 10-1F d
+-- read sector * 0 0 1 0 0 m l t 20-27 sc,sn,c,d,h
+-- write sector * 0 0 1 1 0 m l t 30-37 sc,sn,c,d,h
+-- scan id / verify * 0 1 0 0 0 0 0 t 40,41 d,(sc,sn,c,h)
+-- write format * 0 1 0 1 0 0 0 0 50 c,d,h,(sc,sn)
+-- seek * 0 1 1 1 (rate) 70-7F c,d,(h)
+-- exec diagnostics 1 0 0 1 0 0 0 0 90 d
+-- set drive parameters 1 0 0 1 0 0 0 1 91 sc,(c),d,h
+-- read multiple + 1 1 0 0 0 1 0 0 C4 sc,sn,c,d,h
+-- write multiple + 1 1 0 0 0 1 0 1 C5 sc,sn,c,d,h
+-- set multiple + 1 1 0 0 0 1 1 0 C6 sc,d
+-- power commands + 1 1 1 0 0 x x x E0-E6 sc,d
+-- read sector buffer 1 1 1 0 0 1 0 0 E4 d
+-- write sector buffer 1 1 1 0 1 0 0 0 E8 d
+-- identify drive 1 1 1 0 1 1 0 0 EC d
+-- cache on/off + 1 1 1 0 1 1 1 1 EF d,wp
+-- power save + 1 1 1 1 1 x x x F8-FD ?
+
+-- ------------------------------------------------
+-- register abbr.
+-- ------------------------------------------------
+-- data register d
+-- error reg. / write precomp. reg. e / wp
+-- sector count sc
+-- sector number sn
+-- cylinder low c
+-- cylinder high c
+-- sdh (sector size, drive, head) d,h
+-- status reg. / command reg.
+
+
+--
----------------------------------------------------------------------------
+-- initialize startup settings
+--
----------------------------------------------------------------------------
+procedure pata_hd_init() is begin
+ -- set startup setting for read/read pins
+ pata_hd_iowr = low ^ PATA_HD_NO_INVERTER
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Set register select pins to selected register, for internal use only.
+--
----------------------------------------------------------------------------
+procedure pata_hd_select_register(byte in register) is
+
+ -- set register select pins one at a time
+ var bit bit0 at register : 0
+ var bit bit1 at register : 1
+ var bit bit2 at register : 2
+ var bit bit3 at register : 3
+ var bit bit4 at register : 4
+
+ -- setup data bits
+ pata_hd_a0 = bit0
+ pata_hd_a1 = bit1
+ pata_hd_a2 = bit2
+ pata_hd_cs1 = bit3 ^ PATA_HD_NO_INVERTER
+ pata_hd_cs0 = bit4 ^ PATA_HD_NO_INVERTER
+
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Wait for drive to be ready for a data transfer.
+-- Sets data pins as inputs or outputs for next read or write.
+--
----------------------------------------------------------------------------
+procedure pata_hd_data_request(bit in read_write) is begin
+ var bit s
+ var bit drq at pata_hd_data_low : 3 -- set drq pin to check
+ s = 0
+
+ -- set data pins as inputs
+ pata_hd_data_low_direction = all_input
+ pata_hd_data_high_direction = all_input
+
+ pata_hd_select_register (PATA_HD_STATUS_REG) -- select status register
+
+ -- wait for drq in status register to be high.
+ while s == 0 loop
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- start read pulse
+ if drq == high then
+ s = 1 -- exit loop
+ end if
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER -- end read pulse
+ end loop
+
+ -- after drive is ready for data transfer, go to the data register
+ pata_hd_select_register (PATA_HD_DATA_REG)
+
+ if read_write == PATA_HD_WAIT_READ then -- if we are waiting to
read data in
+ -- do nothing since data pins are already inputs
+ else -- if we are waiting to
write data out
+ -- set data ports to outputs
+ pata_hd_data_low_direction = all_output
+ pata_hd_data_high_direction = all_output
+ end if
+
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Registers may not be accessed unless bsy bit is
+-- low due to internal operations.
+--
----------------------------------------------------------------------------
+procedure pata_hd_busy() is begin
+ var bit s
+ s = 1
+ var bit bsy at pata_hd_data_low : 7 -- set bsy pin to check
+
+ -- set data pins as inputs
+ pata_hd_data_low_direction = all_input
+ pata_hd_data_high_direction = all_input
+
+ pata_hd_select_register (PATA_HD_STATUS_REG) -- select status register
+
+ -- wait for bsy in status register to be high
+ while s == 1 loop
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- start read pulse
+ if bsy == low then
+ s = 0 -- end loop
+ end if
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER -- end read pulse
+ end loop
+
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Wait for drive to be up to speed and ready for a command.
+--
----------------------------------------------------------------------------
+procedure pata_hd_drive_ready() is begin
+ var bit s
+ s = 1
+ var bit rdy at pata_hd_data_low : 6 -- set rdy pin to check
+
+ -- set data pins as inputs
+ pata_hd_data_low_direction = all_input
+ pata_hd_data_high_direction = all_input
+
+ pata_hd_select_register (PATA_HD_STATUS_REG) -- select status register
+
+ -- wait for rdy in status register to be high
+ while s == 1 loop
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- start read pulse
+ if rdy == high then
+ s = 0 -- end loop
+ end if
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER -- end read pulse
+ end loop
+
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Select a register and give it a command or data.
+--
----------------------------------------------------------------------------
+procedure pata_hd_register_write(byte in register, byte in low_byte) is
begin
+ var byte high_byte = 0
+
+ -- registers may not be accessed unless drive is not busy
+ pata_hd_busy()
+
+ if register == PATA_HD_COMMAND_REG then
+ -- make sure the drive is up to speed and ready for a command
+ pata_hd_drive_ready()
+ end if
+
+ pata_hd_select_register (register) -- select register
+
+ -- set data ports to outputs
+ pata_hd_data_low_direction = all_output
+ pata_hd_data_high_direction = all_output
+
+ -- send the data trough the ide interface
+ pata_hd_data_low = low_byte -- set low data byte
+ pata_hd_data_high = high_byte -- set high data byte
+ pata_hd_iowr = high ^ PATA_HD_NO_INVERTER -- send write pulse
+ pata_hd_iowr = low ^ PATA_HD_NO_INVERTER
+
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Select a register and get data from it.
+--
----------------------------------------------------------------------------
+procedure pata_hd_register_read(byte in register, byte out low_byte) is
begin
+ var byte high_byte
+
+ -- registers may not be accessed unless drive is not busy
+ pata_hd_busy()
+
+ pata_hd_select_register (register) -- select register
+
+ -- set data ports to inputs
+ pata_hd_data_low_direction = all_input
+ pata_hd_data_high_direction = all_input
+
+ -- get the data trough the ide interface
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- start read
pulse
+ low_byte = pata_hd_data_low -- get low data
byte
+ high_byte = pata_hd_data_high -- get high data
byte
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER -- end read pulse
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Send a number of write pulses to data register sending 0's as data.
+-- Used to get to the end of a sector or to get to a certain
+-- location in a sector.
+-- Increment pata_hd_word_count
+--
----------------------------------------------------------------------------
+procedure pata_hd_write_pulse( byte in z ) is begin
+
+ pata_hd_data_low = 0
+ pata_hd_data_high = 0
+
+ -- send write pulse z number of times
+ for z loop
+ pata_hd_word_count = pata_hd_word_count + 1 -- increment
pata_hd_word_count
+ pata_hd_iowr = high ^ PATA_HD_NO_INVERTER -- send write
pulse
+ pata_hd_iowr = low ^ PATA_HD_NO_INVERTER
+ end loop
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Send a number of read pulses to data register without getting any data.
+-- Used to get to the end of a sector or to get to a certain
+-- location in a sector.
+-- Increment pata_hd_word_count
+--
----------------------------------------------------------------------------
+procedure pata_hd_read_pulse(dword in z) is
+
+ -- send read pulse z number of times
+ for z loop
+ pata_hd_word_count = pata_hd_word_count + 1
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- send read pulse
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER
+ end loop
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Go to a specific sector, select lba/chs mode and master/slave drive
+-- Max sector number is 0x0F_FF_FF_FF or the number of sectors the drive
has.
+-- Max drive size is 0x0F_FF_FF_FF * 512 = 137.439 GB
+-- Sector count selects number of sectors that will be read
+-- Sector count value of 0 means 256 sectors will be read
+--
----------------------------------------------------------------------------
+procedure pata_hd_set_address(byte in pata_hd_head_addr, byte in
cyl_high_addr, byte in cyl_low_addr, byte in sec_num_addr, byte in
sec_count) is
+
+ -- select lba or chs mode
+ var volatile byte pata_hd_sdh_val = 0b_1110_0000
+ var volatile bit pata_hd_lba at pata_hd_sdh_val : 6
+ var volatile bit pata_hd_slave at pata_hd_sdh_val : 4
+
+ -- select drive options
+ pata_hd_lba = true -- 1 = lba mode, 0 = chs
mode (not tested)
+ pata_hd_slave = false -- 0 = master, 1 =
slave (not tested)
+
+ pata_hd_register_write (PATA_HD_SEC_COUNT_REG,sec_count) -- set sec
count register, sectors to read/write
+ pata_hd_register_write (PATA_HD_SEC_NUM_REG,sec_num_addr) -- set sec
number register address
+ pata_hd_register_write (PATA_HD_CYL_LOW_REG,cyl_low_addr) -- set cyl
low register address
+ pata_hd_register_write (PATA_HD_CYL_HIGH_REG,cyl_high_addr) -- set cyl
high register address
+ -- set sector/drive/head register, head number
+ -- pata_hd_head_val address can be 0 to 15
+ pata_hd_register_write (PATA_HD_SDH_REG,pata_hd_sdh_val +
pata_hd_head_addr)
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Go to a specific sector number (lba mode only)
+-- Max sector number is 268435455 or the number of sectors the drive has.
+-- Max drive size is 268435455 * 512 = 137.439 GB
+-- Sector count selects number of sectors that will be read
+-- Sector count value of 0 means 256 sectors will be read
+--
----------------------------------------------------------------------------
+procedure pata_hd_go_to_sector(dword in sector, byte in sec_count) is
+ var byte sec_num_addr,cyl_low_addr,cyl_high_addr,pata_hd_head_addr
+
+ -- change sector number into bytes
+ var byte dval[4] at sector
+ sec_num_addr = dval[0]
+ cyl_low_addr = dval[1]
+ cyl_high_addr = dval[2]
+ pata_hd_head_addr = dval[3]
+
+ -- go to the address
+ pata_hd_set_address
(pata_hd_head_addr,cyl_high_addr,cyl_low_addr,sec_num_addr,sec_count)
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Read two bytes from disk.
+-- must use pata_hd_data_request(PATA_HD_WAIT_READ) before each 256 reads
+-- (before reading each sector)
+--
----------------------------------------------------------------------------
+procedure pata_hd_read_data(byte out low_byte, byte out high_byte) is
+ pata_hd_word_count = pata_hd_word_count + 1 -- increment
pata_hd_word_count
+
+ -- get the data trough the ide interface
+ pata_hd_iord = high ^ PATA_HD_NO_INVERTER -- start read pulse
+ low_byte = pata_hd_data_low -- get low data byte
+ high_byte = pata_hd_data_high -- get high data byte
+ pata_hd_iord = low ^ PATA_HD_NO_INVERTER -- end read pulse
+end procedure
+
+--
----------------------------------------------------------------------------
+-- Write two bytes to disk
+-- must use pata_hd_data_request(PATA_HD_WAIT_WRITE) before each 256 writes
+-- (before writing each sector)
+-- Data will not be written unless 256 writes are sent.
+--
----------------------------------------------------------------------------
+procedure pata_hd_write_data(byte in low_byte, byte in high_byte) is
+ pata_hd_word_count = pata_hd_word_count + 1 -- increment
pata_hd_word_count
+
+ -- send the data trough the ide interface
+ pata_hd_data_low = low_byte -- set low data byte
+ pata_hd_data_high = high_byte -- set high data byte
+ pata_hd_iowr = high ^ PATA_HD_NO_INVERTER -- send write pulse
+ pata_hd_iowr = low ^ PATA_HD_NO_INVERTER
+end procedure
+
Added: trunk/sample/16f877_pata_hard_disk.jal
==============================================================================
--- (empty file)
+++ trunk/sample/16f877_pata_hard_disk.jal Fri Jul 10 07:32:57 2009
@@ -0,0 +1,236 @@
+-- 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.4k
+--
+-- 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 chip
+include 16f877 -- target picmicro
+;include 16f877a -- target picmicro
+;include 18F452 -- target picmicro
+
+-- this program assumes a 20 mhz resonator or crystal
+-- is connected to pins osc1 and osc2.
+pragma target osc hs -- hs crystal or resonator
+pragma target clock 20_000_000 -- oscillator frequency
+--
+pragma target wdt disabled
+pragma target lvp disabled
+--
+
+enable_digital_io() -- disable all analog pins if any
+
+include delay -- include the delay library
+
+-- setup uart for communication
+const usart_hw_serial = true -- true = rs232, false = spi
+const serial_hw_baudrate = 38400 -- set the baudrate
+include serial_hardware
+serial_hw_init()
+
+-- pin assignments
+var volatile byte pata_hd_data_low is portb -- data port
(low bits)
+var volatile byte pata_hd_data_low_direction is portb_direction
+var volatile byte pata_hd_data_high is portd -- data port
(high bits)
+var volatile byte pata_hd_data_high_direction is portd_direction
+var volatile bit pata_hd_a0 is pin_a0
+var volatile bit pata_hd_a0_direction is pin_a0_direction
+var volatile bit pata_hd_a1 is pin_a1
+var volatile bit pata_hd_a1_direction is pin_a1_direction
+var volatile bit pata_hd_a2 is pin_a2
+var volatile bit pata_hd_a2_direction is pin_a2_direction
+var volatile bit pata_hd_cs1 is pin_a3
+var volatile bit pata_hd_cs1_direction is pin_a3_direction
+var volatile bit pata_hd_cs0 is pin_a4
+var volatile bit pata_hd_cs0_direction is pin_a4_direction
+var volatile bit pata_hd_iowr is pin_c2
+var volatile bit pata_hd_iowr_direction is pin_c2_direction
+var volatile bit pata_hd_iord is pin_c1
+var volatile bit pata_hd_iord_direction is pin_c1_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_cs1_direction = output -- register select pin
+pata_hd_cs0_direction = output -- register select pin
+pata_hd_iowr_direction = output -- used for write pulse
+pata_hd_iord_direction = output -- used for read pulse
+
+var byte pata_hd_word_count = 0 -- counts words read, 256 words in a
sector.
+const bit PATA_HD_NO_INVERTER = true -- if true, an external inverter chip
is not needed on /iowr, /iord, /cs0, /cs1 pins
+
+include pata_hard_disk -- include the parallel ata ide hard disk
library
+pata_hd_init() -- initialize startup settings
+
+-- Function for sending hard disk data via serial port, data is read 2
bytes at a time.
+procedure send_word(byte in lowbit, byte in highbit) is
+ serial_hw_write( lowbit ) -- send 1st serial data byte
+ serial_hw_write( highbit ) -- send 2nd serial data byte
+end procedure
+
+-- Declare variables for this example.
+var byte in_a
+var byte in_b
+
+-----main prog----
+
+_usec_delay (1_000_000) -- wait for power to stabilize
+
+-- send "start" to pc / test uart communication
+send_word ("S", "T")
+send_word ("A", "R")
+send_word ("T", 0x20)
+send_word (13, 10)
+send_word (13, 10)
+
+--
----------------------------------------------------------------------------
+-- Example spin up & spin down drive command
+--
----------------------------------------------------------------------------
+for 2 loop
+ pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP) --
turn on motor
+ _USEC_DELAY (5_000_000) -- 5 sec delay
+ pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN) --
turn off motor
+ _USEC_DELAY (5_000_000) -- 5 sec delay
+END LOOP
+
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP) --
turn on motor
+
+_USEC_DELAY (10_000_000) -- wait 10 seconds before next example
+
+--
----------------------------------------------------------------------------
+-- Example read sectors command
+--
----------------------------------------------------------------------------
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_RECALIBRATE) --
recalibrate the drive
+
+-- go to sector 0 (the boot sector)
+-- and set sector count to read 2 sectors
+pata_hd_go_to_sector (0,2)
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_READ_SECTOR) -- send
the read command to the command register
+
+-- hard disk led will turn on at this point
+
+-- check if drive is ready for reading and set data ports as inputs
+-- this MUST be used before reading each sector
+pata_hd_data_request(PATA_HD_WAIT_READ)
+-- Read one sector
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_read_data (in_b, in_a) -- read data
+ send_word (in_b, in_a) -- send data via serial port
+end loop
+
+-- You will see hard disk LED on during this delay
+-- because you did not read 2 sectors yet.
+_USEC_DELAY (2_000_000) -- 2 second delay
+
+-- check if drive is ready for reading and set data ports as inputs
+-- this MUST be used before reading each sector
+pata_hd_data_request(PATA_HD_WAIT_READ)
+-- Read 2nd sector.
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_read_data (in_b, in_a) -- read data
+ send_word (in_b, in_a) -- send data via serial port
+end loop
+
+-- hard disk led will turn off at this point.
+
+_USEC_DELAY (10_000_000) -- wait 10 seconds before next example
+
+--
----------------------------------------------------------------------------
+-- Example identify drive command (Read drive information)
+-- size of drive, make, model, serial number, etc.
+--
----------------------------------------------------------------------------
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE) --
recalibrate the drive
+
+-- check if drive is ready reading and set data ports as inputs
+-- this MUST be used before reading each sector
+pata_hd_data_request(PATA_HD_WAIT_READ)
+-- Read 512 bytes
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_read_data (in_b, in_a) -- read data
+ send_word (in_a, in_b ) -- send data via serial port
+end loop -- drive info high/low bytes are
in reverse order
+
+
+_USEC_DELAY (10_000_000) -- wait 10 seconds before next example
+
+--
----------------------------------------------------------------------------
+-- Example write sectors command
+-- note: this will over write data currently on your drive
+--
----------------------------------------------------------------------------
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_RECALIBRATE) --
recalibrate the drive
+
+-- go to sector 200
+-- and set sector count to write 2 sectors
+pata_hd_go_to_sector (200,2)
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_WRITE_SECTOR) -- send
the write command to the command register
+
+-- check if drive is ready for next write and set data ports as outputs
+-- this MUST be used before writing each sector
+pata_hd_data_request(PATA_HD_WAIT_WRITE)
+-- write one sector, data will not be written unless 512 bytes are sent
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_write_data (0xAA, 0xBB) -- write data 0xAA, 0xBB over and over
+end loop
+
+-- You will see hard disk LED on during this delay
+-- because you did not write 2 sectors yet.
+_USEC_DELAY (2_000_000) -- 2 second delay
+
+-- check if drive is ready for next write and set data ports as outputs
+-- this MUST be used before writing each sector
+pata_hd_data_request(PATA_HD_WAIT_WRITE)
+-- now write one more sector, data will not be written unless 512 bytes
are sent
+for 250 loop
+ pata_hd_write_data (0xCC, 0xDD) -- write data 0xCC, 0xDD over and over
+end loop
+-- only 250 writes sent so lets finnish the sector with 6 more write
pulses (0's as data)
+pata_hd_write_pulse (6)
+
+-- hard disk led will turn off at this point.
+
+
+
+-- Now read the 1st sector you just wrote, should get 0xAA, 0xBB over and
over
+pata_hd_go_to_sector (200,2) -- go sector 200
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_READ_SECTOR) -- send
the read command
+
+-- check if drive is ready for reading and set data ports as inputs
+-- this MUST be used before reading each sector
+pata_hd_data_request(PATA_HD_WAIT_READ)
+-- now get the data
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_read_data (in_b, in_a) -- read data
+ send_word (in_b, in_a) -- send data via serial port
+end loop
+
+-- Now read the 2nd sector you just wrote, should get 250 x (0xCC, 0xDD)
+-- and you will get 6 x (0x00 0x00) at the end of the sector that we wrote.
+
+-- check if drive is ready for reading and set data ports as inputs
+-- this MUST be used before reading each sector
+pata_hd_data_request(PATA_HD_WAIT_READ)
+-- now get the data
+for 256 loop -- 256 words, 512 bytes per sector
+ pata_hd_read_data (in_b, in_a) -- read data
+ send_word (in_b, in_a) -- send data via serial port
+end loop
+
+-- We're done, lets turn off the hd motor
+pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)
+
+
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"jallib" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/jallib?hl=en
-~----------~----~----~----~------~----~------~--~---