diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c | 365 | ||||
| -rw-r--r-- | os/hal/ports/NRF51/NRF51822/hal_pwm_lld.h | 276 | ||||
| -rw-r--r-- | os/hal/ports/NRF51/NRF51822/platform.mk | 6 | 
3 files changed, 646 insertions, 1 deletions
| diff --git a/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c b/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c new file mode 100644 index 0000000..6952fcb --- /dev/null +++ b/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c @@ -0,0 +1,365 @@ +/*
 +    ChibiOS/HAL - Copyright (C) 2016 Stéphane D'Alu
 +
 +    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.
 +*/
 +
 +/**
 + * @file    hal_pwm_lld.c
 + * @brief   NRF51 PWM subsystem low level driver source.
 + *
 + * @addtogroup PWM
 + * @{
 + */
 +
 +#include "hal.h"
 +
 +#if HAL_USE_PWM || defined(__DOXYGEN__)
 +
 +/*===========================================================================*/
 +/* Driver local definitions.                                                 */
 +/*===========================================================================*/
 +
 +
 +/*===========================================================================*/
 +/* Driver exported variables.                                                */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   PWMD1 driver identifier.
 + * @note    The driver PWMD1 allocates the timer TIMER0 when enabled.
 + */
 +#if NRF51_PWM_USE_TIMER0 || defined(__DOXYGEN__)
 +PWMDriver PWMD1;
 +#endif
 +
 +/**
 + * @brief   PWMD2 driver identifier.
 + * @note    The driver PWMD2 allocates the timer TIMER1 when enabled.
 + */
 +#if NRF51_PWM_USE_TIMER1 || defined(__DOXYGEN__)
 +PWMDriver PWMD2;
 +#endif
 +
 +/**
 + * @brief   PWMD3 driver identifier.
 + * @note    The driver PWMD3 allocates the timer TIMER2 when enabled.
 + */
 +#if NRF51_PWM_USE_TIMER2 || defined(__DOXYGEN__)
 +PWMDriver PWMD3;
 +#endif
 +
 +/*===========================================================================*/
 +/* Driver local variables and types.                                         */
 +/*===========================================================================*/
 +
 +/*===========================================================================*/
 +/* Driver local functions.                                                   */
 +/*===========================================================================*/
 +
 +static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
 +  // Deal with PWM period 
 +  if (pwmp->timer->EVENTS_COMPARE[pwmp->channels]) {
 +    pwmp->timer->EVENTS_COMPARE[pwmp->channels] = 0;
 + 
 +    if (pwmp->config->callback != NULL) {
 +      pwmp->config->callback(pwmp);
 +    }
 +  }
 +
 +  // Deal with PWM channels     
 +  for (uint8_t n = 0 ; n < pwmp->channels ; n++) {
 +    if (pwmp->timer->EVENTS_COMPARE[n]) {
 +      pwmp->timer->EVENTS_COMPARE[n] = 0;
 +      if (pwmp->config->channels[n].callback != NULL) {
 +	pwmp->config->channels[n].callback(pwmp);
 +      }
 +    }      
 +  }
 +}
 +
 +/*===========================================================================*/
 +/* Driver interrupt handlers.                                                */
 +/*===========================================================================*/
 +
 +#if NRF51_PWM_USE_TIMER0
 +/**
 + * @brief   TIMER0 interrupt handler.
 + *
 + * @isr
 + */
 +OSAL_IRQ_HANDLER(Vector60) {
 +  OSAL_IRQ_PROLOGUE();
 +  pwm_lld_serve_interrupt(&PWMD1);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif /* NRF51_PWM_USE_TIMER0 */
 +
 +#if NRF51_PWM_USE_TIMER1
 +/**
 + * @brief   TIMER1 interrupt handler.
 + *
 + * @isr
 + */
 +OSAL_IRQ_HANDLER(Vector64) {
 +  OSAL_IRQ_PROLOGUE();
 +  pwm_lld_serve_interrupt(&PWMD2);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif /* NRF51_PWM_USE_TIMER1 */
 +
 +#if NRF51_PWM_USE_TIMER2
 +/**
 + * @brief   TIMER2 interrupt handler.
 + *
 + * @isr
 + */
 +OSAL_IRQ_HANDLER(Vector68) {
 +  OSAL_IRQ_PROLOGUE();
 +  pwm_lld_serve_interrupt(&PWMD3);
 +  OSAL_IRQ_EPILOGUE();
 +}
 +#endif /* NRF51_PWM_USE_TIMER2 */
 +
 +/*===========================================================================*/
 +/* Driver exported functions.                                                */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Low level PWM driver initialization.
 + *
 + * @notapi
 + */
 +void pwm_lld_init(void) {
 +
 +#if NRF51_PWM_USE_TIMER0
 +  pwmObjectInit(&PWMD1);
 +  PWMD1.channels = PWM_CHANNELS;
 +  PWMD1.timer = NRF_TIMER0;
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER1
 +  pwmObjectInit(&PWMD2);
 +  PWMD2.channels = PWM_CHANNELS;
 +  PWMD2.timer = NRF_TIMER1;
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER2
 +  pwmObjectInit(&PWMD3);
 +  PWMD3.channels = PWM_CHANNELS;
 +  PWMD3.timer = NRF_TIMER2;
 +#endif
 +}
 +
 +/**
 + * @brief   Configures and activates the PWM peripheral.
 + * @note    Starting a driver that is already in the @p PWM_READY state
 + *          disables all the active channels.
 + *
 + * @param[in] pwmp      pointer to a @p PWMDriver object
 + *
 + * @notapi
 + */
 +void pwm_lld_start(PWMDriver *pwmp) {
 +  // Prescaler value calculation: ftimer = 16MHz / 2^PRESCALER
 +  uint16_t psc_ratio = NRF51_HFCLK_FREQUENCY / pwmp->config->frequency;
 +  // Prescaler ratio must be between 1 and 512, and a power of two.
 +  osalDbgAssert(psc_ratio <= 512 && !(psc_ratio & (psc_ratio - 1)),
 +		"invalid frequency");
 +  // Prescaler value as a power of 2, must be 0..9
 +  uint32_t psc_value;
 +  for (psc_value = 0; psc_value < 10; psc_value++)
 +      if (psc_ratio == (unsigned)(1 << psc_value))
 +	  break;
 +
 +  
 +  // Configure as 16bits timer (only TIMER0 support 32bits)
 +  pwmp->timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
 +  pwmp->timer->MODE = TIMER_MODE_MODE_Timer;
 +
 +  // With clear shortcuts for period
 +  pwmp->timer->SHORTS =
 +      0x1UL << (TIMER_SHORTS_COMPARE0_CLEAR_Pos + pwmp->channels);
 +
 +  // Disable and reset interrupts for compare events
 +  pwmp->timer->INTENCLR = (TIMER_INTENCLR_COMPARE0_Msk |
 +			   TIMER_INTENCLR_COMPARE1_Msk |
 +			   TIMER_INTENCLR_COMPARE2_Msk |
 +			   TIMER_INTENCLR_COMPARE3_Msk );
 +  pwmp->timer->EVENTS_COMPARE[0] = 0;
 +  pwmp->timer->EVENTS_COMPARE[1] = 0;
 +  pwmp->timer->EVENTS_COMPARE[2] = 0;
 +  pwmp->timer->EVENTS_COMPARE[3] = 0;
 +
 +  // Set prescaler
 +  pwmp->timer->PRESCALER = psc_value;
 +
 +  // Set period
 +  pwmp->timer->CC[pwmp->channels] = pwmp->period; 
 +
 +  // Clear everything
 +  pwmp->timer->TASKS_CLEAR = 1;
 +
 +
 +  // Enable interrupt
 +#if NRF51_PWM_USE_TIMER0
 +  if (&PWMD1 == pwmp) {
 +    nvicEnableVector(TIMER0_IRQn, NRF51_PWM_TIMER0_PRIORITY);
 +  }
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER1
 +  if (&PWMD2 == pwmp) {
 +    nvicEnableVector(TIMER1_IRQn, NRF51_PWM_TIMER1_PRIORITY);
 +  }
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER2
 +  if (&PWMD3 == pwmp) {
 +    nvicEnableVector(TIMER2_IRQn, NRF51_PWM_TIMER2_PRIORITY);
 +  }
 +#endif
 +
 +  // Start timer
 +  pwmp->timer->TASKS_START = 1;
 +}
 +
 +/**
 + * @brief   Deactivates the PWM peripheral.
 + *
 + * @param[in] pwmp      pointer to a @p PWMDriver object
 + *
 + * @notapi
 + */
 +void pwm_lld_stop(PWMDriver *pwmp) {
 +  pwmp->timer->TASKS_STOP = 1;
 +
 +#if NRF51_PWM_USE_TIMER0
 +  if (&PWMD1 == pwmp) {
 +    nvicDisableVector(TIMER0_IRQn);
 +  }
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER1
 +  if (&PWMD2 == pwmp) {
 +    nvicDisableVector(TIMER1_IRQn);
 +  }
 +#endif
 +
 +#if NRF51_PWM_USE_TIMER2
 +  if (&PWMD3 == pwmp) {
 +    nvicDisableVector(TIMER2_IRQn);
 +  }
 +#endif
 +}
 +
 +/**
 + * @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    The function has effect at the next cycle start.
 + * @note    Channel notification is not enabled.
 + *
 + * @param[in] pwmp      pointer to a @p PWMDriver object
 + * @param[in] channel   PWM channel identifier (0...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) {
 +  pwmp->timer->CC[channel] = width;
 +}
 +
 +/**
 + * @brief   Disables a PWM channel and its notification.
 + * @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    The function has effect at the next cycle start.
 + *
 + * @param[in] pwmp      pointer to a @p PWMDriver object
 + * @param[in] channel   PWM channel identifier (0...channels-1)
 + *
 + * @notapi
 + */
 +void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
 +  pwmp->timer->CC[channel] = 0;
 +}
 +
 +/**
 + * @brief   Enables the periodic activation edge notification.
 + * @pre     The PWM unit must have been activated using @p pwmStart().
 + * @note    If the notification is already enabled then the call has no effect.
 + *
 + * @param[in] pwmp      pointer to a @p PWMDriver object
 + *
 + * @notapi
 + */
 +void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
 +  pwmp->timer->INTENSET =
 +      0x1UL << (TIMER_INTENSET_COMPARE0_Pos + pwmp->channels);
 +}
 +
 +/**
 + * @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) {
 +  pwmp->timer->INTENCLR =
 +      0x1UL << (TIMER_INTENCLR_COMPARE0_Pos + pwmp->channels);
 +}
 +
 +/**
 + * @brief   Enables 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 enabled 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_enable_channel_notification(PWMDriver *pwmp,
 +                                         pwmchannel_t channel) {
 +  pwmp->timer->INTENSET =
 +      0x1UL << (TIMER_INTENSET_COMPARE0_Pos + channel);
 +}
 +
 +/**
 + * @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) {
 +  pwmp->timer->INTENCLR =
 +      0x1UL << (TIMER_INTENCLR_COMPARE0_Pos + channel);
 +}
 +
 +#endif /* HAL_USE_PWM */
 +
 +/** @} */
 diff --git a/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.h b/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.h new file mode 100644 index 0000000..0ddd65c --- /dev/null +++ b/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.h @@ -0,0 +1,276 @@ +/*
 +    ChibiOS/HAL - Copyright (C) 2016 Stéphane D'Alu
 +
 +    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.
 +*/
 +
 +/**
 + * @file    hal_pwm_lld.h
 + * @brief   NRF51 PWM subsystem low level driver header.
 + *
 + * @addtogroup PWM
 + * @{
 + */
 +
 +#ifndef HAL_PWM_LLD_H_
 +#define HAL_PWM_LLD_H_
 +
 +#if HAL_USE_PWM || defined(__DOXYGEN__)
 +
 +/*===========================================================================*/
 +/* Driver constants.                                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Number of PWM channels per PWM driver.
 + */
 +#define PWM_CHANNELS                            3
 +
 +
 +#define PWM_FREQUENCY_16MHZ  16000000 /** @brief   16MHz */
 +#define PWM_FREQUENCY_8MHZ    8000000 /** @brief    8MHz */
 +#define PWM_FREQUENCY_4MHZ    4000000 /** @brief    4MHz */
 +#define PWM_FREQUENCY_2MHZ    2000000 /** @brief    2MHz */
 +#define PWM_FREQUENCY_1MHZ    1000000 /** @brief    1MHz */
 +#define PWM_FREQUENCY_500KHZ   500000 /** @brief  500kHz */
 +#define PWM_FREQUENCY_250KHZ   250000 /** @brief  250kHz */
 +#define PWM_FREQUENCY_125KHZ   125000 /** @brief  125kHz */
 +#define PWM_FREQUENCY_62500HZ   62500 /** @brief 62500Hz */
 +#define PWM_FREQUENCY_31250HZ   31250 /** @brief 31250Hz */
 +
 +/*===========================================================================*/
 +/* Driver pre-compile time settings.                                         */
 +/*===========================================================================*/
 +
 +#if !defined(NRF51_PWM_USE_TIMER0)
 +#define NRF51_PWM_USE_TIMER0 FALSE
 +#endif
 +
 +#if !defined(NRF51_PWM_USE_TIMER1)
 +#define NRF51_PWM_USE_TIMER1 FALSE
 +#endif
 +
 +#if !defined(NRF51_PWM_USE_TIMER2)
 +#define NRF51_PWM_USE_TIMER2 FALSE
 +#endif
 +
 +/**
 + * @brief   TIMER0 interrupt priority level setting.
 + */
 +#if !defined(NRF51_PWM_TIMER0_PRIORITY) || defined(__DOXYGEN__)
 +#define NRF51_PWM_TIMER0_PRIORITY        12
 +#endif
 +
 +/**
 + * @brief   TIMER1 interrupt priority level setting.
 + */
 +#if !defined(NRF51_PWM_TIMER1_PRIORITY) || defined(__DOXYGEN__)
 +#define NRF51_PWM_TIMER1_PRIORITY        12
 +#endif
 +
 +/**
 + * @brief   TIMER2 interrupt priority level setting.
 + */
 +#if !defined(NRF51_PWM_TIMER2_PRIORITY) || defined(__DOXYGEN__)
 +#define NRF51_PWM_TIMER2_PRIORITY        12
 +#endif
 +
 +/** @} */
 +
 +/**
 + * @name    Configuration options
 + * @{
 + */
 +/** @} */
 +
 +/*===========================================================================*/
 +/* Configuration checks.                                                     */
 +/*===========================================================================*/
 +
 +#if !NRF51_PWM_USE_TIMER0 && !NRF51_PWM_USE_TIMER1 && !NRF51_PWM_USE_TIMER2
 +#error "PWM driver activated but no TIMER peripheral assigned"
 +#endif
 +
 +#if (NRF51_ST_USE_TIMER0 == TRUE) && (NRF51_PWM_USE_TIMER0 == TRUE)
 +#error "TIMER0 used for ST and PWM"
 +#endif
 +
 +/*===========================================================================*/
 +/* Driver data structures and types.                                         */
 +/*===========================================================================*/
 +
 +/**
 + * @brief   Type of a PWM mode.
 + */
 +typedef uint32_t pwmmode_t;
 +
 +/**
 + * @brief   Type of a PWM channel.
 + */
 +typedef uint8_t pwmchannel_t;
 +
 +/**
 + * @brief   Type of a channels mask.
 + */
 +typedef uint32_t pwmchnmsk_t;
 +
 +/**
 + * @brief   Type of a PWM counter.
 + */
 +typedef uint16_t pwmcnt_t;
 +
 +/**
 + * @brief   Type of a PWM driver channel configuration structure.
 + */
 +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   Type of a PWM driver configuration structure.
 + */
 +typedef struct {
 +  /**
 +   * @brief   Timer clock in Hz.
 +   * @note    The low level can use assertions in order to catch invalid
 +   *          frequency specifications.
 +   */
 +  uint32_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 a PWM driver.
 + */
 +struct PWMDriver {
 +  /**
 +   * @brief Driver state.
 +   */
 +  pwmstate_t                state;
 +  /**
 +   * @brief Current driver configuration data.
 +   */
 +  const PWMConfig           *config;
 +  /**
 +   * @brief   Current PWM period in ticks.
 +   */
 +  pwmcnt_t                  period;
 +  /**
 +   * @brief   Mask of the enabled channels.
 +   */
 +  pwmchnmsk_t               enabled;
 +  /**
 +   * @brief   Number of channels in this instance.
 +   */
 +  pwmchannel_t              channels;
 +#if defined(PWM_DRIVER_EXT_FIELDS)
 +  PWM_DRIVER_EXT_FIELDS
 +#endif
 +  /* End of the mandatory fields.*/
 +  /**
 +   * @brief Pointer to the TIMER registers block.
 +   */
 +  NRF_TIMER_Type           *timer;
 +};
 +
 +/*===========================================================================*/
 +/* Driver macros.                                                            */
 +/*===========================================================================*/
 +
 +/**
 + * @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
 + */
 +#define pwm_lld_change_period(pwmp, period)                             \
 +  do { 									\
 +    (pwmp)->timer->CC[(pwmp)->channels] = ((period) - 1);		\
 +  } while(0)
 +
 +/*===========================================================================*/
 +/* External declarations.                                                    */
 +/*===========================================================================*/
 +
 +#if NRF51_PWM_USE_TIMER0 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD1;
 +#endif
 +#if NRF51_PWM_USE_TIMER1 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD2;
 +#endif
 +#if NRF51_PWM_USE_TIMER2 || defined(__DOXYGEN__)
 +extern PWMDriver PWMD3;
 +#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_enable_channel(PWMDriver *pwmp,
 +                              pwmchannel_t channel,
 +                              pwmcnt_t width);
 +  void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
 +  void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
 +  void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
 +  void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
 +                                           pwmchannel_t channel);
 +  void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
 +                                            pwmchannel_t channel);
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif /* HAL_USE_PWM */
 +
 +#endif /* HAL_PWM_LLD_H_ */
 +
 +/** @} */
 diff --git a/os/hal/ports/NRF51/NRF51822/platform.mk b/os/hal/ports/NRF51/NRF51822/platform.mk index fbe977e..b937e39 100644 --- a/os/hal/ports/NRF51/NRF51822/platform.mk +++ b/os/hal/ports/NRF51/NRF51822/platform.mk @@ -34,6 +34,9 @@ endif  ifneq ($(findstring HAL_USE_RNG TRUE,$(HALCONF)),)  PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_rng_lld.c  endif +ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),) +PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c +endif  else  PLATFORMSRC  = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \                 ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_lld.c \ @@ -47,7 +50,8 @@ PLATFORMSRC  = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \                 ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_adc_lld.c \                 ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_gpt_lld.c \                 ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_wdg_lld.c \ -               ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_rng_lld.c +               ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_rng_lld.c \ +               ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_pwm_lld.c  endif  # Required include directories | 
