Smartcat (BL2100) User's Manual

> ## 4. Software

> Dynamic C Premier is an integrated development system for writing embedded software. It runs on an IBM-compatible PC and is designed for use with Z-World single-board computers and other devices based on the Rabbit microprocessor.

> Chapter 4 provides the libraries, function calls, and sample programs related to the BL2100.

> You have a choice of doing your software development in the flash memory or in the static RAM included on the BL2100. The advantage of working in RAM is to save wear on the flash memory, which is limited to about 100,000 write cycles.

> NOTE | An application can be developed in RAM, but cannot run standalone from RAM after the programming cable is disconnected. All standalone applications can only run from flash memory.

> The disadvantage of using flash memory for debug is that interrupts must be disabled for approximately 5 ms whenever a break point is set in the program. This can crash fast interrupt routines that are running while you stop at a break point or single-step the program. Flash memory or RAM is selected on the Options > Compiler menu.

> Dynamic C Premier provides a number of debugging features. You can single-step your program, either in C, statement by statement, or in assembly language, instruction by instruction. You can set break points, where the program will stop, on any statement. You can evaluate watch expressions. A watch expression is any C expression that can be evaluated in the context of the program. If the program is at a break point, a watch expression can view any expression using local or external variables.

> ### 4.1 Programming Cable

> The programming cable has a level converter board in the middle of the cable since the BL2100 programming port supports CMOS logic levels, and not the higher voltage RS-232 levels that are used by PC serial ports. When the programming cable is connected, Dynamic C running on the PC can hard-reset the BL2100 and cold-boot it. The cold boot includes compiling and downloading a BIOS program that stays resident while you work. If you crash the target, Dynamic C will automatically reboot and recompile the BIOS if it senses that a target communication error occurred or that the BIOS source code has changed.

> #### 4.1.1 Switching Between Program Mode and Run Mode

> The BL2100 is automatically in Program Mode when the programming cable is attached, and is automatically in Run Mode when no programming cable is attached. See Figure 21.

> Figure 21. BL2100 Program Mode and Run Mode Set-Up

> #### 4.1.2 Detailed Instructions: Changing from Program Mode to Run Mode

> 1. Disconnect the programming cable from header J1 of the BL2100 module.
> 2. Reset the BL2100 by unplugging the AC adapter, then plugging it back in.

> The BL2100 is now ready to operate in the Run Mode.

> #### 4.1.3 Detailed Instructions: Changing from Run Mode to Program Mode

> 1. Attach the programming cable to header J1 of the BL2100 module.
> 2. Reset the BL2100 by unplugging the AC adapter, then plugging it back in. Alternatively, you may press <Ctrl-Y> on your PC if Dynamic C is running.

> The BL2100 is now ready to operate in the Program Mode.

> ### 4.2 BL2100 Libraries

> With Dynamic C running, click File > Open, and select Lib. The following list of Dynamic C libraries and library directories will be displayed.

> Two library directories provide libraries of function calls that are used to develop applications for the BL2100.

> - BL2100--libraries associated with features specific to the BL2100. The functions in the BL21xx.LIB library are described in Section 4.3, "BL2100 Function APIs,".
> - TCPIP--libraries specific to using TCP/IP functions on the BL2100.

> Two other library directories provide libraries of function calls that are used to develop applications for the optional BL2100 LCD/keypad module.

> - DISPLAYS\GRAPHIC--libraries associated with LCD display.
> - KEYPADS-libraries associated with the keypad.

> The LCD/keypad module functions are described in Section C.6. Other generic functions applicable to all devices based on the Rabbit 2000 microprocessor are described in the Dynamic C Premier User's Manual.

> ### 4.3 BL2100 Function APIs

> #### 4.3.1 Board Initialization

> ##

> void brdInit (void);

> Call this function at the beginning of your program. This function initializes the system I/O ports and loads all the A/D converter and D/A converter calibration constants from flash memory into SRAM for use by your program. If the LCD/keypad module is installed, this function will turn off LED DS1 to indicate that the initialization was successful.
> The ports are initialized according to Table A-4 in Appendix A-5.
> SEE ALSO

>     digOut, digIn, serMode, anaOut, anaIn, anaInDriver, anaOutDriver

> #### 4.3.2 Digital I/O

> ##

> void digOutConfig(unsigned int outputMode);

