0

I hope there are a few people here who have advanced experience in embedded systems: I designed a PCB with an Atmel Samd21 MCU which is supposed to play .wav files over the amplifier TAS5805 (connected by i2s). The .wav file is run via DMA (data from SD card). Everything works fine and I can hear my selected sounds. But when I start to run a watchdog timer or sleep function, I can't hear my sounds after that, even when I disabled the WDT before again.

My question is: Can a clock in an MCU be influenced by initializing another clock? I guess there are some troubles with the RT clock & i2s sync. Did someone have similar problems and knows how to solve it? I am grateful for every advice/approach.

Also I appended a test code. Maybe that's helpful to understand what I am talking about.

Thank you!

#include <SPI.h>
#include <SD.h>
#include <ArduinoSound.h>
#include <TAS5805.h>
#include <Adafruit_SleepyDog.h>
#include <ArduinoLowPower.h>

//Amplifier/ Audio
class TAS5805 TAS5805_AMP;
SDWaveFile waveFile;

//SD Card
volatile int SDCARD_CS_PIN = 28;

bool wdt_on = false;

void setup() {
  Serial.begin(9600);
  while(!Serial){};

  pinMode(8, OUTPUT); //PIN_TAS5805_SHDN =8
  digitalWrite(8, HIGH);


  //initialize SD card
  SDcardInit();

  TAS5805_AMP.powerDown();
}

void loop(){


  if(Serial.available()){
    char c = Serial.read();

    if(c=='x'){
      LowPower.sleep(5000); //sleep for 5 seconds
    }
    else if(c=='c'){
      Serial.println("Enable WDT");
      Watchdog.enable(1000000); //set Watchdog (1000 seconds timer)
      wdt_on=true;
    }
    else if(c=='v'){
      Serial.println("Disable WDT");
      Watchdog.disable();
      wdt_on=false;
    }
    else if(c=='b'){
      playFile("test.wav",0); //play single
    }
    else if(c=='n'){
      playFile("test.wav",1); //loop
    }
    else if(c=='m'){
      Serial.println("stop playing");
      AudioOutI2S.stop();
    }
  }
  if(wdt_on)
    Watchdog.reset();
}

void SDcardInit(){
  if (!SD.begin(SDCARD_CS_PIN)) {
    Serial.println("SD Card Error");
    while (1);
  }
  Serial.println("SD Card detected");
  delay(3000);
}

void playFile(String s, bool loopMode){

  waveFile = SDWaveFile(s);

  // check if the WaveFile is valid
  if (!waveFile) {
    Serial.println("WAV invalid");
    delay(3000);
  }
  else{

    Serial.println("found valid file");

    TAS5805_AMP.begin(0x2D); //0x2D -> slave address

    TAS5805_AMP.setVol(5);//50% volume from amplifier

    // full volume from MCU
    AudioOutI2S.volume(100);

    // check if the I2S output can play the wave file
    if (!AudioOutI2S.canPlay(waveFile)) {
    Serial.println("unable to play!");
    delay(3000);
    }
    else{
      Serial.println("play file");
      if(loopMode==0){
        AudioOutI2S.play(waveFile);       
      }
      else{
        AudioOutI2S.loop(waveFile);
      }
    }
  }
}
  • A 1000 second watchdog period is unlikely - the maximum period is 16384 GCLK_WDT cycles - what is your GCLK_WDT frequency? It gac be as high as 48MHz which would allow you only 1.36ms. What is the input sequence that causes the error? – Clifford Apr 28 '20 at 16:18
  • The code at https://github.com/adafruit/Adafruit_SleepyDog/blob/master/utility/WatchdogSAMD.cpp states that GCLK_WDT is 1024Hz, so 16.384MHz is the limit, however the GCLK generators are shared, if some other peripheral driver you are using modifies the same GCLKGEN that might cause the WDT timeout to be much shorter. It uses GCLKGEN 2 – Clifford Apr 28 '20 at 16:47
  • Sorry - typo - should have written 16.384 seconds not MHz. – Clifford Apr 29 '20 at 07:28
  • @Clifford thanks for your answer! So you think 1000s WD period are way too much? But the watchdog works fine. So it might be a conflict in the clock generator which disrupt the i2s/DMA sync? – Tiborko Apr 29 '20 at 18:23
  • No, I am saying you are kidding yourself if you think it will run for 1000 seconds without being reset. The documentation states that it will set the nearest timeout supported by the hardware - about 16.5 seconds. I am not suggesting that it is in any way relevant to your problem, just an observation. It is an odd value to set in any case; if it were achievable and your code hung, you'd unnecessarily wait more than 16 minutes before a restart. I looked at the source for some of the libraries you are using, but I didn't search exhaustively, you are in a better position to do that. – Clifford Apr 29 '20 at 18:41
  • To be completely clear nothing I have written in _comments_ should be considered an _answer_. If I had an answer, I'd post one. Just some things for _you_ to investigate. – Clifford Apr 29 '20 at 18:45

0 Answers0