cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U585 need help with getting ADC -> DMA working in trivial case.

psabela
Associate II

This is what I am doing and want to accomplish:   
I am using ADC4 to convert internal temperature sensor in 1 second intervals, and move the converted value from ADC_DR register to a fixed address in RAM (no increment).  At the end, I want to be able to watch one RAM address in debug mode memory browser and see its value change every 1 second.

ALREADY HAVE THE FOLLOWING WORKING:
TIM2 timer is triggering ACD4 every 1 second, and ADC4 is placing the converted value to ADC_DR register.  I am able to observer the value using the EOC interrupt when reading ADC_DR value in interrupt handler.

I CANNOT GET THIS WORKING:  
When I incorporate GPDMA and select source as ADC_DR register and destination as , for example, 0x20000008U address.   I cannot see any values places at this RAM address. 
(Note: I stop reading the ADC_DR register value in the EOC interrupt handler so the converted value can be picked up by GPDMA.)

I NEED HELP with figuring out what other registers and register values I need to set/clear to get GPDMA working.   

Here is what I have so far:
(Note:  No HAL, No LL.  The following are my functions defined in assembly language where each function sets/clears appropriate bits of a register, based on reference manual and datasheet.)  

1. To integrate GPDMA on ADC4, I:
ADC4_DMAEN_Mode_Enable();
ADC4_DMACFG_Circular_Set();
ADC4_Set_Single();  //Set single conversion mode so on each timer update it does one conversion.

1. To configure GPDMA, I do the following:

RCC_DMA_Set_Clock();

DMA_SECCFGR_Set_Nonsecure();

DMA_PRIVCFGR_Set_Unprivileged();

DMA_C0SAR_Set_Source(); //ADC_DR register address 0x46021040U

DMA_C0DAR_Set_Destination(); //0x20000008U

DMA_C0TR1_Set_DestInc_Fixed();

DMA_C0TR1_Set_SrcInc_Fixed();

DMA_C0BR1_Set_NumOfItemsInBlockToTransfer(); //2 for 2 bytes, 16bits as ADC_DR is 16bits

DMA_C0TR1_Set_SBL_1_Burst_Lenght(); //set to 0

DMA_C0TR1_Set_SDW_LOG2_Source_Block_Size(); //set to 1

DMA_C0TR1_Set_DBL_1_Set_Burst_Lenght(); //set to 0

DMA_C0TR1_Set_DDW_LOG2_Dest_Block_Size(); //set to 1

DMA_C0CR_Set_Interrupts();

NVIC_DMA_Enable_Interupt();

DMA_C0CR_Set_Enable();

 

What other registers and register values I need to set/clear for GPDMA to work for the scenario?

1 REPLY 1

>>No HAL, No LL.  The following are my functions defined in assembly language where each function sets/clears appropriate bits of a register, based on reference manual and datasheet.

Understand the most everyone ISN'T doing it that way. Even if you choose not to use the HAL/LL it's still a good resource to understand the sequences and nuances of the hardware.

You'll perhaps need to dump the involved registers on the ADC and GPDMA side for review.

Look for error, fault or status reported by the peripheral

The DMA counts transfer units, not bytes. The width on the Read(Src) and Write(Dst) are controlled independently

DMA_SRC_DATAWIDTH_HALFWORD ? for 16-bit read

Count of 1 for single HALFWORD

 

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..