Mozzi  version v1.1.0
sound synthesis library for Arduino
mozzi_analog.h
1 /*
2  * mozzi_analog.h
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 #ifndef MOZZI_ANALOG_H_
13 #define MOZZI_ANALOG_H_
14 
15  #if ARDUINO >= 100
16  #include "Arduino.h"
17 #else
18  #include "WProgram.h"
19 #endif
20 
21 #if (USE_AUDIO_INPUT==true)
22 #warning "Using AUDIO_INPUT_PIN defined in mozzi_config.h for audio input."
23 #endif
24 
25 void adcReadSelectedChannels();
26 //void receiveFirstControlADC();
27 void startSecondControlADC();
28 void receiveSecondControlADC();
29 
30 // hack for Teensy 2 (ATmega32U4), which has "adc_mapping" instead of "analog_pin_to_channel_PGM"
31 #if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
32 //pasted from hardware/arduino/variants/leonardo/pins_arduino.h, doesn't work as of mozzi 0.01.2a
33 // __AVR_ATmega32U4__ has an unusual mapping of pins to channels
34 //extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
35 //#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
36 
37 // look at Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy/pins_teensy.c - analogRead
38 // adc_mapping is already declared in pins_teensy.c, but it's static there so we can't access it
39 static const uint8_t PROGMEM adc_mapping[] = {
40 // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
41  0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
42 };
43 #define analogPinToChannel(P) ( pgm_read_byte( adc_mapping + (P) ) )
44 #endif
45 
46 
47 // include this although already in teensy 3 analog.c, because it is static there
48 #if defined(__MK20DX128__)
49 static const uint8_t channel2sc1a[] = {
50  5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
51  0, 19, 3, 21, 26, 22, 23
52 };
53 #elif defined(__MK20DX256__)
54 static const uint8_t channel2sc1a[] = {
55  5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
56  0, 19, 3, 19+128, 26, 18+128, 23,
57  5+192, 5+128, 4+128, 6+128, 7+128, 4+192
58 // A15 26 E1 ADC1_SE5a 5+64
59 // A16 27 C9 ADC1_SE5b 5
60 // A17 28 C8 ADC1_SE4b 4
61 // A18 29 C10 ADC1_SE6b 6
62 // A19 30 C11 ADC1_SE7b 7
63 // A20 31 E0 ADC1_SE4a 4+64
64 };
65 #endif
66 
67 
68 // for setupFastAnalogRead()
69 enum ANALOG_READ_SPEED {FAST_ADC,FASTER_ADC,FASTEST_ADC};
70 
71 /**
72 @ingroup analog
73 This is automatically called in startMozzi.
74 It makes mozziAnalogRead() happen faster than the standard Arduino analogRead(), changing the
75 duration from about 105 in unmodified Arduino to about 16 microseconds for a
76 dependable read with the default speed parameter FAST_ADC.
77 If you want to set on of the faster modes (see params) you can call this after startMozzi().
78 See: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11, and
79 http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/
80 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. If no parameter is supplied, the
81 default is FAST_ADC, which sets the analog conversion clock predivide rate to
82 16, giving 1Mhz on a 16MHz board, the fastest rate for which behaviour is
83 defined (~16us per sample). However, divisors of 8 and 4 also show usable
84 results in the graphs in this paper:
85 http://dam.mellis.org/Mellis%20-%20Sensor%20Library%20for%20Arduino%20-%20Paper.pdf,
86 so you can also try FASTER_ADC or FASTEST_ADC for divide rates of 8 or 4, giving
87 times of about 8us or 4us per sample. Beware, reliable results will depend on
88 the sort of input signal you have. Only use FASTER_ADC or FASTEST_ADC if you
89 know what you're doing.
90 */
91 void setupFastAnalogRead(int8_t speed=FAST_ADC);
92 
93 
94 
95 /* @ingroup analog
96 Set up for asynchronous analog input, which enables analog reads to take
97 place in the background without blocking the processor.
98 @param speed FAST_ADC, FASTER_ADC or FASTEST_ADC. See setupFastAnalogRead();
99 */
100 void setupMozziADC(int8_t speed=FAST_ADC);
101 
102 
103 
104 /** @ingroup analog
105 Prepare an analog input channel by turning off its digital input buffer.
106 This helps to reduce noise, increase analog reading speed, and save power.
107 
108 Here's more detail from http://www.openmusiclabs.com/learning/digital/atmega-adc/:
109 
110 The DIDR (Data Input Disable Register) disconnects the digital inputs from
111 whichever ADC channels you are using. This is important for 2 reasons. First
112 off, an analog input will be floating all over the place, and causing the
113 digital input to constantly toggle high and low. This creates excessive noise
114 near the ADC, and burns extra power. Secondly, the digital input and associated
115 DIDR switch have a capacitance associated with them which will slow down your
116 input signal if you are sampling a highly resistive load.
117 
118 And from the ATmega328p datasheet, p266:
119 
120 When an analog signal is applied to the ADC pin and the digital input from
121 this pin is not needed, this bit should be written logic one to reduce power
122 consumption in the digital input buffer. Note that ADC named_pins ADC7
123 and ADC6 do not have digital input buffers, and therefore do not require
124 Digital Input Disable bits.
125 @param channel_num the analog input channel you wish to use.
126 */
127 void disconnectDigitalIn(uint8_t channel_num);
128 
129 
130 /** @ingroup analog
131 Reconnect the digital input buffer for an analog input channel which has
132 been set for analog input with disconnectDigitalIn().
133 @param channel_num the analog input channel you wish to reconnect.
134 */
135 void reconnectDigitalIn(uint8_t channel_num);
136 
137 
138 /** @ingroup analog
139 Prepare all analog input channels by turning off their digital input buffers.
140 This helps to reduce noise, increase analog reading speed, and save power.
141 */
143 
144 
145 /** @ingroup analog
146 Reconnect the digital input buffers for analog input channels which have
147 been set for analog input with disconnectDigitalIn().
148 */
150 
151 
152 
153 /* @ingroup analog
154 Starts an analog to digital conversion of the voltage on a specified channel. Unlike
155 Arduino's analogRead() function which waits until a conversion is complete before
156 returning, adcStartConversion() only sets the conversion to begin, so you can use
157 the cpu for other things and call for the result later with adcGetResult().
158 @param channel is the analog channel number (0 to ....), which is not necessarily the same as the pin number
159 Use adcPinToChannelNum() to convert the pin number to its channel number.
160 @note Timing: about 1us when used in updateControl() with CONTROL_RATE 64.
161 */
162 void adcStartConversion(uint8_t channel);
163 
164 
165 
166 /** @ingroup analog
167 Reads the analog input of a chosen channel, without blocking other operations from running.
168 It actually returns the most recent analog reading and puts the chosen pin or channel
169 on the stack of channels to be read in the background before the next control
170 interrupt.
171 @param pin_or_channel the analog pin or channel number.
172 @return the digitised value of the voltage on the chosen channel, in the range 0-1023. @Note that non-AVR
173 hardware may return a different range, e.g. 0-4095 on STM32 boards.
174 */
175 int mozziAnalogRead(uint8_t pin);
176 
177 
178 /* Used in MozziGuts.cpp, in updateControlWithAutoADC() to kick off any mozziAnalogReads waiting on the stack
179 */
180 void adcStartReadCycle();
181 
182 
183 uint8_t adcPinToChannelNum(uint8_t pin);
184 
185 #endif /* MOZZI_ANALOG_H_ */
int mozziAnalogRead(uint8_t pin)
Reads the analog input of a chosen channel, without blocking other operations from running...
void adcReconnectAllDigitalIns()
Reconnect the digital input buffers for analog input channels which have been set for analog input wi...
void reconnectDigitalIn(uint8_t channel_num)
Reconnect the digital input buffer for an analog input channel which has been set for analog input wi...
void disconnectDigitalIn(uint8_t channel_num)
Prepare an analog input channel by turning off its digital input buffer.
void setupFastAnalogRead(int8_t speed=FAST_ADC)
This is automatically called in startMozzi.
void adcDisconnectAllDigitalIns()
Prepare all analog input channels by turning off their digital input buffers.