Skip to main content
Explorer II
July 10, 2025
Question

Reducing interrupt latency on STM32U575

  • July 10, 2025
  • 4 replies
  • 676 views

I'm trying to implement a serial bit-stream input (PCM-style) on an STM32U575. I have set up an EXTI channel to capture the incoming clock signal and then I'm using the following code in the ISR to capture the data bits:

__attribute__ ((section(".RamFunc"))) void EXTI7_IRQHandler(void) {
	SPLITTER_CLK_OUT_GPIO_Port->ODR |= SPLITTER_CLK_OUT_Pin;

	if(haveFS == 0) {
		// CLK pulse whilst in idle state - is there a FS?
		if(PCM_FS_IN_GPIO_Port->IDR & PCM_FS_IN_Pin) {
			haveFS = 1;
			slotCount = 0;
			bitsCount = bits_per_slot;
			pDataSlot = pData;
		} else {
			return;
		}
	}

	// Read next data bit
	if(PCM_DATA_IN_GPIO_Port->IDR & PCM_DATA_IN_Pin) {
		*pDataSlot |= (1 << --bitsCount);	// Set bit
	} else {
		*pDataSlot &= ~(1 << --bitsCount);	// Clear bit
	}

	if(_internal.bitsCount == 0) {
		// Received one slot
		slotCount++;
		pDataSlot++;
		bitsCount = bits_per_slot;
	}

	// Have we received all slots?
	if(_internal.slotCount == _internal.total_slots) {
		// Signal done somehow?
		slotCount = 0;
		haveFS = 0;	// Now we need to expect another FS pulse...
	}

	__HAL_GPIO_EXTI_CLEAR_RISING_IT(PCM_CLK_IN_Pin);
	SPLITTER_CLK_OUT_GPIO_Port->ODR &= ~SPLITTER_CLK_OUT_Pin;
}

This works for incoming clock frequencies up to approx 2MHz, but I really need to be able to handle about 4MHz. I've got the main clock configured at 160MHz.

I think my immediate issue is the interrupt latency, using the pin toggles in the ISR I can measure ~250ns latency, even after attempting to run the ISR from RAM. I'm not overly familiar with the architecture of the M33 core etc. - hoping someone might be able to give me some suggestions on how to improve this further!

TIA

    This topic has been closed for replies.

    4 replies

    Graduate II
    July 10, 2025

    Why not use the SAI interfaces? (reference manual rm0456 chapter 69)

    Explorer II
    July 10, 2025

    Unfortunately the PCM interface I'm using has 18 slots of 16bits, the SAI interfaces only seem to support up to 16 slots @ 16 bits.

    Super User
    July 10, 2025

    And what about 9 slots of 32 bits?

    JW

    Super User
    July 10, 2025

    You may quench out a few cycles here and there, but such a high number of interrupts will, if feasible at all, use up the entire CPU. If so, why not simply using polling?

    Alternatively, you may look into receiving with SPI with DMA triggered by the FS edge.

    hth

    KnarfB

    Explorer II
    July 14, 2025

    Hi @KnarfB - I've tried a simple example of using SPI with DMA to receive my bitstream, and it looks promising. How would I configure the DMA to be triggered by the FS edge? I've tried to set up my GPDMA channel with an EXTI trigger, but I still seem to have to call HAL_SPI_ReceiveDMA() before it will fire? Have I missed something?

    Super User
    July 15, 2025

    Sorry, I don't have STM32U5 specific experience.

    If calling HAL_SPI_ReceiveDMA is too slow, you may switch to register level or you may be able to trigger the DMA via a timer event triggered by a GPIO edge.

    hth

    KnarfB 

     

     

     

    Graduate II
    July 10, 2025

    I'd use GPIO->BSRR write (singular) over GPIO->ODR RMW actions, those will be slow/constraining, as force stalling and bus transactions.

    Now, for higher speed, I'd suggest looking at using DMA, triggered by a TIM->CHx, copying GPIO->IDR into a pattern buffer, that you can process at a more leisurely pace, and decimate interrupt loading.

    Explorer II
    July 10, 2025

    Thanks both - I'll try these and see how I get on

    To follow on from your suggestion @Tesla DeLorean , I had been looking for a way to do this with TIM Input Capture, but I've not got anywhere with that