From 131d81ee695bed1b57df177807587a6c600f2f29 Mon Sep 17 00:00:00 2001 From: tomcombriat Date: Sun, 3 Oct 2021 22:18:32 +0200 Subject: [PATCH] Port to Teensy4 --- AudioConfigTeensy3_12bit.h | 1 + AudioConfigTeensy4_10bitPwm.h | 17 ++++++++ AudioOutput.h | 13 ++++++ MozziGuts.cpp | 41 +++++++++++-------- MozziGuts.h | 4 +- .../PT8211_stereo_16bits.ino | 2 +- .../PT8211_stereo_16bits_STM32_SPI2.ino | 2 +- hardware_defines.h | 7 ++-- mozzi_analog.cpp | 21 +++++----- mozzi_analog.h | 8 ++++ mozzi_config.h | 2 +- 11 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 AudioConfigTeensy4_10bitPwm.h diff --git a/AudioConfigTeensy3_12bit.h b/AudioConfigTeensy3_12bit.h index 9d0d18ad0..0f9a7d550 100644 --- a/AudioConfigTeensy3_12bit.h +++ b/AudioConfigTeensy3_12bit.h @@ -1,6 +1,7 @@ #ifndef AUDIOCONFIGTEENSY3_12BIT_H #define AUDIOCONFIGTEENSY3_12BIT_H +#warning If you get a compilation error you should probably update Teensyduino to its latest version /** @ingroup core */ diff --git a/AudioConfigTeensy4_10bitPwm.h b/AudioConfigTeensy4_10bitPwm.h new file mode 100644 index 000000000..6c8d9f124 --- /dev/null +++ b/AudioConfigTeensy4_10bitPwm.h @@ -0,0 +1,17 @@ +#ifndef AUDIOCONFIGTEENSY4_10BITPWM_H +#define AUDIOCONFIGTEENSY4_10BITPWM_H + +#warning If you get a compilation error you should probably update Teensyduino to its latest version + +/** @ingroup core +*/ +/* Used internally to put the 0-biased generated audio into the centre of the output range (10 bits on Teensy 4 using PWM) */ +#define AUDIO_BIAS ((uint16_t) 512) +#define AUDIO_BITS 10 + +#define AUDIO_CHANNEL_1_PIN A8 +#define AUDIO_CHANNEL_2_PIN A9 + + +#endif // #ifndef AUDIOCONFIGTEENSY4_10BITPWM_H + diff --git a/AudioOutput.h b/AudioOutput.h index e078e027e..3f296c262 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -241,6 +241,19 @@ inline void audioOutput(const AudioOutput f) #endif +///////////////////// TEENSY4 +#if IS_TEENSY4() +#include "AudioConfigTeensy4_10bitPwm.h" +inline void audioOutput(const AudioOutput f) +{ + analogWrite(AUDIO_CHANNEL_1_PIN, f.l()+AUDIO_BIAS); +#if (AUDIO_CHANNELS > 1) + analogWrite(AUDIO_CHANNEL_2_PIN, f.r()+AUDIO_BIAS); +#endif +} +#endif + + ///////////////////// STM32 #if IS_STM32() #include "AudioConfigSTM32.h" diff --git a/MozziGuts.cpp b/MozziGuts.cpp index d7ecd7775..5b05289ee 100644 --- a/MozziGuts.cpp +++ b/MozziGuts.cpp @@ -27,7 +27,7 @@ #if IS_AVR() #include "FrequencyTimer2.h" #include "TimerOne.h" -#elif IS_TEENSY3() +#elif (IS_TEENSY3() || IS_TEENSY4()) // required from http://github.com/pedvide/ADC for Teensy 3.* #include "IntervalTimer.h" #include @@ -49,7 +49,7 @@ uint16_t output_buffer_size = 0; "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds." #endif -#if IS_TEENSY3() +#if (IS_TEENSY3() || IS_TEENSY4()) ADC *adc; // adc object uint8_t teensy_pin; #elif IS_STM32() @@ -150,8 +150,8 @@ uint8_t adc_count = 0; int getAudioInput() { return audio_input; } static void startFirstAudioADC() { -#if IS_TEENSY3() - adc->startSingleRead( +#if (IS_TEENSY3() || IS_TEENSY4()) + adc->adc0->startSingleRead( AUDIO_INPUT_PIN); // ADC lib converts pin/channel in startSingleRead #elif IS_STM32() uint8_t dummy = AUDIO_INPUT_PIN; @@ -170,8 +170,8 @@ static void receiveFirstAudioADC() */ static void startSecondAudioADC() { -#if IS_TEENSY3() - adc->startSingleRead(AUDIO_INPUT_PIN); +#if (IS_TEENSY3() || IS_TEENSY4()) + adc->adc0->startSingleRead(AUDIO_INPUT_PIN); #elif IS_STM32() uint8_t dummy = AUDIO_INPUT_PIN; adc.setPins(&dummy, 1); @@ -183,8 +183,8 @@ static void startSecondAudioADC() { static void receiveSecondAudioADC() { if (!input_buffer.isFull()) -#if IS_TEENSY3() - input_buffer.write(adc->readSingle()); +#if (IS_TEENSY3() || IS_TEENSY4()) + input_buffer.write(adc->adc0->readSingle()); #elif IS_STM32() input_buffer.write(adc.getData()); #else @@ -192,8 +192,8 @@ static void receiveSecondAudioADC() { #endif } -#if IS_TEENSY3() || IS_STM32() || IS_AVR() -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_STM32() || IS_AVR() || IS_TEENSY4() +#if IS_TEENSY3() || IS_TEENSY4() void adc0_isr(void) #elif IS_STM32() void stm32_adc_eoc_handler() @@ -362,7 +362,7 @@ static void CACHED_FUNCTION_ATTR defaultAudioOutput() { #endif #if (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) || IS_STM32() -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() IntervalTimer timer1; #elif IS_STM32() && (EXTERNAL_AUDIO_OUTPUT == true) HardwareTimer audio_update_timer(2); @@ -395,13 +395,22 @@ void samd21AudioOutput() { #if !IS_AVR() static void startAudioStandard() { -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() adc->adc0->setAveraging(0); adc->adc0->setConversionSpeed( - ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier - + ADC_CONVERSION_SPEED::MED_SPEED); // could be HIGH_SPEED, noisier +#if IS_TEENSY3() analogWriteResolution(12); - timer1.begin(defaultAudioOutput, 1000000UL / AUDIO_RATE); +#elif IS_TEENSY4() + analogWriteResolution(10); +#if (!EXTERNAL_AUDIO_OUTPUT) + analogWriteFrequency(AUDIO_CHANNEL_1_PIN, 146484.38f); +#if (AUDIO_CHANNELS > 1) + analogWriteFrequency(AUDIO_CHANNEL_2_PIN, 146484.38f); +#endif // end #if (AUDIO_CHANNELS > 1) +#endif // end #if (!EXTERNAL_AUDIO_OUTPUT) +#endif + timer1.begin(defaultAudioOutput, 1000000. / AUDIO_RATE); #elif IS_SAMD21() #ifdef ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS { @@ -702,7 +711,7 @@ void startMozzi(int control_rate_hz) { } void stopMozzi() { -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() timer1.end(); #elif IS_STM32() audio_update_timer.pause(); diff --git a/MozziGuts.h b/MozziGuts.h index d953f34c2..f49397bbe 100644 --- a/MozziGuts.h +++ b/MozziGuts.h @@ -22,7 +22,7 @@ #include "hardware_defines.h" -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() // required from http://github.com/pedvide/ADC for Teensy 3.* #include #endif @@ -191,6 +191,8 @@ HIFI is not available/not required on Teensy 3.* or ARM. #if (EXTERNAL_AUDIO_OUTPUT != true) #if IS_TEENSY3() #include "AudioConfigTeensy3_12bit.h" +#elif IS_TEENSY4() +#include "AudioConfigTeensy4_10bitPwm.h" #elif IS_STM32() #include "AudioConfigSTM32.h" #elif IS_ESP8266() diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino index a10d842f4..996d94101 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits/PT8211_stereo_16bits.ino @@ -79,7 +79,7 @@ void setup() { // Initialising the SPI connection on default port SPI.begin(); - SPI.beginTransaction(SPISettings(200000000, MSBFIRST, SPI_MODE0)); //MSB first, according to the DAC spec + SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0)); //MSB first, according to the DAC spec aCos1.setFreq(440.f); diff --git a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino index 9b1223864..3658191a0 100644 --- a/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino +++ b/examples/13.External_Audio_Output/PT8211_stereo_16bits_STM32_SPI2/PT8211_stereo_16bits_STM32_SPI2.ino @@ -73,7 +73,7 @@ void setup() { mySPI.begin(); - mySPI.beginTransaction(SPISettings(200000000, MSBFIRST, SPI_MODE0)); //MSB first, according to the DAC spec + mySPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0)); //MSB first, according to the DAC spec aCos1.setFreq(440.f); diff --git a/hardware_defines.h b/hardware_defines.h index c82e1694a..4ca312c5e 100644 --- a/hardware_defines.h +++ b/hardware_defines.h @@ -14,12 +14,13 @@ #define IS_AVR() (defined(__AVR__)) // "Classic" Arduino boards #define IS_SAMD21() (defined(ARDUINO_ARCH_SAMD)) -#define IS_TEENSY3() (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__) ) // 32bit arm-based Teensy -#define IS_STM32() (defined(__arm__) && !IS_TEENSY3() && !IS_SAMD21()) // STM32 boards (note that only the maple based core is supported at this time. If another cores is to be supported in the future, this define should be split. +#define IS_TEENSY3() (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)) // 32bit arm-based Teensy +#define IS_TEENSY4() (defined(__IMXRT1062__)) // Teensy4 (no DAC) +#define IS_STM32() (defined(__arm__) && !IS_TEENSY3() && !IS_SAMD21() && !IS_TEENSY4()) // STM32 boards (note that only the maple based core is supported at this time. If another cores is to be supported in the future, this define should be split. #define IS_ESP8266() (defined(ESP8266)) #define IS_ESP32() (defined(ESP32)) -#if !(IS_AVR() || IS_TEENSY3() || IS_STM32() || IS_ESP8266() || IS_SAMD21() || IS_ESP32()) +#if !(IS_AVR() || IS_TEENSY3() || IS_TEENSY4() || IS_STM32() || IS_ESP8266() || IS_SAMD21() || IS_ESP32()) #error Your hardware is not supported by Mozzi or not recognized. Edit hardware_defines.h to proceed. #endif diff --git a/mozzi_analog.cpp b/mozzi_analog.cpp index 08d361e7d..f78396e86 100644 --- a/mozzi_analog.cpp +++ b/mozzi_analog.cpp @@ -17,7 +17,7 @@ //#include "mozzi_utils.h" #include "hardware_defines.h" -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() // required from http://github.com/pedvide/ADC for Teensy 3.* #include #elif IS_STM32() @@ -25,7 +25,7 @@ #endif // defined in Mozziguts.cpp -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() extern ADC *adc; // adc object extern uint8_t teensy_pin; #elif IS_STM32() @@ -69,9 +69,10 @@ void adcEnableInterrupt(){ void setupMozziADC(int8_t speed) { -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() adc = new ADC(); - adc->adc0->enableInterrupts(ADC_0); + //adc->adc0->enableInterrupts(ADC_0); + adc->adc0->enableInterrupts(adc0_isr); #elif IS_STM32() adc.calibrate(); setupFastAnalogRead(speed); @@ -170,7 +171,7 @@ static void adcSetChannel(uint8_t channel) { // basically analogRead() chopped in half so the ADC conversion // can be started here and received by another function. void adcStartConversion(uint8_t channel) { -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() teensy_pin = channel; // remember for second startSingleRead adc->startSingleRead(teensy_pin); // channel/pin gets converted every time in startSingleRead #elif IS_STM32() @@ -249,7 +250,7 @@ void receiveFirstControlADC(){ void startSecondControlADC() { -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() adc->startSingleRead(teensy_pin); #elif IS_STM32() adc.setPins(&stm32_current_adc_pin, 1); @@ -261,8 +262,8 @@ void startSecondControlADC() { void receiveSecondControlADC(){ -#if IS_TEENSY3() - analog_readings[current_channel] = adc->readSingle(); +#if IS_TEENSY3() || IS_TEENSY4() + analog_readings[current_channel] = adc->adc0->readSingle(); #elif IS_STM32() analog_readings[current_channel] = adc.getData(); #elif IS_AVR() @@ -278,14 +279,14 @@ because the first conversion after changing channels is often inaccurate (on atm The version for USE_AUDIO_INPUT==true is in MozziGuts.cpp... compilation reasons... */ #if(USE_AUDIO_INPUT==false) -#if IS_TEENSY3() +#if IS_TEENSY3() || IS_TEENSY4() void adc0_isr(void) #elif IS_STM32() void stm32_adc_eoc_handler() #elif IS_AVR() ISR(ADC_vect, ISR_BLOCK) #endif -#if IS_TEENSY3() || IS_STM32() || IS_AVR() +#if IS_TEENSY3() || IS_STM32() || IS_AVR() || IS_TEENSY4() { if (first) { diff --git a/mozzi_analog.h b/mozzi_analog.h index d9a64b367..03148d3f4 100644 --- a/mozzi_analog.h +++ b/mozzi_analog.h @@ -18,6 +18,8 @@ #include "WProgram.h" #endif +#include "hardware_defines.h" + #if (USE_AUDIO_INPUT==true) #warning "Using AUDIO_INPUT_PIN defined in mozzi_config.h for audio input." #endif @@ -182,4 +184,10 @@ void adcStartReadCycle(); uint8_t adcPinToChannelNum(uint8_t pin); + +#if IS_TEENSY3() || IS_TEENSY4() +void adc0_isr(void); +#endif + + #endif /* MOZZI_ANALOG_H_ */ diff --git a/mozzi_config.h b/mozzi_config.h index 1d8e54819..9d9a7d65d 100644 --- a/mozzi_config.h +++ b/mozzi_config.h @@ -79,7 +79,7 @@ This sets which analog input channel to use for audio input, if you have \#define USE_AUDIO_INPUT true in mozz_config.h */ -#define AUDIO_INPUT_PIN 0 +//#define AUDIO_INPUT_PIN 11 //AUDIO_INPUT_CHANNEL = analogPinToChannel(AUDIO_INPUT_PIN)