
                         1-Wire Public Domain Kit

     General Port Targeted for Dallas Semiconductor's 8051-Equivalent



Introduction
------------

   This port was targeted for and tested on a Systronix development board,
   the HSM550, with a Dallas Semiconductor DS87C550 rev. A7 using a 33 mhz
   crystal.  The code was built and simulated using Keil's PK51 development
   package version 5.10.

   If you're using the same board, processor, and crystal, you're probably
   ready to go with no changes at all (if not, see "Configuring For Another
   Setup" in this document).  Just load the hex file and hook up your 1-
   Wire network.  The default serial port for user I/O is serial1, the same
   port the HSM550's loader runs off of, with a baud rate of 9600bps (8
   data, no parity, 1 start and stop bit).  Just connect a straight-through
   serial cable to the port labeled COM1.  Connect your 1-Wire Network
   using the board's supplied RJ11 connector.

   PLEASE NOTE: There are no protections whatsoever on the HSM550 for the
   microcontroller's port pin if there is something wrong with your 1-Wire
   Network.  If, for example, your 1-Wire Network experiences a surge from
   an external source (say a lamp's power supply connected to a 1-Wire
   switch), you will very likely damage or even destroy your
   microcontroller.  Unless you have an unlimited supply of micros, please
   use this port with caution. For methods of protecting your
   microcontroller, see "Setting up General 1- Wire" in this document.

   After connecting up your I/O, follow the instructions provided by
   Systronix for loading the provided hex file(s) that came with this
   build.  The two applications included are:

     tstfindm.hex - Finds all iButtons on the 1-Wire Network and displays
                    their 48-bit ROM.

     tempm.hex - Finds all temperature devices (Family Code 10) on the 1-Wire
                 Network and loops through them continuously displaying their
                 48-bit ROM followed by the reported temperature in Celsius.


Configuring For Another Setup
-----------------------------

   If you have another setup than what was initially targeted, you should
   be able to configure the source (hopefully only small changes) fairly
   easily and rebuild.  Here are a checklist of some of the options you
   will need to look at:


 - Crystal

      If you're using anything other than a 33mhz crystal or if
      you're using a processor that doesn't support 4 clocks per machine
      cycle, you're going to need to adjust the usDelay routine found in
      the DS550LNK.C file.  Using 33mhz and 4 clocks/cycle, means I'm
      executing at approximately 8.25mhz.  Which means I need 8.25
      instruction cycles for 1 microsecond of time.  There is no quarter of
      a microsecond instruction, so I did 8 cycles and accounted for the
      error in my calling routines. This function will have to be
      calibrated, or possibly re-written, to suit your set up.

      Also, double-check the accuracy of the baud rates. Depending on your
      crystal, some baud rates may not be an option.  The timer reload
      value for a given baud rate is calculated using this formula:
        TH1 = 256 - ( (2^SMOD/32) * ( xtal / (T1DIV * required_baud) ) )

      SMOD is the serial doubler configuration bit.  T1DIV is either 4 or
      12, depending on whether or not you configured the timer to tick off
      4 external clock cycles or 12 external clock cycles.  Go ahead and do
      the math, dropping any fraction (T1DIV defaults to 4 and SMOD to 1 in
      the SER550.H calculations).  Then plug it back into the following
      equation:
        actual_baud = (2^SMOD/32) * ( xtal / (T1DIV * (256-TH1)) )

      Now, calculate your percentage error:
        %error = ((actual_baud - required_baud)/required_baud) *100%

      If the absolute value of your percentage error is greater than 2%,
      than that baud rate isn't going to be an option for you.

      In the file SER550.H, be sure to change the following line to match
      your crystal frequency:
        #define OSCILLATOR 33000000


 - Processor

      If you're using a 8051-equivalent processor other than the 550, there
      are just a few things to check on.  If you're using another Dallas
      Semiconductor high-speed micro that is very similar to the 550, you
      obviously have less to check.  First, check to see if you're
      processor can support 4 clocks/cycle. If it can't, you'll have to re-
      write the usDelay routine in DS550LNK.C.

      If you're using a 550 micro that's an older revision than the A7,
      you're likely to encounter a lot of problems with the serial I/O.  It
      could be that for your application, serial I/O isn't a problem (maybe
      you'd prefer pushbuttons and leds?), but if that isn't the case,
      you're going to have to "tweak" the serial routines a little bit or
      get a newer 550.  The 550 that came with my Systronix HSM550 is a
      revision A2, so I swapped it out with a newer A7.  Here's how to read
      the top of micro to see which revision you have:

      --------------        --------------
      | DS87C550   |   ->   | Part #     |
      | QCL        |   ->   | Type       |
      | 0107A7     |   ->   | yymmREV    |
      | 802AB      |   ->   | Lot info   |
      --------------        --------------

      There are numerous serial bugs on the 550s prior to A7.  If you're
      stuck with the A2 that came with the Systronix board, you're going to
      have to modify the getchar routines to work around some of these
      bugs.  First, you'll need to calculate the magical delay:
        serDelay = 1/(baud*16) seconds

      After clearing the transmit flag, you'll need to wait at least
      serDelay seconds before placing a new byte on the buffer. Also,
      clearing the transmit flag may not succeed, so you'll need to retry it
      until it does.  And lastly, after polling the receive flag, you'll
      need to wait serDelay seconds before reading a byte off the buffer.
      So, serial0_putchar and serial0_getchar (and equivalently
      serial1_putchar and serial1_getchar) from SER550.C can be modified to
      take these changes into account by uncommenting the necessary lines
      from the functions.  By the description of the three bugs, the
      necessary lines should be obvious, but don't forget to check both the
      polling routines and the interrupt-driven routines.

      To test any problems that you're having with serial I/O, the first
      thing I would do is turn off interrupt-driven serial I/O (switch to
      polling) by setting USE_SERIAL_INTERRUPTS to 0 in the SER550.H file.
      This will greatly reduce the complexity of the problem at hand.  If
      the polling routines are working correctly, check the interrupt
      vectors for the serial routines.  For the 550, the serial0 interrupt
      is at vector 0x6B and serial1 is at vector 0x0B.  The way to
      calculate the interrupt number that Keil uses (void serialIRQ(void)
      interrupt X) is:
        vector = (X * delta) + base;  // delta=0x08, base=0x03

      Make sure that the interrupt number matches the proper offset using
      that formula.  Also, you can double-check using the table under
      Interrupt Functions in the C51 Compiler user's guide.  Note that the
      550's interrupt vector table was changed to match the Phillips
      standard, making it unlike most other Dallas Semiconductor high-speed
      micros.


 - Board:

      On the Systronix HSM550, the decision of where to connect your 1-Wire
      network has already been made for you.  You'll find it on port 3, pin
      4. There is only one pin for reading and writing the 1-Wire network
      and there are no protections on this pin for preserving your micro,
      so be careful.  If you're going to attach you're own 1-Wire port to
      the prototyping area or if you've got a different board and you need
      to attach your own, skip ahead to "Setting Up General 1-Wire".  The
      one configuration option you should be aware of is the SER550.H file
      has a definition of the port pin, OW_PORT, which you will probably
      need to update after you select your own port pin.  If you choose a
      dual port configuration, you will, naturally, have to change the code
      to support it.  Don't worry, because the changes should be minor.
      owTouchReset and owTouchBit in the DS550LNK.C file and owAcquire in
      the DS550SES.C should be the only functions you'll need to worry
      about.


