]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D4x_EK_IAR/AtmelFiles/libchip_sama5d4x/source/pwmc.c
Core kernel files:
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D4x_EK_IAR / AtmelFiles / libchip_sama5d4x / source / pwmc.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\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
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\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
16  *\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
28  */\r
29 \r
30 /** \addtogroup pwm_module Working with PWM\r
31  * The PWM driver provides the interface to configure and use the PWM\r
32  * peripheral.\r
33  *\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
36  *\r
37  * Before enabling the channels, they must have been configured first.\r
38  * The main settings include:\r
39  * <ul>\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
43  * </ul>\r
44  *\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
49  *\r
50  * For more accurate information, please look at the PWM section of the\r
51  * Datasheet.\r
52  *\r
53  * Related files :\n\r
54  * \ref pwmc.c\n\r
55  * \ref pwmc.h.\n\r
56  */\r
57 /*@{*/\r
58 /*@}*/\r
59 \r
60 /**\r
61  * \file\r
62  *\r
63  * Implementation of the Pulse Width Modulation Controller (PWM) peripheral.\r
64  *\r
65  */\r
66 \r
67 /*----------------------------------------------------------------------------\r
68  *        Headers\r
69  *----------------------------------------------------------------------------*/\r
70 \r
71 #include "chip.h"\r
72 \r
73 #include <stdint.h>\r
74 #include <assert.h>\r
75 \r
76 /*----------------------------------------------------------------------------\r
77  *        Exported functions\r
78  *----------------------------------------------------------------------------*/\r
79 \r
80 /**\r
81  * \brief Configures PWM clocks  \r
82  */\r
83 void PWMC_ConfigureClocks(Pwm* pPwm, uint32_t mode)\r
84 {\r
85     pPwm->PWM_CLK= mode;\r
86 }\r
87 \r
88 /**\r
89  * \brief Enables the given PWM channel.\r
90  *\r
91  * This does NOT enable the corresponding pin;this must be done in the user code.\r
92  *\r
93  * \param channel  Channel number.\r
94  */\r
95 void PWMC_EnableChannel(Pwm* pPwm,uint8_t channel)\r
96 {\r
97     pPwm->PWM_ENA= 0x1ul<<channel;  \r
98 }\r
99 \r
100 /**\r
101  * \brief Disables the given PWM channel.\r
102  *\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
106  *\r
107  * \param channel  Channel number.\r
108  */\r
109 void PWMC_DisableChannel(Pwm* pPwm,uint8_t channel)\r
110 {\r
111     pPwm->PWM_DIS= 0x1ul<<channel;    \r
112 }\r
113 \r
114 /**\r
115  * \brief Enables the selected interrupts sources on a PWMC peripheral. \r
116  */\r
117 void PWMC_EnableChannelIt(Pwm* pPwm,uint8_t channel)\r
118 {\r
119     pPwm->PWM_IER1= 0x1ul<<channel;  \r
120 }\r
121 \r
122 /**\r
123  * \brief Disables the selected interrupts sources on a PWMC peripheral. \r
124  */\r
125 void PWMC_DisableChannelIt(Pwm* pPwm,uint8_t channel)\r
126 {\r
127    pPwm->PWM_IDR1 = 0x1ul<<channel;\r
128 }\r
129 \r
130 /**\r
131  * \brief Configures PWM a channel with the given parameters, basic configure function.\r
132  *\r
133  * The PWM controller must have been clocked in the PMC prior to calling this\r
134  * function.\r
135  * Beware: this function disables the channel. It waits until disable is effective.\r
136  *\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
141  */\r
142 void PWMC_ConfigureChannel(Pwm* pPwm,uint8_t channel,uint32_t mode)\r
143 {\r
144     pPwm->PWM_CH_NUM[channel].PWM_CMR= mode;\r
145 }\r
146 \r
147 /**\r
148  * \brief Sets the period value used by a PWM channel.\r
149  *\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
152  *\r
153  * \param channel Channel number.\r
154  * \param period  Period value.\r
155  */\r
156 void PWMC_SetPeriod( Pwm* pPwm, uint8_t channel, uint16_t period)\r
157 {\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
161     }\r
162     /* Otherwise use update register */\r
163     else {\r
164         pPwm->PWM_CH_NUM[channel].PWM_CPRDUPD = period;\r
165     }\r
166 }\r
167 \r
168 /**\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
173  * period.\r
174  *\r
175  * \param channel  Channel number.\r
176  * \param duty     Duty cycle value.\r
177  */\r
178 void PWMC_SetDutyCycle( Pwm* pPwm, uint8_t channel, uint16_t duty)\r
179 {\r
180     assert(duty <= pPwm->PWM_CH_NUM[channel].PWM_CPRD);\r
181 \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
185     }\r
186     /* Otherwise use update register */\r
187     else {\r
188         pPwm->PWM_CH_NUM[channel].PWM_CDTYUPD = duty;\r
189     }\r
190 }\r
191 \r
192 \r