2017-07-11 04:30 PM
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:
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 #multimode2017-07-12 01:14 AM
Hi
aurecab
,Which CubeMx version are you using ?
Please share you .ioc file to check your issue.
Regards
Imen
2017-07-12 09:39 AM
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!
2017-10-11 12:02 PM
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 gdbNUCLEO-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