Setting Up General 1-Wire
-------------------------

   Recently, a lot of effort has gone into figuring out just how long that
   wire can be in your 1-Wire network.  There're a lot of "real-world
   physics" problems that pop up when you try to run a few hundred devices
   across a single wire just under a mile long.  If you're going to have a
   complicated setup (by complicated, I mean any cable too long to sit on
   your desk with more 1-Wire devices than will fit on your desk), I
   strongly recommend you spend some time reading the various app notes
   that explain how to build a robust 1-Wire network.  The early investment
   of your time will save you a great deal of debugging headaches and
   oscilliscope work later.  Application Note 132, Application Note 108,
   and the Book of iButton Standards are going to be required reading in
   this case (for URL, see end of document).  If you're using newer parts,
   such as the Thermochron or the humidity sensor, there are known issues
   with regards to sensitivity to noise.  The controlled slew-rate, as
   mentioned in those documents, will be of special importance to resolving
   those sorts of noise issues.  Note also that most of the "good" setups
   for 1-Wire use two port pins, one for reading and one for writing.

   If, however, you're going to use just a few dozen devices around your
   small office, a quick and dirty approach may be more suitable.  While
   porting this software to a development board made by Keil, the MCB520, I
   used a less-robust (yet slew-rate controlled) design found in the pdf
   (schematic.pdf) that came with this distribution.  My initial run with
   that board had only the pull-up resistor.  When talking to multiple
   Thermochron parts, I noticed a lot of noise in the communication.  The
   second revision of the design is what you see in the schematic.  The
   capacitor adds a nice, cleaner descent when the network is pulled to
   ground, removing most of the noise.


