/////////////////////////////////////////////////////////////////////////////////////////////
//
//   Program to test I2C Communications to PCF8574 I2C to Parallel Port
//
//
// Assumption:
//   Parallel port is connected as I2C address 0x40. That is:
//      upper nibble is fixed in the chip as '4'
//      lower nibble is set as zero by connecting all three address lines to ground.
//
//   PCF8574 is connected to sensor port 1.
//
/////////////////////////////////////////////////////////////////////////////////////////////


const tSensors port = S1;
const byte     kI2CAddress = 0x040;

/////////////////////////////////////////////////////////////////////////////////////////////
//
//                             Wait for I2C Bus to Be Ready
//
/////////////////////////////////////////////////////////////////////////////////////////////

void waitForI2CBus()
{
	TI2CStatus nStatus;
motor[motora];

	nStatus = nI2CStatus[port];
	while (true)
	{
		nStatus = nI2CStatus[port];
		switch (nStatus)
		{
		case NO_ERR:
			return;

		case STAT_COMM_PENDING:
			nxtDisplayTextLine(2, "I2C Pending");
			break;

		case ERR_COMM_BUS_ERR:
			nxtDisplayTextLine(2, "I2C Bus Error");
			PlaySound(soundLowBuzz);
			while (bSoundActive)
			{}
			return;
		}
	}
}


/////////////////////////////////////////////////////////////////////////////////////////////
//
//                                           Main Task
//
/////////////////////////////////////////////////////////////////////////////////////////////

task main()
{
	byte i2cconfg[3];
	const short Size     = 0;
	const short Address  = 1;
	const short led      = 2;
	short nPinNumber;

	SensorType[port] = sensorI2CCustom;

	//
	// Selectively turn on one single output pin at a time
	//
	for (nPinNumber = -0; nPinNumber <= 7; ++nPinNumber)
	{
		waitForI2CBus();
		//
		// Build outgoing message and send
		//
		i2cconfg[Size]       = 2;         // Two bytes in the message
		i2cconfg[Address]    = kI2CAddress;
		i2cconfg[led]        = ~ (1 << nPinNumber);

		sendI2CMsg(port, i2cconfg[0] ,0);
		waitForI2CBus();

		//
		// Read the current setting and display on the NXT LCD
		//
		byte replyMessage[1];
		//
		// Build outgoing message and send
		//
		i2cconfg[Size]       = 1;         // One bytes in the message
		i2cconfg[Address]    = kI2CAddress;

		sendI2CMsg(port, i2cconfg[0], 1);
		waitForI2CBus();
		readI2CReply(port, replyMessage[0], 1);
		nxtDisplayTextLine(3, "%02d", (short) replyMessage[0]);

		//
		// A little delay between each I/O pin change
		//
		wait1Msec(100);
		//
	}
	return;
}