Mozzi  version v2.0
sound synthesis library for Arduino
MozziGuts_impl_SAMD.hpp
1 /*
2  * MozziGuts_impl_SAMD21.hpp
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2020-2024 Adrian Freed 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 #if !(IS_SAMD21())
13 # error "Wrong implementation included for this platform"
14 #endif
15 
16 namespace MozziPrivate {
17 
19 #if MOZZI_IS(MOZZI_ANALOG_READ, NOZZI_ANALOG_READ_STANDARD)
20 #error not yet implemented
21 #define getADCReading() 0
22 #define channelNumToIndex(channel) channel
23 uint8_t adcPinToChannelNum(uint8_t pin) {
24  return pin;
25 }
26 void adcStartConversion(uint8_t channel) {
27 }
28 void startSecondADCReadOnCurrentChannel() {
29 }
30 void setupFastAnalogRead(int8_t speed) {
31 }
32 void setupMozziADC(int8_t speed) {
33 }
34 #endif
36 
37 
38 
40 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
41 // These are ARM SAMD21 Timer 5 routines to establish a sample rate interrupt
42 static bool tcIsSyncing() {
43  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
44 }
45 
46 static void tcReset() {
47  // Reset TCx
48  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
49  while (tcIsSyncing())
50  ;
51  while (TC5->COUNT16.CTRLA.bit.SWRST)
52  ;
53 }
54 /* Not currently used, and does not compile with EXTERNAL_AUDIO_OUTPUT
55 static void tcEnd() {
56  // Disable TC5
57  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
58  while (tcIsSyncing())
59  ;
60  tcReset();
61  analogWrite(AUDIO_CHANNEL_1_PIN, 0);
62 } */
63 
64 static void tcConfigure(uint32_t sampleRate) {
65  // Enable GCLK for TCC2 and TC5 (timer counter input clock)
66  GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 |
67  GCLK_CLKCTRL_ID(GCM_TC4_TC5));
68  while (GCLK->STATUS.bit.SYNCBUSY)
69  ;
70 
71  tcReset();
72 
73  // Set Timer counter Mode to 16 bits
74  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
75 
76  // Set TC5 mode as match frequency
77  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
78 
79  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;
80 
81  TC5->COUNT16.CC[0].reg = (uint16_t)(SystemCoreClock / sampleRate - 1);
82  while (tcIsSyncing())
83  ;
84 
85  // Configure interrupt request
86  NVIC_DisableIRQ(TC5_IRQn);
87  NVIC_ClearPendingIRQ(TC5_IRQn);
88  NVIC_SetPriority(TC5_IRQn, 0);
89  NVIC_EnableIRQ(TC5_IRQn);
90 
91  // Enable the TC5 interrupt request
92  TC5->COUNT16.INTENSET.bit.MC0 = 1;
93  while (tcIsSyncing())
94  ;
95 }
96 
97 } // namespace MozziPrivate
98 
99 void TC5_Handler(void) __attribute__((weak, alias("samd21AudioOutput")));
100 
101 #ifdef __cplusplus
102 extern "C" {
103 #endif
104 void samd21AudioOutput() {
105  MozziPrivate::defaultAudioOutput();
106  TC5->COUNT16.INTFLAG.bit.MC0 = 1;
107 }
108 #ifdef __cplusplus
109 }
110 #endif
111 
112 namespace MozziPrivate {
113 
114 #endif // MOZZI_AUDIO_MODE
115 
116 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
117 inline void audioOutput(const AudioOutput f) {
118  analogWrite(MOZZI_AUDIO_PIN_1, f.l()+MOZZI_AUDIO_BIAS);
119 }
120 #endif
121 
122 static void startAudio() {
123 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC)
124 # ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS
125  {
126  static const int CPLAY_SPEAKER_SHUTDOWN = 11;
127  pinMode(CPLAY_SPEAKER_SHUTDOWN, OUTPUT);
128  digitalWrite(CPLAY_SPEAKER_SHUTDOWN, HIGH);
129  }
130 
131 # endif
132 
133  analogWriteResolution(MOZZI_AUDIO_BITS);
134  analogWrite(MOZZI_AUDIO_PIN_1, 0);
135 #endif
136 
137 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_INTERNAL_DAC, MOZZI_OUTPUT_EXTERNAL_TIMED)
138  tcConfigure(MOZZI_AUDIO_RATE);
139 #endif
140 }
141 
142 void stopMozzi() {
143  // TODO: implement me
144  interrupts();
145 }
147 
149 void MozziRandPrivate::autoSeed() {
150 #warning Automatic random seeding is not implemented on this platform
151 }
153 
154 } // namespace MozziPrivate
#define MOZZI_AUDIO_BITS
Output resolution of audio samples.
#define MOZZI_AUDIO_PIN_1
Only for MOZZI_AUDIO_MODE s MOZZI_OUTPUT_PWM and MOZZI_OUTPUT_2PIN_PWM: The IO pin to use as (first) ...
#define MOZZI_AUDIO_RATE
Defines the audio rate, i.e.
void stopMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
Definition: MozziGuts.hpp:303
Internal.
Definition: mozzi_rand_p.h:15
This struct encapsulates one frame of mono audio output.
Definition: AudioOutput.h:111