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?
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
daap_reg_access = __hasDAPRegs();
if (1 == daap_reg_access)
__message "Enabling low ower debug mode in device\r\n";
__writeDPReg(0x01000000, 0x08); // Select AP, 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
__message "No DP/AP reg access available\r\n";
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.
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.
In reply to 4711:
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.
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:
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.