cancel
Showing results for 
Search instead for 
Did you mean: 

SPI TX DMA Request on Timer Update Event (STM32H7R)

JCori
Associate II

Hello! 

I'm having issues having a successful configuration for the setup I need: an SPI TX transaction shall occur through DMA once a timer has reached its overflow count. The timer is then reloaded and proceeds to do cyclical SPI TX transactions. I need this to occur on a TIM Update Event due to a timer synchronization setup I have in place to respect strict timing restrictions.

 

I have tried several configurations, but overall I understand this to be the process:

  • Set up SPI: Define data size, FIFO threshold level, enable DMA TX stream and set transfer size. 
  • Set up DMA: Set source/destination address to data buffer and SPI's TXDR register respectively, set the trigger to match the timx_trgo's event as well as the polarity of the trigger on a rising edge. On DMA setup I have tried also setting up Linked List mode, to point to itself and reload the values. 
  • Set up TIM: Set trigger event to Update Event. I have also tried setting the DIER bit to enable DMA requests.

All peripherals are started and enabled, but I see no clocks being generated nor data getting to the SPI's TXDR register. The SPI reports available space for TX in the status register, but nothing else. Here's an extract of the configuration I have tried

 

uint8_t spi_dummy_data = 0xAB; // data to send

hspi1.Instance->CR1 = 0; //turn off
hspi1.Instance->CFG1 =  (0 << SPI_CFG1_BPASS_Pos) // do not bypass psc
		   	  | (3 << SPI_CFG1_MBR_Pos) // psc by 1/8
		   	  | (7UL << SPI_CFG1_DSIZE_Pos) // 8 bits in a frame
			  | (0 << SPI_CFG1_CRCEN_Pos) // crc disabled
			  | (0 << SPI_CFG1_FTHLV_Pos) //1 byte FIFO threshold level
   	   	   	  | SPI_CFG1_TXDMAEN; //enable the dma stream
hspi1.Instance->CFG2 = SPI_CFG2_MASTER | SPI_CFG2_SSOE; // master, ss driven by peripheral
hspi1.Instance->CR2 = 8;
hspi1.Instance->CR1 |= SPI_CR1_SPE; // enable the peripheral
hspi1.Instance->CR1 |= SPI_CR1_CSTART; //start

// DMA Setup
LLItem_t  dma_ch1 = {
   		.CTR1 = (0 << DMA_CTR1_DBL_1_Pos) // destination burst length - 1
   			|(0 << DMA_CTR1_DINC_Pos) // fixed burst @ destination
   			|(0b11 << DMA_CTR1_DDW_LOG2_Pos) // the destination is 32 bit aligned
   			|(0 << DMA_CTR1_SBL_1_Pos) // // source burst length -1
   			|(1 << DMA_CTR1_SINC_Pos) // increment addr at source (for buffer)
   			|(0b00 << DMA_CTR1_SDW_LOG2_Pos), // we send a single byte
   		 .CTR2 = (0b00 << DMA_CTR2_TRIGM_Pos)
   			|(1 << DMA_CTR2_TRIGPOL_Pos) // trigger on rising edge
   			|(47 << DMA_CTR2_TRIGSEL_Pos) // tim2_trgo trigger selection
   			|(52 << DMA_CTR2_REQSEL_Pos), //spi tx requested
   		  .CBR1 = 1, //1 byte
};

handle_GPDMA1_Channel1.Instance->CCR |=  DMA_CCR_PRIO | 1 << DMA_CCR_LSM_Pos;
handle_GPDMA1_Channel1.Instance->CTR1 = dma_ch1.CTR1;
handle_GPDMA1_Channel1.Instance->CTR2 = dma_ch1.CTR2;
handle_GPDMA1_Channel1.Instance->CBR1 = dma_ch1.CBR1;
handle_GPDMA1_Channel1.Instance->CDAR = (uint32_t)&SPI1->TXDR;
handle_GPDMA1_Channel1.Instance->CSAR = (uint32_t)&spi_dummy_data;
handle_GPDMA1_Channel1.Instance->CCR |= DMA_CCR_EN; //enable the DMA

// TIM 2 Setup
htim2.Instance->CR1 = 0;
htim2.Instance->ARR = 599;
htim2.Instance->CCR2 = 145;
htim2.Instance->EGR = TIM_EGR_UG; // reinitialize with ARR value
htim2.Instance->SR = 0; // clear all flags
htim2.Instance->CCER = TIM_CCER_CC2E; //turn on CH2 PWM
htim2.Instance->CR2 = (0b010 << TIM_CR2_MMS_Pos); // update event
htim2.Instance->DIER = (1 << TIM_DIER_UDE_Pos); // enable dma requests
htim2.Instance->CR1 = (TIM_CR1_CEN | TIM_CR1_ARPE); // arr register is buffered and we turn on the tim

 

This occurs before entering the endless loop, overriding anything set by CubeMX.

I have previously been successful configuring the DMA on SPI RX and I have confirmed TIM2's trigger is being set and have used it to trigger other timers, so my bet is I have a bad/mismatch setup regarding the packing of the data at the SPI and DMA level. 

Any recommendations or guidance is highly appreciated!

 

0 REPLIES 0