cancel
Showing results for 
Search instead for 
Did you mean: 

DMA issues for injected channel in ADC multimode

Posted on July 12, 2017 at 01:30

Dear community,

I have some issues to  make my STM32F446 work properly.

I would like to use ''triple combined regular simultaneous + injected simultaneous mode''. 

The aim is to use the 3 ADCs, each measuring 1 regular and 1 injected channel, and use the DMA to directly transfer them to the memory.

I configured the cube as folllows:

0690X00000607TQQAY.png0690X00000607YdQAI.png

I manage to get the regular channel writting in the main:

         HAL_ADC_Start_DMA(&hadc3,(

uint32_t

*) ADCReads3, 2);

         HAL_ADC_Start_DMA(&hadc2,(

uint32_t

*) ADCReads2, 1);

         HAL_ADCEx_MultiModeStart_DMA(&hadc1, (

uint32_t

*)ADCReads1, 1);

However I can't manage to get the injected channels since:

HAL_ADCEx_InjectedStart_DMA(&hadc1,(

uint32_t

*)ADCReads1, 1);

is not accepted.

Could you please help me to solve this issue?

Many thanks

#injected #regular #adc #dma #multimode
3 REPLIES 3
Imen.D
ST Employee
Posted on July 12, 2017 at 10:14

Hi

aurecab

,

Which CubeMx version are you using ?

Please share you .ioc file to check your issue.

Regards

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Posted on July 12, 2017 at 18:39

Thank you for your reply Imen.

I have attached the .ioc file.

My version is: 4.0

I have just find a link:

https://community.st.com/0D50X00009XkgQ3SAJ

where it is said that '

only regular group has DMA capability'.

So I thing there is only two more options

:

-use only regular group triggered by the timer and send to memory with the DMA. However, is it possible to assign more than 1 stream of the DMA to 1 ADC?

-use regular and injected triggered by the timer. The regular are stored by the DMA and the triggered values are obtained by the micro through Interrupt mode or polling mode.

Is it possible to use the interrupt mode for the three ADC knowing that there are in

simultaneous mode?

Should I usepolling mode for the three injected, but will the micro loose a lot of time to obtain those values?

Where can I find aexamples?

Thank you very much for your help!

Posted on October 11, 2017 at 19:02

Hi

cabarbaye.Aur_lien

‌,

With the help of RM0390 'STM32F446xx advanced ARM®-based 32-bit MCUs' document, I have set up the use-case for 'Triple combined regular simultaneous + inject simultaneous mode' with 2 regular channels per ADC and one channel for injected with ADC1.

'Scan Conversion Mode' is set to 'Enabled'.

'End Of Conversion Selection' is set to 'EOC flag at end of all conversions', i.e. the EOC bit is set at the end of each sequence of regular conversions. Overrun detection is enabled only if DMA=1.

'DMA Continuous Requests' set to 'Enabled', i.e. DMA requests are issued as long as data are converted and DMA=1.

'Sampling Time' is set the same value for each channel.

'DMA Request' is added for ADC1 as master in 'DMA Settings', with corresponding interrupt handler function, i.e. 'DMA2 stream0 global interrupt' in 'NVIC Settings' for 'ADC1 Configuration'.

DMA 'Mode' is set to 'Circular' for 'Peripheral' to Memory with 'Data Width' set to Word (32bits).

For ADC1 for example, a channel is added in 'ADC_Injected_Conversion Mode' and 'ADC1, ADC2 and ADC3 interrupts' is 'Enabled' in 'NVIC Settings'

The ADC1 is master in 'Triple combined regular simultaneous + inject simultaneous mode' use case

and the following user-code sequence is needed:

#define ADC_REGULAR_CONVERTERTED_NUMBER_OF_CHANNEL (uint32_t)6

static volatile uint32_t adcRegularConvertedValue[ADC_REGULAR_CONVERTERTED_NUMBER_OF_CHANNEL] /*__attribute__ ((aligned (4)))*/;

...

HAL_ADC_Start(&hadc3)

HAL_ADC_Start(&hadc2)

HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t*)&adcRegularConvertedValue[0], ADC_REGULAR_CONVERTERTED_NUMBER_OF_CHANNEL)

...

HAL_ADCEx_InjectedStart_IT(&hadc1)

...

HAL_ADC_Stop(&hadc3)

HAL_ADC_Stop(&hadc2)

HAL_ADC_Stop(&hadc1)

with

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle){

if(ADC1 == AdcHandle->Instance){

LoggerSetMessage('R-ADC1-E\n');

}

}

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* AdcHandle){

if(ADC1 == AdcHandle->Instance){

LoggerSetMessage('R-ADC1-H\n');

}

}

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* AdcHandle){

if(ADC1 == AdcHandle->Instance){

adcInjectedConvertedValue_0 = HAL_ADCEx_InjectedGetValue(AdcHandle, ADC_INJECTED_RANK_1);

LoggerSetMessage('I-ADC1\n');

}

}

