cancel
Showing results for 
Search instead for 
Did you mean: 

I3C Target Mode: Can TX FIFO Be Loaded in RXFNE for Repeated Start Reads?

DominikPrause
Associate

Hardware & Setup

- MCU: STM32H523RE (I3C target/slave mode) - Controller: STM32H533RE (I3C controller mode)
- HAL Version: STM32CubeIDE 1.16.1, HAL for STM32H5
- Bus Speed: 3.205 MHz I3C SDR

Problem Description

We're implementing an I3C target that needs to respond to random address reads with repeated start:

[START][ADDR_W][0x01][RESTART][ADDR_R][DATA][STOP]

Where:
- ADDR_W writes the address byte (0x01) to tell the target which register to read
- RESTART signals the repeated start
- ADDR_R begins the read phase
- Target should respond with data from address 0x01

The problem: Loading the TX FIFO in the RXFNE interrupt handler doesn't work. The hardware transmits stale data before the ISR can fill the TX FIFO with the requested data.

1. RXFNE interrupt fires when address byte (0x01) is received
2. ISR starts executing (~1-2µs interrupt latency)
3. ISR flushes TX FIFO and writes fresh data to TDR registers
4. But hardware has already started transmitting from the (empty/stale) TX FIFO

The I3C peripheral begins clocking out data from TX FIFO before the CPU can service RXFNE and load the requested data.

Transaction sequence captured:
T=0.000000: [START][ADDR_W=0x12][ACK]
T=0.000004: [DATA=0x01][T-bit=ODD] // Address byte received
T=0.000007: [RESTART]
T=0.000009: [ADDR_R=0x12][ACK]
T=0.000013: [DATA=0xFF][T-bit=nEOD] // Wrong! Stale data transmitted

Current Implementation

void I3C2_EV_IRQHandler(void) {
I3C_TypeDef* i3c = p_i3c_handle.Instance;
UInt32 evr = i3c->EVR;

// RXFNE: Address byte received
if (evr & I3C_EVR_RXFNEF) {
UInt8 rx_byte = (UInt8)(i3c->RDR & 0xFF);

if (rx_count == 0) { // First byte = address
// Flush TX FIFO
LL_I3C_RequestTxFIFOFlush(i3c);
while (!(i3c->EVR & 0x02)); // Wait TXFEF (TX FIFO Empty)

// Fill TX FIFO with data from requested address
i3c->TGTTDR = 0;
for (int i = 0; i < 8; i++) {
i3c->TDR = tx_buffer[rx_byte + i];
}
}
rx_buffer[rx_count++] = rx_byte;
}
}

 

Instrumentation shows the ISR is loading the correct data, but it's too late:

RXFNE interrupt: Loading tx_buffer[0x01] = 0x02 into TX FIFO
Protocol Analyzer: Hardware transmitted 0xFF (stale data)

The data we write to TDR doesn't make it to the wire before transmission starts.

Questions

Primary question: Is it even possible to load TX FIFO in the RXFNE interrupt handler for repeated start read transactions? Or is interrupt latency fundamentally too slow for this use case?

Specific questions:

1. Should TX FIFO be pre-filled before knowing the requested address? How can we know what data to load before receiving the address byte?
2. Is there a way to delay transmission until software explicitly signals ready? We haven't found a control bit for this.
3. Does TGTTDR preload count affect transmission start timing?
4. Should DMA be used instead of interrupt-driven FIFO management for target mode?
5. Is this a known limitation of I3C target mode for this use case on STM32H5?
6. Is there example code from ST showing correct I3C target implementation for random address reads with repeated start?

What Works vs. What Doesn't

:white_heavy_check_mark: Separate transactions work fine:
[START][ADDR_W][0x01][STOP] // Write address
<time passes>
[START][ADDR_R][DATA][STOP] // Read data (sequential read)

:cross_mark: Repeated start reads fail:
[START][ADDR_W][0x01][RESTART][ADDR_R][DATA][STOP] // No time for ISR

The issue is 100% reproducible - every repeated start read returns stale/wrong data.

Summary

We need to understand if:
- A) Our implementation is wrong and there's a correct way to handle this
- B) This is a fundamental limitation and repeated start reads cannot work with interrupt-driven target mode on STM32H5

Any guidance on the correct approach would be greatly appreciated. If this is a known limitation, we need to understand the recommended alternative.

 

Thank you!

2 REPLIES 2
FBL
ST Employee

Hi  @DominikPrause 

Based on the RM, there is no hardware mechanism in the STM32H5 I3C peripheral to delay or block the start of transmission until software explicitly indicates that the TX data is ready. In protocol spec, the target cannot stretch or stall the SCL line. The exact behavior when the TX FIFO underruns during a read is not fully detailed in controller specifications; I'm checking internally.

Before that, some questions to clarify :

How do you detect the start/end of a write transaction and reset rx_countAre you using a specific event like private command complete, STOP/END flag in EVR?

If you reduce the bus speed to:  ( like I2C speed) or , does the repeated‑start random read begin to work reliably? In fact, busy waiting on TXFE inside the ISR may consume precious microseconds; at 3.2 MHz this is likely to be too slow.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.




Best regards,
FBL
DominikPrause
Associate

Hi FBL,

the end of the write transaction is detected with FCF flag. rx_count is reset at the end of the whole transaction sequence.

I will check with reduced bus speed.

 

Thanks!