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

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

ライブラリとOS及びベーシックなサンプルの追加.

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 synchroinization
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 // ATTENTION : On this board the default is not 5volts or 3.3volts BUT 1.65 volt
61
62
63
64 ADC->CTRLA.bit.ENABLE = 0; // Enable ADC
65 while( ADC->STATUS.bit.SYNCBUSY == 1 )
66 {
67 // Waiting for synchroinization
68 }
69 switch(ulMode)
70 {
71 case AR_DEFAULT:
72 //default:
73
74 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
75 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val;
76 break;
77 case AR_INTERNAL:
78 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;
79 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val;
80 break;
81
82 case AR_EXTERNAL:
83 ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;
84 ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
85 break;
86 }ADC->CTRLA.bit.ENABLE = 1; // Enable ADC
87 while( ADC->STATUS.bit.SYNCBUSY == 1 )
88 {
89 // Waiting for synchroinization
90 }
91}
92
93uint32_t analogRead( uint32_t ulPin )
94{
95 uint32_t valueRead = 0;
96 pinPeripheral(ulPin, g_APinDescription[ulPin].ulPinType);
97 if ( ulPin == 24 ) // Only 1 DAC on A0 (PA02)
98 {
99 DAC->CTRLA.bit.ENABLE = 0; //disable DAC on A0
100 }
101
102 ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber;
103
104 // Start conversion
105 ADC->SWTRIG.bit.START = 1;
106
107 while( ADC->INTFLAG.bit.RESRDY == 0 || ADC->STATUS.bit.SYNCBUSY == 1 )
108 {
109 // Waiting for a complete conversion and complete synchronization
110 }
111
112 // Store the value
113 valueRead = ADC->RESULT.reg;
114
115 // Clear the Data Ready flag
116 ADC->INTFLAG.bit.RESRDY = 1;
117
118 // Flush the ADC for further conversions
119 // ADC->SWTRIG.bit.FLUSH = 1;
120
121 while( ADC->STATUS.bit.SYNCBUSY == 1 || ADC->SWTRIG.bit.FLUSH == 1 )
122 {
123 // Waiting for synchronization
124 }
125
126 //valueRead = mapResolution(valueRead, ADC_RESOLUTION, _readResolution);
127 return valueRead;
128
129}
130
131
132// Right now, PWM output only works on the pins with
133// hardware support. These are defined in the appropriate
134// pins_*.c file. For the rest of the pins, we default
135// to digital output.
136void analogWrite( uint32_t ulPin, uint32_t ulValue )
137{
138 uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ;
139// uint32_t pwm_name = g_APinDescription[ulPin].ulTCChannel ;
140 uint8_t isTC = 0 ;
141 uint8_t Channelx ;
142 Tc* TCx ;
143 Tcc* TCCx ;
144
145 if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG )
146 {
147 if ( ulPin == 24 ) // Only 1 DAC on A0 (PA02)
148 {
149 ulValue = mapResolution(ulValue, _writeResolution, DAC_RESOLUTION);
150 DAC->DATA.reg = ulValue & 0x3FF; // Dac on 10 bits.
151 DAC->CTRLA.bit.ENABLE = 1; // DAC Enabled
152 syncDAC();
153 return;
154 }
155
156
157 }
158
159 if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM )
160 {
161 if ( (g_APinDescription[ulPin].ulPinType == PIO_TIMER) || g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT )
162 {
163 pinPeripheral( ulPin, g_APinDescription[ulPin].ulPinType ) ;
164 }
165
166 switch ( g_APinDescription[ulPin].ulPWMChannel )
167 {
168 case PWM3_CH0 :
169 TCx = TC3 ;
170 Channelx = 0 ;
171 isTC = 1 ;
172 break;
173
174 case PWM3_CH1:
175 TCx = TC3 ;
176 Channelx = 1;
177 isTC = 1;
178 break;
179
180 case PWM0_CH0 :
181 TCCx = TCC0;
182 Channelx = 0;
183 break;
184
185 case PWM0_CH1 :
186 TCCx = TCC0;
187 Channelx = 1;
188 break;
189
190 case PWM0_CH4 :
191 TCCx = TCC0;
192 Channelx = 0;
193 break;
194
195 case PWM0_CH5 :
196 TCCx = TCC0;
197 Channelx = 1;
198 break;
199
200 case PWM0_CH6 :
201 TCCx = TCC0;
202 Channelx = 2;
203 break;
204
205 case PWM0_CH7 :
206 TCCx = TCC0;
207 Channelx = 3;
208 break;
209
210 case PWM1_CH0 :
211 TCCx = TCC1;
212 Channelx = 0;
213 break;
214
215 case PWM1_CH1 :
216 TCCx = TCC1;
217 Channelx = 1;
218 break;
219
220 case PWM2_CH0 :
221 TCCx = TCC2;
222 Channelx = 0;
223 break;
224
225 case PWM2_CH1 :
226 TCCx = TCC2;
227 Channelx = 1;
228 break;
229 }
230
231
232 // Enable clocks according to TCCx instance to use
233 switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) )
234 {
235 case 0: // TCC0
236 //Enable GCLK for TCC0 (timer counter input clock)
237 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
238 break;
239
240 case 1: // TCC1
241 //Enable GCLK for TCC1 (timer counter input clock)
242 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
243 break;
244
245 case 2: // TCC2
246 //Enable GCLK for TCC2 (timer counter input clock)
247 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;
248 break;
249
250 case 3: // TC3
251 //Enable GCLK for TC3 (timer counter input clock)
252 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 ));
253 break;
254
255 case 4: // TC4
256 //Enable GCLK for TC4 (timer counter input clock)
257 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 ));
258 break;
259
260 case 5: // TC5
261 //Enable GCLK for TC5 (timer counter input clock)
262 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )) ;
263 break;
264 }
265
266 // Set PORT
267 if ( isTC )
268 {
269 // -- Configure TC
270 //DISABLE TCx
271 TCx->COUNT8.CTRLA.reg &=~(TC_CTRLA_ENABLE);
272 //Set Timer counter Mode to 8 bits
273 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8;
274 //Set TCx as normal PWM
275 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM;
276 //Set TCx in waveform mode Normal PWM
277 TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue;
278 //Set PER to maximum counter value (resolution : 0xFF)
279 TCx->COUNT8.PER.reg = 0xFF;
280 // Enable TCx
281 TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE;
282 }
283 else
284 {
285 // -- Configure TCC
286
287 //DISABLE TCCx
288 TCCx->CTRLA.reg &=~(TCC_CTRLA_ENABLE);
289 //Set TCx as normal PWM
290 TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
291 //Set TCx in waveform mode Normal PWM
292 TCCx->CC[Channelx].reg = (uint32_t)ulValue;
293 //Set PER to maximum counter value (resolution : 0xFF)
294 TCCx->PER.reg = 0xFF;
295 //ENABLE TCCx
296 TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
297 }
298
299 return ;
300 }
301
302 // -- Defaults to digital write
303 pinMode( ulPin, OUTPUT ) ;
304
305 if ( ulValue < 128 )
306 {
307 digitalWrite( ulPin, LOW ) ;
308 }
309 else
310 {
311 digitalWrite( ulPin, HIGH ) ;
312 }
313}
314
315#ifdef __cplusplus
316}
317#endif
Note: See TracBrowser for help on using the repository browser.