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.

AM3352: I2C Slave transmit length

Part Number: AM3352

We currently have a problem with I2C slave transmitting more than 32bytes. 

We are using interrupt mode, and the I2C_DATA reg to receive and transmit bytes. 

According to the am335x datasheet, 21.3.14.4, to transmit more than fifo size, we need to enable the draining feature. But in the draining feature there’s no mention of the i2c slave mode write. There are mentioning of the fifo and XUDF or XDR interrupt. 

Our current model is to waiting for XDR interrupt, and then read all the accumulated received bytes from the fifo, and then send the response back to the master by writing to the txfifo in the XDR interrupt directly. This works quite well when the response message is smaller than 32bytes.

When the reponse message is larger than 32bytes, we tried to enable the XUDF, and continue our send to the tx fifo.  but it seems too late when the XUDF int came, and the message is not complete. 

What would be the correct way to response send messages longer than 32bytes as I2C slave on AM3352

  • It is on linux, with TI sdk released in 2018

    We modified i2c-omap driver to support slave mode. For messages shorter than 32 the code work ok. We want  to understand how to send data over 32bytes in slave mode. 

    Jeff

  • Hi,

    a reminder, this is very urgent for us.

    Thanks,

    Nadav

  • Hi Jeff, Nadav,

    As you already identified, the draining feature cannot be used with slave TX mode. Section 21.3.14.1 (FIFO Interrupt Mode Operation) of the AM335x TRM describes another option for handling the XRDY interrupts. This option supports slave TX mode and should be used instead.

    Alternatively, if you chose to use FIFO DMA mode, there are some configuration comments in the TRM for when the I2C is in Slave TX Mode.

    Regards,
    Melissa
  • Hi Melissa,

    I'm trying to follow 21.3.14.1 FIFO interrupt mode, but I don't seem to be able to get it working.
    Here's what I'm doing.

    Wait for XRDY interrupt
    Read the request data sent from the master. Then construct the response (we do this in very short time), and send it inside the interrupt.
    For response smaller than 32 bytes, I set tx threshold to the same as the response size.

    Below is a dmesg dump of a small message response. And we have no problem with small messages, the master side receives this response correctly.
    [ 155.551363] BB |XUDF|AAS | <- this means an interrupt is received>
    [ 155.551371] BB |XUDF|XRDY|
    [ 155.551381] [FUNC = ubmc_i2c_receive_data_multi LINE = 160]= Receiving 11 bytes, from idx 0, DCOUNT 0 <- this reading request
    [ 155.551395] [FUNC = ubmc_ssif_parse_i2c_slave_msg LINE = 964]= netfn 0x28 cmdid 0x23 len 8
    [ 155.551407] [FUNC = ubmc_i2c_slave_send_current_buf LINE = 295]= Start TX, len 11 <-This start of sending response
    [ 155.551414] [FUNC = ubmc_i2c_resize_fifo_thresh LINE = 235]= TX threshold set to 11
    [ 155.551422] [FUNC = __ubmc_i2c_slave_write_buf LINE = 182]= tx fifo size 53
    [ 155.551433] SSIF MSG TX:00000000: 0a 2c 23 00 01 00 00 00 51 01 38
    [ 155.551440] [FUNC = __ubmc_i2c_slave_write_buf LINE = 193]= tx fifo size 42 after
    [ 155.551446] [FUNC = ubmc_i2c_slave_send_current_buf LINE = 325]= Finished tx

    For a response larger than 32 bytes,
    I'm setting the tx threshold to 16 bytes, and then write 24 bytes to the fifo, return from interrupt handler, and wait for another XRDY interrupt, in the second XRDY interrupt, I send the rest of data.
    Below is a dmesg dump of transmitting a 39 bytes of data, it seems to finish the transmit, but the other side is not receiving the response correctly. I get a lot retry request from master, and master is reporting receive a short message.

    [ 155.561251] BB |AAS |
    [ 155.561282] BB |XUDF|AAS |XRDY|
    [ 155.561295] [FUNC = ubmc_i2c_receive_data_multi LINE = 160]= Receiving 11 bytes, from idx 0, DCOUNT 0
    [ 155.561310] [FUNC = ubmc_ssif_parse_i2c_slave_msg LINE = 964]= netfn 0x28 cmdid 0x23 len 8
    [ 155.561321] [FUNC = ubmc_i2c_slave_send_current_buf LINE = 295]= Start TX, len 39
    [ 155.561327] [FUNC = ubmc_i2c_resize_fifo_thresh LINE = 235]= TX threshold set to 16
    [ 155.561335] [FUNC = __ubmc_i2c_slave_write_buf LINE = 182]= tx fifo size 53 <- this is
    [ 155.561345] SSIF MSG TX:00000000: 26 2c 23 00 00 00 20 00 00 03 01 7f 68 01 01 00
    [ 155.561351] SSIF MSG TX:00000010: 72 00 72 3f 3f 80 01 00
    [ 155.561358] [FUNC = __ubmc_i2c_slave_write_buf LINE = 193]= tx fifo size 29 after
    [ 155.561915] BB |XUDF|XRDY|
    [ 155.561924] [FUNC = ubmc_i2c_slave_send_current_buf_continue LINE = 342]= Finishing TX, len 15, continue from 24
    [ 155.561930] [FUNC = __ubmc_i2c_slave_write_buf LINE = 182]= tx fifo size 29
    [ 155.561936] SSIF MSG TX:00000000: 00 01 00 00 00 00 00 07 28 59 fc 7f 80 5a 5a
    [ 155.561942] [FUNC = __ubmc_i2c_slave_write_buf LINE = 193]= tx fifo size 14 after
    [ 155.561948] [FUNC = ubmc_i2c_slave_send_current_buf_continue LINE = 366]= Finished tx
    [ 155.562134] BF |


    So, do you see any problem in the above procedure?
    In first XRDY, Set TXTHRESH to 16, write 24 bytes, then return from irq
    In second XRDY, write the rest 15 bytes,
  • Hi Jeff,

    When are you configuring the TXTRSH bitfield?  The TRM has the following note in this bitfield description: "Note... the threshold must not be changed while a transfer is in progress (after STT was configured or after the module was addressed as a slave)."

    Depending on when you're setting the TXTRSH bitfield, two suggestions to try:

    1.  Make sure I2C_BUF.TXTRSH = 15h when you're setting it to 16.  Otherwise, you could be overfilling the FIFO and the last byte write to I2C_DATA may be getting ignored. 

    2.   Set the TX FIFO threshold to 1 (I2C_BUF.TXTRSH=0), similar to the I2C Slave TX Mode instructions in section 22.3.14.3 (FIFO DMA Mode Operation) of the TRM.

    Regards,

    Melissa

  • Hi Melissa, 

    We were setting the TXTRSH after addressed as a slave, but only at the beginning of TX. 

    I followed your suggestion, using a global TXTRSH, and removed TXTRSH set in each transmit, 

    And I tried both 16(15)  1(0) for TXTRSH values, and the results are the same as before.

    Anything else you see that could be wrong here?

    Best Regards

    Jeff

  • One thing I notice, is that if I write 32 bytes(the fifo size), then I won't get a second interrupt. When I write shorter say 24 bytes, then I get the second TXDY interrupt. But on the master side it is the same behavior, I wonder whether in both cases only 32bytes are sent.

    How does the i2c slave logic determine how many bytes needs to be sent? I don't see any place I can read this. The BUF_STAT.TXSTAT value seems totally irrelavant, but it does decrease on every valid DATA_REG write (when it is not full).
  • Hi Jeff,

    The number of bytes to be sent is determined by the master’s acknowledgements. At the end of every byte of data the slave sends, the master will send an ACK to indicate it’s ready for more data. After the master has received the desired number of bytes, it will send a NACK. (Here’s a helpful app note about I2C— www.ti.com/.../slva704.pdf.)

    How many bytes are you loading into the FIFO when you set TXTRSH to 1 (0)? Can you try only loading one byte and then waiting for XRDY before loading the next byte? Note you should only get an XRDY interrupt when the master expects more data and sends an ACK. How many data bits are you able to successfully send with this configuration?

    If you're still seeing the same results as before, can you connect an oscilloscope or logic analyzer to the I2C lines and capture what's happening when the I2C slave is sending data?

    Regards,
    Melissa
  • Hi Jeff,

    I haven't heard from you in a while and am assuming this issue has been resolved.

    As such, I'm marking this post as "TI thinks resolved."

    Regards,
    Melissa
  • Thanks, Melissa, that didn't quite resovle my issue, but did help understand the issue better. We now think the issue is not on am335x side. Thanks for your help .