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.

MSP432P401R: MSP432 I2C Master Read operation.

Part Number: MSP432P401R

Working with a TCA6408A I'm trying to do an I2C read, and the EUSCI_B peripheral appears to be behaving badly as reported here: 

 and marked as resolved (but the resolution is claimed to be insufficient by the poster and appears insufficient on my end.

After a sequence of writes to configure an I2C Peripheral I try to perform a read as shown:

With the following code:

I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
I2C_masterSendMultiByteStart(EUSCI_B0_BASE,0x00);
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
buttonState = I2C_masterReceiveSingleByte(EUSCI_B0_BASE);

On the bus I can observe: 0x42,0xFF,0x43,0x7F so I'm concerned it doesn't transmit the register address properly unless I insert a delay.

I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
I2C_masterSendMultiByteStart(EUSCI_B0_BASE,INPUTMANAGERINPUTPORTREG);
for(volatile unsigned long i = 500;i;i--){}
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
buttonState = I2C_masterReceiveSingleByte(EUSCI_B0_BASE);

I intend to clean up that delay and make something interrupt driven in the future. but for now I can get it to transmit the register address with the above code: 0x42,0x00,0x43,0xDF,0xDF

So having paused and gotten through the transmission, I find that I2C_masterReceiveSingleByte doesn't in fact send a NACK or STOP. Why does it receive so much more than a byte?

Why does it leave the bus busy after I2C_masterReceiveSingleByte?

Is there a good example out there of an I2C read with this driver?

Thanks

 

  • Oh and while I'm at it, what's the best way to recover from the busy state it's left in?
  • I think these examples will be the closest to what you are trying to do:

    I believe that you are correct that a delay is required.  Please note that in the examples and also in the TRM, that two bytes are being transmitted and specifically in the TRM in Figure 26-12. I2C Master Transmitter Mode, that there is no mechanism for sending a repeated start until during or after the transmission of the 2nd byte.  

    Regards,

    Chris

  • Thanks for pointing me to that resource. My hope had been to use higher level code in the drivers to control it, but this has fixed it and I'm grateful for that. In the end my read ends up appearing as:

    while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE));

    I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    I2C_masterSendMultiByteStart(EUSCI_B0_BASE,INPUTMANAGERINPUTPORTREG);

    while(!(EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG0));

    // Send the restart condition, read one byte, send the stop condition right away
    EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_TR);
    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;
    while(MAP_I2C_masterIsStartSent(EUSCI_B0_BASE));
    EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
    while(!(EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG0));
    output = EUSCI_B0->RXBUF;

    And it appears to work, sending a NACK at the end and signalling a stop.

**Attention** This is a public forum