This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0C1104: How to send more than 4 bytes using SMBUS .

Part Number: MSPM0C1104
Other Parts Discussed in Thread: BQ40Z50

Tool/software:

Hi 

      

In MSPM0C1104  [ #define I2C_SYS_FENTRIES   (4) /* !< Number of FIFO entries */] . SMBUS/I2C TX/RX buffer size is 4 bytes only. And  we can not increase this. So we are not able to fill and transmit more than 4 byte data using functions like [DL_I2C_fillControllerTXFIFO],[ DL_I2C_startControllerTransferAdvanced] , [DL_I2C_startControllerTransfer].For flash write/Block write we need more than 4 bytes. I tried many options like below but still it is sending 4 bytes only.

 

We are using this MCU and functionality with BQ40Z50 R2.

gI2cControllerStatus = I2C_STATUS_IDLE;

gTxLen = count+1;// I2C_TX_PACKET_SIZE;//count+1;//I2C_TX_PACKET_SIZE;

gTxCount = DL_I2C_fillControllerTXFIFO(SMBUS_0_INST, &I2Ctxbuff[0], gTxLen);
/* Enable TXFIFO trigger interrupt if there are more bytes to send */
if (gTxCount < gTxLen) {
DL_I2C_enableInterrupt(SMBUS_0_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
}
else
{
DL_I2C_disableInterrupt(SMBUS_0_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
}

/*
* Send the packet to the controller.
* This function will send Start + Stop automatically.
*/
gI2cControllerStatus = I2C_STATUS_TX_STARTED;

while (!(DL_I2C_getControllerStatus(SMBUS_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) ;

DL_I2C_startControllerTransfer(SMBUS_0_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, gTxLen);

/* Wait until the Controller sends all bytes */
while ((gI2cControllerStatus != I2C_STATUS_TX_COMPLETE) && (gI2cControllerStatus != I2C_STATUS_ERROR))
{
__WFE();
}

while (DL_I2C_getControllerStatus(SMBUS_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
;
uint32_t status = DL_I2C_getControllerStatus(SMBUS_0_INST);
/* Trap if there was an error */
if (DL_I2C_getControllerStatus(SMBUS_0_INST) &
DL_I2C_CONTROLLER_STATUS_ERROR) {
/* LED will remain high if there is an error */
__BKPT(0);


// if (status & DL_I2C_CONTROLLER_STATUS_NACK)
// printf("NACK received!\n");

if (status & DL_I2C_CONTROLLER_STATUS_ARBITRATION_LOST)
__BKPT(2);

// if (status & DL_I2C_CONTROLLER_STATUS_BUS_ERROR)
// printf("Bus error!\n");

if (status & DL_I2C_CONTROLLER_STATUS_ERROR)
__BKPT(3);

}

while (!(
DL_I2C_getControllerStatus(SMBUS_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))

it stops at _BKPT(3); always.

  • 1) The FIFOs are actually 8 bytes [Ref TRM (SLAU893A) Sec 13.1.2]. But yes, if you want to do larger transfers, you need to fill/drain the FIFOs while the transaction is running.

    2) This code looks like it originated in example i2c_controller_rw_multibyte_fifo_interrupts. That example uses the ISR to fill/drain the FIFOs as needed. (As provided, it uses Tx/Rx lengths of 16.)

    3) If you reached _BKPT(3) my first guess is that you got a NACK. The first thing to check for that case is the I2C address you're using (I2C_TARGET_ADDRESS in the example).

    [Edit: Added Reference]