2022-07-04 09:34 AM
Hi, I'm starting to design motor control driver using discrete analog H bridges - first time with STM32 micro. Currently using Nucleo G031K8 for experiments until custom board will be ready. So far I configured 3 PWM channels - normal and complementary central aligned PWMs (20 kHz) with deadtime using advanced TIM1 timer. TIM1 also generates update event trigger for ADC1 to start conversion. I'm using DMA to capture 10 ADC conversions in one sequence (2*3 values for H bridges and + 4 additional values). Using Cube and LL drivers. ADC settings captured in screenshot. It seems to work, TIM1 update interrupt comes in the middle of PWM pulse as expected. ADC data are coming into DMA double circular buffer, half transfer interrupt takes about 4.8us: 64 MHz internal oscillator clock, 32 MHz ADC clock, 1.5 clock sampling time. Based on datasheet formula it is: (1.5 + 12.5) * 1/32MHz * 10 = 4.4 us - close to expected value.
Now the problem - I want to read motor current (the first ADC channel) ASAP every PWM period so I can run control loop in paralell with the rest of ADC conversions. I was searching for solution. I found that F4 and G4 have possibility to create ADC injected conversion group which seems to be ideal solution, but we cannot use these micros because of cost limitation. Is there another way? Can I read ADC channel data (the first channel) when DMA is active somehow? I tried to enable ADC EOC (End of Conversion) interrupt, but it triggers interrupt in very slow period around 6.5 ms. Any idea why? Maybe it is not possible to use it when DMA is enabled? I also notices that enabling EOC enables EOS (End of Sequence) interrupt. EOS is triggering every 9.8 us. Why? In Cube there is also parameter called "End of Conversion Selection" but it doesn't seem to have any impact on the generated code when I switch from "End of single conversion" to "End of sequence of conversion". Is there maybe any example how to drive brushless motor using STM32G0 or similar micro?
2022-07-05 03:29 AM
Hi,
How quickly do you need to access data?
A you mention, there is the half transfer interrupt, at which point you know the first ADC value has been written.
The DMA writes to memory… nothing stopping you from reading if you are sure it is valid data.
Alternatively, could you could trigger another single shot timer off TIM1 to reduce latency? i.e set it to (1.5 + 12.5) * 1/32MHz * 1.5.
2022-07-07 12:46 AM
Hi, thanks for reply. Currently my DMA buffer size is 20 halfwords - for 10 ADC halfword values. It means DMA half interrupt triggers when all 10 values is ready to read. I can reduce buffer size to 10 and read data when the first 5 ADC values were converted. This is so far the only solution I have how to run at least second half of ADC values in parallel with running control loop function (which takes a long time to run). What I want to ideally achieve is to read only first ADC value (input parameter to control loop function) and then the rest (9) of them using DMA while control loop is being processed. I understand that once DMA writes value to memory I can read it, but how to know when the first ADC value is stored to DMA buffer? I was hopping that ADC end of conversion interrupt can tell me this, but for unknown reason it triggers in very slow period which doesn't make sense.