1MHz output compare
Hello,
I would like to ask regarding the highest speed I can toggle using output compare.
When I try to toggle the output with the frequency of  1M Hz, I do not get what I expect.
As attached program, I can get the correct frequency for Channel 1 to 3, but not channel 4. Could you please take a look at it and explain what could be the issue?
I attached the logic analyzer output screen for reference.
I am using Windows 7 64 bit, STM32f4Discovery Board & System Workbench Version: 1.13.1.201701261206
Thank you.
/* Includes ----------------------*/
- include “myTimer4.h”
/* Private variables ---------------------*/
TIM_TimeBaseInitTypeDef  TIM4_TimeBaseStructure;
TIM_OCInitTypeDef  TIM4_OCInitStructure;
static uint16_t TIM4_PrescalerValue = 0;
static uint32_t TIM4_Frequency = 42000000;
static uint16_t uhCapture = 0;
//static uint16_t myTimer = RCC_APB1Periph_TIM4;
__IO uint16_t TIM4_CCR1_Val = 42000;
__IO uint16_t TIM4_CCR2_Val = 4200;
__IO uint16_t TIM4_CCR3_Val = 420;
__IO uint16_t TIM4_CCR4_Val = 42;
/* Private function prototypes -------------------*/
void TIM4_OC_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  /* TIM4 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  /* GPIOC clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  /* GPIOC Configuration: TIM4 CH1 (PD12), TIM4 CH2 (PD13), TIM4 CH2 (PD14) and TIM4 CH4 (PD15) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  /* Connect TIM Channels to AF2 */
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);
  /* Enable the TIM4 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* ---------------------------
  	    TIM4 Configuration: Output Compare Toggle Mode:
  	    In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1),
  	    since APB1 prescaler is different from 1.
  	      TIM4CLK = 2 * PCLK1
  	      PCLK1 = HCLK / 4
  	      => TIM4CLK = HCLK / 2 = SystemCoreClock /2
  	    To get TIM4 counter clock at 42 MHz, the prescaler is computed as follows:
  	       Prescaler = (TIM4CLK / TIM4 counter clock) - 1
  	       Prescaler = ((SystemCoreClock /2) /42 MHz) - 1
  	     CC1 update rate = TIM4 counter clock / TM4_CCR1_Val = 1k Hz
  		   ==> So the TIM4 Channel 1 generates a periodic signal with a
  		       frequency equal to 500 Hz.
  	     CC2 update rate = TIM4 counter clock / TM4_CCR2_Val = 10k Hz
  		   ==> So the TIM4 Channel 2 generates a periodic signal with a
  		       frequency equal to 5k Hz.
  	     CC3 update rate = TIM4 counter clock / TM4_CCR3_Val = 100k Hz
  		   ==> So the TIM4 Channel 3 generates a periodic signal with a
  		       frequency equal to 50k Hz.
  	     CC4 update rate = TIM4 counter clock / TM4_CCR4_Val = 1M Hz
  		   ==> So the TIM4 Channel 4 generates a periodic signal with a
  		       frequency equal to 500k Hz.
  	    Note:
  	     SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
  	     Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
  	     function to update SystemCoreClock variable value. Otherwise, any configuration
  	     based on this variable will be incorrect.
  	  --------------------------- */
  	  /* Compute the prescaler value */
  	  TIM4_PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / TIM4_Frequency) - 1;
  	  /* Time base configuration */
  	  TIM4_TimeBaseStructure.TIM_Period = 65535;
  	  TIM4_TimeBaseStructure.TIM_Prescaler = TIM4_PrescalerValue;
  	  TIM4_TimeBaseStructure.TIM_ClockDivision = 0;
  	  TIM4_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM4_TimeBaseStructure);
  	  /* Output Compare Toggle Mode configuration: Channel1 */
  	  TIM4_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  	  TIM4_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  	  TIM4_OCInitStructure.TIM_Pulse = TIM4_CCR1_Val;
  	  TIM4_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  	  TIM_OC1Init(TIM4, &TIM4_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable);
  	  /* Output Compare Toggle Mode configuration: Channel2 */
  	  TIM4_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  	  TIM4_OCInitStructure.TIM_Pulse = TIM4_CCR2_Val;
TIM_OC2Init(TIM4, &TIM4_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);
  	  /* Output Compare Toggle Mode configuration: Channel3 */
  	  TIM4_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  	  TIM4_OCInitStructure.TIM_Pulse = TIM4_CCR3_Val;
TIM_OC3Init(TIM4, &TIM4_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable);
  	  /* Output Compare Toggle Mode configuration: Channel4 */
  	  TIM4_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  	  TIM4_OCInitStructure.TIM_Pulse = TIM4_CCR4_Val;
TIM_OC4Init(TIM4, &TIM4_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);
  	  /* TIM enable counter */
  	  TIM_Cmd(TIM4, ENABLE);
  	  /* TIM IT enable */
  	  TIM_ITConfig(TIM4, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
}
void TIM4_InterruptHandler()
{
	if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_CC1 );
		uhCapture = TIM_GetCapture1(TIM4);
		TIM_SetCompare1(TIM4, uhCapture + TIM4_CCR1_Val );
	}
	if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
		uhCapture = TIM_GetCapture2(TIM4);
		TIM_SetCompare2(TIM4, uhCapture + TIM4_CCR2_Val);
	}
	if (TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
		uhCapture = TIM_GetCapture3(TIM4);
		TIM_SetCompare3(TIM4, uhCapture + TIM4_CCR3_Val);
	}
	if (TIM_GetITStatus(TIM4, TIM_IT_CC4) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);
		uhCapture = TIM_GetCapture4(TIM4);
		TIM_SetCompare4(TIM4, uhCapture + TIM4_CCR4_Val);
	}
}



