STM32G4 trigger DMA request from SPI to Memory with timer
Hello,
I'm trying to get SPI to receive data from an ADC in a periodic interval, and must not use interrupts, as the whole application is already pushing the upper limit of what the MCU can handle. The code below is just a rough test, adapted from what I found in another thread in this forum. However, I still can't get it to work. Timer runs, DMA and DMAMUX seem to get configured, but nothing happens on the SPI CLK. Any ideas?
void acq_configure_adc_transfer()
{
uint32_t circular_buffer[10];
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_TIM1_CLK_ENABLE();
DMA1_Channel1->CCR = 0x0; //Disable DMA stream
DMA1_Channel1->CPAR = (uint32_t)&SPI1->DR; //Set source memory region
DMA1_Channel1->CMAR = (uint32_t)&circular_buffer; //Set peripheral data register as destination
DMA1_Channel1->CNDTR = sizeof(circular_buffer) ; //Number of items to transfer
//NVIC_EnableIRQ(DMA1_Channel2_IRQn); //Enable interrupt for DMA Channel 2, to deal with finished transfers
DMA1_Channel1->CCR =
DMA_CCR_EN | //Enable
DMA_CCR_HTIE | //half transfer interrupt enable
DMA_CCR_TCIE | //transfer complete interrupt enable
DMA_CCR_CIRC | //DMA Circular mode
DMA_PINC_DISABLE | //Do not increment peripheral
DMA_MINC_DISABLE | //Do not increment memory //DMA_MINC_DISABLE
DMA_CCR_PSIZE_1 | //Peripheral data size 0 = 16bit , 1 = 32bit
DMA_CCR_MSIZE_1 | //Memory data size 0 = 16bit , 1 = 32bit
DMA_PRIORITY_VERY_HIGH; //DMA Priority
DMAMUX1_Channel0->CCR = 0;
DMAMUX1_Channel0->CCR |= DMA_REQUEST_TIM1_UP | DMAMUX_CxCR_EGE;
HAL_TIM_Base_Start(&htim1); //Start Timer
//Reset SPI1 Configuration Register (-> this will disable the SPI1)
SPI1->CR1 = 0b00000000;
//SPI1->CR2 = SPI_CR2_TXEIE | SPI_CR2_TXDMAEN | SPI_CR2_SSOE; //TXEIE:Txbuffer empty interrupt enable, TXDMAEN: Enable TX dma, SSOE:SSoutputenable
SPI1->CR2 = SPI_CR2_RXNEIE | SPI_CR2_RXDMAEN; //TXEIE:Txbuffer empty interrupt enable, TXDMAEN: Enable TX dma, SSOE:SSoutputenable
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE | SPI_DATASIZE_16BIT; //Enable SPI, configuration as master, Data frame format 16bit
//Reset Timer Configuration Registers (-> this will disable the timer)
TIM1->CR1 = 0b00000000;
TIM1->CR2 = 0b00000000;
TIM1->DIER = TIM_DIER_UDE; //UDE Update DMA request enable
TIM1->PSC = 500; //Set the prescaler
TIM1->ARR = 1000; //Set the autoreload value
TIM1->CR1 = TIM_CR1_CEN | TIM_CR1_ARPE; //the CEN is set (Counter enable) and ARPE:Auto-reloadpreloadenable is buffered (TIMx_ARR register is buffered)
//Timer is now started and triggers SPI at each overflow
}
