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.

CCS/TM4C123GE6PM: Multiple Byte receive I2C

Part Number: TM4C123GE6PM

Tool/software: Code Composer Studio

Hi All,

Ive been playing around with I2C for a while now but i cant find out how to receive multiple bytes with my I2C Slave. The Idea is to send two bytes from the Master to the Slave. The Slave will controll three Servos so In Byte one i want to transmit the "Adress" of the Servo and in Byte two i want to have the "Value".

To do so i startet to transmit a single byte using I2C_MASTER_CMD_SINGLE_SEND. Transmition works perfectly using the slave data get command.

Next step was sending out two bytes using the Master Burst send. This also works fine. Now i just dont know how to receive it. Using slave data get twice always brings the second byte sent. How can I receive those two bytes with my Slave module?

Thanks for your advice,

Alex

  • Hello Alex

    Can you please share your code that you are using?
  • sry for the late answer ;)

    This is the code i use to send the two bytes.


    void Send(int M_Adress, int M_Data)
    {
    I2CMasterSlaveAddrSet(I2C0_BASE,Slave_Adress, false);
    I2CMasterDataPut(I2C0_BASE,M_Adress);

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

    while(I2CMasterBusy(I2C0_BASE));

    I2CMasterDataPut(I2C0_BASE,M_Data);

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);

    while(I2CMasterBusy(I2C0_BASE));
    }


    Sending works perfect. I checked it with the Oszilloskop.

    Here is the Interrupt Handler of the Slave module.

    void I2C1SlaveIntHandler(void)
    {

    I2CSlaveIntClear(I2C1_BASE);
    S_Adress = I2CSlaveDataGet(I2C1_BASE);
    S_Data = I2CSlaveDataGet(I2C1_BASE);
    I2CSlaveStatus(I2C1_BASE);

    }


    The Code works fine so far but in both S_Data and S_Adress I get the M_Data.
  • If I didn't miss something, we would need to know the kind of I2C slave, too. Say, the name of the IC, or at least a hint to the protocol used. Such issues (reading multiple byte from one slave) are not covered by the "generic" I2C spec. in very detail ...

  • It is just the TM4C123GE6PM Board with IC0 module initialized as a Master and IC1 Module initialized as a slave. In the application later the whole thing is going to be a slave. The master is just for evaluating the functionality. I will give you the initializations aswell:


    void InitI2C0(void) //Master
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);

    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), true);


    }


    void InitI2C1(void) //Slave
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);


    I2CIntRegister(I2C1_BASE, &I2C1SlaveIntHandler);
    IntEnable(INT_I2C1);
    I2CSlaveIntEnableEx(I2C1_BASE,I2C_SLAVE_INT_DATA);
    I2CSlaveEnable(I2C1_BASE);
  • I haven't used the I2C peripheral of the TM4C123 yet. But since there is no FIFO involved, you will probably need to keep track of your transmission state (first byte, second byte, etc.) in your application code.
  • Hello Alexander

    Have you tried coding the Receive part or is it that you don't know what to code for the Receive operation? The above code(s) only show Master Transmit operations.
  • Hello Amit,

    this is the receive part i tried:


    void I2C1SlaveIntHandler(void)
    {

    I2CSlaveIntClear(I2C1_BASE);
    S_Adress = I2CSlaveDataGet(I2C1_BASE);
    S_Data = I2CSlaveDataGet(I2C1_BASE);
    I2CSlaveStatus(I2C1_BASE);

    }

    But it doesnt work . And yes, the receive part i want to know how to code sinsce the SlaveGet command doesnt work for multiple bytes.

  • Hello Alexander

    The SlaveData Get cannot work in a single interrupt handler. Since the data being sent to the Slave device is sent as two separate bytes, the slave must enter the interrupt handler twice (at the end of each byte being received on the bus). Waht you would need is to keep a track of the byte using the FBR status on the slave to read the first byte in the address variable. If the FBR bit in status is not set then read the byte in the S_Data variable.
  • Thanks for the quick answer ;)

    so in the interupt handler im going to save depending on the FBR bit into adress or Data variable. the only thing that i still dont get is how to enter the interupt handler a second time then ?
  • Hello Alexander

    Once the interrupt status bit is cleared and so is the condition that caused it (in this case reading the data byte from the I2C slave), the I2C slave will generate the next interrupt when the next time the interrupt condition is satisfied.
  • Thank you so much :)

    i wont be able to try it before the end of holidays now but i will make sure to let you know if i got it to work.

    I wish you a happy new year and thanks once again.

    Alex