Chapter 18 - Hongjayeong-02/Basic_SoC_implementation GitHub Wiki

18. Power Management โ€” Standby Mode + Wakeup Pin

Verification Status

Build / Link       : PASS
B1 โ†’ Standby Entry : PASS
PA0 WKUP โ†’ Wakeup  : NOT VERIFIED

Standby ์ง„์ž…๊นŒ์ง€๋Š” ์‹ค์ œ NUCLEO-F439ZI์—์„œ ํ™•์ธํ–ˆ๋‹ค.

PA0(WKUP)์„ ์ด์šฉํ•œ wake-up์€ ์ ํผ์„ ์ด ์—†์–ด ์•„์ง ๊ฒ€์ฆํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.


Goal

NUCLEO-F439ZI์˜ B1 ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ STM32F439ZI๋ฅผ Standby Mode๋กœ ์ง„์ž…์‹œํ‚จ๋‹ค.

์ดํ›„ PA0์˜ WKUP ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ system์„ ๊นจ์šฐ๋Š” ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•œ๋‹ค.

Normal Operation
      โ†“
B1 Press
      โ†“
PC13 EXTI
      โ†“
LED OFF
      โ†“
Configure Standby
      โ†“
SLEEPDEEP = 1
      โ†“
__WFI()
      โ†“
STANDBY

Wake-up ๋ชฉํ‘œ:

PA0 WKUP
LOW โ†’ HIGH
      โ†“
Wakeup Event
      โ†“
System Reset
      โ†“
main() from beginning
      โ†“
SBF Check
      โ†“
"System resume from Standby....."

1. STM32 Low-Power Modes

STM32F4์˜ ๋Œ€ํ‘œ์ ์ธ low-power mode:

Mode | ์ ˆ์ „ ์ˆ˜์ค€ | Wake-up | ํŠน์ง• -- | -- | -- | -- Sleep | ๋‚ฎ์Œ | ๋น ๋ฆ„ | CPU core ์ค‘์‹ฌ์œผ๋กœ ์ •์ง€ Stop | ์ค‘๊ฐ„ | ๋ณดํ†ต | ์ฃผ์š” system clock ์ •์ง€ Standby | ๊ฐ€์žฅ ๋†’์Œ | ๊ฐ€์žฅ ๋А๋ฆผ | ๋Œ€๋ถ€๋ถ„์˜ ํšŒ๋กœ์™€ SRAM ์ƒํƒœ ์†Œ์‹ค

5. Board Signals

์ด๋ฒˆ ์‹ค์Šต:

B1
โ†’ PC13
โ†’ EXTI13
โ†’ Standby ์ง„์ž…

Wake-up target:

PA0
โ†’ WKUP pin

LED:

LD1
โ†’ PB0

LED ์ƒํƒœ๋ฅผ ์ด์šฉํ•ด:

ON
โ†’ Normal Operation

OFF โ†’ Entering Standby

๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.


6. Practice Code

Project:

Inc/
โ”œโ”€โ”€ gpio.h
โ”œโ”€โ”€ gpio_exti.h
โ”œโ”€โ”€ standby_mode.h
โ””โ”€โ”€ uart.h

Src/ โ”œโ”€โ”€ gpio.c โ”œโ”€โ”€ gpio_exti.c โ”œโ”€โ”€ standby_mode.c โ”œโ”€โ”€ uart.c โ””โ”€โ”€ main.c

Ch07:

GPIO

Ch10:

UART

Ch14:

EXTI

driver๋ฅผ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.


7. standby_mode.h

#ifndef STANDBY_MODE_H__
#define STANDBY_MODE_H__

#include <stdint.h> #include "stm32f4xx.h"

/*

  • Configure PA0 as the external WKUP input. */ void wakeup_pin_init(void);

/*

  • Configure Standby mode and enter low-power state. */ void standby_wakeup_pin_setup(void);

/*

  • Return the current PA0 input state.
  • Complete archived function body was not preserved
  • in the current Notion source. */ uint8_t get_wakeup_pin_state(void);

#endif


8. wakeup_pin_init()