> Each of the BL2100 high-current outputs (OUT00-OUT15) has the capability of being configured in software as either sinking or sourcing using the digOutConfig function. Execute digOutConfig at the start of your application to initially set OUT00-OUT15 to be OFF for the type of circuit that you have, either sinking or sourcing.
> To properly set the high-current outputs, you will need to decide for each channel whether the output is sinking or sourcing. The digOutConfig function will then ensure that each output remains OFF when the digital output control interface is initialized. The individual high-current outputs remaininactivated until you activate the desired output driver(s)/channel(s) using digOut.

> NOTE | The brdInit function must be executed before calling digOutConfig.
> NOTE | You must execute the digOutConfig function to set the high-current drivers to be either sinking or sourcing. A runtime error will occur in digOut if digOutConfig has not executed.
> NOTE | The extra digital outputs resulting from the reconfiguration of IN16-IN23 as digital outputs are sinking outputs only and cannot be configured with digOutConfig.

> PARAMETER
> outputMode is a 16-bit parameter where each bit corresponds to one of the following high current outputs.
>   Bit 15 = high-current output channel OUT15
>   Bit 14 = high-current output channel OUT14
>   Bit 13 = high-current output channel OUT13
>   Bit 12 = high-current output channel OUT12
>   Bit 11 = high-current output channel OUT11
>   Bit 10 = high-current output channel OUT10
>   Bit 9 = high-current output channel OUT09
>   Bit 8 = high-current output channel OUT08
>   Bit 7 = high-current output channel OUT07
>   Bit 6 = high-current output channel OUT06
>   Bit 5 = high-current output channel OUT05
>   Bit 4 = high-current output channel OUT04
>   Bit 3 = high-current output channel OUT03
>   Bit 2 = high-current output channel OUT02
>   Bit 1 = high-current output channel OUT01
>   Bit 0 = high-current output channel OUT00
> The high-current outputs can be configured to be sinking or sourcing outputs by setting the corresponding bit to an 0 or 1: 0 = sinking, 1 = sourcing.
> RETURN VALUE
> None.
> SEE ALSO

>     brdInit, digOut

> EXAMPLE

>     outputMode = 0x0ff1; // Outputs OUT15-OUT12 = Sinking
>                          // Outputs OUT11-OUT08 = Sourcing
>                          // Outputs OUT07-OUT04 = Sourcing
>                          // Outputs OUT03-OUT01 = Sinking
>                          // Output OUT00 = Sourcing

> ##

> void digOut(int channel, int value);

> Sets the state of a digital output (OUT00-OUT15).
> Remember to call the brdInit and the digOutConfig functions before executing this function.
> A runtime error will occur for the following conditions:
> 1. channel or value out of range.
> 2. brdInit or digOutConfig was not executed before executing digOut.
> PARAMETERS
> channel is the output channel number (0-15, 0-23 if IN16-IN23 are configured as digital outputs).
> value is the output value (0 or 1).
> SEE ALSO

>     brdInit, digIn, digOutConfig

> ##

> int digIn(int channel);

> Reads the state of an input channel.
> A run-time error will occur for the following conditions:
> 1. channel out of range.
> 2. brdInit was not executed before executing digIn.
> PARAMETER
> channel is the input channel number (0-23)
> RETURN VALUE
> The state of the input (0 or 1).
> SEE ALSO

>     brdInit, digOut

> #### 4.3.3 Serial Communication

> Library files included with Dynamic C provide a full range of serial communications support. The RS232.LIB library provides a set of circular-buffer-based serial functions. The PACKET.LIB library provides packet-based serial functions where packets can be delimited by the 9th bit, by transmission gaps, or with user-defined special characters. Both libraries provide blocking functions, which do not return until they are finished transmitting or receiving, and nonblocking functions, which must be called repeatedly until they are finished. For more information, see the Dynamic C Premier User's Manual and Technical Note 213, Rabbit 2000 Serial Port Software.

> Use the following function calls with the BL2100.

> ##

> int serMode(int mode);

> User interface to set up BL2100 serial communication lines. Call this function after serXOpen().
> Whether you are opening one or multiple serial ports, this function must be executed after executing the last serXOpen function AND before you start using any of the serial ports. This function is non-reentrant.
> If Mode 1 is selected, CTS/RTS flow control is exercised using the serCflowcontrolOn and serCflowcontrolOff functions from the RS232.LIB library.
> PARAMETER
> mode is the defined serial port configuration.

