1 | // Right now, PWM output only works on the pins with
|
2 | // hardware support. These are defined in the appropriate
|
3 | // pins_*.c file. For the rest of the pins, we default
|
4 | // to digital output.
|
5 | void analogWrite(uint8_t pin, int val)
|
6 | {
|
7 | // We need to make sure the PWM output is enabled for those pins
|
8 | // that support it, as we turn it off when digitally reading or
|
9 | // writing with them. Also, make sure the pin is in output mode
|
10 | // for consistenty with Wiring, which doesn't require a pinMode
|
11 | // call for the analog output pins.
|
12 | pinMode(pin, OUTPUT);
|
13 | if (val == 0)
|
14 | {
|
15 | digitalWrite(pin, LOW);
|
16 | }
|
17 | else if (val == 255)
|
18 | {
|
19 | digitalWrite(pin, HIGH);
|
20 | }
|
21 | else
|
22 | {
|
23 | switch(digitalPinToTimer(pin))
|
24 | {
|
25 | // XXX fix needed for atmega8
|
26 | #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
|
27 | case TIMER0A:
|
28 | // connect pwm to pin on timer 0
|
29 | sbi(TCCR0, COM00);
|
30 | OCR0 = val; // set pwm duty
|
31 | break;
|
32 | #endif
|
33 |
|
34 | #if defined(TCCR0A) && defined(COM0A1)
|
35 | case TIMER0A:
|
36 | // connect pwm to pin on timer 0, channel A
|
37 | sbi(TCCR0A, COM0A1);
|
38 | OCR0A = val; // set pwm duty
|
39 | break;
|
40 | #endif
|
41 |
|
42 | #if defined(TCCR0A) && defined(COM0B1)
|
43 | case TIMER0B:
|
44 | // connect pwm to pin on timer 0, channel B
|
45 | sbi(TCCR0A, COM0B1);
|
46 | OCR0B = val; // set pwm duty
|
47 | break;
|
48 | #endif
|
49 |
|
50 | #if defined(TCCR1A) && defined(COM1A1)
|
51 | case TIMER1A:
|
52 | // connect pwm to pin on timer 1, channel A
|
53 | sbi(TCCR1A, COM1A1);
|
54 | OCR1A = val; // set pwm duty
|
55 | break;
|
56 | #endif
|
57 |
|
58 | #if defined(TCCR1A) && defined(COM1B1)
|
59 | case TIMER1B:
|
60 | // connect pwm to pin on timer 1, channel B
|
61 | sbi(TCCR1A, COM1B1);
|
62 | OCR1B = val; // set pwm duty
|
63 | break;
|
64 | #endif
|
65 |
|
66 | #if defined(TCCR1A) && defined(COM1C1)
|
67 | case TIMER1C:
|
68 | // connect pwm to pin on timer 1, channel B
|
69 | sbi(TCCR1A, COM1C1);
|
70 | OCR1C = val; // set pwm duty
|
71 | break;
|
72 | #endif
|
73 |
|
74 | #if defined(TCCR2) && defined(COM21)
|
75 | case TIMER2:
|
76 | // connect pwm to pin on timer 2
|
77 | sbi(TCCR2, COM21);
|
78 | OCR2 = val; // set pwm duty
|
79 | break;
|
80 | #endif
|
81 |
|
82 | #if defined(TCCR2A) && defined(COM2A1)
|
83 | case TIMER2A:
|
84 | // connect pwm to pin on timer 2, channel A
|
85 | sbi(TCCR2A, COM2A1);
|
86 | OCR2A = val; // set pwm duty
|
87 | break;
|
88 | #endif
|
89 |
|
90 | #if defined(TCCR2A) && defined(COM2B1)
|
91 | case TIMER2B:
|
92 | // connect pwm to pin on timer 2, channel B
|
93 | sbi(TCCR2A, COM2B1);
|
94 | OCR2B = val; // set pwm duty
|
95 | break;
|
96 | #endif
|
97 |
|
98 | #if defined(TCCR3A) && defined(COM3A1)
|
99 | case TIMER3A:
|
100 | // connect pwm to pin on timer 3, channel A
|
101 | sbi(TCCR3A, COM3A1);
|
102 | OCR3A = val; // set pwm duty
|
103 | break;
|
104 | #endif
|
105 |
|
106 | #if defined(TCCR3A) && defined(COM3B1)
|
107 | case TIMER3B:
|
108 | // connect pwm to pin on timer 3, channel B
|
109 | sbi(TCCR3A, COM3B1);
|
110 | OCR3B = val; // set pwm duty
|
111 | break;
|
112 | #endif
|
113 |
|
114 | #if defined(TCCR3A) && defined(COM3C1)
|
115 | case TIMER3C:
|
116 | // connect pwm to pin on timer 3, channel C
|
117 | sbi(TCCR3A, COM3C1);
|
118 | OCR3C = val; // set pwm duty
|
119 | break;
|
120 | #endif
|
121 |
|
122 | #if defined(TCCR4A)
|
123 | case TIMER4A:
|
124 | //connect pwm to pin on timer 4, channel A
|
125 | sbi(TCCR4A, COM4A1);
|
126 | #if defined(COM4A0) // only used on 32U4
|
127 | cbi(TCCR4A, COM4A0);
|
128 | #endif
|
129 | OCR4A = val; // set pwm duty
|
130 | break;
|
131 | #endif
|
132 |
|
133 | #if defined(TCCR4A) && defined(COM4B1)
|
134 | case TIMER4B:
|
135 | // connect pwm to pin on timer 4, channel B
|
136 | sbi(TCCR4A, COM4B1);
|
137 | OCR4B = val; // set pwm duty
|
138 | break;
|
139 | #endif
|
140 |
|
141 | #if defined(TCCR4A) && defined(COM4C1)
|
142 | case TIMER4C:
|
143 | // connect pwm to pin on timer 4, channel C
|
144 | sbi(TCCR4A, COM4C1);
|
145 | OCR4C = val; // set pwm duty
|
146 | break;
|
147 | #endif
|
148 |
|
149 | #if defined(TCCR4C) && defined(COM4D1)
|
150 | case TIMER4D:
|
151 | // connect pwm to pin on timer 4, channel D
|
152 | sbi(TCCR4C, COM4D1);
|
153 | #if defined(COM4D0) // only used on 32U4
|
154 | cbi(TCCR4C, COM4D0);
|
155 | #endif
|
156 | OCR4D = val; // set pwm duty
|
157 | break;
|
158 | #endif
|
159 |
|
160 |
|
161 | #if defined(TCCR5A) && defined(COM5A1)
|
162 | case TIMER5A:
|
163 | // connect pwm to pin on timer 5, channel A
|
164 | sbi(TCCR5A, COM5A1);
|
165 | OCR5A = val; // set pwm duty
|
166 | break;
|
167 | #endif
|
168 |
|
169 | #if defined(TCCR5A) && defined(COM5B1)
|
170 | case TIMER5B:
|
171 | // connect pwm to pin on timer 5, channel B
|
172 | sbi(TCCR5A, COM5B1);
|
173 | OCR5B = val; // set pwm duty
|
174 | break;
|
175 | #endif
|
176 |
|
177 | #if defined(TCCR5A) && defined(COM5C1)
|
178 | case TIMER5C:
|
179 | // connect pwm to pin on timer 5, channel C
|
180 | sbi(TCCR5A, COM5C1);
|
181 | OCR5C = val; // set pwm duty
|
182 | break;
|
183 | #endif
|
184 |
|
185 | case NOT_ON_TIMER:
|
186 | default:
|
187 | if (val < 128) {
|
188 | digitalWrite(pin, LOW);
|
189 | } else {
|
190 | digitalWrite(pin, HIGH);
|
191 | }
|
192 | }
|
193 | }
|
194 | }
|