
#include <legacymsp430.h>

// P4.1 is data, P4.2 is clock

void initi2c(void)
{
	UCB1CTL1|= UCSWRST;		// reset
	P4SEL |= BIT1|BIT2;		// USCI_B1 I2C
	P4REN |= BIT1|BIT2;		// Enable pullups
	// 7-bit address, single master, master mode, I2C mode, synchronous
	UCB1CTL0 = UCMST|UCMODE_3|UCSYNC;
	// smclk, transmitter, normal ack
	UCB1CTL1 |= UCSSEL__SMCLK|UCTR;
	UCB1BR0 = 0x7f;			// 33 KHz scl ??
	UCB1BR1 = 0;
	// enable arbitration lost, not-acknowledge, start condition, transmit interrupts.
	UCB1IE |= UCALIE|UCNACKIE|UCSTTIE|UCTXIE;
	UCB1CTL1 &= ~UCSWRST;	// release for operation
}
#define ERR_NOACK	1;		// not acknowledge received
#define ERR_ARBT	2;		// arbitration lost

int nbytes, done, error;
char *bufPtr;

interrupt (USCI_B1_VECTOR) i2cB1_Interrupt (void)
{
int iv = UCB1IV;
	switch (iv)
	{
		case 2:			// arbitration lost
			error = ERR_ARBT;
			done = 1;
			break;
		case 4:			// not acknowledge
			error = ERR_NOACK;
			done = 1;
			break;
		case 6:			// start condition received
			UCB1TXBUF = *bufPtr++;			// load first byte
			nbytes--;
			break;
		case 0xc:		// transmit buffer empty
			if (nbytes)
			{
				UCB1TXBUF = *bufPtr++;
				nbytes--;
			}
			else
			{
				UCB1CTL1 |= UCTXSTP;		// generate stop
				done = 1;
			}
			break;
		default:
			break;
	}
}

int i2cWrite(char address, char *datap, int ndata)
{
	nbytes = ndata;
	bufPtr = datap;
	done = 0;
	error = 0;
	UCB1CTL1|= UCSWRST;			// reset
	UCB1I2CSA = address;
	UCB1CTL1 &= ~UCSWRST;		// release for operation
	UCB1CTL1 |= UCTXSTT;		// generate START condition
	while (!done)
		;
	return error;
}


