2022-05-06 05:23 AM
Here is how I setup my DMA ;
How I setup the DMAMUX :
I configured the DMAREQ_ID bits to 10 (adc2_dma). Is there no clock I need to enable for the DMAMUX ?? This setup feels a bit too light!
How I setup ADC :
Classic way just set the Data management to DMA circular.
Just to be sure thanks to the DMAMUX there is no longer a peripheral linked to only one DMA? Wether I use DMA1 or DMA2 for my ADC does not matter?
Code for DMA :
void DMA_Config(void) {
/************DMA CLock Enable******************/
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA1EN_Msk);
delay(1000);
/***************P2M****************************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1);
/******************Disable FIFO*************************/
//LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
//LL_DMA_SetMemoryBurstxfer(DMA1, LL_DMA_STREAM_1, LL_DMA_MBURST_SINGLE);
/******************Memory size**************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_1);
/******************MEM Increment**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MINC_Msk);
/******************MEM Address to buffer**************/
DMA1_Stream1->M0AR = 0x30000000;
/******************Circular Mode**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_CIRC_Msk);
/*******************Flow controller*******************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PFCTRL_Msk);//ADC in control
/******************Periph size************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_1);
/******************Peripheral no Increment*************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PINCOS_Msk);
/******************Periph request**********************/
SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_DMAREQ_ID_1 | DMAMUX_CxCR_DMAREQ_ID_3);//adc2_dma
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SYNC_ID_0 | DMAMUX_CxCR_SYNC_ID_1 | DMAMUX_CxCR_SYNC_ID_2);//TIM12_TRGO
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SPOL_0);//rising edge
// DMAMUX1_Channel1->CCR = 0; //Number of requests after synchro (add 1 to the reg value)
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_EGE_Msk);//Event Generation end of synchro req
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SE_Msk);//Synchro Enable
/******************Periph address***********************/
DMA1_Stream1->PAR = (uint32_t)&ADC2->DR;
/******************TC IT********************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_TCIE_Msk | DMA_SxCR_TEIE_Msk); //TC IT
DMA1->LIFCR = DMA_LIFCR_CTCIF1;//Clear IT in LISR Register
NVIC_SetVector(DMA1_Stream1_IRQn, (uint32_t)&DMA1_Stream1_IRQHandler);
NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/*******************Enable DMA****************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_EN_Msk);
}
void DMA1_Stream1_IRQHandler(void) {
if (DMA1->LISR & DMA_LISR_TCIF1 ) {
DMABuffered = DMABuffered + 1;
DMA1->LIFCR = DMA_LIFCR_CTCIF1;
}
if(DMA1->LISR & DMA_LISR_TEIF1 ){
DMAError = DMAError +1;
DMA1->LIFCR = DMA_LIFCR_CTEIF1;
}
}
Code for ADC :
void ADC_Init(void) {
/*******************Horloges**************************/
SET_BIT(RCC->APB4ENR, RCC_APB4ENR_SYSCFGEN_Msk); //SYSCFG clock
delay(1000);
SET_BIT(RCC->APB4ENR, RCC_APB4ENR_RTCAPBEN_Msk); //RTCAPB clock
delay(1000);
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN_Msk); //ADC12 clocks
delay(1000);
SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN_Msk); //GPIOA clock
delay(1000);
/********************Port config************************/
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_0);
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_1);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_0);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_1);
SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk);
delay(1000);//PA0_C in analog mode
/********************ADC voltage regulator***************/
CLEAR_BIT(ADC2->CR, ADC_CR_DEEPPWD_Msk); //END DEEPPWD
SET_BIT(ADC2->CR, ADC_CR_ADVREGEN_Msk); //ENABLE ADC VOLTAGE REG
delay(1000);//WAIT VOLTAGE REG
/********************ADC calibration*********************/
CLEAR_BIT(ADC2->CR, ADC_CR_ADCALDIF_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCALLIN_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
/******************ADC clock*****************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
/*******************ADC Prescaler************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 );
/*******************Input Mode***************************/
CLEAR_BIT(ADC2->DIFSEL, ADC_DIFSEL_DIFSEL_0); //Single Ended
/*******************ADC Enable***************************/
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADEN_Msk);
while (ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk != 1) {}
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
/********************ADC RES*****************************/
SET_BIT(ADC2->CFGR, ADC_CFGR_RES_2 | ADC_CFGR_RES_1);
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_RES_0);
/********************ADC Data Management*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1);//DMA Circular mode
/********************OVRMODE*****************************/
SET_BIT(ADC2->CFGR, ADC_CFGR_OVRMOD_Msk); //Erase old data
/********************CONT/Single/Discont*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DISCEN_Msk); // discontinuous mode
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_CONT_Msk); // | ADC_CFGR_DISCEN_Msk
/********************Trigger Detection*******************/
SET_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3);//Trig rising edge TRGO2
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_4);
/********************INput Preselection******************/
SET_BIT(ADC2->PCSEL, ADC_PCSEL_PCSEL_0);//Chan 0
/********************Sample Time reg*********************/
SET_BIT(ADC2->SMPR1, ADC_SMPR1_SMP0_0); //2.5 CLCK Cycles
/********************ADC IT******************************/
SET_BIT(ADC2->IER, ADC_IER_EOCIE_Msk | ADC_IER_EOSMPIE_Msk );//| ADC_IER_EOSIE_Msk | ADC_IER_OVRIE_Msk
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetVector(ADC_IRQn, (uint32_t)&ADC_IRQHandler);
}
Code for timer
void AC_TIMER1_Init(void) {
//------------------------------Horloge Timer1----------------------------------------//
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Msk);
//------------------------------Select TRGO source-----------------------------------//
TIM1->PSC = 8399; //PSC=1
//----------------------------------------------------------TIM2 autoreload register--------------------------------------------//
TIM1->ARR = 10000;
//---------selectupdatevent-----------------//
SET_BIT(TIM1->CR2, TIM_CR2_MMS2_1);
//-----------IT-----------------------//
// SET_BIT(TIM1->DIER,TIM_DIER_UIE_Msk);
// NVIC_SetPriority(TIM1_UP_IRQn,0);
// NVIC_SetVector(TIM1_UP_IRQn, (uint32_t)&TIM1_UP_IRQHandler);
// NVIC_EnableIRQ(TIM1_UP_IRQn);
SET_BIT(TIM1->CR1, TIM_CR1_CEN_Msk);//CEN=1
}
Main :
void setup() {
// put your setup code here, to run once:
VREFBUF_Init();
DMA_Config();
AC_TIMER1_Init();
ADC_Init();
ADC_Start();
}
2022-05-06 05:34 AM
Nevermind I am a lost cause 🙂 missed :
/*******************Number of data transfer***********/
SET_BIT(DMA1_Stream1->NDTR, DMA_SxNDT_0);
There is still something I do not understand : why is it that it only works when the one in control is the DMA (PFCTRL=0) isn't the ADC the one who can tell the DMA to move the DATA after each EOC?