void AdcPrintRegularConvertedValue(void){

for(uint8_t i = 0; i < sizeof(adcRegularConvertedValue)/sizeof(adcRegularConvertedValue[0]); i++) {

printf('R-%d: %08lx ', i, adcRegularConvertedValue[i]);

}

printf('\n\n');

}

A log for execution of the use-case.

$ stty -F /dev/ttyS17 115200 && cat /dev/ttyS17

main()> Oct 11 2017 18:31:25

@ Looping 0

@ Just started regular

0 R-ADC1-H

1 R-ADC1-E

R-0: 00000415 R-1: 00000308 R-2: 000002dd R-3: 000002ea R-4: 000002be R-5: 000001f5

@ Just started injected

2 I-ADC1

@ I-0: 000003a5

@ Just stopped all

@ Looping 1

@ Just started regular

3 R-ADC1-H

4 R-ADC1-E

R-0: 00000387 R-1: 000001fc R-2: 000001cb R-3: 00000308 R-4: 000002c6 R-5: 000001f6

@ Just started injected

5 I-ADC1

@ I-0: 000003a1

@ Just stopped all

@ Looping 2

@ Just started regular

6 R-ADC1-H

7 R-ADC1-E

R-0: 00000391 R-1: 000001fc R-2: 000001dd R-3: 0000032a R-4: 000002df R-5: 0000022b

@ Just started injected

8 I-ADC1

@ I-0: 0000039c

@ Just stopped all

Some debug elements:

NUCLEO-F446RE-ADC Debug [Ac6 STM32 Debugging]

NUCLEO-F446RE-ADC.elf

Thread #1 (Suspended : Breakpoint)

HAL_ADC_ConvHalfCpltCallback() at main.c:187 0x80004e6

ADC_MultiModeDMAHalfConvCplt() at stm32f4xx_hal_adc_ex.c:1,085 0x800160c

HAL_DMA_IRQHandler() at stm32f4xx_hal_dma.c:850 0x80023e2

DMA2_Stream0_IRQHandler() at stm32f4xx_it.c:214 0x8000cdc

<signal handler called>() at 0xfffffff9

UART_WaitOnFlagUntilTimeout() at stm32f4xx_hal_uart.c:2,113 0x800354a

HAL_UART_Transmit() at stm32f4xx_hal_uart.c:672 0x8003736

_write() at main.c:280 0x8000642

_write_r() at 0x80045d0

__sflush_r() at 0x8003b36

__swbuf_r() at 0x800394e

_puts_r() at 0x800388c

main() at main.c:367 0x80009e4 ---> printf('@ Just started regular\n');

openocd

gdb

NUCLEO-F446RE-ADC Debug [Ac6 STM32 Debugging]

NUCLEO-F446RE-ADC.elf

Thread #1 (Suspended : Breakpoint)

HAL_ADC_ConvCpltCallback() at main.c:167 0x8000492

ADC_MultiModeDMAConvCplt() at stm32f4xx_hal_adc_ex.c:1,066 0x8001668

HAL_DMA_IRQHandler() at stm32f4xx_hal_dma.c:929 0x8002492

DMA2_Stream0_IRQHandler() at stm32f4xx_it.c:214 0x8000cdc

<signal handler called>() at 0xfffffff9

UART_WaitOnFlagUntilTimeout() at stm32f4xx_hal_uart.c:2,113 0x800354a

HAL_UART_Transmit() at stm32f4xx_hal_uart.c:672 0x8003736

_write() at main.c:280 0x8000642

_write_r() at 0x80045d0

__sflush_r() at 0x8003b36

__swbuf_r() at 0x800394e

_puts_r() at 0x800388c

main() at main.c:367 0x80009e4 ---> printf('@ Just started regular\n');

openocd

gdb

NUCLEO-F446RE-ADC Debug [Ac6 STM32 Debugging]

NUCLEO-F446RE-ADC.elf

Thread #1 (Suspended : Breakpoint)

HAL_ADCEx_InjectedConvCpltCallback() at main.c:207 0x800053a

HAL_ADC_IRQHandler() at stm32f4xx_hal_adc.c:970 0x80013b0

ADC_IRQHandler() at stm32f4xx_it.c:198 0x8000cb8

<signal handler called>() at 0xfffffff9

UART_WaitOnFlagUntilTimeout() at stm32f4xx_hal_uart.c:2,113 0x800354e

HAL_UART_Transmit() at stm32f4xx_hal_uart.c:672 0x8003736

_write() at main.c:280 0x8000642

_write_r() at 0x80045d0

__sflush_r() at 0x8003b36

__swbuf_r() at 0x800394e

_puts_r() at 0x800388c

main() at main.c:379 0x8000a0a ---> printf('@ Just started injected\n');

openocd

gdb

Note also that CubeMx in 4.1 version is currently available and it is recommended to upgrade to new version.

Hopping it helps understanding the use-case.

Regards.

Cyril