Part Number: MSP430FR2633
Tool/software: Code Composer Studio
Hi all,
I have written I2C functions using polling onto a MSP430FR2633 (MSP-CAPT-FR2633 board) to communicate with a peripheral MAX77818 battery charger fuel gauge chip.
My read function hangs at the repeated start condition. By that I mean the check for UCTXSTT being cleared. I have copied the I2C read function code below. My write function seems to work. So I am eliminating the possibility of hardware. I have pull up resistors of 2.2k on SDA and SCL. I also checked the registers in debug which confirmed NACKIFG was not set.
void Read_I2C_Reg(unsigned char Slave_Addr, unsigned char Reg, unsigned char ReadLength)
{
UCB0IFG = 0x00;
PRxDataPtr = 0; // Initialise starting index of rxBuffer
PRxData = (unsigned char *)RxBuffer[0]; // Initialise PRxData pointer to start of RX buffer
RXByteCtr = ReadLength; // Load arguement ReadLength to RXByteCtr which is for number of bytes to read
while(UCB0STAT & UCBBUSY); // ensure bus isn't busy
UCB0I2CSA = Slave_Addr >> 1; // Slave Address is Slave_Addr's 7 MSB's written on to UCB012CSA
UCB0CTLW0 |= UCTR; // I2C TX mode
UCB0CTLW0 |= UCTXSTT; // start condition
UCB0TXBUF = Reg; // Register address to read. this will be the first byte of data transmitted.
while(UCB0CTLW0 & UCTXSTT); // Wait till I2C STT is sent
while (!(UCB0IFG & UCTXIFG)); // Reg has been sent
UCB0CTLW0 &= ~UCTR; // Switch to receive mode
UCB0CTLW0 = UCTXSTT; // Send repeated start condition.
while(UCB0CTLW0 & UCTXSTT); // Wait till I2C STT is sent<<<<<<<<<<<<<<<<<<<<<<<<<<<< UCTXSTT doesn't get cleared. Waits here.
while(RXByteCtr > 0) // If we have requested to read multiple bytes, loop
{
while(!(UCB0IFG & UCRXIFG)); // Wait till RX flag goes up. Then UCB0RXBUF has data
RxBuffer[PRxDataPtr] = UCB0RXBUF; // Fill RxBuffer at the index PRxDataPtr with received UCB0RXBUF
PRxDataPtr++; // Increment PRxDataPtr
RXByteCtr--; // decrement RXByteCtr
}
while(!(UCB0IFG & UCRXIFG));
*PRxData = UCB0RXBUF; // Move final RX data to PRxData
UCB0CTLW0 |= UCTXNACK; // NACK before stop
UCB0CTLW0 |= UCTXSTP; // Issue stop condition
while (!(UCB0CTL1 & UCTXSTP)); // Ensure stop condition got set
}
My initialisation for the I2C is as below. DCO at 16MHz sources SMCLK:
void Init_MSP430_I2C(void)
{
P1SEL0 |= BIT2 | BIT3; //Assign I2C pins to USCI_B0
UCB0CTLW0 |= UCSWRST; // Enable SW reset
UCB0CTLW0 |= UCMST | UCMODE_3 | UCSYNC ; //I2C Master, synchronous mode, 7 bit mode by default
UCB0CTLW0 &= ~UCMM; //Setting for multi master I2C, not relevant, but &~'d as a precaution
UCB0CTLW0 = UCSSEL_3 ; // Use SMCLK,
UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kHz Above 100kHz upto 400kHzwould be 'Fast I2C
UCB0BR1 = 0;
UCB0I2CSA = 0x00; // Set to AA for initialisation purposes. Slave address is accepted as a parameter in the read and write function.
UCB0CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IFG |= 0x00;
}
Another bizzare observation : Up until the point it gets to the never ending check for UCTXSTT, my register settings stay as I initialised. When it hangs at the highlighted line, I paused and observed a change in some registers through the debugger. Under USCI_B0_I2C registers, most importantly UCB0CTLW0 is showing 0x01D2. Which would mean that the UCMODEx bits are 00b which is not in I2C mode anymore! and UCTR has been turned back on although it was turned off just before.
Is anyone able to help me fix, and understand why the code halts at the repeated start please? Any guidance will be greatly appreciated.
Thanks & kind regards,
Guyan