cancel
Showing results for 
Search instead for 
Did you mean: 

Why low the GPIO output speed?

ExtSol
Associate II

Dear ST Community,

The MCU type is: STM32F407VGT6

I try to write GPIOx->ODR register with DMA2. The trigger signal is TIM1 update event. I set the timer period frequency is 9Mhz and i measure 4.429Mhz on GPIO pin. Why?

here is my code:

#include "stm32f4xx.h"
 
uint8_t puffer[100];
 
int main(void)
{
  SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN | FLASH_ACR_DCEN | FLASH_ACR_ICEN);
	SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP);
  
  //HSE: 24Mhz
  SET_BIT(RCC->CR, RCC_CR_HSEON);
  while(!READ_BIT(RCC->CR, RCC_CR_HSERDY));
  
  //PLL: 162Mhz
  SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
  MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLM, 12 << RCC_PLLCFGR_PLLM_Pos);
  MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLN, 162 << RCC_PLLCFGR_PLLN_Pos);
  MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLP, 0 << RCC_PLLCFGR_PLLP_Pos);
  SET_BIT(RCC->CR, RCC_CR_PLLON);
  while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY));
  
  //FLASH
  MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, 5 << FLASH_ACR_LATENCY_Pos);
  
  //egyéb órajel osztók
  MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, 0 << RCC_CFGR_HPRE_Pos); //AHB /1
  MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, 5 << RCC_CFGR_PPRE1_Pos); //APB1 /4
  MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, 4 << RCC_CFGR_PPRE2_Pos); //APB2 /2
  
  //switch to PLL
  MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, 2 << RCC_CFGR_SW_Pos);
  
  
  
  //load buffer
  for(uint8_t i=0;i<100;i +=2)
  {
    puffer[i] = 0;
    puffer[i+1] = 255;
  }
  
  
  //TIM1 Ch1 9Mhz PWM -> PE9
  SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);
  MODIFY_REG(GPIOE->MODER, GPIO_MODER_MODE9, 2 << GPIO_MODER_MODE9_Pos);  //AF
  MODIFY_REG(GPIOE->AFR[1], GPIO_AFRH_AFRH1, 1 << GPIO_AFRH_AFSEL9_Pos);
  MODIFY_REG(GPIOE->OSPEEDR, GPIO_OSPEEDER_OSPEEDR9, 3 << GPIO_OSPEEDR_OSPEED9_Pos);  //Very high speed
  
  SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);
  
  TIM1->ARR = 17; //162Mhz / 18 = 9Mhz
  TIM1->CCR1 = 8; //50% PWM
  
  /*TIM1->PSC = 2499;
  TIM1->ARR = 64799;
  TIM1->CCR1 = 32399; //1s*/
  
  MODIFY_REG(TIM1->CCMR1, TIM_CCMR1_OC1M, 6 << TIM_CCMR1_OC1M_Pos);
  SET_BIT(TIM1->CCER, TIM_CCER_CC1E);
  SET_BIT(TIM1->BDTR, TIM_BDTR_MOE);
  SET_BIT(TIM1->DIER, TIM_DIER_UDE);  //Update DMA request enabled DMA2_Stream5 -> Channel6
  
  //DMA2
  SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA2EN);
  CLEAR_BIT(DMA2_Stream5->CR, DMA_SxCR_EN);   //Stream 5 kikapcsolása TIM1_UP
  while(READ_BIT(DMA2_Stream5->CR, DMA_SxCR_EN));
  DMA2_Stream5->PAR = (uint32_t)&GPIOC->ODR;
  DMA2_Stream5->M0AR = (uint32_t)&puffer[0];
  DMA2_Stream5->NDTR = 100;
  MODIFY_REG(DMA2_Stream5->CR, DMA_SxCR_CHSEL, 6 << DMA_SxCR_CHSEL_Pos);  //Channel6
  MODIFY_REG(DMA2_Stream5->CR, DMA_SxCR_PL, 3 << DMA_SxCR_PL_Pos);  // Priority level: Very high
  MODIFY_REG(DMA2_Stream5->CR, DMA_SxCR_DIR, 1 << DMA_SxCR_DIR_Pos);  // Memory-to-peripheral
  SET_BIT(DMA2_Stream5->CR, DMA_SxCR_MINC); // Memory address pointer is incremented after each data transfer (increment is done according to MSIZE)
  //MODIFY_REG(DMA2_Stream5->CR, DMA_SxCR_PSIZE, 1 << DMA_SxCR_PSIZE_Pos);  //Peripheral data size: Half-word (16-bit)
  
  SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
  MODIFY_REG(GPIOC->MODER, GPIO_MODER_MODE0, 1 << GPIO_MODER_MODE0_Pos);
  MODIFY_REG(GPIOC->OSPEEDR, GPIO_OSPEEDER_OSPEEDR0, 0 << GPIO_OSPEEDR_OSPEED0_Pos);
  
  SET_BIT(DMA2_Stream5->CR, DMA_SxCR_EN);
  SET_BIT(TIM1->CR1, TIM_CR1_CEN);
  
  while (1)
  {
    /*SET_BIT(GPIOE->BSRR, 1 << 10);
    SET_BIT(GPIOE->BSRR, 1 << 26);*/
    
    /*SET_BIT(GPIOD->ODR, 1 << 0);
    CLEAR_BIT(GPIOD->ODR, 1 << 0);*/
    
    if(READ_BIT(DMA2->HISR, DMA_HISR_TCIF5))
    {
      SET_BIT(DMA2->HIFCR, DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5);
      DMA2_Stream5->NDTR = 100;
      SET_BIT(DMA2_Stream5->CR, DMA_SxCR_EN);
    }
  }
}

2 REPLIES 2

9MHz update, it means 111ns between the DMA events. One DMA event sets the pin, another - after 111ns - clears it, yet another - 222ns from the first - sets it again. That's s 222ns period, i.e. 4.5MHz frequency.

JW

ExtSol
Associate II

You are right, I was wrong, I'm stupid :face_with_tears_of_joy:

Thank you :)