static void timer_setup(void)
{
/* Enable TIM3 clock. */
rcc_periph_clock_enable(RCC_TIM3);
timer_reset(TIM3);
/* Timer global mode: - No divider, Alignment edge, Direction up */
timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT,TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
timer_continuous_mode(TIM3);
timer_set_period(TIM3, PERIOD);
timer_disable_preload(TIM3);

/* prescaler F_SYS/48 = TIM3 clock is 1 MHz */
timer_set_prescaler(TIM3,48);
//timer_disable_oc_output(TIM3, TIM_OC2 | TIM_OC3 | TIM_OC4);
timer_enable_oc_output(TIM3, TIM_OC1);
timer_disable_oc_output(TIM3,TIM_OC2);

timer_enable_oc_output(TIM3, TIM_OC3);
//timer_enable_oc_output(TIM3, TIM_OC4);
// motor ch1
timer_set_oc_mode(TIM3, TIM_OC1, TIM_OCM_PWM1);
// motor ch2
timer_set_oc_mode(TIM3, TIM_OC2, TIM_OCM_PWM1);
// motor ch3
timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM1);
// motor ch3
timer_set_oc_mode(TIM3, TIM_OC4, TIM_OCM_PWM1);


/* disable preload */
timer_disable_oc_preload(TIM3, TIM_OC1);
timer_disable_oc_preload(TIM3, TIM_OC2);
timer_disable_oc_preload(TIM3, TIM_OC3);
timer_disable_oc_preload(TIM3, TIM_OC4);

/* polarity */
timer_set_oc_polarity_high(TIM3,TIM_OC1);
timer_set_oc_polarity_high(TIM3,TIM_OC2);
timer_set_oc_polarity_high(TIM3,TIM_OC3);
timer_set_oc_polarity_high(TIM3,TIM_OC4);
//timer_enable_oc_clear(TIM3, TIM_OC1);
//timer_set_oc_slow_mode(TIM3, TIM_OC1);
timer_set_oc_value(TIM3, TIM_OC1, PULSE);
timer_set_oc_value(TIM3, TIM_OC2, PULSE*3);
timer_set_oc_value(TIM3, TIM_OC3, PULSE*2);
timer_set_oc_value(TIM3, TIM_OC4, PULSE*4);
//timer_generate_event(TIM3,TIM_EGR_CC1G);
//timer_enable_update_event(TIM3);
nvic_enable_irq(NVIC_TIM3_IRQ);
timer_enable_irq(TIM3,TIM_DIER_CC1IE);
timer_enable_irq(TIM3,TIM_DIER_CC2IE);
timer_enable_irq(TIM3,TIM_DIER_CC3IE);
timer_enable_irq(TIM3,TIM_DIER_CC4IE);
//timer_enable_irq(TIM3,TIM_DIER_CC2IE);
timer_enable_irq(TIM3,TIM_DIER_UIE);
/* Set the timer trigger output (for the DAC) to the channel 1 output
compare */
//timer_set_master_mode(TIM3, TIM_CR2_MMS_COMPARE_OC1REF);
timer_enable_counter(TIM3);

}
/** Set Timer configuration
 * @param[in] timer Timer register address base
 * @param[in] period period in us
 * @param[in] channels_mask output compare channels to enable
 */
