Wake up duo 256m after poweroff

Hi, all

could you please help me to figure out how to wake up duo256m after power off without reconnecting the power source?

Are there some pins which must be shorted to wake up? From what I have understood from data sheet, there are none, but I’m not good at understanding schematics at all )

Assume the following scenario:

  1. execute poweroff command. Duo will power off
  2. Do not disconnect the PSU
  3. Short the pins
  4. duo starts
1 Like

AFAIK, ARM or RISC-V cores in such an SoC either go deep sleep (wakeups are possible from low power cores — secondary or MCU), or stop. And in the second case you can’'t do a thing unless you power-cycle the whole system.

What you need, as I see it, is the first scenario: the first core goes to sleep until woken up by other cores or an interrupt.

Maybe you can do something with the 8051 core.

1 Like

Thank you guys. Simple power on/off button seems to be a much longer story than I expected. I planned to utilize gpiokeys and busybox acpid for safe power off, but hoped that wake up could be not so complex

2 Likes

Hi, all

To continue the topic, I would like to share my experience in creating a hardware power-off button to safely shutdown Duo256m. There are a lot of such guides for Raspberry Pi, but as we do not have such luxury as prebuilt device tree overlays, all-in-one kernel, etc, it makes sense to describe how to achieve the same with Duo Buildroot SDK v2. I built RISCV version, but this is applicable for ARM, and original Duo

The outline of steps is as follows:

  1. Connect a button (push button) to Duo via some GPIO pin
  2. Make it recognized by linux kernel as power key
  3. Handle key press in user space to power off the board

For step 1 select a pin and make sure it is configured as GPIO in duo-pinmux (pinmux | Milk-V ). Connect it to the one contact of the button, and other contact to the ground.

For step 2 we will utilize the gpio-keys feature (gpio-keys). First, we have to add our button to the device tree as a “device”. For this we have to add its definition to the root node in build/boards/cv181x/sg2002_milkv_duo256m_musl_riscv64_sd/dts_riscv/sg2002_milkv_duo256m_musl_riscv64_sd.dts ( path will be slightly different for other boards/platforms). Using this file is most straightforward but not the most elegant way to add a new device.

gpio-keys {
    compatible = "gpio-keys";
    power-button {
        label = "power";
        linux,code = <116>;  // KEY_POWER
        gpios = <&porte 4 GPIO_ACTIVE_LOW>;
        wakeup-source;
    };
};

Key codes are in dt-bindings/input/linux-event-codes.h. You have to lookup your pin GPIO bank and offset in Duo256M | Milk-V I use GP22, which belongs to porte and has offset 4.

Launch kernel menuconfig as described in Using a usb camera on milk-v Duos and select Device Drivers → Input Device Support → Keyboards → GPIO Buttons to buit in kernel [*] ( CONFIG_KEYBOARD_GPIO =y). Rebuild and flash firmware. If everything is ok, in dmesg there will be something like:

[    1.207892] input: gpio-keys as /devices/platform/gpio-keys/input/input0

There will also be /dev/input/event0 device node.

To test the button, it makes sense also add evtest utility in buildroot configuration before build as described in Introduction | Milk-V

After reflashing, launch it and press the button a couple of times . If everything is set up properly, evtest will report key up/down events as below:

[root@milkv-duo]~# evtest /dev/input/event0 
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 116 (KEY_POWER)
Properties:
Testing ... (interrupt to exit)
Event: time 1747244396.860994, type 1 (EV_KEY), code 116 (KEY_POWER), value 1
Event: time 1747244396.860994, -------------- SYN_REPORT ------------
Event: time 1747244397.138591, type 1 (EV_KEY), code 116 (KEY_POWER), value 0
Event: time 1747244397.138591, -------------- SYN_REPORT ------------
Event: time 1747244399.938112, type 1 (EV_KEY), code 116 (KEY_POWER), value 1
Event: time 1747244399.938112, -------------- SYN_REPORT ------------
Event: time 1747244400.164853, type 1 (EV_KEY), code 116 (KEY_POWER), value 0
Event: time 1747244400.164853, -------------- SYN_REPORT ------------

Now step 3 - handle key press to power off. Most common options are systemd-logind or acpid daemons. But 1) we do not have systemd-logind and definitely do not want it 2) we don’t have ACPI as well… There is acpid implementation in busybox, and before I’ve realized 2), I had built it as described in Introduction | Milk-V by including

CONFIG_ACPID=y
CONFIG_FEATURE_ACPID_COMPAT=y

In busybox.config. To my surprise, it is pretty able to detect key presses!

[root@milkv-duo]~# acpid -d
acpid: power

Now we have to configure acpid to execute the poweroff command at key press. There is a tutorial Power management - Alpine Linux for this. The last step is to launch acpid at system start-up. For this let’s create /etc/init.d/S03acpid script, using S49ntp as an example and make it executable. Now we have a fully working power-off button!

The last step to finalize the design would be creating an external circuit to safely disconnect the PSU after power off and re-apply power to turn the board on.

2 Likes