/*  Filename      ZPCF8574.C
    Description   Example Program 3B PORT(1) 
    Hardware     SLAB-51 + EX-Relay(2 - 16 Unit) 
    Chip              89V51RD2BN Xtal 11.0592 MHz (Speed x1)
    Compiler       Keil PK51 v7.10
    Engineer        Kriangsak B.	
    Company      Sila Research Co.,Ltd. 
*/

#include <reg52.h>
#include <intrins.h>

sbit     XXSCL			= P3^3;             // I2C BUS
sbit     XXSDA			= P3^5; 
         
//******** Basic Function ********//
void dmsec (unsigned int count) {           // mSec Delay
    unsigned int i;                         // for Keil CA51 (Speed x1)
    while (count) {
        i = 115; while (i>0) i--;
        count--;
    }
}

/********** 3B-Port I2C **********/

void ipdel (void) {                    // I2C delay 
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
    _nop_ ();
}

void xxchigh (void) {                  // I2C clock high 
    XXSCL = 1;
    ipdel ();
}

void xxclow (void) {                   // I2C clock low 
    XXSCL = 0;
    ipdel ();
}

void xxstart (void) {                  // start condition 
    XXSDA = 1;
    XXSCL = 1;
    XXSDA = 0;
    ipdel ();
    XXSCL = 0;
    XXSDA = 1;
}
                                        
void xxstop (void) {                   // stop condition 
    XXSDA = 0;
    XXSCL = 1;
    ipdel ();
    XXSDA = 1;
}

bit xxwrbyte (unsigned dat) {          // write one byte 
    unsigned char i;                   // return 0 = ok 
    bit outbit;                        // return 1 = error 
    for (i=1;i<=8;i++) {
        outbit = dat & 0x80;
        XXSDA = outbit;
        dat = dat << 1;
        xxchigh ();
        xxclow ();
    }
    XXSDA = 1;
    xxchigh ();
    outbit = XXSDA;
    xxclow ();
    return (outbit);
}

/*
unsigned char xxrdbyte () {            // read one byte 
    unsigned char i,dat;               // return 0xff = error 
    bit inbit;
    dat = 0;
    for (i=1;i<=8;i++) {
        xxchigh ();
        inbit = XXSDA;
        dat = dat << 1;
        dat = dat | inbit;
        xxclow ();
    }
    XXSDA = 1;
    xxchigh ();
    inbit = XXSDA;
    xxclow ();
    if (~inbit) dat = 0xff;
    return (dat);
}
*/

void xxwr (unsigned char addr,dat) {        // write port (pcf8574a)
    xxstart ();
    addr = ((addr << 1) & 0x0e) | 0x70;
    xxwrbyte (addr);
    xxwrbyte (dat);
    xxstop ();
}

/*
unsigned char xxrd (unsigned char addr) {   // read port 
    unsigned char dat;                      // return 0xff = error 
    xxstart ();
    addr = ((addr << 1) & 0x0e) | 0x71;
    xxwrbyte (addr);
    dat = xxrdbyte (); 
    xxstop ();
    return (dat);
}
*/

/********** MAIN **********/

void main (void) {
    unsigned char x,i,j;
    while (1) {
		for(i=0;i<=7;i++){
			x = 0xfe;
			for (j=0;j<=7;j++) {
				xxwr (i,x);
				dmsec (100);
				x <<= 1;
			}
			xxwr (i,0xff);
		}
	}
}