Other Parts Discussed in Thread: MSP430FR2311
I2C unable to receive from slave MSP430FR5994
The transmit part of this test code (commented out) works ok and sends data correctly to the slave. But the receive part (shown) is not able
to receive anything from the slave. Scope waveform shows just a short positive pulse on the i2c data line and the clock line remains solid high.
During initialization:
UCB1CTLW0 comes out 0x680. Thus UCMST (0x800) is not set and UCTR (0x10) is not set in transmit mode.
When running receive only one byte, only get a short pulse on data line with clk staying high,
So it is not sending the slave address on receive. ConfigI2C() is still called prior to running the Testi2c() program, but is now redundant.
/*******************************************************************************
Configure USCI_B1 for I2C mode
400khz clock
Writes to pot in 68.8us
*******************************************************************************/
void ConfigI2C(void)
{
// Configure GPIO for i2c:
P5SEL0 |= BIT0 | BIT1;
P5SEL1 &= ~(BIT0 | BIT1);
//UCB1CTLW0 = UCSWRST; // put eUSCI_B in reset state
UCB1CTLW0 |= (UCMODE_3 | 0x800 | UCSSEL__SMCLK ) ; // I2C master mode, SMCLK
UCB1BRW = 0x12; // baudrate = SMCLK / 18. With this fclk=400khz or 2.5us. Writes in 68.8us to pot.
//UCB1CTLW0 &= ~UCSWRST; // clear reset register
UCB1IE |= UCTXIE0 | UCNACKIE; // transmit and NACK interrupt enable
}
/*************************************************************************
* Transmit bytes to slave i2c
* Transmit start, slave adx, command, data, stop to slave: (could see nack)
************************************************************************/
void TransmitBytesI2c(uint8 nbytes)
{
TxIrqFlag=1; //indicate now transmitting to irq
UCB1CTLW0 = UCSWRST; // put eUSCI_B in reset state
UCB1I2CSA = 0x04c; // 4c configure slave adx. MCSID bat U3=0x1a
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; //0x680 I2C master mode, SMCLK
TXByteCtr = nbytes; // Load TX byte counter
ByteCnt =0; //inc data byte counter for irq
UCB1CTLW0 &= ~UCSWRST; // clear reset register
while (UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB1IE |= UCTXIE0 | UCNACKIE; // transmit and NACK interrupt enable
UCB1CTLW0 |= (UCTR | UCTXSTT); //I2C transmit start condition
}
/*************************************************************************
//Read Slave Data
//Send start, slave adx, instruction wo stop
//then send start, slave adx w read, read slave data, stop:
*
* start is data goes down with clock high.
**************************************************************************/
uint8 Read1byteI2c(uint8 SlaveAdx)
{
//TransmitBytesI2c( 1); //1 byte after slave adx = 0 command, stop
//__delay_cycles(1000); // wait to finish writing to slave
TxIrqFlag=0; //indicate now receiving to irq
UCB1CTLW0 = UCSWRST; // put eUSCI_B in reset state
UCB1I2CSA = 0x04c; // 4c configure slave adx. MCSID bat U3=0x1a
//UCB1TBCNT = 1; //no bytes to be received
UCB1CTLW0 &= ~UCTR ; //clear UCTR for receive//UCB1CTLW0 = UCSWRST; // put eUSCI_B in reset state
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; // 0x680 I2C master mode, SMCLK
UCB1CTLW0 &= ~UCSWRST; // clear reset register
UCB1IE |= UCRXIE0 | UCNACKIE; // receive and NACK interrupt enable
UCB1CTLW0 = UCTXSTT; //I2c Read slave data, start condition
while (UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
__delay_cycles(1000); // wait to finish reading the slave
return RxData;
}
/**********************************************************************
* TestI2c() Sends MSB first
* 3.3Vccp is always on the i2c chip.
* This routine is normally not called. Must be called to test.
* It writes to the i2c chip and increments the data written.
*********************************************************************/
void TestI2c(void)
{
//SlaveFlag = 0; // Initialize SlaveFlag
while(1)
{
__delay_cycles(50000); // Delay between transmissions
//write test data I2CData[1] to i2c pot:
//TransmitBytesI2c( 2); //2 bytes adx, command, stop
__delay_cycles(1000); // wait to finish writing to slave
Read1byteI2c(0x4c); //slave adx for qsm005 is 4c, mcsid u3 is 1a
__delay_cycles(10000); // wait to finish reading slave data
// __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data // is TX'd
I2CData[1] = I2CData[1] +1 ; // inc data for test!!!
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = EUSCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
UCB1CTLW0 |= UCTXSTT; // resend start if NACK
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: // Vector 14: RXIFG2
;
break;
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
RxData = UCB1RXBUF; // Get RX data
break;
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0 (txbuffer empty irq)
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = I2CData[ByteCnt]; // Load TX buffer
ByteCnt++; //inc the byte count
TXByteCtr--; // Decrement TX byte counter
}
else
{
if( TxIrqFlag==1) //if a transmitter then send stop condition
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
break;
case USCI_I2C_UCBCNTIFG: break; // Vector 26: BCNTIFG
case USCI_I2C_UCCLTOIFG: break; // Vector 28: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 30: 9th bit
default: break;
}
}