2406084_en-US

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2406084_en-US

2406084_en-US

S32K344 FlexIO I2C DMA

Hello,

I have some questions regarding the FlexIO I2C DMA  on S32K344, and I would appreciate your insights.

1. When using FlexIO to emulate I2C, the Tx length is set to Size + 1. Is this because "The transmit shifter loads one additional word on the last falling edge of the SCL pin"?1.png1.png1.png1.png1.png2.png2.png2.png2.png2.png

2. When using DMA for sending data, the MAJORLOOP_COUNT is also set to Size + 1. Is this for the same reason? When using DMA, all transmitted data comes from Master->TxData. When calling Flexio_I2c_Ip_MasterSendData, should the TxBuff length be Size + 1, and should the last byte be 0xFF or 0x00?

3.png3.png3.png3.png3.png

3. For receiving data, the MAJORLOOP_COUNT is set to Size – 1. Why is this?

4. I tested this on the S32K344 and found that when using DMA for FlexIO I2C receiving data, the received data is one byte less than expected. Observing with an oscilloscope, the clock signal for the last byte shows only about five or six bits of waveform. The same test on the S32K312 works fine.

S32K344

S32DS3.6.4

RTD700

 

BR,

Jason

Re: S32K344 FlexIO I2C DMA

Hi @Jason07 

As FlexIO is not a dedicated I2C peripheral, its implementation requires additional internal steps to complete the I2C bus sequence correctly.

The Size + 1U in the transmission is related to the final shifter load required by FlexIO to complete the I2C frame sequence. This additional transfer does not represent an extra payload byte. Instead, it is used internally by the FlexIO hardware to generate the final clock pulses and correctly transition the bus to the end-of-transfer state.

The Size - 1U in the reception is necessary because the last received byte is handled separately. This allows the driver to generate the required NACK and STOP conditions at the correct time.

Also, take into consideration that when using DMA transfer mode, data transfers may be affected by cache coherency issues. To avoid potential problems when D-Cache is enabled, ensure that the buffers used as the source and destination of the DMA TCD are allocated in a non-cacheable memory region.

There is no need to increase the TRANSFER_SIZE parameter when calling the Flexio_I2c_Ip_MasterReceiveData() function. The driver already handles the required internal adjustments for the receive sequence.

By last, while reviewing your configuration, I noticed that the same DMA interrupt callback has been assigned to both DMA channels. According to the descriptions provided in Flexio_I2c_Ip.c, different callbacks should be used for the transmit and receive:

  • FlexIO_I2c_Ip_DmaTransferCompleteNotificationShifter0() for the FlexIO Channel 0/1 TX
  • FlexIO_I2c_Ip_DmaTransferCompleteNotificationShifter1() for the FlexIO Channel 0/1 RX

BR,VaneB

Re: S32K344 FlexIO I2C DMA

Hi@VaneB

I found the code where “the last received byte is handled separately”.

However, I still have a question regarding sending. When using interruptdriven sending, the length is set to Size + 1. During sending, the code checks whether it is the last byte; if so, it sends 0xFF or 0x00. The actual sent data length is still Size. But when using DMA for sending, the DMA copies Size + 1 bytes from the send buffer, and in the Flexio_I2c_Ip_MasterEndDmaTransfer function, it also fills 0xFF or 0x00 into the ShiftBuffer. This means the actual sent data length is Size + 1, not Size. Why?

1.png1.png1.png1.png

2.png2.png2.png2.png

I modified all occurrences of TRANSFER_SIZE + 1 in the attached project to TRANSFER_SIZE (8), and also modified the DMA interrupt callback as described. I also disabled the DCache.

When using DMA for FlexIO I2C sending, I observed with an oscilloscope that at -Os optimization level, the clock signal is normal with only 8 bytes. However, at -O0 optimization level, the clock for the first 8 bytes is normal, but after the ACK is sent, the stop signal is not generated as expected; instead, an extra 1bit clock pulse appears.

3.jpg3.jpg3.jpg3.jpg

For FlexIO I2C receiving via DMA, LPI2C0 is used as a slave to send 8 bytes (0x10–0x17). At -O0 optimization level, the clock signal becomes abnormal during the transmission of the 7th byte, and the FlexIO receive buffer contains only 6 bytes (0x10–0x15).

4.jpg4.jpg4.jpg4.jpg

At -Os optimization level, the clock signal becomes abnormal during the transmission of the 8th byte, and the FlexIO receive buffer contains only 7 bytes (0x10–0x16).

5.jpg5.jpg5.jpg5.jpg

All of the above issues are reliably reproducible.

Re: S32K344 FlexIO I2C DMA

Hi @Jason07 

I think the key point is that I2C uses open-drain signaling:

  • Logical 0 actively pulls SDA low.
  • Logical 1 releases SDA, allowing the pull-up resistor to drive the line high.

Since FlexIO is a programmable peripheral rather than a dedicated I2C controller, the driver must generate I2C protocol events by controlling the bit patterns loaded into the shifters.

Because of this, the final 0x00 and 0xFF values should not necessarily be considered additional payload bytes. Instead, they are used to place SDA in the correct state to complete the rotine.

When Master->SendStop == TRUE, the driver loads 0x00, forcing SDA low. Once the shifter finishes and FlexIO releases the line, the pull-up brings SDA high while SCL is already high, creating the required STOP condition (SDA: LOW → HIGH while SCL is HIGH).

When Master->SendStop == FALSE, the driver loads 0xFF, which keeps SDA released. The pull-up keeps SDA high, preventing a STOP condition and leaving the bus ready for a Repeated START (SDA: HIGH → LOW while SCL is HIGH).

Also, I recommend enabling the DMA Optimize mode. An example is available in the thread: Example S32K344 FlexIO I2C with DMA Optimize option S32DS 3.6.0 RTD 6.0.0.

By last, Are working with a custom board or an EVB/FRDM?

タグ(1)
評価なし
バージョン履歴
最終更新日:
6 時間前
更新者: