audio library wakes up teensy from hibernate

Both would have to be set after I2S was started but before going to sleep.
For the transmitter : I2S0_TCSR |= I2S_TCSR_STOPE which keeps it running even in STOP mode
For the receiver : I2S0_RCSR |= I2S_RCSR_STOPE which keeps it running even in STOP mode

Another method to give a try would be forcing the I2S enable after waking up, which should also relaunch the clock generation.
For the transmitter : I2S0_TCSR |= I2S_TCSR_TE
For the receiver : I2S0_RCSR |= I2S_RCSR_RE

More info in Chapter 48, page 1297 of the MK20DX256 reference manual.
 
Both would have to be set after I2S was started but before going to sleep.
For the transmitter : I2S0_TCSR |= I2S_TCSR_STOPE which keeps it running even in STOP mode
For the receiver : I2S0_RCSR |= I2S_RCSR_STOPE which keeps it running even in STOP mode

Another method to give a try would be forcing the I2S enable after waking up, which should also relaunch the clock generation.
For the transmitter : I2S0_TCSR |= I2S_TCSR_TE
For the receiver : I2S0_RCSR |= I2S_RCSR_RE

More info in Chapter 48, page 1297 of the MK20DX256 reference manual.

Is this meant to be used in addition to turning off the I2S clock gate or instead?
 
In addition. Just try it out.

Versuch macht kluch, as the Germans say... ;)

The SIM handles the clock and the activation of the I2S module. My additional "tweaks" affect a different thing, the clock generated by the I2S module afterwards. IMHO it is not an optimal idea to deactivate the I2S fully via the SIM, especially that the I2S module has support for low power and stop modes.

Study the reference manual for better understanding.
 
Last edited:
I tried both your suggestions, with and without shutting down the I2S clock via SIM and also some other configurations that I thought were clever :p Neither worked as expected.
Not of the configurations resulted in empty files, others produced the beeping sound again :confused:

Versuch macht kluch, as the Germans say...
Didn't work out for now :D
 
Both would have to be set after I2S was started but before going to sleep.
For the transmitter : I2S0_TCSR |= I2S_TCSR_STOPE which keeps it running even in STOP mode
For the receiver : I2S0_RCSR |= I2S_RCSR_STOPE which keeps it running even in STOP mode
The K66/K20 manuals says: Configures receiver operation in Stop mode. This bit is ignored and the receiver is disabled in all low- leakage stop modes


and also from the manuals:
61.1.3.2 Low-leakage modes
When entering low-leakage modes, the Stop Enable (TCSR[STOPE] and RCSR[STOPE]) bits are ignored and the SAI is disabled after completing the current transmit and receive Frames. Entry into stop mode is prevented (not acknowledged) while waiting for the transmitter and receiver to be disabled at the end of the current frame.

'deepSleep' and 'hibernate' are low-leakage modes so that clock cannot remain active. You might have to monitor the I2S Transmitter and Receiver for them to be officially disabled before going into low power mode i.e. 'deepSleep', 'hibernate'
 
Great, it's working! Thank you WMXZ and duff.

You have to enable the I2S-clock after the wake up:
Code:
SIM_SCGC6 |= SIM_SCGC6_I2S;
worked for me!

What file is this code being added to and which line? I am using a teensy 4.0 and the corresponding Audio Adapter Board. When I searched "SIM_SCGC6" in Duff's github, I see that it's used in the SnoozeAlarm.cpp for other teensy models, but it is not in the code for the teensy 4.0. Was hoping to find it in used in there for context clues.

Background on my issue:
I'm trying to integrate two pieces of code: 1) The first is the code Duff provided here (link 1 below) which enables you to schedule snooze functionality. The second is Arduino's example file (examples>Audio>WavFilePlayer). Perhaps somewhat obviously, the aim is to play audio on a schedule and have the teensy go into low power mode when the audio isn't playing.

link 1: https://forum.pjrc.com/threads/60695-Teensy-3-6-RTC-not-continues-time-in-hibernation

I've pasted my code below. After incorporating the code under the "Teensy Audio Setup" heading, my teensy no longer wakes up from hibernate. In the name of isolating the problem for more efficient debugging, I've commented out all lines following these ones that have to do with the audio player. I think my problem is caused by issue noted in this thread, but I do not know where to insert that line of code in the header files. Including these other details in case my thinking is mistaken and the problem lies elsewhere. Thanks so much for your help in advance!

Code:
//This code combines Duff's code for scheduled teensy sleep with the WAV File player example