Rebuilding From the Sources
---------------------------

   All of the development for this build was done on Windows 2000 using
   UltraEdit for an editing environment and Cygwin for a build environment.
   Cygwin is a unix environment for windows, including a lot of free tools
   such as Make, hence the Makefile that is included with this build.  You
   don't need Cygwin to build from the sources, Make will just ease the
   pain.  One note though, if you are using Make, Keil's linker (BL51)
   returns an error status if it produces a warning.  When Make sees this,
   it aborts the build process.  Using "make -i" is a workaround to this
   problem.  The same setup rules for C51 still apply, even if you are
   using Make (i.e. don't forget to set environment variables C51INC and
   C51LIB to point to your include and library directories).

   Otherwise, if you're not using make, you'll use the standard build
   process.  Compile all the the source files, one at a time, using C51:
      C51 filex.c MODDP2 LARGE OT(6,SIZE)

   You can set flags on the command line using DF:
      C51 filex.c MODDP2 LARGE OT(6,SIZE) DF(DEBUG,MAX_PORTNUM=2)

   After compiling DS550LNK.c, you'll have to assemble the generated file:
      A51 ds550lnk.a51

   Then link the files together:
      BL51 tempm.o, ds550lnk.o, etc, etc

   Finally, convert the outputted file into a HEX file:
      OH51 tempm

   Some things to look into if you're using a non-Keil compiler are, first,
   how does your compiler handle interrupt routines?  You'll have to modify
   the routines in SER550.C to match your compilers syntax.  Second, how
   does your compiler handle inline assembly?  Keil uses "#pragma asm" and
   "#pragma endasm" to delimit the inline assembly, but you also have to
   use "#pragma src(file.a51)" to specify the output filename for the
   generated assembly file (see DS550LNK.C).  Other than that, there should
   be no compiler specific code (other than the definitions of the
   registers in the header file, but hopefully your compiler has an
   equivalent header file.)


Debugging Problems
------------------

   New to this release of the 1-Wire Public Domain Kit is a mechanism for
   managing an exception stack along with a structure for communicating to
   the debugger (you, in this case) what error occurred as well as the
   filename and line number where it occurred.  Additionally, compile-time
   options allow you to "choose" the overhead involved with storing the
   errors.  For example, if you compile with a DEBUG flag set, the line
   number and filename are stored along with the error, otherwise just the
   error number is kept on the stack.  Compiling with the
   SMALL_MEMORY_TARGET flag set, excludes the array of meaningful error
   message strings.  Now only the error number is available for reporting.
   This is very likely a good choice for 1-Wire developers using
   microcontrollers.

   Due to the limited code size, the reporting part of that error handling
   is turned off by default in the provided sample applications.  If you
   encounter any problems that are related to the library calls, try
   "turning it on" with something like the following:

     if( this_line_failed() )
     {
        while( owHasErrors() )
           owPrintErrorMsgStd();
     }

   If you ask questions on the 1-Wire mailing list about problems with the
   library, the output of this code will help tremendously in debugging the
   problem.


New Version of Public Domain Kit
--------------------------------

   This microprocessor-specific release of the Public Domain Kit has a sort
   of sneak preview of what's to come in the next release of the rest of
   the applications in that kit.  Since this build for the 550 will be
   released well before the new version of the entire kit is released, it's
   a good idea to look at some of these changes.  This will effect the
   interoperability between the source included with this build and source
   that we distribute with the library.

   The first change is, as mentioned in the previous section, a mechanism
   for managing an exception stack.  The second change, and probably most
   intrusive, is the introduction of a new type, SMALLINT.  A lot of
   functions in the 1-Wire PD kit used integers (where a much smaller type
   could have been used) with the assumption that the integer was going to
   default to be the most comfortable size for the architecture.  This is
   definitely true for most desktop architectures, but not true in the
   realm of microcontrollers.  You'll notice a lot of functions that used
   to return an 'int' for true or false, now return SMALLINT.  This allows
   for compile-time selection of the size of the type, so it can easily be
   adjusted for different platforms.  Any place where a SMALLINT is used,
   it is assumed that a variable as small as a single byte is large enough
   to hold the value.

   This means, if you try to link the source included with this build with
   source from a previous version of the library, you're going to have some
   problems.  If you must link against old libraries, compiling with
   SMALLINT as 'int' should fix the problem.  Otherwise, you're going to
   have to incorporate the SMALLINT into your code and/or wait for the next
   major release of the Public Domain Kit.

   Another change was made to the library to accomodate microprocessors.
   A few functions passed messages between each other through the use of a
   message buffer (a large character array).  This was especially useful
   for communicating if there were any failures and what possibly caused
   them.  The callee module could then display the error message to the
   user for debugging.  This is an "expensive" way to do error handling as
   low memory devices can't really afford to give every module a large
   character array.  This technique was made obsolete by the new error
   handling API and, as such, the methods that used the old technique
   (like owAcquire and owRelease) have been modified.


General Notes
-------------

   - All relevant application notes can be found at:
     http://www.ibutton.com/ibuttons/data-apps.html

   - High-Speed Micro User's Guide:
     http://www.dalsemi.com/datasheets/userguides.html

   - Datasheet for Systronix HSM550:
     http://www.systronix.com/hsm550/hsm550.htm

   - 1-Wire Mailing List:
     http://lists.dalsemi.com/mailman/listinfo/1-wire-software-development
