cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 3 Phase Current measurement with DMA with precise location defined by HRTIM (problem)

Linas L
Senior II

Hello,
In my project I need to sample 3 phase current to see if where is short or not. I am using STM32H753 HRTIM. Not only that I must place sampling point as close to PWM transition from high to low as possible (peak current)

I connected phase current measurement to ADC1, ADC2, and ADC3 thinking that I would simply use each ADC with DMA, so I would always have data ready in my HRTIM update interrupt.

Problem is that only two channels are allowed to be regular (TRG1 and TRG3), and two must be injected (TRG2 and TRG4).

LinasL_0-1713185723924.png

LinasL_1-1713185830415.png

Injected:

LinasL_2-1713185900329.png

I am using BDMA and ADC3 PC0 (same pin is working on non injected with BDMA no problem)

But when I try to use TRIGGER4 from HRTIM, well, I don't get any data, while I do sampling event of scope (10k resistor to VDD, and I see low voltage glitch down, that position can be controlled based on CCR register value, so this part is working)

LL_ADC_INJ_SetTriggerSource(ADC3,LL_ADC_INJ_TRIG_EXT_HRTIM_TRG4);

My Question is :

Why I can't get DMA to work ? IS there any limitation that preventing me on doing this ? ( I am using JDR1 regsiter for DMA)

 

  LL_BDMA_DisableChannel(BDMA, LL_BDMA_CHANNEL_0);
  LL_BDMA_ConfigTransfer(BDMA,LL_BDMA_CHANNEL_0,LL_BDMA_DIRECTION_PERIPH_TO_MEMORY | LL_BDMA_PRIORITY_VERYHIGH | LL_BDMA_MODE_CIRCULAR |LL_BDMA_PERIPH_NOINCREMENT | LL_BDMA_MEMORY_NOINCREMENT | LL_BDMA_PDATAALIGN_HALFWORD | LL_BDMA_MDATAALIGN_HALFWORD);
  LL_BDMA_ConfigAddresses(BDMA, LL_BDMA_CHANNEL_0 , (uint32_t)&ADC3->JDR1, (uint32_t)0x38000000, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

  LL_BDMA_SetDataLength(BDMA, LL_BDMA_CHANNEL_0, 1);
  LL_BDMA_SetPeriphRequest(BDMA, LL_BDMA_CHANNEL_0, LL_DMAMUX2_REQ_ADC3);

 

Note, this is not triggered at all ( also, PWM is active and working)

 

uint32_t BDMA_TC = 0;
uint32_t BDMA_TE = 0;

void BDMA_Channel0_IRQHandler(void)
{
  if(LL_BDMA_IsActiveFlag_TC0(BDMA))
  {
    BDMA_TC++;
    LL_BDMA_ClearFlag_GI0(BDMA);
  }
  else if(LL_BDMA_IsActiveFlag_TE0(BDMA))
  {
    BDMA_TE++;
    LL_BDMA_ClearFlag_TE0(BDMA);
  }
}

 

BDMA_TE is always zero, while TC was working in regular non injected mode.... ( so my clocks and other config is ok)


1 REPLY 1
Linas L
Senior II

I was unable to do it, so just reading injected ADC channel register in timer update, and it looks like working.