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.

MSP432 I2C I2C_masterReceiveStart problem

Hi,

i am trying to use the 2C_masterReceiveStart function on my project.

This is the content from it:

EUSCI_B_CMSIS(moduleInstance)->CTLW0 =(EUSCI_B_CMSIS(moduleInstance)->CTLW0 & (~EUSCI_B_CTLW0_TR)) | EUSCI_B_CTLW0_TXSTT;

When the MCU excecutes it i measure this:

I do not have any interrupt set this is the output that i get from the receive start function.

Any idea? Maybe the Slave is putting the driving the data out?

The first 8Bit is the value i want to read, but this is done on the interrupt that i didnt initiate. The last 8 bit is the content from the next register.

I dont know why the last 8bit is send out too, i only want to know the first one and i want to read the RXBUF on the interrupt but i cant because the data is already been send out.

  • Hi Michael,

    The I2C_masterReceiveStart function is going to send the slave address plus read bit, and after the slave responds with an ACK it will immediately begin to send data from the requested register. So with I2C_masterReceiveStart you are in fact requesting the first byte of data, a EUSCIB0_IRQHandler (like those shown in the MSP432 DriverLib I2C examples) needs to be ready to receive this byte and determine what action should be taken next. The labels on your oscilloscope are a bit confusing as they do not include proper room for the ACK bits which show that both the slave and then the master send the proper ACKs to continue communication. The slave will continue to send out register data until the master does not acknowledge the previous byte or a stop condition is issued, if you want to only receive one byte then you might consider using I2C_masterReceiveSingleByte.

    Regards,
    Ryan
  • Hi Ryan,

    so the slave will send data after a Start+SlaveAddress+ACK. 

    I have implemented an interrupt function that handles the EUSCI_B_I2C_RECEIVE_INTERRUPT0 from the bus.

    How do i read the received buffer without sending any further clocks?

    data = UCB3RXBUF;  <-------------- Doing this inside the interrupt handle the master sends out 9bit clock out and the slave responds with new value.

    or

    data = EUSCI_B_CMSIS(EUSCI_B3_BASE)->RXBUF & 0x00FF;<--- same problem

    or

    data = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B3_BASE); <----same problem

    Regards,

    Michael

  • i think i got it now!
    In the interrupt handler i first send a stop command and then i read the received buffer:
    MAP_I2C_masterSendMultiByteStop(EUSCI_B3_BASE);
    data= UCB3RXBUF;
  • Hi Ryan,

    the slave is sending 1 byte of data the master aknowledge and the slave sends 1 byte again and then the interrup gets fired.
    I am reading 2 bytes and my goal is only 1 byte.
    For that the master has to fire the interrup on the first byte received.
    Is there a way of doing it?
  • Michael,

    If you have enabled receive interrupts then the interrupt will fire each time the RXBUF is populated and reset each time the buffer is read from. Have you tried using I2C_masterReceiveSingleByte? Providing code segments would be helpful in debugging your issue.

    Regards,
    Ryan
  • Hi Rayan,

    i fixed it by adding a byte counter threshold:

    MAP_I2C_disableModule(EUSCI_B3_BASE);
    i2cConfig2.byteCounterThreshold = 1;
    i2cConfig2.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD;
    MAP_I2C_initMaster(EUSCI_B3_BASE, (const eUSCI_I2C_MasterConfig *)&i2cConfig2);
    /* Load device slave address */
    MAP_I2C_setSlaveAddress(EUSCI_B3_BASE, slaveAdr);
    /* Enable I2C Module to start operations */
    MAP_I2C_enableModule(EUSCI_B3_BASE);
    EUSCI_B_I2C_setMode(EUSCI_B3_BASE, EUSCI_B_I2C_RECEIVE_MODE);
    MAP_I2C_masterReceiveStart(EUSCI_B3_BASE);

    now i receive only one byte and it works.

    Thanks,

    Michael

**Attention** This is a public forum