void wakeup_pin_init(void)
{
/*
* --------------------------------------------------------
* Step 1. Enable GPIOA Clock
* --------------------------------------------------------
*
* PA0 is used as the WKUP input pin.
*/
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
/*
 * --------------------------------------------------------
 * Step 2. Configure PA0 as Input
 * --------------------------------------------------------
 *
 * MODER<span>[1:0]</span>:
 *
 *     00 = Input
 *
 * Clear both bits.
 */
GPIOA-&gt;MODER &amp;= ~(1U &lt;&lt; 0);
GPIOA-&gt;MODER &amp;= ~(1U &lt;&lt; 1);


/*
 * --------------------------------------------------------
 * Step 3. Disable Internal Pull-up / Pull-down
 * --------------------------------------------------------
 *
 * PUPDR<span>[1:0]</span>:
 *
 *     00 = No Pull
 *
 * External wiring directly determines
 * whether PA0 is LOW or HIGH.
 */
GPIOA-&gt;PUPDR &amp;= ~(1U &lt;&lt; 0);
GPIOA-&gt;PUPDR &amp;= ~(1U &lt;&lt; 1);

}


9. standby_wakeup_pin_setup()

์•„๋ž˜๋Š” ๊ธฐ์กด ์‹ค์Šต์— ๋ณด์กด๋œ ํ•ต์‹ฌ ์ฝ”๋“œ๋‹ค.

void standby_wakeup_pin_setup(void)
{
/*
* --------------------------------------------------------
* Step 1. Check Wakeup Pin State
* --------------------------------------------------------
*
* ORIGINAL PRACTICE CODE:
*/
while (get_wakeup_pin_state() == 0U)
{
}
/*
 * IMPORTANT โ€” RE-TEST REQUIRED
 *
 * Existing notes described the code above as:
 *
 *     "wait until PA0 is stably LOW"
 *
 * However the actual C condition means:
 *
 *     while PA0 == 0
 *         keep waiting
 *
 * Therefore this loop exits only when:
 *
 *     PA0 != 0
 *     โ†’ HIGH
 *
 * The code and archived explanation do not agree.
 *
 * Because PA0 wake-up was NOT hardware-tested,
 * do not silently change this condition.
 *
 * Verify the intended PA0 sequence during re-test.
 */


/*
 * --------------------------------------------------------
 * Step 2. Temporarily Disable Wakeup Pin
 * --------------------------------------------------------
 *
 * PWR-&gt;CSR bit8 controls the wakeup pin.
 *
 * Disable it before clearing the old
 * wakeup condition.
 */
PWR-&gt;CSR &amp;= ~(1U &lt;&lt; 8);


/*
 * --------------------------------------------------------
 * Step 3. Clear Wakeup Flag
 * --------------------------------------------------------
 *
 * PWR-&gt;CR bit2:
 *
 *     CWUF
 *
 * Clears a previously latched wakeup event.
 */
PWR-&gt;CR |= (1U &lt;&lt; 2);


/*
 * --------------------------------------------------------
 * Step 4. Enable Wakeup Pin Again
 * --------------------------------------------------------
 *
 * PA0 WKUP detection becomes active.
 */
PWR-&gt;CSR |= (1U &lt;&lt; 8);


/*
 * --------------------------------------------------------
 * Step 5. Select Standby Mode
 * --------------------------------------------------------
 *
 * set_power_mode(PWR_MODE_STANDBY)
 *
 * configures PWR-&gt;CR.PDDS.
 *
 * Full helper implementation is not preserved
 * in the archived chapter source.
 */
set_power_mode(PWR_MODE_STANDBY);


/*
 * --------------------------------------------------------
 * Step 6. Enable Deep Sleep at Cortex-M4 Level
 * --------------------------------------------------------
 *
 * SCB SCR bit2:
 *
 *     SLEEPDEEP = 1
 *
 * Tells the Cortex-M core that WFI should
 * enter a deep low-power mode.
 */
SCB-&gt;SCR |= (1U &lt;&lt; 2);


/*
 * --------------------------------------------------------
 * Step 7. Wait For Interrupt
 * --------------------------------------------------------
 *
 * __WFI()
 *
 * WFI = Wait For Interrupt
 *
 * With:
 *
 *     PDDS = 1
 *     SLEEPDEEP = 1
 *
 * this instruction causes the MCU
 * to enter Standby.
 *
 * After this point normal code execution stops.
 */
__WFI();


/*
 * In Standby mode, successful wake-up causes
 * a reset-like restart.
 *
 * Therefore normal execution is not expected
 * to continue here.
 */

}


