cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-U575 board, GPDMA destination address update problem

Skfir
Senior

Hello everybody!

So what I want to do, is to update the destination address (DAR) register of the DMA after the last transfer. So I write the desired destination address in a variable "dest_address", then I take the address of that variable and write the high 16 bits to the LBAR register and the low 16 bites to the LA section in the LLR register. And also set the UDA bit. However, after the transfer, the DAR register is not updated with the value I put in the variable "dest_address". What is my mistake? I have almost broken my head already. If someone please could help, here is the code, the first seven lines matter. Thank you

void DMA_adc1FuncInit(void){
	int dest_address = 0x20000034;
	int final = (volatile unsigned int)&dest_address;
	PowerOn();
	DMA_ADC1_port->CCR &= ~(DMA_CCR_EN);	//Disable DMA channel
	DMA_ADC1_port->CLBAR |= (final & 0xFFFF0000); //Writing higher 16bits
	DMA_ADC1_port->CLLR |= ((final & 0x0000FFFF) + DMA_CLLR_UDA); //Writing lower bits + setting the "destination address update bit"
	DMA_ADC1_port->CCR |= ((3 << DMA_CCR_PRIO_Pos) + DMA_CCR_TCIE);		//Highest priority to ADC1 transfers, transfer complete interrupt
	//Burst length equals the length of all channels together, source/destination data width = 4 bytes, destination port = AHB1
	DMA_ADC1_port->CTR1 |= ((NO_OF_ADC1_CHANNELS*4 << DMA_CTR1_DBL_1_Pos) + (NO_OF_ADC1_CHANNELS*4 << DMA_CTR1_SBL_1_Pos) + DMA_CTR1_DDW_LOG2_1 + DMA_CTR1_DAP + DMA_CTR1_SDW_LOG2_1);
	DMA_ADC1_port->CTR2 |= (DMA_CTR2_BREQ + (0 << DMA_CTR2_REQSEL_Pos));	//Block transfer request, ADC1 request selected
	DMA_ADC1_port->CSAR = (volatile unsigned int)(&ADC1->DR);	//The source is ADC1 data register
	DMA_ADC1_port->CTR2 |= DMA_CTR2_TCEM_0;		//The "Transfer Complete" interrupt is generated after all the repetitions of the block
	DMA_ADC1_port->CBR2 |= (4 << DMA_CBR2_BRDAO_Pos);	//After each block transfer point at the next destination array item
	DMA_ADC1_port->CDAR = (volatile unsigned int)ff;	//Letting the DMA know the destination place in memory
	DMA_ADC1_port->CBR1 |= (4 /*transfer 4 bytes per block*/ + ((NO_OF_ADC1_CHANNELS - 1) << DMA_CBR1_BRC_Pos));
	NVIC_EnableIRQ(GPDMA1_Channel13_IRQn);	//Activating interrupts
	NVIC_SetPriority(GPDMA1_Channel13_IRQn, 5);
	DMA_ADC1_port->CCR |= (DMA_CCR_EN);
}

1 ACCEPTED SOLUTION

Accepted Solutions
Skfir
Senior

Figured it out. the "int dest_address" had a limited scope and the compiler didn't preserve its value after the function had finished. Declaring is as "static" solves the problem.

View solution in original post

1 REPLY 1
Skfir
Senior

Figured it out. the "int dest_address" had a limited scope and the compiler didn't preserve its value after the function had finished. Declaring is as "static" solves the problem.