However when I attempt to write to the USI Slave the timings are all off and very strange data is written out.
Correct (with no slaves on the line hence the NACKs)
[0x90 0xA0 0x0fd0]
Incorrect (with USI Slave Attached)
It looks like something is getting messed up when the USI Slave is sending the ACK and holding SDA low but I cannot for the life of me figure out what it happening.
These are both MSP430G2231's running on Launchpads. The Masters are running on buses on a breadboard with 10K Pull-up resistors to VCC on the Launchpads. I believe the issue is in the state machine for the receive code and specifically when the code grabs data and ACKs below is just that snippet.
Below will be my code for the USI Slave (mostly in the USI_TXRX intertupt routine) and the Master.
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
if (USICTL1 & USISTTIFG) // Start entry?
{
P1OUT |= 0x01; // LED on: sequence start
I2C_State = 2; // Enter 1st state on start
//READ_ADDR = I2C_State;
}
switch(I2C_State)
{
case 0: // Idle, should not get here
break;
case 2: // RX Address
USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX address
USICTL1 &= ~USISTTIFG; // Clear start flag
I2C_State = 4; // Go to next state: check address
//READ_ADDR = I2C_State;
break;
case 4: // Process Address and send (N)Ack
//READ_ADDR = USISRL;
/*if (USISRL & 0x01) // If read...
{
SLV_Addr++; // Save R/W bit
}*/
USICTL0 |= USIOE; // SDA = output
//READ_ADDR = USISRL;
//READ_ADDR1 = SLV_Addr;
if (USISRL == SLV_Addr) // Address match?
{
USISRL = 0x00; // Send Ack
P1OUT &= ~0x01; // LED off
I2C_State = 8; // Go to next state: RX data
//READ_ADDR = 0xAA;
}
else
{
//READ_ADDR = 0xAB;
USISRL = 0xFF; // Send NAck
P1OUT |= 0x01; // LED on: error
I2C_State = 6; // Go to next state: prep for next Start
}
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
//I2C_Send_Data();
break;
case 6: // Prep for Start condition
USICTL0 &= ~USIOE; // SDA = input
SLV_Addr = 0x90; // Reset slave address
I2C_State = 0; // Reset state machine
break;
case 8: // Receive data byte
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x08; // Bit counter = 8, RX data
I2C_State = 10; // Go to next state: Test data and (N)Ack
break;
USICTL0 |= USIOE; // SDA = output
READ_ADDR1 = USISRL;
//I2C_Send_Data();
if (USISRL == MST_Data) // If data valid...
{
USISRL = 0x00; // Send Ack
//MST_Data++; // Increment Master data
P1OUT &= ~0x01; // LED off
}
else
{
USISRL = 0xFF; // Send NAck
P1OUT |= 0x01; // LED on: error
}
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
I2C_State = 6; // Go to next state: prep for next Start
break;
}
Send_I2C = 1;
USICTL1 &= ~USIIFG; // Clear pending flags
}
USI Slave Code:
Master Code:
They both use the TI provided master .c and header
mspgcc compiler directives for the Master are:
sudo msp430-gcc -0s -g -Wall -mmcu=msp430g2231 msp430g2x21_Injector.c MSP430_SWI2C_Master.c -o MT.elf
For the Slave:
sudo msp430-gcc -0s -g -Wall -mmcu=msp430g2231 msp430g2x21_usi_08.c MSP430_SWI2C_Master.c -o MT.elf
And I am using mspdebug to program my launchpads.
