correct way to restart the encoding procedure

Designing hardware that use VLSI Solution's devices as the system controller for the entire design.
Post Reply
Davides
Senior User
Posts: 34
Joined: Thu 2016-05-26 17:37

correct way to restart the encoding procedure

Post by Davides » Wed 2016-10-26 18:24

Hi,

i'm working with the vs1063a, and I have some questions about the correct way to restart the encoding procedure (i'm using ogg encoding) :

I used the encoding procedure explained in the datasheet (11.6.2, pag. 61), but i'm not sure what is the correct way to restart the encoding procedure after finalizing recording; the datasheet says to give a software reset, is ok to use "((void (*)(void))(0x50))();" ? After a software reset, do I have to set the SCI_CLOCK again? Do I have to call InitHardware() again?

Do I have set samplerate and the other parameters again?

Because I'm reading the adc value (DECIM_DATA_LEFT) to check the volume, after a software reset do i have to set DECIM_CONTROL again? I ask this because, I obtained DECIM_DATA_LEFT values very different (for example, 30 decibel and 50 decibel) in the same environmental conditions before and after restart encoding (calling "((void (*)(void))(0x50))();" ).

What about the interrupt? I'm already re-activating the timer interrupt in the idle_hook function after CallIROM4(Encoders), so my question is: after a software reset, in order to start encoding again, do I have to disable and re-enable the interrupt ? Or set to zero the timer counter registers?

Thank you very much for any kind of help you can provide.

Davide

User avatar
Henrik
VLSI Staff
Posts: 1101
Joined: Tue 2010-06-22 14:10

Re: correct way to restart the encoding procedure

Post by Henrik » Thu 2016-10-27 9:23

Hello Davide!

You are now in slightly uncharted territory as our customers usually do "one-time recordings", i.e. their default operating mode is playback, and recording is only started once in a while. So, by default I would suggest doing a software reset back to playback mode, then doing a full encoder setup again. This will of course take time, so it would be interesting to see whether there might be some shortcuts.

Kind regards,
- Henrik
Good signatures never die. They just fade away.

Davides
Senior User
Posts: 34
Joined: Thu 2016-05-26 17:37

Re: correct way to restart the encoding procedure

Post by Davides » Thu 2016-10-27 10:43

Hello Henrik,

thanks for your answer.

As regards the software reset, in order to get consistent behavior after every restart , which one do you think is better to use?

1) ((void (*)(void))(0x4000))(); /*restart ROM*/

2) ((void (*)(void))(0x0050))(); /*restart your firmware without reloading*/

Kind regards

Davide

User avatar
Henrik
VLSI Staff
Posts: 1101
Joined: Tue 2010-06-22 14:10

Re: correct way to restart the encoding procedure

Post by Henrik » Thu 2016-10-27 11:00

Davides wrote:Hello Henrik,

thanks for your answer.

As regards the software reset, in order to get consistent behavior after every restart , which one do you think is better to use?

1) ((void (*)(void))(0x4000))(); /*restart ROM*/

2) ((void (*)(void))(0x0050))(); /*restart your firmware without reloading*/
I would recommend SciWrite(SCI_MODE, SciRead(SCI_MODE) | SM_RESET); which is almost equivalent to (1), the only difference being that (1) sets bit SM_SDINEW and the SciWrite() method doesn't. As you probably are using SM_SDINEW anyhow, there is no practical difference. This requires you to reload and restart the Patches package.

You could also try method (2) after setting appropriate bits in SCI_MODE (turning encoding mode on or off), but I am not absolutely sure if it works. But if it does a couple of times, then it would do so indefinitely.

Kind regards,
- Henrik
Good signatures never die. They just fade away.

User avatar
pasi
VLSI Staff
Posts: 1468
Joined: Thu 2010-07-15 16:04

Re: correct way to restart the encoding procedure

Post by pasi » Thu 2016-10-27 12:35

I think Henrik is answering the case when the chip is controlled from the outside through SCI.

If you are running code inside the vs1063 restarting by watchdog reset would be the most reliable. (You need to drop to 1.0x clock, then enable watchdog.)

Code: Select all

	      clockX = 2;
	      SetRate(10);
	      USEX(WDOG_CONFIG) = 1;
	      USEX(WDOG_RESET) = WDOG_RESET_VAL;
	      while (1)
		  ;