> Mode | Serial Port
> B | C | D
> 0 | RS-232, 3-wire | RS-232, 3-wire | RS-485
> 1 | RS-232, 5-wire | CTS/RTS | RS-485

> RETURN VALUE
> 0 if valid mode, 1 if not.
> SEE ALSO

>     ser485Tx, ser485Rx

> ##

> void ser485Tx(void);

> Sets pin 3 (DE) high to enable the RS-485 transmitter.
> SEE ALSO

>     serMode, ser485Rx

> ##

> void ser485Rx(void);

> Resets pin 3 (DE) low to disable the RS-485 transmitter.
> SEE ALSO

>     serMode, ser485Tx, serCflowcontrolOn, serCflowcontrolOff

> #### 4.3.4 A/D Converter Inputs

> The functions in this section apply only to the BL2100 and the BL2120 models.

> ##

> int anaInCalib(int channel, int value1, float volts1, int value2, float volts2);

> Calibrates the response of the A/D converter channel as a linear function using the two conversion points provided. Gain and offset constants are calculated and placed into global table _adcCalib.
> PARAMETERS
> channel is the A/D converter input channel (0-10).
> value1 is the first A/D converter channel value (0-4095).
> volts1 is the voltage corresponding to the first A/D converter channel value (-10 V to +10 V).
> value2 is the second A/D converter channel value (0-4095).
> volts2 is the voltage corresponding to the second A/D converter channel value (-10 V to +10 V).
> RETURN VALUE
> 0 if successful.
> -1 if not able to make calibration constants.
> SEE ALSO

>     anaIn, anaInVolts, brdInit

> ##

> int anaInDriver(unsigned char cmd, char len);

> Reads the voltage of an analog input channel by serially clocking out an 8-bit command to the A/D converter. The driver has been designed for the Texas Instruments TLC2543 A/D converter used on the BL2100 and the BL2120.
> PARAMETERS
> cmd is formatted as follows.
> TLC2543 commands
> D7-D4
>   Channel 0-10
>   Channel 11 = (Vref+ - Vref-)/2
>   Channel 12 = Vref-
>   Channel 13 = Vref+
>   Channel 14 = software powerdown
> D3-D2
>   Output data length:
>   01--8 bits
>   00--12 bits (normally used as default)
>   11--16 bits (not supported by driver)
> D1
>   Output data format
>   0--MSB first
>   1--LSB first (not supported by driver)
> D0
>   Mode of operation
>   0--Unipolar (normally used as default)
>   1--Bipolar
> len is the output data length:
>   0 = 12-bit mode
>   1 = 8-bit mode
> RETURN VALUE
> A value corresponding to the voltage on the A/D converter input channel, which will be:
>   0-4095 for 12-bit A/D conversions
>   0-255 for 8-bit A/D conversions
> SEE ALSO

>     anaIn, anaInVolts, brdInit

> EXAMPLE
> Look at the sample programs in SAMPLES\BL2100\ADC.

> ##

> int anaIn(unsigned int channel);

> Reads the state of an A/D converter input channel.
> PARAMETER
> channel is the A/D converter input channel (0-10) to read.
> RETURN VALUE
> A value corresponding to the voltage on the analog input channel ( 0-4095).
> SEE ALSO

>     anaInVolts, anaInCalib, anaInfast, brdInit

> ##

> float anaInVolts(unsigned int channel);

> Reads the state of an A/D converter input channel and uses the previously set calibration constants to convert it to volts.
> PARAMETER
> channel is the A/D converter input channel (0-10).
> RETURN VALUE
> A voltage value corresponding to the voltage on the analog input channel.
> SEE ALSO

>     anaIn, anaInCalib, brdInit

> ##

> int anaInEERd(unsigned int channel);

> Reads the calibration constants, gain, and offset from the simulated EEPROM in flash memory (located in reserved user block memory area 0x1C00-0x1FFF).
> PARAMETER
> channel is the A/D converter input channel (0-10).
> RETURN VALUE
> 0 if successful.
> -1 if address is invalid or out of range.
> SEE ALSO

>     anaInEEWr, brdInit

> ##

> int anaInEEWr(unsigned int channel);