#include <Snooze.h>
#include <TimeLib.h>
#include <TimeAlarms.h>

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
//---------------------------------------------------------------------------
// Load drivers
SnoozeAlarm alarm;
// SnoozeUSBSerial driver does what Serial does like "print", -
// "println", "prinf", etc and also handles the effects of using -
// the Arduino Serial monitor and sleeping. Use it when you -
// want to print to serial monitor for sleeping applications.
SnoozeUSBSerial usb;
//---------------------------------------------------------------------------
// install drivers to a SnoozeBlock
SnoozeBlock config_teensy36(usb, alarm);
//---------------------------------------------------------------------------
// Teensy Audio Setup

//Going sequentially from the top, commenting out all audio stuff, this is where I hit issues
//once these lines are uncommented, the teensy does not wake up as instructed
AudioPlaySdWav           playWav1;
AudioOutputI2S           audioOutput;
AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
AudioControlSGTL5000     sgtl5000_1;

// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

//---------------------------------------------------------------------------
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWriteFast(LED_BUILTIN, HIGH); //turn the LED on
  
  // Set RtcTimer for test mode (Teensy should wake up in 10 seconds)
  alarm.setRtcTimer(0, 0, 10);// hour, min, sec
  // set the Time library to use Teensy 3.6's RTC to keep time
  setSyncProvider(getTeensy3Time);
  
  while (!usb);  // Wait for Arduino Serial Monitor to open
  delay(100);
  if (timeStatus() != timeSet) {
    usb.println("Unable to sync with the RTC");
  } else {
    usb.println("RTC has set the system time");
  }
  
  // Set timer for test mode
  Alarm.timerRepeat(10, GoToSleep); //go to sleep 10 sec after power on
  // Set timer For productive mode
  //Alarm.alarmRepeat(22,00,00,GoToSleep);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  /*
  AudioMemory(8);
  
  // Comment these out if not using the audio adaptor board.
  // This may wait forever if the SDA & SCL pins lack
  // pullup resistors
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  */
}
//---------------------------------------------------------------------------
void loop() {
  if (usb.available()) {
    time_t t = processSyncMessage();
    if (t != 0) {
      Teensy3Clock.set(t); // set the RTC
      setTime(t);
    }
  }
  digitalClockDisplay();
  Alarm.delay(1000);
}
//---------------------------------------------------------------------------
void GoToSleep() {
  // Set RtcTimer for productive mode (Teensy should wake up at 7:00am )
  //alarm.setRtcTimer(9, 0, 0);// hour, min, sec
  usb.println("Going to hibernate Sleep now");
  delay(5);
  digitalWriteFast(LED_BUILTIN, LOW);
  Snooze.hibernate( config_teensy36 );
  digitalWriteFast(LED_BUILTIN, HIGH);
  setSyncProvider(getTeensy3Time);
  //usb.println("Playing Audio");
  //delay(5);
  //playFile("BACH.WAV");  // filenames are always uppercase 8.3 format
}
//---------------------------------------------------------------------------
time_t getTeensy3Time() {
  return Teensy3Clock.get();
}
//---------------------------------------------------------------------------
void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(year());
  Serial.print("-");
  Serial.print(month());
  Serial.print("-");
  Serial.print(day());
  Serial.println();
}
//---------------------------------------------------------------------------
/*  code to process time sync messages from the serial port   */
#define TIME_HEADER  "T"   // Header tag for serial time sync message
unsigned long processSyncMessage() {
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
  if (Serial.find(TIME_HEADER)) {
    pctime = usb.parseInt();
    return pctime;
    // check the value is a valid time (greater than Jan 1 2013)
    if ( pctime < DEFAULT_TIME) {
      // return 0 to indicate that the time is not valid
      pctime = 0L; 
    }
  }
  return pctime;
}
//---------------------------------------------------------------------------
void printDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0
  usb.print(":");
  if (digits < 10)
    usb.print('0');
  usb.print(digits);
}
//---------------------------------------------------------------------------
/*
void playFile(const char *filename)
{
  Serial.print("Playing file: ");
  Serial.println(filename);

  // Start playing the file.  This sketch continues to
  // run while the file plays.
  playWav1.play(filename);

  // A brief delay for the library read WAV info
  delay(25);

  // Simply wait for the file to finish playing.
  while (playWav1.isPlaying()) {
    // uncomment these lines if you audio shield
    // has the optional volume pot soldered
    //float vol = analogRead(15);
    //vol = vol / 1024;
    // sgtl5000_1.volume(vol);
  }
}
  */
  //---------------------------------------------------------------------------
 
Back
Top