Hi,
I tried to use MSP430G2553 + LDC1614 + MPU6050 in my own PCB, but I encountered some problems in communicating with LDC1614 via I2C channel.
PCB configuration:
pull high resistance 10K
P1.6 > I2C SCL
P1.7 > I2C SDA
P2.4 > LDC1614 INTB
P2.5 > LDC1614 SD
LDC1614 ADDR > GND
LDC1614 CLKIN > GND
Problems:
1.The last packet cannot be sent when LDC1614 is I2C slave.
Assuming there are 3 Bytes, the code sends one byte as a packet each time.
UCB0TXIFG of IFG2 will be cleared when the second one is sent successfully.
Noise will then appear when the oscilloscope measures the signal from SCL pin.
2.MPU6050 works well with MSP430G2553 for I2C communication in the PCB.
3.The same code can work well for Launch pad (MSP430G2553 embedded) and LDC1614 EVM board.
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_8MHZ; //20201127 1M -> 8M
DCOCTL = CALDCO_8MHZ;
BCSCTL2 |= DIVS_1; //20201127 SMCLK / 2 = 4MHz
__delay_cycles(10000);
//reset EVM
P2SEL &= ~BIT5;
P2REN |= BIT5;
P2DIR |= BIT5; //P2.5 > SD
P2OUT |= BIT5;
__delay_cycles(480);
P2OUT &= ~BIT5;
I2C_init();
EVM_init();
MPU_init();
for(;;)
{
sensor_mode();
MPU_read();
}
}
void MPU_init()
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x68;
UCB0CTL1 &= ~UCSWRST; //20210927
TX_Data[1] = 0x6B;
TX_Data[0] = 0x00;
TX_ByteCtr = 2;
I2C_TX_DATA();
}
void MPU_read()
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x68;
UCB0CTL1 &= ~UCSWRST; //20210927
TX_Data[0] = 0x3B;
TX_ByteCtr = 1;
I2C_TX_DATA();
RX_ByteCtr = 6;
I2C_RX_DATA();
xAccel = RX_Data[5] << 8 | RX_Data[4];
yAccel = RX_Data[3] << 8 | RX_Data[2];
zAccel = RX_Data[1] << 8 | RX_Data[0];
__no_operation();
__delay_cycles(600000);
}
void EVM_init()
{
//LDC1614 INTB setup
EVM_INT_DIR &= ~EVM_INT_BIT; // INPUT
EVM_INT_IE |= EVM_INT_BIT; // interrupt enabled
EVM_INT_IES |= EVM_INT_BIT; // Hi->Lo Edge
EVM_INT_IFG &= ~EVM_INT_BIT; // Clear IFG
Transmit(0x1C,0x8000); //LDC13xx16xx_CMD_RESET_DEVICE
Transmit(0x08,0xFFFF); //LDC13xx16xx_CMD_REF_COUNT_CH0
Transmit(0x0C,0x0000); //LDC13xx16xx_CMD_OFFSET_CH0
Transmit(0x10,0x044c); //LDC13xx16xx_CMD_SETTLE_COUNT_CH0
Transmit(0x14,0x1001); //LDC13xx16xx_CMD_CLOCK_DIVIDERS_CH0
Transmit(0x1E,0x8c40); //LDC13xx16xx_CMD_DRIVE_CURRENT_CH0
Transmit(0x1A,0x1d01); //LDC13xx16xx_CMD_CONFIG
Transmit(0x1B,0x020C); //LDC13xx16xx_CMD_MUX_CONFIG
Transmit(0x19,0x0001); //LDC13xx16xx_CMD_ERROR_CONFIG
}
void sensor_mode()
{
EVM_INT_IE |= EVM_INT_BIT;
EVM_read();
}
void EVM_read()
{
static unsigned int evmStatus;
if(dataReady == 0)
{
if(evmStatus & 0x0048)
{
dataReady=1;
}
}
if(dataReady==1)
{
Receive(LDC13xx16xx_CMD_STATUS,&evmStatus);
Receive(LDC13xx16xx_CMD_DATA_MSB_CH0,&allData[0]);
Receive(LDC13xx16xx_CMD_DATA_LSB_CH0,&allData[1]);
uHcal(allData[0],allData[1]);
dataReady=0;
}
}
void Transmit(unsigned char code, unsigned int data)
{
__disable_interrupt();
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x2A;
UCB0CTL1 &= ~UCSWRST;
TX_Data[2] = code;
TX_Data[1] = (data >> 8) & 0xFF;
TX_Data[0] = data & 0xFF;
TX_ByteCtr = 3;
done = FALSE;
I2C_TX_DATA();
}
void Receive(unsigned char code, unsigned int* data)
{
UCB0CTL1 |= UCSWRST; //20210927
UCB0I2CSA = 0x2A;
UCB0CTL1 &= ~UCSWRST;
TX_Data[0] = code;
I2C_TX_DATA();
RX_ByteCtr = 2;
I2C_RX_DATA();
}
void I2C_TX_DATA()
{
__disable_interrupt();
IE2 |= UCB0TXIE;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 |= UCTR + UCTXSTT;
if(UCB0I2CSA == 0x2A)
{
__bis_SR_register(GIE);
__no_operation();
}
else
{
__bis_SR_register(CPUOFF + GIE);
__no_operation();
}
}
void I2C_RX_DATA()
{
__disable_interrupt();
IE2 |= UCB0RXIE;
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
__bis_SR_register(CPUOFF + GIE);
__no_operation();
IE2 &= ~UCB0RXIE;
}
// USCIAB0TX_ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if(UCB0CTL1 & UCTR) // TX mode (UCTR == 1)
{
if (TX_ByteCtr) // TRUE if more bytes remain
{
TX_ByteCtr--; // Decrement TX byte counter
UCB0TXBUF = TX_Data[TX_ByteCtr]; // Load TX buffer
}
else // no more bytes to send
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
else // (UCTR == 0) // RX mode
{
if (--RX_ByteCtr) // RxByteCtr != 0
{
RX_Data[RX_ByteCtr] = UCB0RXBUF; // Get received byte
if (RX_ByteCtr == 1) // Only one byte left?
{
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
}
}
else // RxByteCtr == 0
{
RX_Data[RX_ByteCtr] = UCB0RXBUF; // Get final received byte
IFG2 &= ~UCB0RXIFG;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}