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