Hey Guys,
Having a bit of trouble using I2S on a SAMD51 and then disabling I2S, sleeping and then re-enabling and using I2S again.
I’m using a modified version of the WavFilePlayer example from the Adafruit fork of the Audio library (GitHub - adafruit/Audio: Teensy Audio Library). I’ve been struggling a bit trying to figure out how to re-initialize I2S after going into a low-power sleep mode. It would be useful to look at the code I am using to give you guys an idea of what I am talking about. Here is what I am using, basically as I said a modified version of the WavFilePlayer example, with sleep integrated into it:
#include <Audio.h>[color=#2e8b57][/color]
#include <SdFat.h>[color=#2e8b57][/color]
#include <Adafruit_SPIFlash.h>[color=#2e8b57][/color]
#include <play_fs_wav.h>[color=#2e8b57][/color]
#include <Adafruit_SleepyDog.h>[color=#2e8b57][/color]
[color=#2e8b57][/color]
AudioPlayFSWav playFSWav;[color=#2e8b57][/color]
AudioOutputI2S audioOutput;[color=#2e8b57][/color]
AudioConnection patchCord1(playFSWav, 0, audioOutput, 1);[color=#2e8b57][/color]
AudioConnection patchCord2(playFSWav, 1, audioOutput, 0);[color=#2e8b57][/color]
[color=#2e8b57][/color]
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS, PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);[color=#2e8b57][/color]
[color=#2e8b57][/color]
Adafruit_SPIFlash flash(&flashTransport);[color=#2e8b57][/color]
FatFileSystem QSPIFS;[color=#2e8b57][/color]
SdFat SD;[color=#2e8b57][/color]
bool QSPIOK = false;[color=#2e8b57][/color]
[color=#2e8b57][/color]
int pin_i2s_power = 6;[color=#2e8b57][/color]
int pin_i2s_din = 11;[color=#2e8b57][/color]
int pin_i2s_lrclk = 10;[color=#2e8b57][/color]
int pin_i2s_tx_d1 = 1;[color=#2e8b57][/color]
[color=#2e8b57][/color]
void setup() {[color=#2e8b57][/color]
pinMode(6, OUTPUT);[color=#2e8b57][/color]
digitalWrite(6, HIGH);[color=#2e8b57][/color]
[color=#2e8b57][/color]
AudioMemory(8);[color=#2e8b57][/color]
[color=#2e8b57][/color]
QSPIOK = false;[color=#2e8b57][/color]
if (!flash.begin()) {[color=#2e8b57][/color]
Serial.println("Error, failed to initialize flash chip!");[color=#2e8b57][/color]
} else if (!QSPIFS.begin(&flash)) {[color=#2e8b57][/color]
Serial.println("Failed to mount QSPI filesystem!");[color=#2e8b57][/color]
Serial.println("Was CircuitPython loaded on the board first to create the filesystem?");[color=#2e8b57][/color]
} else {[color=#2e8b57][/color]
Serial.println("QSPI OK!");[color=#2e8b57][/color]
QSPIOK = true;[color=#2e8b57][/color]
}[color=#2e8b57][/color]
playFSWav.changeVolume(1.0);[color=#2e8b57][/color]
}[color=#2e8b57][/color]
[color=#2e8b57][/color]
void playFile(const char *filename)[color=#2e8b57][/color]
{[color=#2e8b57][/color]
File f = QSPIFS.open(filename);[color=#2e8b57][/color]
[color=#2e8b57][/color]
if (!playFSWav.play(f)) {[color=#2e8b57][/color]
Serial.println("Failed to play");[color=#2e8b57][/color]
return;[color=#2e8b57][/color]
}[color=#2e8b57][/color]
Serial.println("QSPI OK!");[color=#2e8b57][/color]
}[color=#2e8b57][/color]
[color=#2e8b57][/color]
[color=#2e8b57][/color]
void loop() {[color=#2e8b57][/color]
[color=#2e8b57][/color]
digitalWrite(6, HIGH);[color=#2e8b57][/color]
[color=#2e8b57][/color]
playFile("battery.wav");[color=#2e8b57][/color]
delay(6);[color=#2e8b57][/color]
while(playFSWav.isPlaying()) delay(1);[color=#2e8b57][/color]
[color=#2e8b57][/color]
enterLowPowerState();[color=#2e8b57][/color]
Watchdog.sleep(2000);[color=#2e8b57][/color]
[color=#2e8b57][/color]
}[color=#2e8b57][/color]
[color=#2e8b57][/color]
void enterLowPowerState() {[color=#2e8b57][/color]
[color=#2e8b57][/color]
if (!playFSWav.isPlaying()) {[color=#2e8b57][/color]
digitalWrite(pin_i2s_power, LOW);[color=#2e8b57][/color]
I2S->CTRLA.bit.ENABLE=0;//THIS ACHIEVES HUGE POWER SAVINGS, BUT I DON'T KNOW HOW TO TURN IT BACK ON[color=#2e8b57][/color]
}[color=#2e8b57][/color]
[color=#2e8b57][/color]
}
You can see where I turn off “I2S->CTRLA.bit.ENABLE=0;” and it achieves amazing power savings, but I can’t figure out how to reinitialize and make it work. How do I get out of sleep and play another WAV file? I thought it would be something simple like I2S->CTRLA.bit.ENABLE=1; … any ideas on why that wouldn’t work or other solutions? Could one simply shut off the clocks to I2S? I couldn’t figure out how to do that. Thanks guys!