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
-~----------~----~----~----~------~----~------~--~---

Reply via email to