How to permanently enter the LPM-mode on S1JA with Power Profiles V2 Framework

Following goal:

I've two S1JA (48-pin). Both shall stay the most time in a low power mode. Only the necessary IOs enabled and only the LOCO running. One processor shall wake up every 500ms by AGT1, do some checks and, if needed, wake up the second processor by a UART-transmission to its RXD0.
Unfortunately it seems that there are only two lpm-modes available. "standby" and "standby with snooze enabled". Setting both of them the lowPowerApply-api-call immediatelly returns without waiting for the AGT-underflow or the falling-edge on the RXD0. So I have to wait by software for the AGT1-interrupt or the incoming UART-transmission before reenter the run-mode. I'm not sure if there will be saved power in this way.
Attached an example for  the wakeup every 500ms. I need to create a while-loop to wait for the AGT1-interrupt. Beside I found, that the lpm_return_callback is called four times a second instead 2 times as to be expected due to the 500ms-timer.
The description and examples written for the S7G2 are not really helpful for the S1JA.
Does anyone have a hint how to get the lpm-mode work in the wished way on the S1JA?

 lpm-test.zip

  • First, a few assumptions.

    1. From looking at your code you are using IAR tool chain?

    2. You are trying to debug your application when you are see this behaviour of the the S1JA not staying in SW Standby mode?

     

     

    If point 2 is correct, have you set the Low Power Macro file in the debugger settings?

    By default the on chip debugger will not allow the device to enter SW Standby mode.  If you issue an instruction to enter SW Standby mode, you will only enter Sleep mode.

    This can be overwritten, by use of a MACRO file.

    Rename the attached file (low_power_debug.txt) to low_power_debug.mac and copy it to a sensible location.

    I typically have a copy of this file in the project directory of the application

     

    low_power_debug.txt
    clear_DBIRQ()
    {
    	__var daap_reg_access;
    	daap_reg_access = __hasDAPRegs();
    	if (1 == daap_reg_access)
    	{
    		__message "Enabling low ower debug mode in device\r\n";
    		__writeDPReg(0x01000000, 0x08);  // Select AP[1], bank 0
    		__writeAPReg(0x80000002, 0x00); // AP-access size. Fixed to 2: 32-bit  // Enable software access to the Debug APB bus.
    		__writeAPReg(0x80000410, 0x04); //MCUCTRL register
    		__writeAPReg(0x00000000, 0x0C); //Clear DBIRQ bit
    		
    		__writeMemory16(0xA502, 0x4001E3FE, "Memory");  // PRCR register. Enable access to SYOCDCR register
    		__writeMemory8(0x80, 0x4001E40E, "Memory");    // SYOCDR register, set DBGEN bit
    		__writeMemory16(0xA500, 0x4001E3FE, "Memory");  // PRCR register. Disable access to SYOCDCR register
    	}
    	else
    	{
    	__message "No DP/AP reg access available\r\n";
    	}
    }
    
    
    execUserPreload() 
    {
    	clear_DBIRQ();
    }
    
    execUserReset() 
    {
    	clear_DBIRQ();
    }
    

    Select this .mac file in the Options -> Debugger as shown here:

     

    You should now be able to debug your application in and out or SW Standby mode.

     

    Regards,

    Richard

  • In reply to Richard:

    Hi Richard,
    yes, I'm using IAR and indeed I'm at the moment working on the eval board until the development of target hardware will be finished.
    With your macro entering the lpm-mode now works as expected. Thank you very much for this essential hint.
    Have you an additional hint for the clock configuration in low power mode? I'm not sure if I've made the correct configuration to disable all clocks except the LOCO. There is no possibility to configure the clock direct within the lpm-profile.



    Regards
    Uwe

  • In reply to 4711:

    Uwe,
    You do not have to do anything with the clock config to enter or exit SW Standby Mode.
    When you enter SW Standby mode all clocks (except LOCO and 32kHz Sub clock [if enabled]) will stop.
    When the device wakes any clocks that were active before going into SW Standby mode will restart. When the clocks are stable, the device will begin to operate.
    The Clock source that the CPU was operating on before entering SW Standby will be the same when exiting SW Standby mode.
    A consideration is the clock startup time.
    If you are using the HOCO or external Main clock, these have a long startup and stabilisation time: several milliseconds. In comparison, the MOCO has a very short startup time: microseconds.
    You may wish to consider setting the MOCO as the clock source before entering SW Standby so that you have a quick wakeup, but the MOCO has a max freq = 8MHz.
    If required, you could switch from MOCO to the HOCO / Main clock when these are stable.
    But be aware that the MOCO has an accuracy of +/- 10% whilst the HOCO is +/- 0.1% and an external Main clock Crystal is likely to be more accurate that.
    This could be an issue as you seem to indicate that you are using the UART as a wake source. I assume that you wish to wake when you receive some data? If this is the case, what BAUD rate are you using? Is the first byte of data that you receive just used to wake the device or do you need to process that as valid data?
    If the first data byte is to be kept and processed, using the RX wake source may mean that the first data byte received in not maintained.
    A work around I have used previously is to tie the RX data line to an IRQ pin. The IRQ can be used to wake the device and then the first data byte can be received successfully.
    The issue is that for this fast wake up we need to be running on the MOCO. But because this has a low accuracy, it can introduce a large %error on data reception. Again, there is a work around of measuring the accuracy of the MOCO against a more accurate clock source, such as the HOCO, using the Clock Frequency Accuracy Measurement Circuit (CAC) peripheral. You can periodically use the CAC to run a measurement and the CAC will give an indication of what frequency the MOCO is running at. The SCI UART has a very nice fractional BAUD rate register setting which means that that BAUD rate register can be trimmed so that the SCI UART will receive data with minimal % error, even if the MOCO is running at a large + or - frequency.

    I can post some projects that show some of the above in action if you are interested?
    However, most of my work is in GCC / e2studio so it would take me a while to port to IAR.

    Regards,
    Richard
  • In reply to Richard:

    Hi Richard,
    in run mode the chips are clocked by an external 12MHz crystal. The communication is planned at 115.2 kBaud and the first byte of a transmission is important for the start sequence of the stream.
    I'll make an additional connection from RXD0 to a pin able to generate an external interrupt hoping that the crystal oscillator starts fast enough to be able to receive the first byte correct. Otherwise I'll send a dummy-zero-byte for wakeup which can than be dumped by the awakened receiver due to the framing error.
    Working examples of different wakeup techniques always would be appreciated.

    Regards
    Uwe
  • In reply to 4711:

    Uwe,

    So please be aware that if you are waking on the external main clock, this could take 2 to 3 ms.

    From the electrical characteristics in the user's hardware manual:

     

     

    At 115200 BAUD, an 8-N-1 byte only takes 86.8us

    You could miss up to 35 bytes of data whilst you are waiting for the main clock to stabilise.

    Please consider using the HOCO.  Here the wake up time is 50us MAX.  So you would only miss the first byte.

    You can always switch to the main clock once it is stable if you require the highest accuracy clock.

     

    Regards,

    Richard

  • In reply to Richard:

    I Richard,

    I paid heed to your advice and created two different clock configurations. Before entering the low power mode I switch the clock to HOCO, after return to run mode I activate the crystal oscillator. Additionally the slaves closes their incoming uart before entering the lpm, so the incomming wakeup-byte will be safe ignored.

    Now the LPM-code of the master (to be woken up by AGT1) looks like this (the ThreadX "Timer Ticks Per Second" is set to 1000):

                uint8_t dummy = 0;
                g_agt1.p_api->periodSet(g_agt1.p_ctrl, 16384, TIMER_UNIT_PERIOD_RAW_COUNTS);
                g_agt1.p_api->start(g_agt1.p_ctrl);
                g_sf_power_profiles_v2_common.p_api->lowPowerApply(g_sf_power_profiles_v2_common.p_ctrl, &g_sf_power_profiles_v2_low_power);
                g_agt1.p_api->stop(g_agt1.p_ctrl);
                g_sf_power_profiles_v2_common.p_api->runApply(g_sf_power_profiles_v2_common.p_ctrl, &g_sf_power_profiles_v2_run);    
                g_sf_uart_next.p_api->write(g_sf_uart_next.p_ctrl, &dummy, 1, TX_NO_WAIT);
    tx_thread_sleep(4);

    The consecutive slaves (to be woken up by falling edge on RXD0) sleeps in this way:

                uint8_t dummy = 0;
                g_sf_uart_prev.p_api->close(g_sf_uart_prev.p_ctrl);
                g_cgc.p_api->clocksCfg(&g_cgc_cfg_HOCO);
                g_sf_power_profiles_v2_common.p_api->lowPowerApply(g_sf_power_profiles_v2_common.p_ctrl, &g_sf_power_profiles_v2_low_power);
                g_ext_wakeup_irg.p_api->enable(g_ext_irq_sens.p_ctrl);
                g_sf_power_profiles_v2_common.p_api->runApply(g_sf_power_profiles_v2_common.p_ctrl, &g_sf_power_profiles_v2_run);    
                g_ext_wakeup_irg.p_api->disable(g_ext_irq_sens.p_ctrl);
                g_cgc.p_api->clocksCfg(&g_cgc_cfg_CRYSTAL);
                if(!is_last)
                    g_sf_uart_next.p_api->write(g_sf_uart_next.p_ctrl, &dummy, 1, TX_NO_WAIT);
                tx_thread_sleep(4);
                g_sf_uart_prev.p_api->open(g_sf_uart_prev.p_ctrl, g_sf_uart_prev.p_cfg);

     

    For the final test I've to wait for the second eval board to have at least one slave.

    Thank you very much for your support.

  • In reply to 4711:

    Hmm, with hindsight the slaves code doesn't make much sense. If I close the slaves incoming uart before lpm and wait on master at least 4 milliseconds before sending the next data after the wakeup-byte It is not necessary furthermore to change the clock to HOCO before sleep.