void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask) {
  // WARNING, this reset is only implemented for TIM1-8 in libopencm3!!
  timer_reset(timer);

  /* Timer global mode:
   * - No divider.
   * - Alignement edge.
   * - Direction up.
   */
  if ((timer == TIM9) || (timer == TIM12))
    //There are no EDGE and DIR settings in TIM9 and TIM12
    timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
  else
    timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);


  // By default the PWM_BASE_FREQ is set to 1MHz thus the timer tick period is 1uS
  uint32_t timer_clk = timer_get_frequency(timer);
  timer_set_prescaler(timer, (timer_clk / PWM_BASE_FREQ) -1);

  timer_disable_preload(timer);

  timer_continuous_mode(timer);

  timer_set_period(timer, (PWM_BASE_FREQ / period) - 1);

  /* Disable outputs and configure channel if needed. */
  if (bit_is_set(channels_mask, 0)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC1);
  }
  if (bit_is_set(channels_mask, 1)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC2);
  }
  if (bit_is_set(channels_mask, 2)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC3);
  }
  if (bit_is_set(channels_mask, 3)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC4);
  }

  /*
   * Set initial output compare values.
   * Note: Maybe we should preload the compare registers with some sensible
   * values before we enable the timer?
   */
  //timer_set_oc_value(timer, TIM_OC1, 1000);
  //timer_set_oc_value(timer, TIM_OC2, 1000);
  //timer_set_oc_value(timer, TIM_OC3, 1000);
  //timer_set_oc_value(timer, TIM_OC4, 1000);

  /* -- Enable timer -- */
  /*
   * ARR reload enable.
   * Note: In our case it does not matter much if we do preload or not. As it
   * is unlikely we will want to change the frequency of the timer during
   * runtime anyways.
   */
  timer_enable_preload(timer);

  /* Counter enable. */
  timer_enable_counter(timer);

}
static void tim_setup(void)
{
	/* Enable TIM2 clock. */
	rcc_periph_clock_enable(RCC_TIM2);

	/* Enable TIM2 interrupt. */
	nvic_enable_irq(NVIC_TIM2_IRQ);

	/* Reset TIM2 peripheral. */
	timer_reset(TIM2);

	/* Timer global mode:
	 * - No divider
	 * - Alignment edge
	 * - Direction up
	 */
	timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
		       TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);

	/* Reset prescaler value.
	 * Running the clock at 5kHz.
	 */
	/*
	 * On STM32F4 the timers are not running directly from pure APB1 or
	 * APB2 clock busses.  The APB1 and APB2 clocks used for timers might
	 * be the double of the APB1 and APB2 clocks.  This depends on the
	 * setting in DCKCFGR register. By default the behaviour is the
	 * following: If the Prescaler APBx is greater than 1 the derived timer
	 * APBx clocks will be double of the original APBx frequencies. Only if
	 * the APBx prescaler is set to 1 the derived timer APBx will equal the
	 * original APBx frequencies.
	 *
	 * In our case here the APB1 is devided by 4 system frequency and APB2
	 * divided by 2. This means APB1 timer will be 2 x APB1 and APB2 will
	 * be 2 x APB2. So when we try to calculate the prescaler value we have
	 * to use rcc_apb1_freqency * 2!!!
	 *
	 * For additional information see reference manual for the stm32f4
	 * familiy of chips. Page 204 and 213
	 */
	timer_set_prescaler(TIM2, ((rcc_apb1_frequency * 2) / 10000));

	/* Enable preload. */
	timer_disable_preload(TIM2);

	/* Continous mode. */
	timer_continuous_mode(TIM2);

	/* Period (36kHz). */
	timer_set_period(TIM2, 65535);

	/* Disable outputs. */
	timer_disable_oc_output(TIM2, TIM_OC1);
	timer_disable_oc_output(TIM2, TIM_OC2);
	timer_disable_oc_output(TIM2, TIM_OC3);
	timer_disable_oc_output(TIM2, TIM_OC4);

	/* -- OC1 configuration -- */

	/* Configure global mode of line 1. */
	timer_disable_oc_clear(TIM2, TIM_OC1);
	timer_disable_oc_preload(TIM2, TIM_OC1);
	timer_set_oc_slow_mode(TIM2, TIM_OC1);
	timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_FROZEN);

	/* Set the capture compare value for OC1. */
	timer_set_oc_value(TIM2, TIM_OC1, 1000);

	/* ---- */

	/* ARR reload enable. */
	timer_disable_preload(TIM2);

	/* Counter enable. */
	timer_enable_counter(TIM2);

	/* Enable commutation interrupt. */
	timer_enable_irq(TIM2, TIM_DIER_CC1IE);
}
/** Set Timer configuration
 */