> Writes the calibration constants, gain, and offset to the simulated EEPROM in flash memory (located in reserved user block memory area 0x1C00-0x1FFF).
> PARAMETER
> channel is the A/D converter input channel (0-10) for which the calibration constants will be read.
> RETURN VALUE
> 0 if successful.
> -1 if address is invalid or out of range.
> SEE ALSO

>     anaInEERd,  brdInit

> #### 4.3.5 D/A Converter Outputs

> The functions in this section apply only to the BL2100 and the BL2120 models.

> ##

> int anaOutCalib(int channel, int value1, float volts1, int value2, float volts2);

> Calibrates the response of the D/A converter channel desired as a linear function using the two conversion points provided. Gain and offset constants are calculated and placed into global table _dacCalib.
> PARAMETERS
> channel is the D/A converter output channel (0-3).
> value1 is the first D/A converter value (0-4095).
> volts1 is the voltage corresponding to the first D/A converter value (0 V to +10 V).
> value2 is the second D/A converter value (0-4095).
> volts2 is the voltage corresponding to the second D/A converter value (0 V to +10 V).
> RETURN VALUE
> 0 if sucessful.
> -1 if not able to make calibration constants.
> SEE ALSO

>     anaOut, anaOutVolts, brdInit

> ##

> void anaOutDriver(int power_control, int speed_control, int channel, unsigned int rawcount);

> Sets the voltage of a D/A converter output channel by serially clocking in 16 bits to a D/A converter using the following format:
> D15, D12
>   Register R1, Register R0
>   00--Write data to DAC OUTB
>   01--Write data to buffer
>   10--Write data to DAC OUTA
>   11--Reserved
> D14
>   Speed control
>   0--slow
>   1--fast (default)
> D13
>   Power control
>   0--normal (default)
>   1--powerdown
> D11-D0
>   Data bits, MSB-LSB (0-4095)
> PARAMETERS
> power_control is the D/A converter power control option (0--normal (default) or 1--powerdown).
> When the power-down mode is selected, the only other parameter that is used is the D/A converter channel (channel). The values of the other parameters are not considered.
> Two D/A converter channels are affected when putting a D/A converter output in powerdown or normal mode.
> Powerdown Mode:
> When power_control equals 1 and channel is 0 or 1, then both D/A converter channels 0 and 1 are put in powerdown mode (channels 2 and 3 not affected).
> When power_control equals 1 and channel is 2 or 3, then both D/A converter channels 2 and 3 are put in powerdown mode (channels 0 and 1 not affected).
> Normal Mode:
> When power_control equals 1 and channel is 0 or 1, then both D/A converter channels 0 and 1 are put in normal mode. (channels 2 and 3 not affected).
> When power_control equals 1 and channel is 2 or 3, then both D/A converter channels 2 and 3 are put in normal mode (channels 0 and 1 not affected).
> speed_control is the D/A converter power control option (0--slow or 1--fast (default)).

> Mode | Speed vs. Power Dissipation
> 0--slow | 12 µs access vs. 1 mA
> 1--fast (default) | 3 µs access vs. 2.3 mA

> Test conditions from TI's data sheet (TLV5618A D/A converter) for the speed-control option:
> - No load.
> - All inputs are at GND or VDD.
> - D/A converter latch = 0x800.
> channel is the D/A converter output channel to write (0-3).
> rawcount is the data value corresponding to the desired voltage on the analog output channel (0-4095).
> RETURN VALUE
> None
> SEE ALSO

>     anaOut, anaOutVolts, anaOutCalib

> ##

> void anaOut(unsigned int channel, unsigned int rawcount);

> Sets the voltage of a D/A converter output channel.
> PARAMETERS
> channel is the D/A converter output channel (0-3).
> rawcount is a data value corresponding to the voltage desired on the output channel (0-4095).
> RETURN VALUE
> 0 if sucessful.
> -1 if rawcount is more than 4095.
> SEE ALSO

>     anaOutDriver, anaOutVolts, anaOutCalib

> ##

> void anaOutVolts(unsigned int ch, float voltage);

> Sets the voltage of a D/A converter output channel by using the previously set calibration constants to calculate the correct data values.
> PARAMETERS
> channel is the D/A converter output channel (0-3).
> voltage is the voltage desired on the output channel.
> RETURN VALUE
> None.
> SEE ALSO

