Hi @ all!
I really got a big problem with my MSP430G2553 device. I'm using the I²C to communicate to either an DAC and an ADC. I have written a code that communicates to each device in "ping pong mode" - therefore i built up a state-machine for each device which are sequently called by the main. Once they are called, the communication runs interrupt driven. Sending data to the DAC and to the ADC (config-data) works without problems, but receiving data from the ADC aborts every time.
The following data is transfered until it stops:
START -> ADDRESS with Write-Bit -> ACK -> 1st read data byte -> ACK -> 7 bits of the 2nd data byte........then SCL and SDA both go low and stay there.
If I step through the debugger I can see, that the ISR for the RX interrupt is never called. Instead the TX-ISR comes up and the controller never leaves this ISR so that the program stops here.
The funny thing about it: UCB0TXIE is NOT set. After sending the start both, RXIFG and TXIFG are set - is that normal? Anyway the TX-ISR should not be called!! What's wrong? I read the device errata and topic USCI30 could be my problem...maybe. The workaround says, that the received byte should be fetched by a ISR and that is exactly what I do. My receive-buffer for the data is not filled, too, because this would be done in the ISR. But it is very strange, that the state-machine of the USCI requests further bytes without the RX-buffer read.
Is there someone having the same problem? I'm working on that problem for about 2 days now and I'll get crazy!
Here is some code:
case ADC_STATE__SEND_START:
{
UCB0CTL1 |= UCSWRST;
UCB0I2CSA = ( (MCP3425_DEVICE_CODE | MCP3425_DEVICE_ADDRESS) >> 1 );
UCB0CTL1 &= ~UCSWRST;
adc_control.bytecounter = 0;
adc_control.bytecount = 3;
IFG2 &= ~UCB0RXIFG;
IE2 |= UCB0RXIE;
adc_control.state = ADC_STATE__RECEIVING_DATA;
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
break;
}
and the RX-ISR:
// USCI_A/B0 receive interrupt service routine
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR( void )
{
if( IFG2 & UCB0RXIFG )
{
if( i2c_sm_control_flags == ADC_SM_ACTIVE )
{
switch( adc_control.state )
{
case ADC_STATE__RECEIVING_DATA:
{
if( adc_control.bytecounter < adc_control.bytecount )
{
adc_control.adc_data[adc_control.bytecounter++] = UCB0RXBUF;
}
else
{
IFG2 &= ~UCB0RXIFG;
IE2 &= ~UCB0RXIE;
adc_set_flag( ADC_FLAG__DATA_TO_PROCESS );
adc_change_state( ADC_STATE__WAIT_FOR_STOP_COMPLETE );
UCB0CTL1 |= UCTXSTP;
}
break;
}
default: break;
}
}
}
}
But as I said, only the TX-ISR is entered without TXIE enabled :-(