2 * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: pwm.c,v 1.8.4.8 2008-04-06 17:33:57 zer0 Exp $
22 /* Droids-corp, Eirbot, Microb Technology 2005 - Zer0
23 * Implementation for PWM
26 * \brief Implementation for the PWM module.
28 * \todo Test the module.
30 * \test The modul fonctions and had been tested by Lamygalle.
32 * This module provides functions for using a pwm
39 #include <aversive/parts.h>
40 #include <aversive/timers.h>
42 #include <pwm_config.h>
44 #include "timers_synch.h"
46 #if _PWM_CONFIG_VERSION_ != 2
47 #warning "You are using an old version of pwm_config.h file"
48 #warning "_PWM_CONFIG_VERSION_ is != 2"
49 #warning "Look in modules/base/pwm/config directory to import changes"
50 #warning "You should now use TIMERx_PRESCALER_DIV_XX from"
51 #warning "include/aversive/parts.h that is arch specific"
57 #if (TIMER1_MODE == TIMER_16_MODE_PWM_10)
58 #define TIMER1_PWM_BITS 10
59 #elif (TIMER1_MODE == TIMER_16_MODE_PWM_9)
60 #define TIMER1_PWM_BITS 9
61 #elif (TIMER1_MODE == TIMER_16_MODE_PWM_8)
62 #define TIMER1_PWM_BITS 8
64 #error TIMER1 mode not valid, check pwm_config.h
71 #if (TIMER3_MODE == TIMER_16_MODE_PWM_10)
72 #define TIMER3_PWM_BITS 10
73 #elif (TIMER3_MODE == TIMER_16_MODE_PWM_9)
74 #define TIMER3_PWM_BITS 9
75 #elif (TIMER3_MODE == TIMER_16_MODE_PWM_8)
76 #define TIMER3_PWM_BITS 8
78 #error TIMER3 mode not valid, check pwm_config.h
83 #if (PWM0_MODE & PWM_SIGNED)
84 #define pwm0_init_ddr() \
85 sbi(DDR(PWM0_SIGN_PORT), PWM0_SIGN_BIT); \
86 cbi(PWM0_SIGN_PORT, PWM0_SIGN_BIT);
87 #if (PWM0_MODE & PWM_SIGN_INVERTED)
88 #define pwm0_sign_set() sbi(PWM0_SIGN_PORT, PWM0_SIGN_BIT);
89 #define pwm0_sign_reset() cbi(PWM0_SIGN_PORT, PWM0_SIGN_BIT);
90 #else /* (PWM0_MODE & PWM_SIGN_INVERTED) */
91 #define pwm0_sign_set() cbi(PWM0_SIGN_PORT, PWM0_SIGN_BIT);
92 #define pwm0_sign_reset() sbi(PWM0_SIGN_PORT, PWM0_SIGN_BIT);
93 #endif /* (PWM0_MODE & PWM_SIGN_INVERTED) */
94 #else /* (PWM0_MODE & PWM_SIGNED) */
95 #define pwm0_init_ddr()
96 #define pwm0_sign_set()
97 #define pwm0_sign_reset()
98 #endif /* (PWM0_MODE & PWM_SIGNED) */
100 #if (PWM1A_MODE & PWM_SIGNED)
101 #define pwm1A_init_ddr() \
102 sbi(DDR(PWM1A_SIGN_PORT), PWM1A_SIGN_BIT); \
103 cbi(PWM1A_SIGN_PORT, PWM1A_SIGN_BIT);
104 #if (PWM1A_MODE & PWM_SIGN_INVERTED)
105 #define pwm1A_sign_set() sbi(PWM1A_SIGN_PORT, PWM1A_SIGN_BIT);
106 #define pwm1A_sign_reset() cbi(PWM1A_SIGN_PORT, PWM1A_SIGN_BIT);
107 #else /* (PWM1A_MODE & PWM_SIGN_INVERTED) */
108 #define pwm1A_sign_set() cbi(PWM1A_SIGN_PORT, PWM1A_SIGN_BIT);
109 #define pwm1A_sign_reset() sbi(PWM1A_SIGN_PORT, PWM1A_SIGN_BIT);
110 #endif /* (PWM1A_MODE & PWM_SIGN_INVERTED) */
111 #else /* (PWM1A_MODE & PWM_SIGNED) */
112 #define pwm1A_init_ddr()
113 #define pwm1A_sign_set()
114 #define pwm1A_sign_reset()
115 #endif /* (PWM1A_MODE & PWM_SIGNED) */
117 #if (PWM1B_MODE & PWM_SIGNED)
118 #define pwm1B_init_ddr() \
119 sbi(DDR(PWM1B_SIGN_PORT), PWM1B_SIGN_BIT); \
120 cbi(PWM1B_SIGN_PORT, PWM1B_SIGN_BIT);
121 #if (PWM1B_MODE & PWM_SIGN_INVERTED)
122 #define pwm1B_sign_set() sbi(PWM1B_SIGN_PORT, PWM1B_SIGN_BIT);
123 #define pwm1B_sign_reset() cbi(PWM1B_SIGN_PORT, PWM1B_SIGN_BIT);
124 #else /* (PWM1B_MODE & PWM_SIGN_INVERTED) */
125 #define pwm1B_sign_set() cbi(PWM1B_SIGN_PORT, PWM1B_SIGN_BIT);
126 #define pwm1B_sign_reset() sbi(PWM1B_SIGN_PORT, PWM1B_SIGN_BIT);
127 #endif /* (PWM1B_MODE & PWM_SIGN_INVERTED) */
128 #else /* (PWM1B_MODE & PWM_SIGNED) */
129 #define pwm1B_init_ddr()
130 #define pwm1B_sign_set()
131 #define pwm1B_sign_reset()
132 #endif /* (PWM1B_MODE & PWM_SIGNED) */
134 #if (PWM1C_MODE & PWM_SIGNED)
135 #define pwm1C_init_ddr() \
136 sbi(DDR(PWM1C_SIGN_PORT), PWM1C_SIGN_BIT); \
137 cbi(PWM1C_SIGN_PORT, PWM1C_SIGN_BIT);
138 #if (PWM1C_MODE & PWM_SIGN_INVERTED)
139 #define pwm1C_sign_set() sbi(PWM1C_SIGN_PORT, PWM1C_SIGN_BIT);
140 #define pwm1C_sign_reset() cbi(PWM1C_SIGN_PORT, PWM1C_SIGN_BIT);
141 #else /* (PWM1C_MODE & PWM_SIGN_INVERTED) */
142 #define pwm1C_sign_set() cbi(PWM1C_SIGN_PORT, PWM1C_SIGN_BIT);
143 #define pwm1C_sign_reset() sbi(PWM1C_SIGN_PORT, PWM1C_SIGN_BIT);
144 #endif /* (PWM1C_MODE & PWM_SIGN_INVERTED) */
145 #else /* (PWM1C_MODE & PWM_SIGNED) */
146 #define pwm1C_init_ddr()
147 #define pwm1C_sign_set()
148 #define pwm1C_sign_reset()
149 #endif /* (PWM1C_MODE & PWM_SIGNED) */
151 #if (PWM2_MODE & PWM_SIGNED)
152 #define pwm2_init_ddr() \
153 sbi(DDR(PWM2_SIGN_PORT), PWM2_SIGN_BIT); \
154 cbi(PWM2_SIGN_PORT, PWM2_SIGN_BIT);
155 #if (PWM2_MODE & PWM_SIGN_INVERTED)
156 #define pwm2_sign_set() sbi(PWM2_SIGN_PORT, PWM2_SIGN_BIT);
157 #define pwm2_sign_reset() cbi(PWM2_SIGN_PORT, PWM2_SIGN_BIT);
158 #else /* (PWM2_MODE & PWM_SIGN_INVERTED) */
159 #define pwm2_sign_set() cbi(PWM2_SIGN_PORT, PWM2_SIGN_BIT);
160 #define pwm2_sign_reset() sbi(PWM2_SIGN_PORT, PWM2_SIGN_BIT);
161 #endif /* (PWM2_MODE & PWM_SIGN_INVERTED) */
162 #else /* (PWM2_MODE & PWM_SIGNED) */
163 #define pwm2_init_ddr()
164 #define pwm2_sign_set()
165 #define pwm2_sign_reset()
166 #endif /* (PWM2_MODE & PWM_SIGNED) */
168 #if (PWM3A_MODE & PWM_SIGNED)
169 #define pwm3A_init_ddr() \
170 sbi(DDR(PWM3A_SIGN_PORT), PWM3A_SIGN_BIT); \
171 cbi(PWM3A_SIGN_PORT, PWM3A_SIGN_BIT);
172 #if (PWM3A_MODE & PWM_SIGN_INVERTED)
173 #define pwm3A_sign_set() sbi(PWM3A_SIGN_PORT, PWM3A_SIGN_BIT);
174 #define pwm3A_sign_reset() cbi(PWM3A_SIGN_PORT, PWM3A_SIGN_BIT);
175 #else /* (PWM3A_MODE & PWM_SIGN_INVERTED) */
176 #define pwm3A_sign_set() cbi(PWM3A_SIGN_PORT, PWM3A_SIGN_BIT);
177 #define pwm3A_sign_reset() sbi(PWM3A_SIGN_PORT, PWM3A_SIGN_BIT);
178 #endif /* (PWM3A_MODE & PWM_SIGN_INVERTED) */
179 #else /* (PWM3A_MODE & PWM_SIGNED) */
180 #define pwm3A_init_ddr()
181 #define pwm3A_sign_set()
182 #define pwm3A_sign_reset()
183 #endif /* (PWM3A_MODE & PWM_SIGNED) */
185 #if (PWM3B_MODE & PWM_SIGNED)
186 #define pwm3B_init_ddr() \
187 sbi(DDR(PWM3B_SIGN_PORT), PWM3B_SIGN_BIT); \
188 cbi(PWM3B_SIGN_PORT, PWM3B_SIGN_BIT);
189 #if (PWM3B_MODE & PWM_SIGN_INVERTED)
190 #define pwm3B_sign_set() sbi(PWM3B_SIGN_PORT, PWM3B_SIGN_BIT);
191 #define pwm3B_sign_reset() cbi(PWM3B_SIGN_PORT, PWM3B_SIGN_BIT);
192 #else /* (PWM3B_MODE & PWM_SIGN_INVERTED) */
193 #define pwm3B_sign_set() cbi(PWM3B_SIGN_PORT, PWM3B_SIGN_BIT);
194 #define pwm3B_sign_reset() sbi(PWM3B_SIGN_PORT, PWM3B_SIGN_BIT);
195 #endif /* (PWM3B_MODE & PWM_SIGN_INVERTED) */
196 #else /* (PWM3B_MODE & PWM_SIGNED) */
197 #define pwm3B_init_ddr()
198 #define pwm3B_sign_set()
199 #define pwm3B_sign_reset()
200 #endif /* (PWM3B_MODE & PWM_SIGNED) */
202 #if (PWM3C_MODE & PWM_SIGNED)
203 #define pwm3C_init_ddr() \
204 sbi(DDR(PWM3C_SIGN_PORT), PWM3C_SIGN_BIT); \
205 cbi(PWM3C_SIGN_PORT, PWM3C_SIGN_BIT);
206 #if (PWM3C_MODE & PWM_SIGN_INVERTED)
207 #define pwm3C_sign_set() sbi(PWM3C_SIGN_PORT, PWM3C_SIGN_BIT);
208 #define pwm3C_sign_reset() cbi(PWM3C_SIGN_PORT, PWM3C_SIGN_BIT);
209 #else /* (PWM3C_MODE & PWM_SIGN_INVERTED) */
210 #define pwm3C_sign_set() cbi(PWM3C_SIGN_PORT, PWM3C_SIGN_BIT);
211 #define pwm3C_sign_reset() sbi(PWM3C_SIGN_PORT, PWM3C_SIGN_BIT);
212 #endif /* (PWM3C_MODE & PWM_SIGN_INVERTED) */
213 #else /* (PWM3C_MODE & PWM_SIGNED) */
214 #define pwm3C_init_ddr()
215 #define pwm3C_sign_set()
216 #define pwm3C_sign_reset()
217 #endif /* (PWM3C_MODE & PWM_SIGNED) */
220 #define pwm_invert_value(mode, value) \
222 if ( mode & PWM_SPECIAL_SIGN_MODE ) { \
223 value = value & PWM_MAX; \
231 #define pwm_timer_8bits_init(n, mode, prescale, timer_mode) \
233 TCCR##n = ( ( ( timer_mode & 0x01 )?( 1 << WGM##n##0 ):0 ) | \
234 ( ( timer_mode & 0x02 )?( 1 << WGM##n##1 ):0 ) | \
235 ( ( prescale << CS##n##0 ) ) ); \
236 if(mode & PWM_REVERSE) { \
237 TCCR##n = ( ( (TCCR##n) & (~(0x03 << COM##n##0)) ) | \
238 (0x01 << COM##n##0) ); \
241 TCCR##n = ( ( (TCCR##n) & (~(0x03 << COM##n##0)) ) | \
242 (0x02 << COM##n##0) ); \
245 sbi(OCR##n##_DDR,OCR##n##_BIT); \
246 pwm##n##_init_ddr(); \
249 /***********************************************************/
252 #define pwm_timer_16bits_init(n, m, mode, prescale, timer_mode) \
254 TCCR##n##A = (TCCR##n##A | \
255 ( ( timer_mode & 0x01 )?( 1 << WGM##n##0 ):0 ) | \
256 ( ( timer_mode & 0x02 )?( 1 << WGM##n##1 ):0 ) ) ; \
258 TCCR##n##B = ( ( ( timer_mode & 0x04 )?( 1 << WGM##n##2 ):0 ) | \
259 ( ( timer_mode & 0x08 )?( 1 << WGM##n##3 ):0 ) | \
260 ( ( prescale << CS##n##0 ) ) ); \
261 if(mode & PWM_REVERSE) { \
262 TCCR##n##A = ( ( (TCCR##n##A) & \
263 (~(0x03 << COM##n##m##0)) ) | \
264 (0x01 << COM##n##m##0) ); \
267 TCCR##n##A = ( ( (TCCR##n##A) & \
268 (~(0x03 << COM##n##m##0)) ) | \
269 (0x02 << COM##n##m##0) ); \
272 sbi(OCR##n##m##_DDR,OCR##n##m##_BIT); \
273 pwm##n##m##_init_ddr(); \
276 /***********************************************************/
279 #define pwm_timer_8bits_set(n, value, mode) \
281 MAX(value, PWM_MAX); \
282 if ( mode & PWM_SIGNED ) { \
283 MIN(value, PWM_MIN); \
285 pwm##n##_sign_set(); \
286 pwm_invert_value(mode, value); \
289 pwm##n##_sign_reset(); \
295 OCR##n =(uint8_t) ( value >> ( PWM_SIGNIFICANT_BITS - 8 )); \
298 /***********************************************************/
301 #define pwm_timer_16bits_set(n, m, value, mode) \
303 MAX(value, PWM_MAX); \
304 if ( mode & PWM_SIGNED ) { \
305 MIN(value, PWM_MIN); \
307 pwm##n##m##_sign_set(); \
308 pwm_invert_value(mode, value); \
311 pwm##n##m##_sign_reset(); \
317 OCR##n##m = ( value >> ( PWM_SIGNIFICANT_BITS \
318 - TIMER##n##_PWM_BITS )) ; \
322 /***********************************************************/
324 #if (defined PWM0_NUM) && (defined PWM0_ENABLED)
325 void pwm_init_0(void)
330 pwm_timer_8bits_init(0,PWM0_MODE,TIMER0_PRESCALE, TIMER0_MODE);
334 /***********************************************************/
336 void pwm_set_0(int16_t value)
341 pwm_timer_8bits_set(0,value,PWM0_MODE);
344 #endif // (defined PWM0_NUM) && (defined PWM0_ENABLED)
346 /***********************************************************/
349 /***********************************************************/
351 #if (defined PWM1A_NUM) && (defined PWM1A_ENABLED)
352 void pwm_init_1A(void)
357 pwm_timer_16bits_init(1,A,PWM1A_MODE,TIMER1_PRESCALE, TIMER1_MODE);
362 /***********************************************************/
364 void pwm_set_1A(int16_t value)
369 pwm_timer_16bits_set(1,A,value,PWM1A_MODE);
372 #endif // (defined PWM1A_NUM) && (defined PWM1A_ENABLED)
376 /***********************************************************/
379 /***********************************************************/
381 #if (defined PWM1B_NUM) && (defined PWM1B_ENABLED)
382 void pwm_init_1B(void)
387 pwm_timer_16bits_init(1,B,PWM1B_MODE,TIMER1_PRESCALE, TIMER1_MODE);
392 /***********************************************************/
394 void pwm_set_1B(int16_t value)
399 pwm_timer_16bits_set(1,B,value,PWM1B_MODE);
402 #endif // (defined PWM1B_NUM) && (defined PWM1B_ENABLED)
406 /***********************************************************/
409 /***********************************************************/
411 #if (defined PWM1C_NUM) && (defined PWM1C_ENABLED)
412 void pwm_init_1C(void)
417 pwm_timer_16bits_init(1,C,PWM1C_MODE,TIMER1_PRESCALE, TIMER1_MODE);
422 /***********************************************************/
424 void pwm_set_1C(int16_t value)
429 pwm_timer_16bits_set(1,C,value, PWM1C_MODE);
432 #endif // (defined PWM1C_NUM) && (defined PWM1C_ENABLED)
436 /***********************************************************/
439 /***********************************************************/
441 #if (defined PWM2_NUM) && (defined PWM2_ENABLED)
442 void pwm_init_2(void)
447 pwm_timer_8bits_init(2,PWM2_MODE,TIMER2_PRESCALE, TIMER2_MODE);
452 /***********************************************************/
454 void pwm_set_2(int16_t value)
459 pwm_timer_8bits_set(2,value,PWM2_MODE);
462 #endif // (defined PWM2_NUM) && (defined PWM2_ENABLED)
466 /***********************************************************/
469 /***********************************************************/
471 #if (defined PWM3A_NUM) && (defined PWM3A_ENABLED)
472 void pwm_init_3A(void)
477 pwm_timer_16bits_init(3,A,PWM3A_MODE,TIMER3_PRESCALE, TIMER3_MODE);
482 /***********************************************************/
484 void pwm_set_3A(int16_t value)
489 pwm_timer_16bits_set(3,A,value,PWM3A_MODE);
492 #endif // (defined PWM3A_NUM) && (defined PWM3A_ENABLED)
496 /***********************************************************/
499 /***********************************************************/
501 #if (defined PWM3B_NUM) && (defined PWM3B_ENABLED)
502 void pwm_init_3B(void)
507 pwm_timer_16bits_init(3,B,PWM3B_MODE,TIMER3_PRESCALE, TIMER3_MODE);
512 /***********************************************************/
514 void pwm_set_3B(int16_t value)
519 pwm_timer_16bits_set(3,B,value,PWM3B_MODE);
522 #endif // (defined PWM3B_NUM) && (defined PWM3B_ENABLED)
526 /***********************************************************/
529 /***********************************************************/
531 #if (defined PWM3C_NUM) && (defined PWM3C_ENABLED)
532 void pwm_init_3C(void)
537 pwm_timer_16bits_init(3,C,PWM3C_MODE,TIMER3_PRESCALE, TIMER3_MODE);
542 /***********************************************************/
544 void pwm_set_3C(int16_t value)
549 pwm_timer_16bits_set(3,C,value,PWM3C_MODE);
552 #endif // (defined PWM3C_NUM) && (defined PWM3C_ENABLED)
555 /***********************************************************/
558 /***********************************************************/
563 #if (defined PWM0_NUM) && (defined PWM0_ENABLED)
567 #if (defined PWM1A_NUM) && (defined PWM1A_ENABLED)
570 #if (defined PWM1B_NUM) && (defined PWM1B_ENABLED)
573 #if (defined PWM1C_NUM) && (defined PWM1C_ENABLED)
577 #if (defined PWM2_NUM) && (defined PWM2_ENABLED)
581 #if (defined PWM3A_NUM) && (defined PWM3A_ENABLED)
584 #if (defined PWM3B_NUM) && (defined PWM3B_ENABLED)
587 #if (defined PWM3C_NUM) && (defined PWM3C_ENABLED)
592 #if ( (defined TIMER0_SYNCH) || (defined TIMER1_SYNCH) || (defined TIMER2_SYNCH) || (defined TIMER3_SYNCH) )
594 #endif // ( (defined TIMER0_SYNCH) || (defined TIMER1_SYNCH) || (defined TIMER2_SYNCH) || (defined TIMER3_SYNCH) )
598 /***********************************************************/
601 /***********************************************************/
603 /* global SET FUNCTION : we use a (void *) to be compliant with
604 * control_system functions. For instance pwm_set((void *)(PWM1B_NUM), x)
605 * is equivalent to pwm_set_1B(x) */
606 void pwm_set(void * data, int32_t value)
608 uint8_t num = (uint8_t)(int)data;
609 S_MAX(value, 0x7FFF);
613 #if (defined PWM0_NUM) && (defined PWM0_ENABLED)
619 #if (defined PWM1A_NUM) && (defined PWM1A_ENABLED)
624 #if (defined PWM1B_NUM) && (defined PWM1B_ENABLED)
629 #if (defined PWM1C_NUM) && (defined PWM1C_ENABLED)
635 #if (defined PWM2_NUM) && (defined PWM2_ENABLED)
641 #if (defined PWM3A_NUM) && (defined PWM3A_ENABLED)
646 #if (defined PWM3B_NUM) && (defined PWM3B_ENABLED)
651 #if (defined PWM3C_NUM) && (defined PWM3C_ENABLED)