>     anaOut, anaOutCalib, brdInit

> ##

> int anaOutEERd(unsigned int channel);

> Reads the calibration constants, gain, and offset from the simulated EEPROM in flash memory (located in reserved user block memory area 0x1C00-0x1FFF).
> PARAMETER
> channel is the D/A converter output channel (0-3).
> RETURN VALUE
> 0 if successful.
> -1 if address or range is invalid.
> SEE ALSO

>     anaOutEEWr, brdInit

> ##

> int anaOutEEWr(unsigned int channel);

> Writes the calibration constants, gain, and offset to the simulated EEPROM in flash memory (located in reserved user block memory area 0x1C00-0x1FFF).
> PARAMETER
> channel is the D/A converter output channel (0-3).
> RETURN VALUE
> 0 if successful.
> -1 if address or range is invalid.
> SEE ALSO

>     anaOutEERd, brdInit

> #### 4.3.6 TCP/IP Function APIs

> The TCPIP directory contains libraries with generic TCP/IP functions for the BL2100 and the BL2110.

> - ARP.LIB--address resolution protocol functions.
> - BOOTP.LIB--bootstrap protocol functions.
> - BSDNAME.LIB--BSD-style socket routines.
> - DCRTCP.LIB--TCP/IP functions.
> - DNS.LIB--handles host name resolution.
> - FTP_CLIENT.LIB--FTP client functions.
> - FTP_SERVER.LIB--FTP server functions.
> - HTTP.LIB--HTTP handler.
> - ICMP.LIB--ICMP handler.
> - IP.LIB--handles the network layer (just above the link layer and the device driver).
> - MD5.LIB--implements the MD5 algorithm defined in TCP/IP RFC 1321.
> - NET.LIB--general networking API. This is the "top-level" library for the networking library suite. It includes the packet-driver interface.
> - PKTDRV.LIB--packet driver functions.
> - POP3.LIB--POP3 functions.
> - REALTEK.LIB--packet driver functions for the RealTek RTL8019AS.
> - SMTP.LIB--SMTP handler.
> - TCP.LIB--transmission control protocol.
> - UDP.LIB--user datagram protocol.
> - VSERIAL.lib--virtual Telnet functions.
> - ZSERVER.lib--miscellaneous TCP/IP server data structures and routines.

> The functions in these libraries are described in the Dynamic C TCP/IP User's Manual included in the manual set with the Dynamic C Premier User's Manual.

> ### 4.4 Sample Programs

> Sample programs are provided in the Dynamic C Samples folder. The sample program PONG.C demonstrates the output to the STDIO window.

> The various directories in the Samples folder contain specific sample programs that illustrate the use of the corresponding Dynamic C libraries.

> The BL2100 folder provides sample programs specific to the BL2100. Each sample program has comments that describe the purpose and function of the program. Follow the instructions at the beginning of the sample program.

> To run a sample program, open it with the File menu (if it is not still open), compile it using the Compile menu, and then run it by selecting Run in the Run menu. The BL2100 must be in Program mode (see Section 4.1, "Programming Cable,") and must be connected to a PC using the programming cable as described in Section 2.1, "BL2100 Connections."

> More complete information on Dynamic C is provided in the Dynamic C Premier User's Manual. TCP/IP specific functions are described in the Dynamic C TCP/IP User's Manual. Information on using the TCP/IP features and sample programs is provided in Section 5, "Using the TCP/IP Features."

> #### 4.4.1 Digital I/O

> The following sample programs are found in the IO subdirectory in SAMPLES\BL2100.

> - DIGIN.C--Demonstrates the use of the digital inputs. Using the Demonstration Board, you can see an input channel toggle from HIGH to LOW when pressing a pushbutton on the Demonstration Board. See Appendix D for hookup instructions for the Demonstration Board.
> - DIGOUT.C--Demonstrates the use of the high-current outputs configured as either sinking or sourcing outputs. Using the Demonstration Board, you can see an LED toggle on/off via a high-current output. See Appendix D for hookup instructions for the Demonstration Board.
> - PWM.C--Demonstrates the use of Timer B to generate a PWM signal on PE5-INT located on screw terminal header J11. The program generates a 42 Hz PWM signal with the duty cycle adjustable from 1 to 99%.

> #### 4.4.2 Serial Communication

> The following sample programs are found in the RS232 subdirectory in SAMPLES\BL2100.

