This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PCM1862: Problem with Energysense signal loss function

Part Number: PCM1862

Hi,

I want to check if signal is lost in active mode using the energysense function. I'm not using/checking the INT pin, I'm just checking the INT_STAT register (Page.0 0x61) to check if an interrupt occurred due to a signal loss.

The issue I'm having is the interrupt continues to occur even if signal is present above the signa loss threshold. Below is what I'm sending in steps, can you help me figure out what I'm doing wrong.

Step 1, I start by initializing the signal detector and signal lost thresholds, set up the energysense related registers and enable the energysense interrupt:

const cfg_reg data[] = {
// set signal detect to -57dB (minimum -57dB, default -40)
{ 0x00, 0x01 }, // change to register page 1
{ 0x02, 0x2D }, // write the memory address of resume threshold
{ 0x04, 0x00 }, // bit[23:15]
{ 0x05, 0x2E }, // bit[15:8]
{ 0x06, 0x49 }, // bit[7:0]
{ 0x01, 0x01 }, // execute write operation

// set signal lost to -57dB (minimum -110dB, default -80dB)
{ 0x00, 0x01 }, // change to register page 1
{ 0x02, 0x2C }, // write the memory address of loss threshold
{ 0x04, 0x00 }, // bit[23:15]
{ 0x05, 0x2E }, // bit[15:8]
{ 0x06, 0x49 }, // bit[7:0]
{ 0x01, 0x01 }, // execute write operation

// configure rest of registers
{ 0x00, 0x00 }, // change to page 0
{ 0x60, 0x00 }, // disable energy sense interrupt
{ 0x31, 0xF0 }, // SIGDET_TRIG_MASK: mask unused channels 3 & 4
{ 0x32, 0xFF }, // clear the SIGDET_STAT register. Write 0xFF and 0x00 to SIGDET_STAT reg
{ 0x32, 0x00 },
{ 0x33, PCM1862_SIGDET_LOSS_TIME }, // SIGDET_LOSS_TIME: amount of time for signal detect/loss minutes (I'm using 1 minute, but it's actually 30 sec because I'm running at 96KHz)
{ 0x36, 0x00 }, // SIGDET_INT_INTVL: no repeat interrupts
{ 0x62, 0x13 }, // INT_PLS: set duration of the interrupt to be a sticky (on) until cleared (is it only for the physical int pin?)
{ 0x60, 0x01 }, // enable energy sense interrupt
};

transmitRegisters(data, sizeof(data)/sizeof(data[0]));

Step 2, For my application, I then check if the interrupt occurred due to signal loss, if true I go to step 3, if false I poll again:

bool onSignalLossInterrupt()
{
   // stack
   char data = 0x61; // register to read from, look at INT_STAT (Page.0 0x61).

   i2c.write(PCM1862_ADD, &data, 1, true); // do not send stop at end
   int fail = i2c.read(PCM1862_ADD, &data, 1, false); // returns 0 on "ACK"
   if(!fail) {
      if(data & 0x01) { // energy sense interrup ocurred
         // check register 0x32 for SIGDET_STAT over channel 1 or 2,
         // anyway, returning true here should be enough
         data = 0x61;
         i2c.write(PCM1862_ADD, &data, 1, true); // do not send stop at end
         fail = i2c.read(PCM1862_ADD, &data, 1, false); // returns 0 on "ACK"
         if(!fail) {
            if(data > 0)
               return true;
         }
      }
   }
   return false;
}

Step 3, interrupt occurred, so I disable the interrupt flag, change signal loss threshold, and clear SIGDET_STAT (Page.0 0x32) register:

const cfg_reg data[] = {
// disable the interrupt
{ 0x00, 0x00 }, // change to page 0
{ 0x60, 0x00 }, // disable energy sense interrupt

// set the signal loss threshold to –110 dB (so that the interrupt is no longer generated by internal logic)
{ 0x00, 0x01 }, // change to register page 1
{ 0x02, 0x2C }, // write the memory address of loss threshold
{ 0x04, 0x00 }, // bit[23:15]
{ 0x05, 0x00 }, // bit[15:8]
{ 0x06, 0x1A }, // bit[7:0]
{ 0x01, 0x01 }, // execute write operation

// clear the SIGDET_STAT (Page.0 0x32) register
{ 0x00, 0x00 }, // change to page 0
{ 0x32, 0xFF }, // clear the SIGDET_STAT register. Write 0xFF followed by 0x00 to SIGDET_STAT reg
{ 0x32, 0x00 },
};

transmitRegisters(data, sizeof(data)/sizeof(data[0]));

Then I go back to step 1, 2, 3 again.

Your help is appreciated,

Alex

  • Hi Alex,

    For SIGDET_STAT, After writing 0xFF what is the read value, after writing 0x00, what is the read value?

    Also, what is the timing of the loop and the reset sequence. For troubleshooting, disregard the loop and manually test your reset sequence with a 1 min wait after detection in INT_STAT.

    Regards,

  • Hi Daveon,

    Thanks for the suggestion. I did as you said and I'm reading 0x00 after writing 0xFF and 0x00 after writing 0x00. If I'm not mistake, according to the steps in 9.3.15.2.1 in datasheet I believe that is the correct behavior.

    My loop is running to check every 10sec to see if interrupt occurred and it was showing that it did even though it should not until after 1 minute (or in my case 30 sec because sample rate is 96KHz). Also, the interrupt occurs even if there is large signal present above the threshold of signal loss which is -57dB.

    Thanks,

    Alex

  • Hi Alex,

    Additional comments

    • I noticed signal loss and resume threshold are the same, try making resume/detection level greater than loss.
      • Also implement dummy writes and dummy reads for validation ( shown in 9.5.5 & Mixer excel)
    • Despite interrupt or with interrupt masked, does the ADC work properly? i.e good data on SDOUT
    • Instead of RESET method, does transitioning device to sleep mode illicit same interrupt response?

    Regards,

  • Hi Daveon,

    I added dummy writes. Changed the signal\resume detection to -40dB and left the signal loss at -57dB.

    Now it seems to be working. The interrupt is set when there is no signal and not set when there is signal larger than the threshold. However, the interrupt occurs until 2 min and 30 sec after loss of signal, but the setting is for 1 minute.

    I'll check all the settings again and continue testing. At least we are getting somewhere.

    Thanks,

    Alex

  • Hi Alex,

    Good to hear, I will mark as resolved for now, If any additional help is needed just comment on thread and it will open again for my response.

    Regards,