WHAT IS THIS?							wiml@netcom.com
-------------							v0.1  22Oct1994

A PIC programmer. Specifically, I wrote this to program
  a PIC 16C84
  through the parallel printer port
  of a Linux box
  using the PIC's serial programming mode
  and a homebuilt programmer loosely based on David Tait's.

However, it uses a configuration file which should allow it to use almost
any parallel-port based programmer; and the low-level I/O is in a
separate file which could easily be replaced for operating systems
other than Linux.

Right now it reads the "pictools format" files generated by Ian King's
PIC assembler picasm. (Check ftp.funet.fi:pub/microprocs/pic for that
and other PIC tools.) The pictools format has a couple of problems;
I might change the programmer to read INHX files, or develop a third
format. (I don't particularly want to add to the prolifration of file
formats, but...)

This is *not* a "production" programmer; it doesn't do supply margining,
or probably a couple of other things. However, you have the source,
so you can make it do whatever you want.

This file is the only documentation aside from the source code; read
it thoroughly --- there are many gotchas in the system.

This release is stable enough that I'm using it for my own tinkering
with PICs and am doing development basically only when I discover
it won't do something I want it to do. It should work basically
out of the box, but it's not for the technically faint of heart
(but then, if you're not comfortable mucking about with the
system when it misbehaves, why are you running Linux?) 

If you make modifications or improvements, PLEASE send them to me so
that I can maintain a coherent master copy and hopefully integrate
everything into a portable, versatile, bulletproof driver.

INSTALLATION
------------

On a Linux box, this should compile out of the box; just type 'make'. The
executables must be setgid kmem to run from a normal account; the makefile
will prompt you for your root password so it can do this --- if you don't
like that, change the $SETGID variable in the Makefile, or just enter
a garbage password and setgid them yourself. 

On non-Linux machines, you will probably have to replace io_ports.c with
whatever is appropriate to your system. This file contains routines to
implement basic byte I/O by reading and writing /dev/port. On operating
systems with no hardware protection (DOS, Windows, ...), you can just use
inb() and outb().

Please send let me know about any changes you have to make to get this
to work with your setup.

Before running any of the programs (except lpttool) you will have to create
the lp_cfg file. This file tells the program what pins on the I/O port
control what functions of the programmer; it must be found in the cwd
when the program starts. The file contains name-value pairs, one per line,
with the value separated from the name by either a colon or an equals sign.
Blank lines, and anything following a hash mark, are discarded.

To name a pin, use the following symbols:
  d0 through d7  Data bits 0 through 7.
  c0 through c7  control-word bits 0 through 7.
  s0 through s7  status-word bits 0 through 7.
  ! or ~         indicates this bit is active low
  busy	         status 7, the "printer busy" bit
  ack            status 6, the printer "ack" bit
  error          status 3, ... you get the picture.

The control-word and status-word names refer to the word read from
the relevant I/O address. You'll have to look these up somewhere if
you're using something other than busy, ack, and error.

The programmer requires the following bits to be named:
  power --- set to 1 when the programmer wants the PIC's Vdd = +5v
  mclr  --- set to 1 when the programmer wants the PIC's /MCLR = +13v
  clock --- used to clock data into the PIC (connect to PIC pin 12)
  data  --- used to write data (pin 13)
  data_f -- sense return for data (pin 13)
  clock_f - sense return for clock (pin 12)

  rb6   --- synonym for "clock"
  rb7   --- synonym for "data"
  rb6_f --- synonym for "clock_f"
  rb7_f --- synonym for "data_f"

Also, if your parallel port has a base I/O address other than the
default 0x378, you can specify this as e.g. "base = 0x278".

Here's an example configuration file showing some of the legal syntax. This
is the configuration file I use; it works with the simple programmer whose
schematic is in schematic.ps.

power = !d1
mclr: !d0
rb7: ~d2
clock: ~d3
data_f = ~ack
rb6_f = ~s4
base = 0x378

USAGE
-----

Except for lpttool, all of these programs do a little bit of self-testing
when they start up. If you get an error along the lines of "3 bad states"
followed by an exit, this means that the self test failed. The test consists
of putting the clock and data lines into their 4 possible states and checking
that the clock_f and data_f lines change accordingly. The "bad states" 
indicates how many of these combinations were not read back correctly.

lpttool:

This allows you to read and write to & from the parallel port
to test its basic operation or troubleshoot a recalcitrant circuit.
It is invoked with an optional argument which is the base address of the
parallel port to use (default 0x378). It accepts input in the following
forms:
  - blank lines cause lpttool to read the status port (base+1) and
    display its value in decimal and hex, as well as symbolically
  - a line beginning with a question mark will read the data address
    and display the value in decimal and hex
  - anything else will be interpreted as a decimal number and written to
    the data port
    
jig:

This allows you to run a PIC serial programmer under manual control.
It will display simple instructions on startup.

dump:

This will read the first 16 locations of data memory and the first 30
locations of program memory and dump them to stdout in pictools format
(approximately). This is really only a skeleton of what a real 
dumping program would be.

prog84:

what you've been waiting for --- this will program a 16C84 from a pictools
format file. It has the following command-line options:
  -v  be verbose. If this occurs on the command line twice, it will be
      very verbose. Three times is ridiculous.
  -i nnn nnn nnn nnn   Program the ID locations with the supplied values
  -p filename   Program the chip from the given filename (pictools format)
  -h            simple help
  -b, -a  Verify the location being programmed before and/or after it
     is programmed. If you use -b, then prog84 will not waste time
     programming locations that already havethe correct value. If you
     do not use -a, prog84 will not verify locations after it programs them.
     It's probably always a good idea to use both -a and -b.


NOTES
-----

It's assumed that the drivers are open-collector with pullups, so the
program writes a 1 when it wants the PIC to be able to drive the line.

The program is a good deal slower than it needs to be. There are a lot
of places where the Microchip databook requires a delay of at least
one microsecond. In these places I've put a usleep(1) call, since
a fast PC could possibly violate the timing restriction; but I suspect
that Linux is waiting for a full jiffy (1/60 sec?). I need a call
with better resolution. Maybe a busy wait?

TODO
----

lpb_cfg_read() isn't very polished. The "base" spec shouldn't be special-
cased; maybe there should be a "type" field in the name vector.

The parseBit() routine should be spruced up so that it's smart enough to
parse the symbolic names for all the status and control lines. The simpleminded
parsing algorithm it uses now just doesn't cut it.

Although the bits used are very configurable, the programmer can't deal
with not having a clock_f line even though it doesn't ever use it.
The self-test will fail without a clock_f line. If you don't have a 
clock_f line, you can just hack around the self-test in prog84.c.

The configuration file lp_cfg is always read from the cwd. 

Is the name "prog84" taken? If so, I should think of a new one. Come to think
of it, if anyone uses this to program a 6x or 7x, the name should be changed
to reflect its slightly more general abilities...