> - PUTS.C--Transmits and then receives an ASCII string on Serial Ports B and C. It also displays the serial data received from both ports in the STDIO window.
> - RELAYCHR.C--This program echoes characters over Serial Port B to Serial Port C. It must be run with a serial utility such as Hyperterminal.

> The following sample programs are found in the RS485 subdirectory in SAMPLES\BL2100.

> - MASTER.C--This program demonstrates a simple RS-485 transmission of lower case letters to a slave BL2100. The slave will send back converted upper case letters back to the master BL2100 and display them in the STDIO window. Use SLAVE.C to program the slave BL2100.
> - SLAVE.C--This program demonstrates a simple RS-485 transmission of lower case letters to a slave BL2100. The slave will send back converted upper case letters back to the master BL2100 and display them in the STDIO window. Use MASTER.C to program the master BL2100.

> #### 4.4.3 A/D Converter Inputs

> The following sample programs are found in the ADC subdirectory in SAMPLES\BL2100.

> - AD_CALIB.C--Demonstrates how to recalibrate an A/D converter channel using two known voltages to generate two coefficients, gain and offset, which are rewritten into the user block data area. The voltage that is being monitored is displayed continuously. Make sure that you don't exceed the voltage range of the A/D converter input channel.

> NOTE | This sample program will overwrite the calibration constants set at the factory.

> - AD1.C--Demonstrates how to access the A/D internal test voltages in both the TLC2543 and TLC1543 A/D converter chips. The program reads the A/D internal voltages and then uses the STDIO window to display the RAW data.
> - AD2.C--Demonstrates how to access the A/D channels using the anaInVolt function. The program uses the STDIO window to display the voltage that is being monitored.
> - AD3.C--Demonstrates how to access the A/D converter channels with the low- level A/D driver. The program uses the STDIO window to display the voltage that is being monitored on all the A/D channels using the low-level A/D driver.
> - AD4.C--Demonstrates how how to use the A/D converter channels with the low- level A/D driver. The program uses the STDIO window to display the voltage (average of 10 samples) that is being monitored on all the A/D converter channels using the low-level A/D driver.

> #### 4.4.4 D/A Converter Outputs

> The following sample programs are found in the DAC subdirectory in SAMPLES\BL2100.

> - DACAL.C--This program demonstrates how to recalibrate an D/A converter channel using two known voltages, and defines the two coefficients, gain and offset, that will be rewritten into the D/A converter's EEPROM simulated in flash memory.

> NOTE | This sample program will overwrite the calibration constants set at the factory.

> - DAOUT1.C--This program outputs a voltage that can be read with a voltmeter. The output voltage is computed using the calibration constants that are read from the EEPROM simulated in flash memory.
> - DAOUT2.C--This program demonstrates the use of both the D/A and the A/D converters. The user selects both the D/A converter and A/D channel to be used, then sets the D/A converter output voltage to be read by the A/D channel. All activity will be displayed in the STDIO window.

> #### 4.4.5 Using Calibration Constants

> The following sample programs are found in the Calib_Save_Retrieve subdirectory in SAMPLES\BL2100. Note that both sample programs prompt you to use a serial number for the BL2100. This serial number can be any 5-digit number of your choice, and will be unique to a particular BL2100. Do not use the MAC address on the bar code label of the RabbitCore module attached to the BL2100 since you may at some later time use that particular RabbitCore module on another BL2100, and the previously saved calibration data would no longer apply.

> - GETCALIB.C--This program demonstrates how to retrieve your analog calibration data to rewrite it back to the simulated EEPROM in flash with using a serial utility such as Tera Term.

> NOTE | Calibration data must be saved previously in a file by the sample program SAVECALIB.C.

> - SAVECALIB.C--This program demonstrates how to save your analog calibration coefficients using a serial port and a PC serial utility such as Tera Term.

> NOTE | Use the sample program GETCALIB.C to retrieve the data and rewrite it to the single-board computer.

> #### 4.4.6 TCP/IP Sample Programs

> TCP/IP sample programs are described in Chapter 5.

> #### 4.4.7 LCD/Keypad Module Sample Programs

> Sample programs for the LCD/keypad module are described in Section C.7.

Z-World http://www.zworld.com Voice: (530) 753-3737 FAX: (530) 753-5141 sales@zworld.com