2023-12-28 01:30 AM
Hi everyone,
ı was trying to make adc to dac using DMA. Shortly the adc value is writed into DAC data register. So that the potentiometer is turned then the digital value is writed ADC register. The brightness of led is changed. However, ı get ADC value via DMA then ı writed into DAC register and nothing happened. I did the project without DMA and it worked as what ı want. How can ı do that using DMA. In my solutions are multi DMA, triger event. Also, the ADC channel to pin A0 and DAC pin to A4. Do you have any idea ?
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
uint32_t adc;
uint32_t adc1[8];
uint32_t dac;
uint32_t dac1[8];
uint32_t buffer[8];
uint32_t *ptr;
void RCC_Config()
{
RCC->CR |= 0x00030000; // HSEON and HSEONRDY enable
while(!(RCC->CR & 0x00020000)); // HSEON Ready Flag wait
RCC->CR |= 0x00080000; // CSS Enable
RCC->CR |= 0x01000000; // PLL ON
RCC->PLLCFGR |= 0x00400000; // PLL e HSE seçtik
RCC->PLLCFGR |= 0x00000004; // PLL M = 4
RCC->PLLCFGR |= 0x00005A00; // Pll N = 168
RCC->PLLCFGR |= 0x00000000; // PLL p = 2
RCC->CFGR |= 0x00000000; // AHB Prescaler = 1
RCC->CFGR |= 0x00080000; // APB2 Prescaler = 2
RCC->CFGR |= 0x00001400; // APB1 Prescaler = 4
RCC->CIR |= 0x00800000; // CSS Flag clear
}
void GPIO_Config()
{
RCC->AHB1ENR |= (1 << 0); // GPIOA Clock Enable
GPIOA->MODER |= (3 << 0); // AP0 analog (for ADC -> connect the potentiometer)
GPIOA->MODER |= (1 << 8); // AP4 output (for DAC -> connect the led)
GPIOA->OSPEEDR |= (3 << 0); // AP0 very high speed
}
void ADC_Config()
{
RCC->APB2ENR |= 0x00000100; // ADC1 Clock enable
ADC->CCR |= 1 << 16; // ADC Clock Divided By 4
//ADC1->SMPR2 |= 6 << 0; // 144 Cycles for Channel 0
ADC1->CR1 |= 0 << 24; // ADC Resolution 12 bit
ADC1->CR1 |= 1 << 8; // Scan conversion mode enable
ADC1->CR2 |= 1 << 0; // ADC enable
ADC1->CR2 |= 1 << 1; // Continuous conversion mode enable
ADC1->CR2 |= 1 << 8; // DMA Enable
ADC1->CR2 |= 1 << 9; // DDS
ADC1->CR2 |= 1 << 10; // EOCS
//ADC1->CR2 |= 1 << 30; //
ADC1->SQR1 |= 0 << 20; // L = 1 conversion number
//ADC1->CR2 |= (15 << 24);
//ADC->CCR |= 1 << 0; // dual mode
ADC1->SQR3 |= 0 << 0; // put channel number CH0
}
void DMA_ADC_Config()
{
RCC->AHB1ENR |= 0x00400000; // RCC->AHB1ENR |= (1<<22); // DMA2 clk Enable
while((DMA2_Stream4->CR & 0x00000001) == 1); // wait for stream4 to be 0(stop)
DMA2_Stream4->PAR|= (uint32_t) &ADC1->DR;
DMA2_Stream4->M0AR |= (uint32_t) &adc1;
DMA2_Stream4->NDTR = 1;
DMA2_Stream4->CR |= 0 << 6; // Peripheral to Memory
DMA2_Stream4->CR |= 1 << 8; // Circular mode
DMA2_Stream4->CR |= 1 << 10; // memory incremented
DMA2_Stream4->CR |= 2 << 11; // peripheral data size 32 bit (word)
DMA2_Stream4->CR |= 2 << 13; // memory data size 32 bit (word)
DMA2_Stream4->CR |= 2 << 16; // priority level high
DMA2_Stream4->CR |= 0 << 25; // channel 0 selected
DMA2_Stream4->FCR |= 0 << 2; // direct mode enable
DMA2_Stream4->CR |= 1 << 0; // start stream 4
//ADC1->CR2 |= ADC_CR2_SWSTART;
}
void DMA_DAC_Config() // stream5-ch7
{
RCC->AHB1ENR |= (1 << 21); // RCC->AHB1ENR |= (1<<21); // DMA1 clk Enable
while((DMA2_Stream5->CR & 0x00000001) == 1); // wait for stream5 to be 0(stop)
DMA2_Stream5->PAR|= (uint32_t) &DAC->DHR12R1;
DMA2_Stream5->M0AR |= (uint32_t) &dac1;
DMA2_Stream5->NDTR = 1;
DMA2_Stream5->CR |= 1 << 6; // Peripheral to Memory ?
DMA2_Stream5->CR |= 1 << 8; // Circular mode
DMA2_Stream5->CR |= 1 << 10; // memory incremented
DMA2_Stream5->CR |= 2 << 11; // peripheral data size 32 bit (word) 2
DMA2_Stream5->CR |= 2 << 13; // memory data size 32 bit (word) 2
DMA2_Stream5->CR |= 2 << 16; // priority level medium
DMA2_Stream5->CR |= 7 << 25; // channel 7 selected
DMA2_Stream5->FCR |= 1 << 2; // direct mode enable ?
DMA2_Stream5->CR |= 1 << 0; // start stream 7
}
void DAC_Conifg()
{
//RCC->APB1ENR |= (1 << 29); // DAC Clock Enable
RCC->APB1ENR |= 0x20000000;
DAC->CR |= 0x00000001; // DAC Channel 1 enable
//DAC->SWTRIGR |= 0x00000000; // DAC Channel 1 software trigger disable
DAC->CR |= (0 << 6); // Wave generation disabled
DAC->CR |= (0 << 1); // output buffer enabled
DAC->DHR12R1 |= 0x00000000; // DAC Channel 1 12-bit right-aligned data
DAC->CR |= (7 << 3); // software trigger
DAC->CR |= (1 << 12); // DAC Ch1 DMA Enable
}
int main(void)
{
RCC_Config();
GPIO_Config();
ADC_Config();
DMA_ADC_Config();
DMA_DAC_Config();
ADC1->CR2 |= ADC_CR2_SWSTART; //start conversion
while (1)
{
adc = adc1[0];
dac = adc;
DAC->DHR12R1 = adc;
}
}
void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size)
{
/* TODO, implement your code here */
return;
}
uint16_t EVAL_AUDIO_GetSampleCallBack(void)
{
/* TODO, implement your code here */
return -1;
}
2023-12-28 01:44 AM
Hello,
Advice: before starting with direct access to the register coding, use HAL (CubeMx) as it would be easier, when it works you can simplify it using either LL or doing it by accessing directly to the register by inspiring from the generated code.
2023-12-28 05:34 AM
If I understand posred diagram correctly, F4 is not capable to make peripheral-peripheral transaction, there is no switch to routing. Simple solution is to create a buffer in memory, than configure one dma stream adc-mem and another mem-dac, both poited to the same mem buffer.
2023-12-28 07:55 AM
Due two different direction (peripheral to memory and memory to peripheral), Do ı point the memory of buffer
DMA2_Streamx->M0AR &buffer for DMA1 and DMA2 or one of them must be DMA2_Streamx->PAR &buffer ?
Also, do ı need to point data alignment register for DMA1 and DMA2 for example DMA2_Streamx->PAR &DAC->DHR12R1
2023-12-28 04:37 PM
I use HAL driver most of the time, so
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *) bf_dma, (2 * DMA_SIZE)) != HAL_OK) {
it's how I link a buffer to dma channel. For details on low level register programming you can dig into HAL_ADC_Start_DMA function.
I like to read comments hiden inside, sometimes it's much more informative than RM manual
2023-12-30 02:08 AM
ı have a problem, when ı call HAL DAC functions in true studio, these are not called. Though ı activated in cube mx. I can call HAL ADC functions but DAC function is not. Do you have an idea ?
2023-12-31 03:32 AM
Did you generate code again ? + not mark "do not generate" -> in cubeMX
2024-01-01 12:14 AM
I have checked but ı still can't call hal DAC function.