示例#1
0
/**
 * @brief   Disables a PWM channel.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @post    The channel is disabled and its output line returned to the
 *          idle state.
 * @note    Depending on the hardware implementation this function has
 *          effect starting on the next cycle (recommended implementation)
 *          or immediately (fallback implementation).
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 * @param[in] channel   PWM channel identifier (0...PWM_CHANNELS-1)
 *
 * @notapi
 */
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel)
{
  uint8_t i = timer_index(pwmp);
  config_channel(regs_table[i].tccra,
                 7 - 2*channel,
                 6 - 2*channel,
                 PWM_OUTPUT_DISABLED);
  *regs_table[i].timsk &= ~(1 << (channel + 1));
}
示例#2
0
/**
 * @brief   Enables a PWM channel.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @post    The channel is active using the specified configuration.
 * @note    Depending on the hardware implementation this function has
 *          effect starting on the next cycle (recommended implementation)
 *          or immediately (fallback implementation).
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 * @param[in] channel   PWM channel identifier (0...PWM_CHANNELS-1)
 * @param[in] width     PWM pulse width as clock pulses number
 *
 * @notapi
 */
void pwm_lld_enable_channel(PWMDriver *pwmp,
                            pwmchannel_t channel,
                            pwmcnt_t width)
{
  uint16_t val = width;
  if (val > MAX_PWM_VALUE)
    val = MAX_PWM_VALUE;

#if AVR_PWM_USE_TIM2 || defined(__DOXYGEN__)
  if (pwmp == &PWMD2) {
    config_channel(&TCCR2A,
                   7 - 2*channel,
                   6 - 2*channel,
                   pwmp->config->channels[channel].mode);
    TIMSK2 |= (1 << (channel + 1));
    /* Timer 2 is 8 bit */
    if (val > 0xFF)
      val = 0xFF;
    if (pwmp->config->channels[channel].callback) {
      switch (channel) {
      case 0: OCR2A = val; break;
      case 1: OCR2B = val; break;
      }
    }
    return;
  }
#endif

  uint8_t i = timer_index(pwmp);
  config_channel(regs_table[i].tccra,
                 7 - 2*channel,
                 6 - 2*channel,
                 pwmp->config->channels[channel].mode);
  volatile uint8_t *ocrh, *ocrl;
  switch (channel) {
  case 1:
    ocrh = regs_table[i].ocrbh;
    ocrl = regs_table[i].ocrbl;
    break;
  case 2:
    ocrh = regs_table[i].ocrch;
    ocrl = regs_table[i].ocrcl;
    break;
  default:
    ocrh = regs_table[i].ocrah;
    ocrl = regs_table[i].ocral;
  }
  *ocrh = val >> 8;
  *ocrl = val & 0xFF;
  *regs_table[i].tifr |= (1 << (channel + 1));
  if (pwmp->config->channels[channel].callback)
    *regs_table[i].timsk |= (1 << (channel + 1));
}
示例#3
0
/**
 * @brief   Configures and activates the PWM peripheral.
 *
 * @param[in] pwmp      pointer to the @p PWMDriver object
 *
 * @notapi
 */
void pwm_lld_start(PWMDriver *pwmp)
{
  if (pwmp->state == PWM_STOP) {

#if AVR_PWM_USE_TIM2 || defined(__DOXYGEN__)
    if (pwmp == &PWMD2) {
      TCCR2B &= ~((1 << CS22) | (1 << CS21));
      TCCR2B |= (1 << CS20);
      if (pwmp->config->callback != NULL)
        TIMSK2 |= (1 << TOIE2);
      return;
    }
#endif

    /* TODO: support other prescaler options */

    uint8_t i = timer_index(pwmp);
    *regs_table[i].tccrb &= ~(1 << CS11);
    *regs_table[i].tccrb |= (1 << CS12) | (1 << CS10);
    *regs_table[i].timsk = (1 << TOIE1);
  }
}
示例#4
0
/**
 * @brief   Disables a channel de-activation edge notification.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @pre     The channel must have been activated using @p pwmEnableChannel().
 * @note    If the notification is already disabled then the call has no effect.
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 * @param[in] channel   PWM channel identifier (0...channels-1)
 *
 * @notapi
 */
void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
                                          pwmchannel_t channel) {

  uint8_t i = timer_index(pwmp);
  *regs_table[i].timsk &= ~(1 << (channel + 1));
}
示例#5
0
/**
 * @brief   Disables the periodic activation edge notification.
 * @pre     The PWM unit must have been activated using @p pwmStart().
 * @note    If the notification is already disabled then the call has no effect.
 *
 * @param[in] pwmp      pointer to a @p PWMDriver object
 *
 * @notapi
 */
void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
  uint8_t i = timer_index(pwmp);
  *regs_table[i].timsk &= ~(1 << TOIE1);
}
示例#6
0
/**
 * @brief   Deactivates the PWM peripheral.
 *
 * @param[in] pwmp      pointer to the @p PWMDriver object
 *
 * @notapi
 */
void pwm_lld_stop(PWMDriver *pwmp)
{
  uint8_t i = timer_index(pwmp);
  *regs_table[i].tccrb &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));
  *regs_table[i].timsk = 0;
}