Hi,
I have a question about the expected behavior of the SCL line after transmitting the slave address and before putting any data on the TXBUF.
In the source code (below), I am simply transmitting the slave address and then going into an infinite loop. It is my understanding (based in the datasheet) that this code will cause the MSP430 to hold the SCL line low indefinitely after the transmission of the slave address and the R/W bit. I see this behavior occurring when addressing one of the slave devices (address 0x08) but not the other slave device (address 0x10). Please see test code 1 and test code 2.
Circuit schematic:
Test code 1 (UCB0I2CSA = 0x10):
#include <msp430.h> void main (void) { WDTCTL = WDTPW | WDTHOLD; //Disable internal watchdog timer P4DIR |= BIT6; //Configure P4.6 as an output (for debugging on the scope) P1SEL1 |= (BIT6|BIT7); //Configure P1.6 (SDA) and P1.7 (SCL) for i2c functionality PM5CTL0 &= ~LOCKLPM5; //Clear the LOCKLPM5 bit so previous settings take effect //Configure the i2c peripheral UCB0CTLW0 |= UCSWRST; //Hold USCI module in reset UCB0CTLW0 |= ( UCMST | UCMODE_3 ); //I2C master mode UCB0CTLW0 |= UCSSEL__SMCLK; //Use SMCLK (1MHz) UCB0BRW = 10; //Divide SMCLK by 10 to achieve 100KHz baud rate UCB0CTLW0 &= ~UCSWRST; //Pull USCI module out of reset //delay (each cycle is 1us) __delay_cycles( 3000000 ); //Delay to give me time to trigger the scope P4OUT |= BIT6; //Set P4.6 high UCB0I2CSA = 0x10; //Set slave address (0x64 => LTC2943, 0x10 => LT8491, 0x08 => LTC2309) UCB0CTLW0 |= UCTR; //Set I2C bus in transmit mode UCB0CTLW0 |= UCTXSTT; //Issue START condition (start + i2c_address + RW bit) //Infinite loop while(1) { //Read the UCSCLLOW bit and control P4.6 if( UCB0STATW & UCSCLLOW ) { P4OUT &= ~BIT6; //If UCSCLLOW is set, clear P4.6 } else { P4OUT |= BIT6; //If UCSCLLOW is cleared, set P4.6 } } } //main()
Digital and analog capture of test code 1 (addressing 0x10 slave device):
Notice how SCL line clocks 9 times and then holds high. This is NOT expected behavior. Why does the MSP430 release the SCL line here!?
Test code 2 (UCB0I2CSA = 0x08):
#include <msp430.h> void main (void) { WDTCTL = WDTPW | WDTHOLD; //Disable internal watchdog timer P4DIR |= BIT6; //Configure P4.6 as an output (for debugging on the scope) P1SEL1 |= (BIT6|BIT7); //Configure P1.6 (SDA) and P1.7 (SCL) for i2c functionality PM5CTL0 &= ~LOCKLPM5; //Clear the LOCKLPM5 bit so previous settings take effect //Configure the i2c peripheral UCB0CTLW0 |= UCSWRST; //Hold USCI module in reset UCB0CTLW0 |= ( UCMST | UCMODE_3 ); //I2C master mode UCB0CTLW0 |= UCSSEL__SMCLK; //Use SMCLK (1MHz) UCB0BRW = 10; //Divide SMCLK by 10 to achieve 100KHz baud rate UCB0CTLW0 &= ~UCSWRST; //Pull USCI module out of reset //delay (each cycle is 1us) __delay_cycles( 3000000 ); //Delay to give me time to trigger the scope P4OUT |= BIT6; //Set P4.6 high UCB0I2CSA = 0x08; //Set slave address (0x64 => LTC2943, 0x10 => LT8491, 0x08 => LTC2309) UCB0CTLW0 |= UCTR; //Set I2C bus in transmit mode UCB0CTLW0 |= UCTXSTT; //Issue START condition (start + i2c_address + RW bit) //Infinite loop while(1) { //Read the UCSCLLOW bit and control P4.6 if( UCB0STATW & UCSCLLOW ) { P4OUT &= ~BIT6; //If UCSCLLOW is set, clear P4.6 } else { P4OUT |= BIT6; //If UCSCLLOW is cleared, set P4.6 } } } //main()
Digital and analog capture of test code 2 (addressing 0x08 slave device):
Notice how SCL line clocks 8 times and then is held low (indefinitely); this is expected behavior.
1. Why does the MSP430 not hold the line low when addressing slave device 0x10? (i.e. test code 1)
2. Slave device 0x10 may perform i2c clock stretching but I believe this should NOT prevent the MSP430 from continuing to hold the SCL line low. Is this correct? If not, please help me understand why that is the case.
3. What possible condition (hardware or software) can explain the behavior that I'm seeing with the SCL line in test code 1?
Thanks,
Aamer