10. Critical Re-Test Item โ€” PA0 Condition

์ด chapter์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฏธํ™•์ธ ๋ถ€๋ถ„์ด๋‹ค.

ํ˜„์žฌ ์ฝ”๋“œ:

while (get_wakeup_pin_state() == 0U)
{
}

logic:

PA0 = 0
โ†“
Stay in while()

PA0 = 1 โ†“ Exit while()

์ฆ‰ ์ฝ”๋“œ๋งŒ ํ•ด์„ํ•˜๋ฉด:

Wait until PA0 becomes HIGH

์ด๋‹ค.

ํ•˜์ง€๋งŒ ๊ธฐ์กด ์„ค๋ช…์€:

PA0์ด LOW๋กœ ์•ˆ์ •๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ

๋ผ๊ณ  ๊ธฐ๋ก๋˜์–ด ์žˆ์—ˆ๋‹ค.

๋‘˜์€ ๊ฐ™์€ ์˜๋ฏธ๊ฐ€ ์•„๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์žฌ์‹ค์Šต์—์„œ๋Š” debugger๋‚˜ UART๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ˜๋“œ์‹œ:

PA0 LOW์ผ ๋•Œ ํ•จ์ˆ˜ ์ง„ํ–‰ ์—ฌ๋ถ€
PA0 HIGH์ผ ๋•Œ ํ•จ์ˆ˜ ์ง„ํ–‰ ์—ฌ๋ถ€

๋ฅผ ๋จผ์ € ํ™•์ธํ•œ๋‹ค.

์ด ๋ถ€๋ถ„์€ PA0 wake-up ์ž์ฒด๊ฐ€ ์•„์ง ๋ฏธ๊ฒ€์ฆ์ด๋ฏ€๋กœ ํ˜„์žฌ ์ž„์˜๋กœ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.


11. main.c

#include "gpio.h"
#include "gpio_exti.h"
#include "standby_mode.h"
#include "uart.h"

/*

  • Check whether this boot occurred
  • after leaving Standby mode. */ static void check_reset_source(void);

/*

  • Called from EXTI interrupt path. */ static void exti_callback(void);

int main(void) { /* * -------------------------------------------------------- * Step 1. Initialize UART * -------------------------------------------------------- * * Used to report wakeup status. */ uart_init();

/*
 * --------------------------------------------------------
 * Step 2. Initialize LD1
 * --------------------------------------------------------
 *
 * PB0 โ†’ LD1
 */
led_init();


/*
 * --------------------------------------------------------
 * Step 3. Initialize PA0 Wakeup Input
 * --------------------------------------------------------
 */
wakeup_pin_init();


/*
 * --------------------------------------------------------
 * Step 4. Check Previous Reset Source
 * --------------------------------------------------------
 *
 * Standby wake-up causes main() to restart.
 *
 * Therefore check SBF early during boot.
 */
check_reset_source();


/*
 * --------------------------------------------------------
 * Step 5. Indicate Normal Operation
 * --------------------------------------------------------
 *
 * LED ON:
 *
 *     board is awake
 */
led_on();


/*
 * --------------------------------------------------------
 * Step 6. Configure B1 EXTI
 * --------------------------------------------------------
 *
 * B1:
 *
 *     PC13
 *        โ†“
 *     EXTI13
 *        โ†“
 *     Standby entry
 */
pc13_exti_init();


while (1)
{
    /*
     * Main loop has no polling task.
     *
     * B1 interrupt triggers Standby entry.
     */
}

}


12. check_reset_source()