There is a hardware bug in the ADC - disabling and re-enabling it may cause the input channels to be swapped. The patches package contains a workaround for this. The encoding routine disables the ADC when the recording end procedure is used, so the issue will be triggered on the next use if you don't take the precautions. Using the watchdog also gets around the issue because after reset the ADC starts from the correct state.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

User avatar
Henrik
VLSI Staff
Posts: 1101
Joined: Tue 2010-06-22 14:10

Re: correct way to restart the encoding procedure

Post by Henrik » Fri 2016-10-28 14:43

Yes,

my thoughts were in the wrong place. Pasi's advice to use the watchdog is definitely the best way to get to point zero when running your code inside VS10xx.

Kind regards,
- Henrik
Good signatures never die. They just fade away.

Davides
Senior User
Posts: 34
Joined: Thu 2016-05-26 17:37

Re: correct way to restart the encoding procedure

Post by Davides » Wed 2016-11-09 13:48

Ok, thank you very much for your help.

I have an application that streams out ogg audio (MIC-LINE) via UART.
I'm using the DECIM_DATA_LEFT to check the volume (i use the maximum value (calculated within the UserHook function) of a set , and reset it every time i use it). I'm trying to switch the encoder VS1063a into low power mode (by setting USEX(SCI_CLOCKF) = CORE_CLOCK_1X;) when the volume is under a certain threshold.

To switch from normal mode to low power mode I perform a software reset (because i need to keep the value of some flag to restart from right the mode ) with:

((void (*)(void))(0x0050))(); /*restart your firmware without reloading*/

After some tests where I collected the values of DECIM_DATA_LEFT, I noticed that, between the normal mode and the low power mode, there is an offset in the value of DECIM_DATA_LEFT; considering the same environmental conditions, in the normal mode the average volume is 15 dB higher compared to the low power mode.

Could you please help me to solve the problem of this offset?

This is the code:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void UserHook(void)
{
if( startup == 1)
{
USEX(INT_ENABLE) |= (1 << INT_EN_TIM1);
startup = 0;
}

vol = abs(USEX(DECIM_DATA_LEFT));
if(vol > maxVol)
{
maxVol = vol;
}

}

void main() {

inithw();

startup = 1;

CallIROM4(Encoders); /* loop there until reset */

}

void inithw()
{

//disable interrupts temporarily
Disable();

// configure the ADC samplerate at 24 kHz
USEX(DECIM_CONTROL) = DECIM_ENABLE | DECIM_FACTOR24K;

if(flagPlay == 1)
{
// set core clock
USEX(SCI_CLOCKF) = CORE_CLOCK_4_5X;
}
else if(flagPlay == 0)
{

// set core clock
USEX(SCI_CLOCKF) = CORE_CLOCK_1X;
}

// perform essential audio setup
InitHardware();

// set UART speed for serial port
uartByteSpeed = 11520U;
USEX(UART_DIV) = UartDiv();

// disable analog powerdown
USEX(SCI_STATUS) &= ~((1<<SCIST_APDOWN1) | (1<<SCIST_APDOWN2));

// 1 = LINE IN, 0 = MIC
USEX(SCI_MODE) &= ~(1<<SCIMB_LINE);


USEX(SCI_AICTRL0) = 16000;
USEX(SCI_AICTRL1) = 2048;
USEX(SCI_AICTRL3) = AICTRL3_VORBIS | AICTRL3_LEFT; // | AICTRL3_UARTEN; // for the test I left the UART available for checking the volume (see MyTimerInterruptHandler() below)

if(flagPlay == 1)
{
USEX(SCI_AICTRL3) |= AICTRL3_PAUSEON;
}
else if(flagPlay == 0)
{

USEX(SCI_AICTRL3) &= ~ AICTRL3_PAUSEON;
}

parametric_x.i.encoding.serialNumber = 0x87654321;
parametric_x.i.encoding.txUartDiv = 0;
parametric_x.i.encoding.txUartByteSpeed = 11520;
parametric_x.i.encoding.txPauseGpio = 0;

USEX(SCI_WRAMADDR) = RQ_MODE_QUALITY | RQ_OGG_PAR_SERIAL_NUMBER | 5 | (1<<RQ_OGG_LIMIT_FRAME_LENGTH_B);

// set A/D parameters
memcpyXY(agcConsts, agcConstsInit, sizeof(agcConsts));
memset(&adcControl, 0, sizeof(adcControl));

adcControl.agc[0].gain = -32767;
adcControl.agc[1].gain = -32767;
adcControl.adcMode = USEX(SCI_AICTRL3) & 7;

CONFIGURE_LED_1;
CONFIGURE_BUTTON_1;
GPIO_CONFIGURE_AS_INPUT(LED_2);



if(flagPlay == 1)
{
// 0.5 sec (clockF 4_5x)
USEX(TIMER_T1H) = 1;
USEX(TIMER_T1L) = 43743;
USEX(TIMER_CONFIG) = 255;
USEX(TIMER_ENABLE) = (1 << 1);
}
else if(flagPlay == 0)
{

// 0.5 sec (clockF 1x)
USEX(TIMER_T1H) = 0;
USEX(TIMER_T1L) = 23999;
USEX(TIMER_CONFIG) = 255;
USEX(TIMER_ENABLE) |= (1 << 1);
}

USEX(INT_ENABLE) = (1<<INT_EN_MODU) | (1<<INT_EN_TX) | (1 << INT_EN_TIM1);

Enable();


}

