/*
	RS232.C
	
   - sample program to demonstrate:

      (1) Z180 serial port 0 RS232 communication to a PC with or without the
          use of modem.

      (2) master to slave communication thru a half duplex RS485 link with
          a slave running the program RS485.C.

   The program monitors for a CR terminated string from a dumb terminal.
	If a string is present, the program will try to send the string to a slave
	(no. 2) thru the RS485 link. The response of the slave is echoed back to the
	dumb terminal. If slave no. 2 is not present, the program will increase each
	of the byte in the strings by 2 and echo back the string.  By the way, the
	slave program (rs485.c) is supposed to add 3 to each of the byte of the
	string.  For example, if you type a1g (CR), the master will respond with
	c3i if slave no. 2 is not present. If slave no. 2 is present, the response
	from the slave would be d4j.

   If you want to try a link thru a modem, change the baud rate to
	2400 and set ismodem=1.  Then using any pc terminal program, you should
	be able to dial up the board.

   We suggest a Hayes SMARTMODEM. Otherwise, the user would have
	to jumper the following wires:

        SBC                  MODEM
        TX  ----------------  RX
        RX  ----------------  TX
        COMM  --------------  COMM
        RTS---|          |----  RTS
        CTS---|          |----  CTS
                         |----  DTR

	If your modem is truly Hayes Smartmodem compatible, all you
  	need is a null modem between the SBC and the modem.

       Hardware connection for RS485 link (z180 port 1):
        master                       slave (or slaves)
        TX+  |  -----------------  |  TX+
        RX+  |                     |  RX+

        TX-  |  -----------------  |  TX-
        RX-  |                     |  RX-

   Master slave communication uses the new opto22 9th bit binary
	protocol. This means that only the targeted slave will open its
	communication to receive the information other than the slave
	address broadcast during the 9th bit mode.

	A more elaborate example would be z0rem.c or cz0rem.c for the master side
	and sremote.c or csremote.c for the slave side.

	This program would run on the BL11xx/Little Giant, the Tiny Giant and the
	CPLC. If port 0 is also used as the Dynamic C programming port, you have to
	load the serial interrupt routine during run time by doing the following:

   (1) comment out: #INT_VEC SER0_VEC Dz0_circ_int in z0232.lib
   (2) in the code, declare:
         extern void Dz0_circ_int();
   (3) load the routine with:
         reload_vec(14,Dz0_circ_int);

	Depending on the application, you may want to delay initialization of the
	serial port to make sure your hardware is connected. Or an external trigger
	from a keypad or input port could trigger the software to initialized the
	serial port. For example, if you are using a modem, the serial initialization
	routine would also try to set up the modem. Therefore, the modem has to be
	connected before initialization function is executed.

	Need the following libaries: modem232.lib, z0232.lib, network.lib
  	Drivers.lib has to be current also ( 5/17/93 or later).
*/

#use "default.h"

#if ((BOARD_TYPE==CPLC_BOARD) || (BOARD_TYPE==L_STAR))
#use cplc.lib
#endif

// uncomment the following line if you are using a pk23xx controller
//#use eziopk23.lib

/**********************************************
CONTROL PARAMETERS
***********************************************/
#define IBAUD   9600         /* baud rate
                                with modem either 2400 or 1200
                                without modem => 19200,9600, 4800, etc   */
#define TBUFSIZE 384         // size of transmit buffer
#define RBUFSIZE 384         // size of receive buffer

char ismodem = 0;            // set to 1 if you want modem
char isecho  = 1;            // set to 1 if you want character echoed back to the pc

char op_tbuf[255], op_rbuf[255];
extern void Dz0_circ_int();

main()
{
    int  ercode;
    int  i;
    int  count;
    char tbuf[TBUFSIZE];     // transmit buffer
    char rbuf[RBUFSIZE];     // receive buffer
    char buf[RBUFSIZE + 1];  // dummy buffer for receiving a complete command

#if ( (BOARD_TYPE==CPLC_BOARD) || ( BOARD_TYPE==L_STAR) )
        uplc_init();
#endif

    op_kill_z1();

    /*  use reload_vec( ..) instead of #INT_VEC SER0_VEC if port0 is also
        the Dynamic C programming Port                                  */
#if ROM==0
        reload_vec(14, Dz0_circ_int);
#endif

    /* depending on your application, you may have to delay or look for 
       external trigger to proceed to the initialization of the serial port.      */

    // Initialize rs232 serial port for pc to master comm
    hitwd();
    Dinit_z0(rbuf, tbuf, RBUFSIZE, TBUFSIZE, 4, IBAUD / 1200, ismodem, isecho);

    // Initialize opto22 network
    op_init_z1(19200 / 1200, op_rbuf, 0);

    if (!ismodem)            // if no modem, you have to service your own
    {                        // screen at power up
        Dz0send_prompt();
    }

    for (;;)    // endless loop constantly monitoring for new command line
    {
    	  hitwd();
        if( Dread_z0(buf, ENTER) != 0)
        {
            Dz0send_prompt();
            ercode = sendOp22(2, buf, strlen(buf), 2);  // talk to slave 2
                             
            if (ercode == -1)
            {
                Dwrite_z0("slave 2 not present", 19);
                Dz0send_prompt();
                count = strlen(buf);
                for (i = 0; i < count; i++) {
                	*(buf + i) = *(buf + i) + 2;
                	hitwd();
                }
                Dwrite_z0("offsetting by 2", 15);
                Dz0send_prompt();
                Dwrite_z0(buf, count);
            }
            else if (ercode == -2)
            {
                Dwrite_z0("bad crc on return", 17);
            }
            else
            {
                Dwrite_z0("slave 2 is present", 18);
                Dz0send_prompt();
                Dwrite_z0("slave 2 responded with:", 23);
                Dz0send_prompt();
                Dwrite_z0(op_rbuf + 1, op_rbuf[0] -2); // don't show the crc
            }
            Dz0send_prompt();
        }
    }
}