static void check_reset_source(void)
{
/*
* --------------------------------------------------------
* Step 1. Enable Power Controller Clock
* --------------------------------------------------------
*
* PWR peripheral belongs to APB1.
*/
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
/*
 * --------------------------------------------------------
 * Step 2. Check Standby Flag
 * --------------------------------------------------------
 *
 * SBF:
 *
 *     Standby Flag
 *
 * If set:
 *
 *     this boot followed Standby mode.
 */
if ((PWR-&gt;CSR &amp; PWR_CSR_SBF)
    == PWR_CSR_SBF)
{
    /*
     * -----------------------------------------------
     * Clear Standby Flag
     * -----------------------------------------------
     *
     * CSBF:
     *
     *     Clear Standby Flag
     */
    PWR-&gt;CR |= PWR_CR_CSBF;


    /*
     * Inform the user that this boot occurred
     * after Standby wake-up.
     *
     * NOTE:
     *
     * This exact message is the EXPECTED output.
     *
     * Actual PA0 wake-up has not yet been verified.
     */
    uart_write_string(
        "System resume from Standby.....\r\n"
    );


    /*
     * ORIGINAL PRACTICE CODE
     *
     * Same PA0 condition appears here.
     *
     * Again:
     *
     *     while state == 0
     *
     * means the function waits while LOW
     * and exits when HIGH.
     *
     * Re-test required.
     */
    while (get_wakeup_pin_state() == 0U)
    {
    }
}


/*
 * --------------------------------------------------------
 * Step 3. Check Wakeup Flag
 * --------------------------------------------------------
 *
 * WUF:
 *
 *     Wakeup Flag
 */
if ((PWR-&gt;CSR &amp; PWR_CSR_WUF)
    == PWR_CSR_WUF)
{
    /*
     * Clear WUF for the next low-power cycle.
     */
    PWR-&gt;CR |= PWR_CR_CWUF;
}

}


13. EXTI Callback

static void exti_callback(void)
{
/*
* --------------------------------------------------------
* Step 1. Turn LED OFF
* --------------------------------------------------------
*
* This is the last visible indication
* before entering Standby.
*
* It must happen BEFORE __WFI().
*/
led_off();
/*
 * --------------------------------------------------------
 * Step 2. Enter Standby
 * --------------------------------------------------------
 */
standby_wakeup_pin_setup();


/*
 * Once __WFI() enters Standby,
 * normal execution stops.
 */

}


14. Why LED OFF Before __WFI()?

Consider:

standby_wakeup_pin_setup();
led_off();

If standby_wakeup_pin_setup() reaches:

__WFI();

and Standby is successfully entered:

CPU execution stops

so:

led_off();

is never executed.

Therefore correct ordering:

led_off();

standby_wakeup_pin_setup();

์ด๋‹ค.

์ฆ‰:

LED OFF
โ†“
WFI
โ†“
Standby

์ด๋‹ค.


15. Standby Entry Flow

B1 press:

B1
โ†“
PC13 Rising Edge
โ†“
EXTI13
โ†“
EXTI15_10_IRQHandler
โ†“
exti_callback()
โ†“
LED OFF
โ†“
Wakeup Flag Clear
โ†“
Wakeup Pin Enable
โ†“
PDDS = 1
โ†“
SLEEPDEEP = 1
โ†“
__WFI()
โ†“
STANDBY

์ด ๋ถ€๋ถ„์€ ์‹ค์ œ board์—์„œ ํ™•์ธํ–ˆ๋‹ค.


16. Why SLEEPDEEP + PDDS?

๋‘˜์€ ์—ญํ• ์ด ๋‹ค๋ฅด๋‹ค.

SLEEPDEEP

ARM Cortex-M4 core setting:

SCB->SCR |= (1U << 2);

์˜๋ฏธ:

WFI
โ†“
Deep Sleep

PDDS

STM32-specific power setting:

PWR->CR.PDDS = 1

์˜๋ฏธ:

Deep Sleep Mode
์ค‘์—์„œ๋„
Standby ์„ ํƒ

๋”ฐ๋ผ์„œ:

SLEEPDEEP only
โ†’ Deep Sleep category

PDDS + SLEEPDEEP โ†’ Standby

๋กœ ์ดํ•ดํ•œ๋‹ค.


17. __WFI()

__WFI();

๋Š” ARM instruction:

Wait For Interrupt

์ด๋‹ค.

์ผ๋ฐ˜ ์ƒํ™ฉ์—์„œ๋Š” CPU๊ฐ€ interrupt/event๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ sleepํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ฒˆ์—๋Š” ๋ฏธ๋ฆฌ:

SLEEPDEEP = 1
PDDS      = 1

์„ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—:

__WFI()
โ†“
Standby

๋กœ ์ด์–ด์ง„๋‹ค.


18. What Happens to SRAM?

Standby์—์„œ๋Š” SRAM ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ:

uint32_t counter = 1234;

Standby ์ง„์ž… ์ „:

counter = 1234

๋ผ๊ณ  ํ•ด๋„ wake-up ํ›„:

์ด ๋ณ€์ˆ˜ ๊ฐ’์—์„œ ๊ณ„์† ์‹คํ–‰

ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.

Wake-up:

Reset
โ†“
Startup
โ†“
.data initialize
โ†“
.bss clear
โ†“
main()

๊ณผ์ •์„ ๋‹ค์‹œ ๊ฑฐ์นœ๋‹ค.

๋”ฐ๋ผ์„œ Standby๋Š”:

Pause / Resume

๊ฐ€ ์•„๋‹ˆ๋ผ:

Power Down
+
Reboot

์— ๊ฐ€๊น๋‹ค.


19. Standby Flag โ€” SBF

Wake-up ํ›„ CPU๋Š” ๋‹ค์‹œ main()๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— software ์ž…์žฅ์—์„œ๋Š”:

Power-on reset?
NRST?
Standby wake?

๋ฅผ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ:

PWR->CSR & PWR_CSR_SBF

๋ฅผ ํ™•์ธํ•œ๋‹ค.

SBF = 1
โ†“
Previous state was Standby

๋”ฐ๋ผ์„œ:

uart_write_string(
"System resume from Standby.....\r\n"
);

๊ณผ ๊ฐ™์€ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.


20. Wakeup Flag โ€” WUF

Wakeup event๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด:

WUF = 1

์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ low-power cycle์„ ์œ„ํ•ด ์ด์ „ flag๋ฅผ ๋‚จ๊ฒจ๋‘๋ฉด ์•ˆ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ:

PWR->CR |= PWR_CR_CWUF;

๋กœ clearํ•œ๋‹ค.

ํŒจํ„ด:

Check Event
โ†“
Handle Event
โ†“
Clear Flag
โ†“
Prepare Next Event

์ด๋‹ค.


21. PA0 WKUP Re-Test Procedure

์ด ๋ถ€๋ถ„์€ ์•„์ง ์‹ค์ œ ๊ฒ€์ฆ ์ „์ด๋‹ค.

์ ํผ์„ ์„ ์ค€๋น„ํ•œ ํ›„:

Initial State

PA0
โ†’ GND
โ†’ LOW

Enter Standby

B1 Press
โ†“
LED OFF
โ†“
Standby

Wake-up Test

PA0์„:

LOW
โ†“
HIGH

์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

์˜ˆ:

GND
โ†“
3.3 V

Expected:

Wakeup Event
โ†“
System Reset
โ†“
main()
โ†“
SBF detected
โ†“
UART:
System resume from Standby.....
โ†“
LD1 ON

22. Re-Test Priority

์‹ค๊ธฐ ์žฌ๊ฒ€์ฆ ๋•Œ ์ˆœ์„œ๋Š” ๋‹ค์Œ์ด ์ข‹๋‹ค.

1. PA0 IDR ํ™•์ธ
2. get_wakeup_pin_state() return ํ™•์ธ
3. while ์กฐ๊ฑด ํ™•์ธ
4. WUF clear ํ™•์ธ
5. EWUP enable ํ™•์ธ
6. PDDS ํ™•์ธ
7. SLEEPDEEP ํ™•์ธ
8. WFI
9. PA0 LOW โ†’ HIGH
10. SBF ํ™•์ธ

ํŠนํžˆ ๊ฐ€์žฅ ๋จผ์ €:

while (get_wakeup_pin_state() == 0U)
{
}

๊ฐ€ ์›๋ž˜ ์˜๋„ํ•œ sequence์™€ ๋งž๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.


23. Actual Verification Result

ํ˜„์žฌ ์‹ค์ œ ํ™•์ธํ•œ ๋ถ€๋ถ„:

Build
PASS

Download PASS

B1 EXTI PASS

LED OFF before Standby PASS

Standby Entry PASS

์‹ค์ œ ํ˜„์ƒ:

Normal
โ†’ LD1 ON

B1 Press โ†’ LD1 OFF

Standby โ†’ UART communication stops

Standby ์ง„์ž… ์ž์ฒด๋Š” ํ™•์ธํ–ˆ๋‹ค.


24. Pending Verification

์•„์ง ํ™•์ธํ•˜์ง€ ๋ชปํ•œ ๋ถ€๋ถ„:

PA0 WKUP
โ†“
Standby Exit
โ†“
System Reset
โ†“
SBF = 1
โ†“
UART Resume Message

์ด์œ :

PA0 wake-up test์šฉ jumper wire ์—†์Œ

๋”ฐ๋ผ์„œ ํ˜„์žฌ:

Standby Entry

Verified

Wakeup

Pending

์œผ๋กœ ๊ธฐ๋กํ•œ๋‹ค.


25. Build Result

๊ธฐ์กด ์‹ค์Šต ๊ธฐ๋ก:

text = 1660 bytes
data = 0 bytes
bss  = 2560 bytes
Warnings = 0

26. Debugger Verification

PWR Clock

ํ™•์ธ:

RCC->APB1ENR

Expected:

PWREN = 1

Wakeup Pin

ํ™•์ธ:

PWR->CSR

PA0 wakeup function enable bit ํ™•์ธ.


Standby Selection

ํ™•์ธ:

PWR->CR

Expected before WFI:

PDDS = 1

Cortex-M Deep Sleep

ํ™•์ธ:

SCB->SCR

Expected:

SLEEPDEEP = 1

Wakeup After Re-Test

PA0 wake ์„ฑ๊ณต ํ›„:

PWR->CSR

์—์„œ:

SBF
WUF

์ƒํƒœ๋ฅผ ํ™•์ธํ•œ๋‹ค.


27. Screenshots to Add

ํ˜„์žฌ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ:

images/ch18_build.png
images/ch18_before_standby.png
images/ch18_standby_led_off.png
images/ch18_power_registers.png

์žฌ์‹ค์Šต ํ›„ ์ถ”๊ฐ€:

images/ch18_pa0_low.png
images/ch18_pa0_high.png
images/ch18_wakeup_flags.png
images/ch18_resume_uart.png
images/ch18_wakeup.gif

๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ตœ์ข… evidence:

LD1 ON
โ†“
B1 Press
โ†“
LD1 OFF
โ†“
Standby
โ†“
PA0 LOW โ†’ HIGH
โ†“
Reset
โ†“
UART:
System resume from Standby.....
โ†“
LD1 ON

์ด๋‹ค.


28. Key Points

B1
โ†“
EXTI
โ†“
LED OFF
โ†“
PWR.PDDS
+
SCB.SLEEPDEEP
โ†“
__WFI()
โ†“
STANDBY

Wake-up:

PA0 WKUP
โ†“
Reset
โ†“
main()
โ†“
SBF
โ†“
Wakeup Detection
  • Standby๋Š” STM32F4์˜ ๊ฐ€์žฅ ๊นŠ์€ ์ €์ „๋ ฅ mode ์ค‘ ํ•˜๋‚˜๋‹ค.

  • Standby์—์„œ๋Š” SRAM๊ณผ ์ผ๋ฐ˜ execution context๊ฐ€ ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค.

  • Standby wake-up ํ›„์—๋Š” main()๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค.

  • SCB->SCR.SLEEPDEEP์€ Cortex-M core ์ฐจ์›์˜ deep-sleep ์„ค์ •์ด๋‹ค.

  • PWR->CR.PDDS๋Š” STM32์—์„œ Standby mode๋ฅผ ์„ ํƒํ•œ๋‹ค.

  • __WFI()๊ฐ€ ์‹ค์ œ low-power mode ์ง„์ž… trigger๊ฐ€ ๋œ๋‹ค.

  • PA0์€ WKUP input์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

  • SBF๋ฅผ ํ†ตํ•ด Standby์—์„œ ๊นจ์–ด๋‚œ boot์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

  • WUF๋Š” wakeup event flag๋‹ค.

  • B1 โ†’ EXTI โ†’ Standby ์ง„์ž…๊นŒ์ง€๋Š” ์‹ค์ œ ๋ณด๋“œ์—์„œ ๊ฒ€์ฆํ–ˆ๋‹ค.

  • PA0 wake-up์€ ์•„์ง hardware ๋ฏธ๊ฒ€์ฆ์ด๋‹ค.

  • ๊ธฐ์กด while (get_wakeup_pin_state() == 0) ์ฝ”๋“œ์™€ โ€œLOW ์•ˆ์ • ๋Œ€๊ธฐโ€ ์„ค๋ช…์ด ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์žฌ์‹ค์Šต์—์„œ ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•œ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