auto void MyTimerInterruptHandler(void)
{

dbVol = (u_int16)(20*log10(maxVol));

putch(dbVol & 0xFF); // to collect the value during the test

maxVol = 0;

if((dbVol < volThreashold) && (flagPlay == 1))
{
flagPlay = 0;
((void (*)(void))(0x0050))(); /*restart your firmware without reloading*/
}
else if((dbVol > volThreashold) && (flagPlay == 0))
{
flagPlay = 1;
((void (*)(void))(0x0050))(); /*restart your firmware without reloading*/
}


}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Thanks a lot

Davide
Last edited by Davides on Wed 2016-11-09 15:13, edited 1 time in total.

Davides
Senior User
Posts: 34
Joined: Thu 2016-05-26 17:37

Re: correct way to restart the encoding procedure

Post by Davides » Wed 2016-11-09 14:07

Sorry, i forgot a question:

Is it possible to read DECIM_DATA_LEFT without launching the function CallIROM4(Encoders) ?

I tried it but if I don't launch CallIROM4(Encoders), DECIM_DATA_LEFT is always 0x00 (of course i first set USEX(DECIM_CONTROL) = DECIM_ENABLE | DECIM_FACTOR24K;).

Thanks again

Davide

User avatar
pasi
VLSI Staff
Posts: 1468
Joined: Thu 2010-07-15 16:04

Re: correct way to restart the encoding procedure

Post by pasi » Thu 2016-11-10 16:10

Are you making sure the analog is out of powerdown?

Code: Select all

    USEX(SCI_STATUS) &= ~((1<<SCIST_APDOWN1) | (1<<SCIST_APDOWN2));
    USEX(DECIM_CONTROL) = DECIM_FACTOR24K | DECIM_ENABLE;
 
Also note that if you enable, disable, and re-enable DECIM without a reset, you may get the channels swapped.

The following routine uses the powerdown bit to check if the channels are swapped and try restarting the decimator again.

Code: Select all

/* Check for and correct channel swap (DECIM restart bug) */
void DecimCheck(void) {
    register u_int16 decim = USEX(DECIM_CONTROL);
    register u_int16 lim = 0, val;
    register u_int16 tries = 0;
    decim |= DECIM_ENABLE | DECIM_MODU2_PD; /*right chn to powerdown*/
    lim = clockX * (512/2 * 14); /* 13 seems enough, we use 14 */
    if (USEX(SCI_STATUS) & (1<<SCIST_AD_CLOCK))
	lim <<= 1; /*3MHz mode, double the wait*/
 again:
    tries++;
    USEX(DECIM_CONTROL) = decim;
    /* Wait at least 14 samples .. */
    {
	register u_int16 i;
	for (i=0; i<lim; i++) { /*two cycles per loop*/
	    USEX(DECIM_DATA_LEFT);
	    USEX(DECIM_DATA_LEFT);
	}
    }
    /*if left chn is min/max, wrong order*/
    val = USEX(DECIM_DATA_LEFT);
    if (val == 0x8000U || val == 0x7fffU) {
	if (tries < 0x40) {	    
	    USEX(DECIM_CONTROL) &= ~DECIM_ENABLE;
	    goto again;
	}
    }
    /* take the other channel out of powerdown */
    USEX(DECIM_CONTROL) = decim & ~DECIM_MODU2_PD;
}
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

Post Reply