static inline void set_servo_timer(uint32_t timer, uint32_t period, uint8_t channels_mask) {
  timer_reset(timer);

  /* Timer global mode:
   * - No divider.
   * - Alignement edge.
   * - Direction up.
   */
  if ((timer == TIM9) || (timer == TIM12))
    //There are no EDGE and DIR settings in TIM9 and TIM12
    timer_set_mode(timer, TIM_CR1_CKD_CK_INT, 0, 0);
  else
    timer_set_mode(timer, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);


  // TIM1, 8 and 9 use APB2 clock, all others APB1
  if (timer != TIM1 && timer != TIM8 && timer != TIM9) {
    timer_set_prescaler(timer, (TIMER_APB1_CLK / ONE_MHZ_CLK) - 1); // 1uS
  } else {
    // TIM9, 1 and 8 use APB2 clock
    timer_set_prescaler(timer, (TIMER_APB2_CLK / ONE_MHZ_CLK) - 1);
  }

  timer_disable_preload(timer);

  timer_continuous_mode(timer);

  timer_set_period(timer, (ONE_MHZ_CLK / period) - 1);

  /* Disable outputs and configure channel if needed. */
  if (bit_is_set(channels_mask, 0)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC1);
  }
  if (bit_is_set(channels_mask, 1)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC2);
  }
  if (bit_is_set(channels_mask, 2)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC3);
  }
  if (bit_is_set(channels_mask, 3)) {
    actuators_pwm_arch_channel_init(timer, TIM_OC4);
  }

  /*
   * Set initial output compare values.
   * Note: Maybe we should preload the compare registers with some sensible
   * values before we enable the timer?
   */
  //timer_set_oc_value(timer, TIM_OC1, 1000);
  //timer_set_oc_value(timer, TIM_OC2, 1000);
  //timer_set_oc_value(timer, TIM_OC3, 1000);
  //timer_set_oc_value(timer, TIM_OC4, 1000);

  /* -- Enable timer -- */
  /*
   * ARR reload enable.
   * Note: In our case it does not matter much if we do preload or not. As it
   * is unlikely we will want to change the frequency of the timer during
   * runtime anyways.
   */
  timer_enable_preload(timer);

  /* Counter enable. */
  timer_enable_counter(timer);

}
Example #5
0
static void tim_setup(void) {
    /* Enable TIM1 clock. */
    rcc_periph_clock_enable(RCC_TIM1);
    /* Configure TIM1_CH1 and TIM1_CH2 as inputs */
    gpio_set_mode(GPIO_BANK_TIM1_CH1, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_TIM1_CH1);
    gpio_set_mode(GPIO_BANK_TIM1_CH2, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_TIM1_CH2);
    /* Enable TIM1 interrupt. */
    nvic_enable_irq(NVIC_TIM1_CC_IRQ);
    /* Reset TIM1 peripheral. */
    /* timer_reset(TIM1); */

    timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
    /* set prescaler value -> 1us */
    timer_set_prescaler(TIM1, 72 - 1);
    timer_set_period(TIM1, 0xFFFF);
    timer_set_repetition_counter(TIM1, 0);
    /* Enable preload */
    /* timer_disable_preload(TIM1); */
    /* Continous mode */
    timer_continuous_mode(TIM1);

    /* configure Channel 1 */
    timer_ic_set_input(TIM1, TIM_IC1, TIM_IC_IN_TI1);
    timer_ic_set_filter(TIM1, TIM_IC1, TIM_IC_OFF);
    timer_ic_set_polarity(TIM1, TIM_IC1, TIM_IC_RISING);
    timer_ic_set_prescaler(TIM1, TIM_IC1, TIM_IC_PSC_OFF);
    timer_ic_enable(TIM1, TIM_IC1);
    timer_clear_flag(TIM1, TIM_SR_CC1IF);
    timer_enable_irq(TIM1, TIM_DIER_CC1IE);

    /* configure Channel 2 */
    timer_ic_set_input(TIM1, TIM_IC2, TIM_IC_IN_TI2);
    timer_ic_set_filter(TIM1, TIM_IC2, TIM_IC_OFF);
    timer_ic_set_polarity(TIM1, TIM_IC2, TIM_IC_RISING);
    timer_ic_set_prescaler(TIM1, TIM_IC2, TIM_IC_PSC_OFF);
    timer_ic_enable(TIM1, TIM_IC2);
    timer_clear_flag(TIM1, TIM_SR_CC2IF);
    timer_enable_irq(TIM1, TIM_DIER_CC2IE);

    timer_enable_counter(TIM1);

#if 0
    /* Disable outputs. */
    timer_disable_oc_output(TIM1, TIM_OC1);
    timer_disable_oc_output(TIM1, TIM_OC2);
    timer_disable_oc_output(TIM1, TIM_OC3);
    timer_disable_oc_output(TIM1, TIM_OC4);
    /* -- OC1 configuration -- */
    /* Configure global mode of line 1. */
    timer_disable_oc_clear(TIM1, TIM_OC1);
    timer_disable_oc_preload(TIM1, TIM_OC1);
    timer_set_oc_slow_mode(TIM1, TIM_OC1);
    timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_FROZEN);
    /* Set the capture compare value for OC1. */
    timer_set_oc_value(TIM1, TIM_OC1, 1000);
    /* ---- */
    /* ARR reload enable. */
    timer_disable_preload(TIM1);
    /* Counter enable. */
    timer_enable_counter(TIM1);
    /* Enable commutation interrupt. */
    timer_enable_irq(TIM1, TIM_DIER_CC1IE);
