cancel
Showing results for 
Search instead for 
Did you mean: 

Timer cookbook example on STM32F303RE platform?

David Pekin
Senior

Hello,

Has anyone succeeded in getting the timer cookbook examples (specifically the TIM_ExtCLK_ETR)

working on the STM32F303RE? I've been beating my head against the wall for a while now and still haven't seen the light. I'm using the IAR Embedded workbench. I took the original project and did the following:

  1. Changed the target device from STM32F302R8 to STM32F303RE
  2. Replaced startup_stm32f302x8.s with startup_stm32f303xe.s
  3. Changed the Preprocessor Define from STM32F302X8 to STM32F303Xe

The project builds fine with no errors but it doesn't run correctly. I'm driving a 1KHs 0-4.5V square wave into PA1 on a Nucleo 64 board. I turned the compiler optimization option to none so I could debug. When debugging, I see that the program always hangs on the following line:

 /* wait until the transfer complete*/

 while ((DMA1->ISR & DMA_ISR_TCIF7) == RESET) 

 {

 }

So, I assume there is a 302R8 vs 303RE difference in clocking, TIM, or DMA setup but I'm unaware what the key difference is. Below is the setup code from the AN4776 timer cookbook TIM_ExtCLK_ETR example:

Thanks for any pointers.

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct;

 RCC_ClkInitTypeDef RCC_ClkInitStruct;

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

 RCC_OscInitStruct.HSIState = RCC_HSI_ON;

 RCC_OscInitStruct.HSICalibrationValue = 16;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 HAL_RCC_OscConfig(&RCC_OscInitStruct);

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

 HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

 /* SysTick_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

/**

 * @brief Configure the TIM2 peripheral:

 * + ETR MODE : - HSI : 8MHz 

 *       - Divider : 4

 *       - Polarity : High

 *       - ETR pin : Channel 1

 * + Internal source clock mode: - HSI : 8MHz

 *

 *  Counter mode : UP Counter 

 *  Clock Division : 1

 *  Period : 0xFFFFFFFF

 *  Prescaler : 0 

 *  input Channel : Channel 2

 * @param None

 * @retval None

 */

static void TIM2_Config(void)

{

 /* TIM2 clock enable */

 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; 

 /* Set the Timer prescaler to get 8MHz as counter clock */

 Prescaler = (uint16_t) (SystemCoreClock / 8000000) - 1;

 /* Reset the SMCR register */

 TIM2->SMCR = RESET; 

  

#ifdef USE_ETR

 /* Configure the ETR Clock source:

    + Asychronous divider : 4

    + Polarity : Rising Edge

 */

 TIM2->SMCR |= (TIM_ETRPRESCALER_DIV4 | TIM_ETRPOLARITY_NONINVERTED);          

 TIM2->SMCR |= TIM_SMCR_ECE;            

 /******** Configure the Internal Clock source ********************************/

#else /* Internal clock source*/

  

 /* Disable slave mode to clock the prescaler directly with the internal clock 

 if the TIM_SMCR is in the reset value, we can delete the following instruction*/

 TIM2->SMCR &= ~TIM_SMCR_SMS;  

#endif /* USE_ETR*/

 /* Configure the Time base:

    + Counter mode : UP Counter

    + Clock Division : 1

    + Period : 0xFFFFFFFF

    + Prescaler : 0

 */

 /* Select the up counter mode */

 TIM2->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);

 TIM2->CR1 |= TIM_COUNTERMODE_UP;      

 /* Set the clock division to 1 */

 TIM2->CR1 &= ~TIM_CR1_CKD;

 TIM2->CR1 |= TIM_CLOCKDIVISION_DIV1;    

 /* Set the Autoreload value */

 TIM2->ARR = PERIOD ;

 /* Set the Prescaler value */

 TIM2->PSC = Prescaler;    

 /* Generate an update event to reload the Prescaler value immediatly */

 TIM2->EGR = TIM_EGR_UG;

 /* Configure the Timer Input Capture Channels:

    + Channel : Channel 2

 */

 /* Connect the Timer input to IC2 */

 TIM2->CCMR1 &= ~TIM_CCMR1_CC2S;

 TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;

}

/**

 * @brief Configure the DMA1 peripheral:

 * Data Transfer Direction : Peripheral to Memory

 * Peripheral Increment : Disable

 * Memory Increment : Enable

 * Peripheral Data Size : Word

 * Memory Data Size : Word

 * Data Transfer Mode : Normal

 * Priority Level : High

 * Peripheral Address : TIM2_CCR2 register

 * Memory Address : aBuffer

 * The length of transfered data : BUFFER_SIZE

 * @param None

 * @retval None

 */

static void DMA1_Config(void)

{

 /* Reset the DMA Channel 7 Control register*/ 

 DMA1_Channel7->CCR = ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \

           DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \

           DMA_CCR_DIR));

 /* Configure the DMA1 Channel 7 */

 /* Set the direction bits : Peripheral to Memory */

 DMA1_Channel7->CCR |= DMA_PERIPH_TO_MEMORY;

 /* Disable the Peripheral increment */

 DMA1_Channel7->CCR |= DMA_PINC_DISABLE;

 /* Enable the Memory increment */

 DMA1_Channel7->CCR |= DMA_MINC_ENABLE;

 /* Set the Peripheral Data size to Word*/

 DMA1_Channel7->CCR |= DMA_PDATAALIGN_WORD;

 /* Set the Memory Data size to Word*/

 DMA1_Channel7->CCR |= DMA_MDATAALIGN_WORD;

 /* Set the transfer mode to Normal*/

 DMA1_Channel7->CCR |= DMA_NORMAL;

 /* Set the Priority to High*/

 DMA1_Channel7->CCR |= DMA_PRIORITY_HIGH;

 /* Configure the source, destination address and the data length */

 DMA1_Channel7->CNDTR = CAPTURE_BUFFER_SIZE;

 /* Configure DMA Channel destination address */

 DMA1_Channel7->CPAR = (uint32_t)&(TIM2->CCR2);

 /* Configure DMA Channel source address */

 DMA1_Channel7->CMAR = (uint32_t)aCaptureBuffer;

 /* Enable the transfer Error interrupt */

 DMA1_Channel7->CCR |= DMA_IT_TE;

}

/**

 * @brief Starts the TIM2 Input Capture measurement on DMA mode :

 * Channel : TIM_CHANNEL_2

 * @param None

 * @retval None

 */

static void TIM2_DMA1_Capture(void)

{

 /* Enable the DMA1 */

 DMA1_Channel7->CCR |= DMA_CCR_EN;

 /* Enable the TIM Capture/Compare 2 DMA request */

 TIM2->DIER |= TIM_DMA_CC2;

 /*Enables the TIM Capture Compare Channel 2.*/

 TIM2->CCER |= TIM_CCER_CC2E;

 /*Enable the TIM2*/

 TIM2->CR1 |= TIM_CR1_CEN;

 /* wait until the transfer complete*/

 while ((DMA1->ISR & DMA_ISR_TCIF7) == RESET) 

 {

 }

}

/** 

 * Enable DMA controller clock

 */

void MX_DMA_Init(void) 

{

 /* DMA controller clock enable */

 __DMA1_CLK_ENABLE();

 /* DMA interrupt init */

 HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);

}

0 REPLIES 0