source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/wiring_analog.c

Last change on this file was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 8.4 KB
Line 
1/*
2 Copyright (c) 2014 Arduino. All right reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library 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.
12 See the GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 //
20
21#include "wiring_analog.h"
22#include "wiring_digital.h"
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28static int _readResolution = 10;
29static int _writeResolution = 10;
30static int ADC_RESOLUTION = 12;
31static int DAC_RESOLUTION = 10;
32
33void analogReadResolution(int res) {
34 _readResolution = res;
35 while( ADC->STATUS.bit.SYNCBUSY == 1 )
36 {
37 // Waiting for synchronization
38 }
39 if(res == 8) ADC->CTRLB.bit.RESSEL= ADC_CTRLB_RESSEL_8BIT_Val;
40 else if(res == 10) ADC->CTRLB.bit.RESSEL= ADC_CTRLB_RESSEL_10BIT_Val;
41 else ADC->CTRLB.bit.RESSEL= ADC_CTRLB_RESSEL_12BIT_Val;
42}
43
44void analogWriteResolution(int res) {
45 _writeResolution = res;
46}
47
48static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) {
49 if (from == to)
50 return value;
51 if (from > to)
52 return value >> (from-to);
53 else
54 return value << (to-from);
55}
56
57void analogReference( eAnalogReference ulMode )
58{
59
60
61 ADC->CTRLA.bit.ENABLE = 0; // Enable ADC
62 while( ADC->STATUS.bit.SYNCBUSY == 1 )
63 {
64 // Waiting for synchronization
65 }
66 switch(ulMode)
67 {
68 case AR_DEFAULT:
69 //default:
70
71 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
72 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val;
73 break;
74 case AR_INTERNAL:
75 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;
76 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val;
77 break;
78
79 case AR_EXTERNAL:
80 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;
81 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
82 break;
83 }ADC->CTRLA.bit.ENABLE = 1; // Enable ADC
84 while( ADC->STATUS.bit.SYNCBUSY == 1 )
85 {
86 // Waiting for synchronization
87 }
88}
89
90uint32_t analogRead( uint32_t ulPin )
91{
92 uint32_t valueRead = 0;
93 pinPeripheral(ulPin, g_APinDescription[ulPin].ulPinType);
94 if ( ulPin == 24 ) // Only 1 DAC on A0 (PA02)
95 {
96 DAC->CTRLA.bit.ENABLE = 0; //disable DAC on A0
97 }
98
99 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber;
100
101 // Start conversion
102 ADC->SWTRIG.bit.START = 1;
103
104 while( ADC->INTFLAG.bit.RESRDY == 0 || ADC->STATUS.bit.SYNCBUSY == 1 )
105 {
106 // Waiting for a complete conversion and complete synchronization
107 }
108
109 // Store the value
110 valueRead = ADC->RESULT.reg;
111
112 // Clear the Data Ready flag
113 ADC->INTFLAG.bit.RESRDY = 1;
114
115 // Flush the ADC for further conversions
116 // ADC->SWTRIG.bit.FLUSH = 1;
117
118 while( ADC->STATUS.bit.SYNCBUSY == 1 || ADC->SWTRIG.bit.FLUSH == 1 )
119 {
120 // Waiting for synchronization
121 }
122
123 //valueRead = mapResolution(valueRead, ADC_RESOLUTION, _readResolution);
124 return valueRead;
125
126}
127
128
129// Right now, PWM output only works on the pins with
130// hardware support. These are defined in the appropriate
131// pins_*.c file. For the rest of the pins, we default
132// to digital output.
133void analogWrite( uint32_t ulPin, uint32_t ulValue )
134{
135 uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ;
136// uint32_t pwm_name = g_APinDescription[ulPin].ulTCChannel ;
137 uint8_t isTC = 0 ;
138 uint8_t Channelx ;
139 Tc* TCx ;
140 Tcc* TCCx ;
141
142 if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG )
143 {
144 if ( ulPin == 24 ) // Only 1 DAC on A0 (PA02)
145 {
146 ulValue = mapResolution(ulValue, _writeResolution, DAC_RESOLUTION);
147 DAC->DATA.reg = ulValue & 0x3FF; // Dac on 10 bits.
148 DAC->CTRLA.bit.ENABLE = 1; // DAC Enabled
149 while (DAC->STATUS.bit.SYNCBUSY == 1); //wait for synchronization
150 return;
151 }
152
153
154 }
155
156 if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM )
157 {
158 if ( (g_APinDescription[ulPin].ulPinType == PIO_TIMER) || g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT )
159 {
160 pinPeripheral( ulPin, g_APinDescription[ulPin].ulPinType ) ;
161 }
162
163 switch ( g_APinDescription[ulPin].ulPWMChannel )
164 {
165 case PWM3_CH0 :
166 TCx = TC3 ;
167 Channelx = 0 ;
168 isTC = 1 ;
169 break;
170
171 case PWM3_CH1:
172 TCx = TC3 ;
173 Channelx = 1;
174 isTC = 1;
175 break;
176
177 case PWM0_CH0 :
178 TCCx = TCC0;
179 Channelx = 0;
180 break;
181
182 case PWM0_CH1 :
183 TCCx = TCC0;
184 Channelx = 1;
185 break;
186
187 case PWM0_CH4 :
188 TCCx = TCC0;
189 Channelx = 0;
190 break;
191
192 case PWM0_CH5 :
193 TCCx = TCC0;
194 Channelx = 1;
195 break;
196
197 case PWM0_CH6 :
198 TCCx = TCC0;
199 Channelx = 2;
200 break;
201
202 case PWM0_CH7 :
203 TCCx = TCC0;
204 Channelx = 3;
205 break;
206
207 case PWM1_CH0 :
208 TCCx = TCC1;
209 Channelx = 0;
210 break;
211
212 case PWM1_CH1 :
213 TCCx = TCC1;
214 Channelx = 1;
215 break;
216
217 case PWM2_CH0 :
218 TCCx = TCC2;
219 Channelx = 0;
220 break;
221
222 case PWM2_CH1 :
223 TCCx = TCC2;
224 Channelx = 1;
225 break;
226 }
227
228
229 // Enable clocks according to TCCx instance to use
230 switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) )
231 {
232 case 0: // TCC0
233 //Enable GCLK for TCC0 (timer counter input clock)
234 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
235 break;
236
237 case 1: // TCC1
238 //Enable GCLK for TCC1 (timer counter input clock)
239 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
240 break;
241
242 case 2: // TCC2
243 //Enable GCLK for TCC2 (timer counter input clock)
244 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;
245 break;
246
247 case 3: // TC3
248 //Enable GCLK for TC3 (timer counter input clock)
249 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 ));
250 break;
251
252 case 4: // TC4
253 //Enable GCLK for TC4 (timer counter input clock)
254 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 ));
255 break;
256
257 case 5: // TC5
258 //Enable GCLK for TC5 (timer counter input clock)
259 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )) ;
260 break;
261 }
262
263 // Set PORT
264 if ( isTC )
265 {
266 // -- Configure TC
267 //DISABLE TCx
268 TCx->COUNT8.CTRLA.reg &=~(TC_CTRLA_ENABLE);
269 //Set Timer counter Mode to 8 bits
270 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8;
271 //Set TCx as normal PWM
272 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
273 //Set TCx in waveform mode Normal PWM
274 TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue;
275 //Set PER to maximum counter value (resolution : 0xFF)
276 TCx->COUNT8.PER.reg = 0xFF;
277 // Enable TCx
278 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
279 }
280 else
281 {
282 // -- Configure TCC
283
284 //DISABLE TCCx
285 TCCx->CTRLA.reg &=~(TCC_CTRLA_ENABLE);
286 //Set TCx as normal PWM
287 TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
288 //Set TCx in waveform mode Normal PWM
289 TCCx->CC[Channelx].reg = (uint32_t)ulValue;
290 //Set PER to maximum counter value (resolution : 0xFF)
291 TCCx->PER.reg = 0xFF;
292 //ENABLE TCCx
293 TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
294 }
295
296 return ;
297 }
298
299 // -- Defaults to digital write
300 pinMode( ulPin, OUTPUT ) ;
301
302 if ( ulValue < 128 )
303 {
304 digitalWrite( ulPin, LOW ) ;
305 }
306 else
307 {
308 digitalWrite( ulPin, HIGH ) ;
309 }
310}
311
312#ifdef __cplusplus
313}
314#endif
Note: See TracBrowser for help on using the repository browser.