Example #1
0
/**
 * @brief Deactivates the PWM peripheral.
 *
 * @param[in] pwmp pointer to a @p PWMDriver object
 */
void pwm_lld_stop(PWMDriver *pwmp) {
  /* If in ready state then disables the PWM clock.*/
  if (pwmp->pd_state == PWM_READY) {
    stop_channels(pwmp);
    pwmp->pd_tim->CR1 = 0;
    pwmp->pd_tim->BDTR = 0;
    pwmp->pd_tim->DIER = 0;

#if USE_STM32_PWM1
    if (&PWMD1 == pwmp) {
      NVICDisableVector(TIM1_UP_IRQn);
      NVICDisableVector(TIM1_CC_IRQn);
      RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN;
    }
#endif
#if USE_STM32_PWM2
    if (&PWMD2 == pwmp) {
      NVICDisableVector(TIM2_IRQn);
      RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN;
    }
#endif
#if USE_STM32_PWM3
    if (&PWMD3 == pwmp) {
      NVICDisableVector(TIM3_IRQn);
      RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN;
    }
#endif
#if USE_STM32_PWM2
    if (&PWMD4 == pwmp) {
      NVICDisableVector(TIM4_IRQn);
      RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN;
    }
#endif
  }
}
/*!
 * \brief
 * Callback for when new data is available in a pipe
 *
 * \param[in] source     the event source
 * \param[in] condition  the condition which has been satisfied
 * \param[in] data       an unsigned integer as specified by #CHANNEL_ID,
 *                       converted to a \c gpointer using
 *                       \c GUINT_TO_POINTER()
 *
 * \return
 * \c FALSE when the event source should be removed, otherwise \c TRUE
 */
static gboolean
io_watch_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
  const guint8 input_type = GPOINTER_TO_UINT(data);
  gchar buffer[BUFFER_SIZE];
  gsize bytes_read;
  GError *error = NULL;
  GIOStatus status;
  GIOChannel *write_to = NULL;

  if (IS_STDOUT(input_type)) {
    write_to = channel_stdin[1 ^ CLIENT_ID(input_type)];
  }

  do {
    status = g_io_channel_read_chars(source, buffer, BUFFER_SIZE,
                                     &bytes_read, &error);
    if (error != NULL) {
      stop_channels(source, write_to);
      print_error(error->message);
      return FALSE;
    }
    if (bytes_read == 0) continue;
    if (write_to != NULL) {
      g_io_channel_write_chars(write_to, buffer, bytes_read, NULL, NULL);
      g_io_channel_flush(write_to, NULL);
    }
    append_text(buffer, bytes_read, input_type);
  } while (status == G_IO_STATUS_NORMAL);

  if ((condition & ~G_IO_IN) != 0) {
    stop_channels(source, write_to);
    return FALSE;
  }
  /* for some reason I can't figure out, this function is called repeatedly
     with condition==G_IO_IN when the client process ends - this check should
     prevent the program from becoming unresponsive and consuming 100% CPU */
  return clients[CLIENT_ID(input_type)].is_running;
}
Example #3
0
/**
 * @brief Configures and activates the PWM peripheral.
 *
 * @param[in] pwmp pointer to a @p PWMDriver object
 */
void pwm_lld_start(PWMDriver *pwmp) {
  uint16_t ccer;

  if (pwmp->pd_state == PWM_STOP) {
    /* Clock activation.*/
#if USE_STM32_PWM1
    if (&PWMD1 == pwmp) {
      NVICEnableVector(TIM1_UP_IRQn,
                       CORTEX_PRIORITY_MASK(STM32_PWM1_IRQ_PRIORITY));
      NVICEnableVector(TIM1_CC_IRQn,
                       CORTEX_PRIORITY_MASK(STM32_PWM1_IRQ_PRIORITY));
      RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
    }
#endif
#if USE_STM32_PWM2
    if (&PWMD2 == pwmp) {
      NVICEnableVector(TIM2_IRQn,
                       CORTEX_PRIORITY_MASK(STM32_PWM2_IRQ_PRIORITY));
      RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    }
#endif
#if USE_STM32_PWM3
    if (&PWMD3 == pwmp) {
      NVICEnableVector(TIM3_IRQn,
                       CORTEX_PRIORITY_MASK(STM32_PWM3_IRQ_PRIORITY));
      RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    }
#endif
#if USE_STM32_PWM4
    if (&PWMD4 == pwmp) {
      NVICEnableVector(TIM4_IRQn,
                       CORTEX_PRIORITY_MASK(STM32_PWM4_IRQ_PRIORITY));
      RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    }
#endif
  }
  /* Reset channels.*/
  stop_channels(pwmp);

  /* Configuration or reconfiguration.*/
  pwmp->pd_tim->CR1  = 0;                   /* Timer stopped.               */
  pwmp->pd_tim->SMCR = 0;                   /* Slave mode disabled.         */
  pwmp->pd_tim->CR2  = pwmp->pd_config->pc_cr2;
  pwmp->pd_tim->PSC  = pwmp->pd_config->pc_psc;
  pwmp->pd_tim->CNT  = 0;
  pwmp->pd_tim->ARR  = pwmp->pd_config->pc_arr;
  /* Output enables and polarities setup.*/
  ccer = 0;
  switch (pwmp->pd_config->pc_channels[0].pcc_mode) {
  case PWM_OUTPUT_ACTIVE_LOW:
    ccer |= TIM_CCER_CC1P;
  case PWM_OUTPUT_ACTIVE_HIGH:
    ccer |= TIM_CCER_CC1E;
  default:
    ;
  }
  switch (pwmp->pd_config->pc_channels[1].pcc_mode) {
  case PWM_OUTPUT_ACTIVE_LOW:
    ccer |= TIM_CCER_CC2P;
  case PWM_OUTPUT_ACTIVE_HIGH:
    ccer |= TIM_CCER_CC2E;
  default:
    ;
  }
  switch (pwmp->pd_config->pc_channels[2].pcc_mode) {
  case PWM_OUTPUT_ACTIVE_LOW:
    ccer |= TIM_CCER_CC3P;
  case PWM_OUTPUT_ACTIVE_HIGH:
    ccer |= TIM_CCER_CC3E;
  default:
    ;
  }
  switch (pwmp->pd_config->pc_channels[3].pcc_mode) {
  case PWM_OUTPUT_ACTIVE_LOW:
    ccer |= TIM_CCER_CC4P;
  case PWM_OUTPUT_ACTIVE_HIGH:
    ccer |= TIM_CCER_CC4E;
  default:
    ;
  }
  pwmp->pd_tim->CCER = ccer;
  pwmp->pd_tim->EGR  = TIM_EGR_UG;          /* Update event.                */
  pwmp->pd_tim->SR   = 0;                   /* Clear pending IRQs.          */
  pwmp->pd_tim->DIER = pwmp->pd_config->pc_callback == NULL ? 0 : TIM_DIER_UIE;
  pwmp->pd_tim->BDTR = TIM_BDTR_MOE;
  pwmp->pd_tim->CR1  = TIM_CR1_ARPE | TIM_CR1_URS |
                       TIM_CR1_CEN;         /* Timer configured and started.*/
}