2022-11-30 04:45 AM
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);
}
Solved! Go to Solution.
2022-12-01 07:18 PM
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.
2022-12-01 07:18 PM
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.