1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
30 /** \addtogroup pwm_module Working with PWM
\r
31 * The PWM driver provides the interface to configure and use the PWM
\r
34 * The PWM macrocell controls square output waveforms of 4 channels.
\r
35 * Characteristics of output waveforms such as period, duty-cycle can be configured.\n
\r
37 * Before enabling the channels, they must have been configured first.
\r
38 * The main settings include:
\r
40 * <li>Configuration of the clock generator.</li>
\r
41 * <li>Selection of the clock for each channel.</li>
\r
42 * <li>Configuration of output waveform characteristics, such as period, duty-cycle etc.</li>
\r
45 * After the channels is enabled, the user must use respective update registers
\r
46 * to change the wave characteristics to prevent unexpected output waveform.
\r
47 * i.e. PWM_CUPDx register should be used if user want to change duty-cycle
\r
48 * when the channel is enabled.
\r
50 * For more accurate information, please look at the PWM section of the
\r
63 * Implementation of the Pulse Width Modulation Controller (PWM) peripheral.
\r
67 /*----------------------------------------------------------------------------
\r
69 *----------------------------------------------------------------------------*/
\r
76 /*----------------------------------------------------------------------------
\r
77 * Exported functions
\r
78 *----------------------------------------------------------------------------*/
\r
81 * \brief Configures PWM clocks
\r
83 void PWMC_ConfigureClocks(Pwm* pPwm, uint32_t mode)
\r
85 pPwm->PWM_CLK= mode;
\r
89 * \brief Enables the given PWM channel.
\r
91 * This does NOT enable the corresponding pin;this must be done in the user code.
\r
93 * \param channel Channel number.
\r
95 void PWMC_EnableChannel(Pwm* pPwm,uint8_t channel)
\r
97 pPwm->PWM_ENA= 0x1ul<<channel;
\r
101 * \brief Disables the given PWM channel.
\r
103 * Beware, channel will be effectively disabled at the end of the current period.
\r
104 * Application can check channel is disabled using the following wait loop:
\r
105 * while ((PWM->PWM_SR & (1 << channel)) != 0);
\r
107 * \param channel Channel number.
\r
109 void PWMC_DisableChannel(Pwm* pPwm,uint8_t channel)
\r
111 pPwm->PWM_DIS= 0x1ul<<channel;
\r
115 * \brief Enables the selected interrupts sources on a PWMC peripheral.
\r
117 void PWMC_EnableChannelIt(Pwm* pPwm,uint8_t channel)
\r
119 pPwm->PWM_IER1= 0x1ul<<channel;
\r
123 * \brief Disables the selected interrupts sources on a PWMC peripheral.
\r
125 void PWMC_DisableChannelIt(Pwm* pPwm,uint8_t channel)
\r
127 pPwm->PWM_IDR1 = 0x1ul<<channel;
\r
131 * \brief Configures PWM a channel with the given parameters, basic configure function.
\r
133 * The PWM controller must have been clocked in the PMC prior to calling this
\r
135 * Beware: this function disables the channel. It waits until disable is effective.
\r
137 * \param channel Channel number.
\r
138 * \param prescaler Channel prescaler.
\r
139 * \param alignment Channel alignment.
\r
140 * \param polarity Channel polarity.
\r
142 void PWMC_ConfigureChannel(Pwm* pPwm,uint8_t channel,uint32_t mode)
\r
144 pPwm->PWM_CH_NUM[channel].PWM_CMR= mode;
\r
148 * \brief Sets the period value used by a PWM channel.
\r
150 * This function writes directly to the CPRD register if the channel is disabled;
\r
151 * otherwise, it uses the update register CPRDUPD.
\r
153 * \param channel Channel number.
\r
154 * \param period Period value.
\r
156 void PWMC_SetPeriod( Pwm* pPwm, uint8_t channel, uint16_t period)
\r
158 /* If channel is disabled, write to CPRD */
\r
159 if ((pPwm->PWM_SR & (1 << channel)) == 0) {
\r
160 pPwm->PWM_CH_NUM[channel].PWM_CPRD = period;
\r
162 /* Otherwise use update register */
\r
164 pPwm->PWM_CH_NUM[channel].PWM_CPRDUPD = period;
\r
169 * \brief Sets the duty cycle used by a PWM channel.
\r
170 * This function writes directly to the CDTY register if the channel is disabled;
\r
171 * otherwise it uses the update register CDTYUPD.
\r
172 * Note that the duty cycle must always be inferior or equal to the channel
\r
175 * \param channel Channel number.
\r
176 * \param duty Duty cycle value.
\r
178 void PWMC_SetDutyCycle( Pwm* pPwm, uint8_t channel, uint16_t duty)
\r
180 assert(duty <= pPwm->PWM_CH_NUM[channel].PWM_CPRD);
\r
182 /* If channel is disabled, write to CDTY */
\r
183 if ((pPwm->PWM_SR & (1 << channel)) == 0) {
\r
184 pPwm->PWM_CH_NUM[channel].PWM_CDTY = duty;
\r
186 /* Otherwise use update register */
\r
188 pPwm->PWM_CH_NUM[channel].PWM_CDTYUPD = duty;
\r