Mozzi  version v2.0
sound synthesis library for Arduino
config_checks_avr.h
1 /*
2  * config_checks_avr.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10 */
11 
12 /* For Mozzi-internal use: Apply hardware specific config defaults and config checks: AVR */
13 
14 /**
15  * @page hardware_avr Mozzi on classic Arduino, Teensy 2.x, Arduino Mega, and other 8 bit "AVR"/ATMEGA architecture boards
16  *
17  * @section avr_status Port status and notes
18  * This is the original "port" of Mozzi, and thus very elaborate. The main challenges on this platform, compared to other MCUs, are limitations in
19  * flash, RAM, and CPU power.
20  *
21  * @section avr_output Output modes
22  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
23  * - MOZZI_OUTPUT_PWM
24  * - MOZZI_OUTPUT_2PIN_PWM
25  * - MOZZI_OUTPUT_EXTERNAL_TIMED
26  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
27  *
28  * In all modes, except MOZZI_OUTPUT_EXTERNAL_CUSTOM, Timer 1 is claimed, and is not available for any other purpose.
29  * This means, among other things, that pins 9 and 10 cannot be used for analogWrite(), while pins 3 and 11 should still be available
30  * @em except in MOZZI_OUTPUT_2PIN_PWM mode (as Timer2 is also claimed, then; for definite info on which pin is connected to which timer,
31  * check a suitable reference, as your board may differ). See *Mozzi>examples>11.Communication>Sinewave_PWM_pins_HIFI*. for an example
32  * of emulating analogWrite() on any digital pin, without the need for a hardware timer.
33  *
34  * @section avr_pwm MOZZI_OUTPUT_PWM
35  * For MOZZI_OUTPUT_PWM, output is restricted to pins that are hardware-attached to Timer 1, but can be configured
36  * within this tight limit. In particular, the default setup on the
37  * Arduino UNO is:
38  * - Mono: Pin 9 -> configurable using MOZZI_AUDIO_PIN_1
39  * - Stereo: Pin 9 (left) and Pin 10 (right) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_2
40  * For pinouts on other boards, refer to config/known_16bit_timers.
41  *
42  * Rate of the PWM output can be controlled separately from MOZZI_AUDIO_RATE: MOZZI_PWM_RATE.
43  *
44  * The available sample resolution is 488, i.e. almost 9 bits, providing some headroom above the 8 bit table resolution
45  * currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate.
46  *
47  * @section avr_2pin_pwm MOZZI_OUTPUT_2PIN_PWM
48  * In this mode, output is split across two pins (again, both connected to Timer 1), with each outputting 7 bits for a total of 14. This allows for
49  * much better dynamic range, providing much more definition than can be achieved using @ref avr_pwm , while using
50  * only modestly more processing power. Further, it allows for a much higher PWM carrier rate can be much higher (125 kHz by default; see @ref
51  * MOZZI_PWM_RATE), which is well beyond the audible range.
52  *
53  * On the downside, this mode requires an extra hardware timer (Timer2 in addition to Timer1), which may increase compatibility
54  * problems with other Arduino libraries that also require a timer. Further, a more elaborate hardware setup is needed, making it less convenient
55  * for rapid prototyping. For circuit details, see https://sensorium.github.io/Mozzi/learn/output/ .
56  *
57  * On the classic Arduino Uno, the default pinout in this mode is:
58  * - Pin 9 (high bits) and Pin 10 (low bits) -> configurable using MOZZI_AUDIO_PIN_1 and MOZZI_AUDIO_PIN_1_LOW
59  *
60  * Here is table of the default pins on some other boards. Rows with an x on it have actually been tested (and importantly, the outcome recoreded;
61  * input welcome on further boards.)
62  *
63  * resistor.....3.9k......499k \n
64  * x................9..........10...............Arduino Uno \n
65  * x................9..........10...............Arduino Duemilanove \n
66  * x................9..........10...............Arduino Nano \n
67  * x................9..........10...............Arduino Leonardo \n
68  * x................9..........10...............Ardweeny \n
69  * x................9..........10...............Boarduino \n
70  * x...............11.........12...............Freetronics EtherMega \n
71  * .................11.........12...............Arduino Mega \n
72  * .................14.........15...............Teensy \n
73  * .............B5(14)...B6(15)...........Teensy2 \n
74  * x...........B5(25)...B6(26)...........Teensy2++ \n
75  * .................13.........12...............Sanguino \n
76  *
77  * For pinouts on other AVR boards, config/known_16bit_timers might contain some hints.
78  *
79  * Rate of the PWM output can be controlled separately from @ref MOZZI_AUDIO_RATE, and is much higher (125kHz), by default: @ref MOZZI_PWM_RATE.
80  *
81  * The default sample resolution is 7 bits per pin, for a total of 14 bits. This can be configured within hardware limits (@ref MOZZI_PWM_RATE) using
82  * @ref MOZZI_AUDIO_BITS_PER_CHANNEL, but beware that increasing this will require even more accuracy in our output resistors (see the linked documentation, above).
83  *
84  * @section avr_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
85  * See @ref external_audio
86 */
87 
88 
89 #if not defined(MOZZI_AUDIO_MODE)
90 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PWM
91 #endif
92 
93 #if not defined(MOZZI_AUDIO_RATE)
94 #define MOZZI_AUDIO_RATE 16384
95 #endif
96 
97 #if not defined(MOZZI_ANALOG_READ)
98 #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_STANDARD
99 #endif
100 
101 // Pins for regular PWM output
102 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
103 # if !defined(MOZZI_AUDIO_PIN_1)
104 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
105 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
106 # endif
107 # if (MOZZI_AUDIO_CHANNELS > 1) && !defined(MOZZI_AUDIO_PIN_2)
108 #define MOZZI_AUDIO_PIN_2 TIMER1_B_PIN
109 #define MOZZI_AUDIO_PIN_2_REGISTER OCR1B
110 # endif
111 
112 # if !defined(MOZZI_PWM_RATE)
113 #define MOZZI_PWM_RATE 32768
114 # endif
115 
116 #define MOZZI_AUDIO_BITS 8
117 #define MOZZI_AUDIO_BITS_OPTIMISTIC 9
118 #define MOZZI_AUDIO_BIAS ((uint8_t) 244)
119 #endif
120 
121 // Pins for 2 pin HIFI PWM output
122 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
123 # if !defined(MOZZI_AUDIO_PIN_1)
124 #define MOZZI_AUDIO_PIN_1 TIMER1_A_PIN
125 #define MOZZI_AUDIO_PIN_1_REGISTER OCR1A
126 # endif
127 # if !defined(MOZZI_AUDIO_PIN_1_LOW)
128 #define MOZZI_AUDIO_PIN_1_LOW TIMER1_B_PIN
129 #define MOZZI_AUDIO_PIN_1_LOW_REGISTER OCR1B
130 # endif
131 
132 # if !defined(MOZZI_PWM_RATE)
133 #define MOZZI_PWM_RATE 125000
134 # endif
135 
136 # if !defined(MOZZI_AUDIO_BITS_PER_CHANNEL)
137 #define MOZZI_AUDIO_BITS_PER_CHANNEL 7
138 # endif
139 
140 #define MOZZI_AUDIO_BITS (2*MOZZI_AUDIO_BITS_PER_CHANNEL)
141 #endif
142 
143 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
144 
145 // Step 2: Check
146 // NOTE: This step is not technically required, but a good idea in any port
147 
148 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
149 
150 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM)
151 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO, MOZZI_STEREO)
152 #endif
153 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM)
154 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, MOZZI_MONO)
155 #endif
156 
157 /** should we enforce the following?
158 #if (MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_2PIN_PWM))
159 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_RATE, 16384, 32768)
160 #endif */
161 
162 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE, MOZZI_ANALOG_READ_STANDARD)
163 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE, MOZZI_AUDIO_INPUT_STANDARD)
164 #include "../config/known_16bit_timers.h"
165 
166 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM, MOZZI_OUTPUT_2PIN_PWM)
167 # if defined(TIMER1_C_PIN)
168 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN, TIMER1_C_PIN);
169 # else
170 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_PIN_1, TIMER1_A_PIN, TIMER1_B_PIN);
171 # endif
172 #endif