#endif
}
/*--------------------------------------------------------------------*/
void hardware_setup(void)
{
/* Setup the clock to 72MHz from the 8MHz external crystal */

	rcc_clock_setup_in_hse_8mhz_out_72mhz();

/* Enable GPIOA, GPIOB and GPIOC clocks.
   APB2 (High Speed Advanced Peripheral Bus) peripheral clock enable register (RCC_APB2ENR)
   Set RCC_APB2ENR_IOPBEN for port B, RCC_APB2ENR_IOPAEN for port A and RCC_APB2ENR_IOPAEN
   for Alternate Function clock */
	rcc_periph_clock_enable(RCC_GPIOA);
	rcc_periph_clock_enable(RCC_GPIOB);
	rcc_periph_clock_enable(RCC_GPIOC);
	rcc_periph_clock_enable(RCC_AFIO);

/* Digital Test output PC0 */
	gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
		      GPIO_CNF_OUTPUT_PUSHPULL, GPIO0);

/* ----------------- Timer 2 Interrupt and DAC control*/

/* Enable TIM2 clock. */
	rcc_periph_clock_enable(RCC_TIM2);
/* Enable TIM2 interrupt. */
	nvic_enable_irq(NVIC_TIM2_IRQ);
	timer_reset(TIM2);
/* Timer global mode:
 * - No divider
 * - Alignment edge
 * - Direction up
 */
	timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
		       TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
/* Continous mode. */
	timer_continuous_mode(TIM2);
	timer_set_period(TIM2, 1000);
/* Disable outputs. */
	timer_disable_oc_output(TIM2, TIM_OC1 | TIM_OC2 | TIM_OC3 | TIM_OC4);
/* Configure global mode of output channel 1, disabling the output. */
	timer_disable_oc_clear(TIM2, TIM_OC1);
	timer_disable_oc_preload(TIM2, TIM_OC1);
	timer_set_oc_slow_mode(TIM2, TIM_OC1);
	timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_FROZEN);
/* Set the capture compare value for OC1. */
	timer_set_oc_value(TIM2, TIM_OC1, 1000);
/* ARR reload disable. */
	timer_disable_preload(TIM2);
/* Counter enable. */
	timer_enable_counter(TIM2);
/* Enable commutation interrupt. */
	timer_enable_irq(TIM2, TIM_DIER_CC1IE);

/* Set port PA4 for DAC1 to 'alternate function'. Output driver mode is ignored. */
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
		      GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO4);

/* Enable the DAC clock on APB1 */
	rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_DACEN);

/* Setup the DAC, software trigger source. Assume the DAC has
woken up by the time the first interrupt occurs */
	dac_trigger_enable(CHANNEL_D);
	dac_set_trigger_source(DAC_CR_TSEL1_SW | DAC_CR_TSEL2_SW);
	dac_enable(CHANNEL_D);
	dac_load_data_buffer_dual(0, 0, RIGHT8);

}