diff options
Diffstat (limited to 'os/hal/platforms')
| -rw-r--r-- | os/hal/platforms/AVR/platform.mk | 3 | ||||
| -rw-r--r-- | os/hal/platforms/AVR/pwm_lld.c | 492 | ||||
| -rw-r--r-- | os/hal/platforms/AVR/pwm_lld.h | 212 | 
3 files changed, 706 insertions, 1 deletions
| diff --git a/os/hal/platforms/AVR/platform.mk b/os/hal/platforms/AVR/platform.mk index 8cccf813c..05d90d1c1 100644 --- a/os/hal/platforms/AVR/platform.mk +++ b/os/hal/platforms/AVR/platform.mk @@ -5,7 +5,8 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AVR/hal_lld.c \                ${CHIBIOS}/os/hal/platforms/AVR/adc_lld.c \
                ${CHIBIOS}/os/hal/platforms/AVR/i2c_lld.c \
                ${CHIBIOS}/os/hal/platforms/AVR/spi_lld.c \
 -              ${CHIBIOS}/os/hal/platforms/AVR/gpt_lld.c
 +              ${CHIBIOS}/os/hal/platforms/AVR/gpt_lld.c \
 +              ${CHIBIOS}/os/hal/platforms/AVR/pwm_lld.c
  # Required include directories
  PLATFORMINC = ${CHIBIOS}/os/hal/platforms/AVR
 diff --git a/os/hal/platforms/AVR/pwm_lld.c b/os/hal/platforms/AVR/pwm_lld.c new file mode 100644 index 000000000..c223d622a --- /dev/null +++ b/os/hal/platforms/AVR/pwm_lld.c @@ -0,0 +1,492 @@ +/* +    ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + +    Licensed under the Apache License, Version 2.0 (the "License"); +    you may not use this file except in compliance with the License. +    You may obtain a copy of the License at + +        http://www.apache.org/licenses/LICENSE-2.0 + +    Unless required by applicable law or agreed to in writing, software +    distributed under the License is distributed on an "AS IS" BASIS, +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +    See the License for the specific language governing permissions and +    limitations under the License. +*/ + +/* +   This driver is based on the work done by Matteo Serva available at +   http://github.com/matteoserva/ChibiOS-AVR +*/ + +/** + * @file    AVR/pwm_lld.c + * @brief   AVR PWM driver subsystem low level driver. + * + * @addtogroup PWM + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_PWM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions.                                                 */ +/*===========================================================================*/ + +typedef struct { +  volatile uint8_t *tccra; +  volatile uint8_t *tccrb; +  volatile uint8_t *ocrah; +  volatile uint8_t *ocral; +  volatile uint8_t *ocrbh; +  volatile uint8_t *ocrbl; +  volatile uint8_t *ocrch; +  volatile uint8_t *ocrcl; +  volatile uint8_t *tifr; +  volatile uint8_t *timsk; +} timer_registers_t; + +timer_registers_t regs_table[]= +{ +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__) +#if defined(OCR1C) +  {&TCCR1A, &TCCR1B, &OCR1AH, &OCR1AL, &OCR1BH, &OCR1BL, &OCR1CH, &OCR1CL, &TIFR1, &TIMSK1}, +#else +  {&TCCR1A, &TCCR1B, &OCR1AH, &OCR1AL, &OCR1BH, &OCR1BL, NULL, NULL, &TIFR1, &TIMSK1}, +#endif +#endif +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__) +  {&TCCR2A, &TCCR2B, &OCR2A, &OCR2A, &OCR2B, &OCR2B, NULL, NULL, &TIFR2, &TIMSK2}, +#endif +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__) +  {&TCCR3A, &TCCR3B, &OCR3AH, &OCR3AL, &OCR3BH, &OCR3BL, &OCR3CH, &OCR3CL, &TIFR3, &TIMSK3}, +#endif +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__) +  {&TCCR4A, &TCCR4B, &OCR4AH, &OCR4AL, &OCR4CH, &OCR4CL, &OCR4CH, &OCR4CL, &TIFR4, &TIMSK4}, +#endif +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__) +  {&TCCR5A, &TCCR5B, &OCR5AH, &OCR5AL, &OCR5BH, &OCR5BL, &OCR5CH, &OCR5CL, &TIFR5, &TIMSK5}, +#endif +}; + +/*===========================================================================*/ +/* Driver exported variables.                                                */ +/*===========================================================================*/ + +/** @brief PWM driver identifiers.*/ +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__) +PWMDriver PWMD1; +#endif +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__) +PWMDriver PWMD2; +#endif +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__) +PWMDriver PWMD3; +#endif +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__) +PWMDriver PWMD4; +#endif +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__) +PWMDriver PWMD5; +#endif + +/*===========================================================================*/ +/* Driver local variables.                                                   */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions.                                                   */ +/*===========================================================================*/ + +static void config_channel(volatile uint8_t *tccra, +                           uint8_t com1, +                           uint8_t com0, +                           pwmmode_t mode) +{ +  *tccra &= ~((1 << com1) | (1 << com0)); +  if (mode == PWM_OUTPUT_ACTIVE_HIGH) +    *tccra |= ((1 << com1) | (0 << com0)); /* non inverting mode */ +  else if (mode == PWM_OUTPUT_ACTIVE_LOW) +    *tccra |= (1 << com1) | (1 << com0);   /* inverting mode */ +} + +static uint8_t timer_index(PWMDriver *pwmp) +{ +  uint8_t index = 0; +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__) +  if (pwmp == &PWMD1) return index; +  else index++; +#endif +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__) +  if (pwmp == &PWMD2) return index; +  else index++; +#endif +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__) +  if (pwmp == &PWMD3) return index; +  else index++; +#endif +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__) +  if (pwmp == &PWMD4) return index; +  else index++; +#endif +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__) +  if (pwmp == &PWMD5) return index; +  else index++; +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers.                                                */ +/*===========================================================================*/ + +/* + * interrupt for compare1&2 and clock overflow. pwmd1 & pwmd2 + */ +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__) +CH_IRQ_HANDLER(TIMER1_OVF_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD1.config->callback(&PWMD1); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER1_COMPA_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD1.config->channels[0].callback(&PWMD1); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER1_COMPB_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD1.config->channels[1].callback(&PWMD1); +  CH_IRQ_EPILOGUE(); +} +#if PWM_CHANNELS > 2 +CH_IRQ_HANDLER(TIMER1_COMPC_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD1.config->channels[2].callback(&PWMD1); +  CH_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__) +CH_IRQ_HANDLER(TIMER2_OVF_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD2.config->callback(&PWMD2); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER2_COMPA_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD2.config->channels[0].callback(&PWMD2); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER2_COMPB_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD2.config->channels[1].callback(&PWMD2); +  CH_IRQ_EPILOGUE(); +} +#endif + +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__) +CH_IRQ_HANDLER(TIMER3_OVF_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD3.config->callback(&PWMD3); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER3_COMPA_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD3.config->channels[0].callback(&PWMD3); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER3_COMPB_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD3.config->channels[1].callback(&PWMD3); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER3_COMPC_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD3.config->channels[2].callback(&PWMD3); +  CH_IRQ_EPILOGUE(); +} +#endif + +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__) +CH_IRQ_HANDLER(TIMER4_OVF_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD4.config->callback(&PWMD4); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER4_COMPA_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD4.config->channels[0].callback(&PWMD4); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER4_COMPB_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD4.config->channels[1].callback(&PWMD4); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER4_COMPC_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD4.config->channels[2].callback(&PWMD4); +  CH_IRQ_EPILOGUE(); +} +#endif + +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__) +CH_IRQ_HANDLER(TIMER5_OVF_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD5.config->callback(&PWMD5); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER5_COMPA_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD5.config->channels[0].callback(&PWMD5); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER5_COMPB_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD5.config->channels[1].callback(&PWMD5); +  CH_IRQ_EPILOGUE(); +} + +CH_IRQ_HANDLER(TIMER5_COMPC_vect) +{ +  CH_IRQ_PROLOGUE(); +  PWMD5.config->channels[2].callback(&PWMD5); +  CH_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions.                                                */ +/*===========================================================================*/ + +/** + * @brief   Low level PWM driver initialization. + * + * @notapi + */ +void pwm_lld_init(void) +{ +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__) +  pwmObjectInit(&PWMD1); +  TCCR1A = (1 << WGM11) | (1 << WGM10); +  TCCR1B = (0 << WGM13) | (1 << WGM12); +#endif + +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__) +  pwmObjectInit(&PWMD2); +  TCCR2A = (1 << WGM21) | (1 << WGM20); +  TCCR2B = (0 << WGM22); +#endif + +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__) +  pwmObjectInit(&PWMD3); +  TCCR3A = (1 << WGM31) | (1 << WGM30); +  TCCR3B = (0 << WGM33) | (1 << WGM32); +#endif + +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__) +  pwmObjectInit(&PWMD4); +  TCCR4A = (1 << WGM41) | (1 << WGM40); +  TCCR4B = (0 << WGM43) | (1 << WGM42); +#endif + +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__) +  pwmObjectInit(&PWMD5); +  TCCR5A = (1 << WGM51) | (1 << WGM50); +  TCCR5B = (0 << WGM53) | (1 << WGM52); +#endif +} + +/** + * @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_PWM2 || 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); +  } +} + +/** + * @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; +} + +/** + * @brief   Changes the period the PWM peripheral. + * @details This function changes the period of a PWM unit that has already + *          been activated using @p pwmStart(). + * @pre     The PWM unit must have been activated using @p pwmStart(). + * @post    The PWM unit period is changed to the new value. + * @note    The function has effect at the next cycle start. + * @note    If a period is specified that is shorter than the pulse width + *          programmed in one of the channels then the behavior is not + *          guaranteed. + * + * @param[in] pwmp      pointer to a @p PWMDriver object + * @param[in] period    new cycle time in ticks + * + * @notapi + */ +void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) +{ +} + +/** + * @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_PWM2 || 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)); +} + +/** + * @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)); +} + +#endif /* HAL_USE_PWM */ + +/** @} */ diff --git a/os/hal/platforms/AVR/pwm_lld.h b/os/hal/platforms/AVR/pwm_lld.h new file mode 100644 index 000000000..efe60e29d --- /dev/null +++ b/os/hal/platforms/AVR/pwm_lld.h @@ -0,0 +1,212 @@ +/*
 +    ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
 +
 +    Licensed under the Apache License, Version 2.0 (the "License");
 +    you may not use this file except in compliance with the License.
 +    You may obtain a copy of the License at
 +
 +        http://www.apache.org/licenses/LICENSE-2.0
 +
 +    Unless required by applicable law or agreed to in writing, software
 +    distributed under the License is distributed on an "AS IS" BASIS,
 +    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +    See the License for the specific language governing permissions and
 +    limitations under the License.
 +*/
 +
 +/*
 +   This driver is based on the work done by Matteo Serva available at
 +   http://github.com/matteoserva/ChibiOS-AVR
 +*/
 +
 +/**
 + * @file    AVR/pwm_lld.h
 + * @brief   AVR PWM driver subsystem low level driver.
 + *
 + * @addtogroup PWM
 + * @{
 + */
 +
 +#ifndef _PWM_LLD_H_
 +#define _PWM_LLD_H_
 +
 +#if HAL_USE_PWM || defined(__DOXYGEN__)
 +
 +/*===========================================================================*/
 +/* Driver constants.                                                         */
 +/*===========================================================================*/
 +
 +#if !defined(AVR_PWM_USE_PWM1)
 +#define AVR_PWM_USE_PWM1 FALSE
 +#endif
 +#if !defined(AVR_PWM_USE_PWM2)
 +#define AVR_PWM_USE_PWM2 FALSE
 +#endif
 +#if !defined(AVR_PWM_USE_PWM3)
 +#define AVR_PWM_USE_PWM3 FALSE
 +#endif
 +#if !defined(AVR_PWM_USE_PWM4)
 +#define AVR_PWM_USE_PWM4 FALSE
 +#endif
 +#if !defined(AVR_PWM_USE_PWM5)
 +#define AVR_PWM_USE_PWM5 FALSE
 +#endif
 +
 +/*===========================================================================*/
 +/* Driver pre-compile time settings.                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of PWM channels per PWM driver.
 + */
 +#if !defined(PWM_CHANNELS) || defined(__DOXYGEN__)
 +  #if defined(TIMER1_COMPC_vect)
 +    #define PWM_CHANNELS        3
 +  #else
 +    #define PWM_CHANNELS        2
 +  #endif
 +#endif
 +
 +#define MAX_PWM_VALUE           0x3FF
 +
 +/*===========================================================================*/
 +/* Derived constants and error checks.                                       */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* Driver data structures and types.                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @brief PWM mode type.
 + */
 +typedef uint8_t pwmmode_t;
 +
 +/**
 + * @brief   PWM channel type.
 + */
 +typedef uint8_t pwmchannel_t;
 +
 +/**
 + * @brief   PWM counter type.
 + */
 +typedef uint16_t pwmcnt_t;
 +
 +/**
 + * @brief   PWM driver channel configuration structure.
 + * @note    Some architectures may not be able to support the channel mode
 + *          or the callback, in this case the fields are ignored.
 + */
 +typedef struct {
 +  /**
 +   * @brief Channel active logic level.
 +   */
 +  pwmmode_t                 mode;
 +  /**
 +   * @brief Channel callback pointer.
 +   * @note  This callback is invoked on the channel compare event. If set to
 +   *        @p NULL then the callback is disabled.
 +   */
 +  pwmcallback_t             callback;
 +  /* End of the mandatory fields.*/
 +} PWMChannelConfig;
 +
 +/**
 + * @brief   Driver configuration structure.
 + * @note    Implementations may extend this structure to contain more,
 + *          architecture dependent, fields.
 + */
 +typedef struct {
 +  /**
 +   * @brief   Timer clock in Hz.
 +   * @note    The low level can use assertions in order to catch invalid
 +   *          frequency specifications.
 +   */
 +  uint16_t                  frequency;
 +  /**
 +   * @brief   PWM period in ticks.
 +   * @note    The low level can use assertions in order to catch invalid
 +   *          period specifications.
 +   */
 +  pwmcnt_t                  period;
 +  /**
 +   * @brief Periodic callback pointer.
 +   * @note  This callback is invoked on PWM counter reset. If set to
 +   *        @p NULL then the callback is disabled.
 +   */
 +  pwmcallback_t             callback;
 +  /**
 +   * @brief Channels configurations.
 +   */
 +  PWMChannelConfig          channels[PWM_CHANNELS];
 +  /* End of the mandatory fields.*/
 +} PWMConfig;
 +
 +/**
 + * @brief   Structure representing an PWM driver.
 + * @note    Implementations may extend this structure to contain more,
 + *          architecture dependent, fields.
 + */
 +struct PWMDriver {
 +  /**
 +   * @brief Driver state.
 +   */
 +  pwmstate_t                state;
 +  /**
 +   * @brief Current configuration data.
 +   */
 +  const PWMConfig           *config;
 +  /**
 +   * @brief   Current PWM period in ticks.
 +   */
 +  pwmcnt_t                  period;
 +#if defined(PWM_DRIVER_EXT_FIELDS)
 +  PWM_DRIVER_EXT_FIELDS
 +#endif
 +  /* End of the mandatory fields.*/
 +};
 +
 +/*===========================================================================*/
 +/* Driver macros.                                                            */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* External declarations.                                                    */
 +/*===========================================================================*/
 +
 +#if AVR_PWM_USE_PWM1 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD1;
 +#endif
 +#if AVR_PWM_USE_PWM2 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD2;
 +#endif
 +#if AVR_PWM_USE_PWM3 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD3;
 +#endif
 +#if AVR_PWM_USE_PWM4 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD4;
 +#endif
 +#if AVR_PWM_USE_PWM5 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD5;
 +#endif
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +  void pwm_lld_init(void);
 +  void pwm_lld_start(PWMDriver *pwmp);
 +  void pwm_lld_stop(PWMDriver *pwmp);
 +  void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
 +  void pwm_lld_enable_channel(PWMDriver *pwmp,
 +                              pwmchannel_t channel,
 +                              pwmcnt_t width);
 +  void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif /* HAL_USE_PWM */
 +
 +#endif /* _PWM_LLD_H_ */
 +
 +/** @} */
 | 
