mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 10:03:50 +01:00
cpu/gdv32: add pm_layered support
This commit is contained in:
parent
b02ffb21b8
commit
cfbda4022a
@ -22,7 +22,9 @@ config CPU_FAM_GD32V
|
|||||||
|
|
||||||
select MODULE_PERIPH_CLIC if TEST_KCONFIG
|
select MODULE_PERIPH_CLIC if TEST_KCONFIG
|
||||||
select MODULE_PERIPH_WDT if MODULE_PERIPH_PM && HAS_PERIPH_WDT
|
select MODULE_PERIPH_WDT if MODULE_PERIPH_PM && HAS_PERIPH_WDT
|
||||||
select PACKAGE_NUCLEI_SDK
|
select PACKAGE_NMSIS_SDK
|
||||||
|
|
||||||
|
menu "GD32V configuration"
|
||||||
|
|
||||||
config CPU_MODEL_GD32VF103VBT6
|
config CPU_MODEL_GD32VF103VBT6
|
||||||
bool
|
bool
|
||||||
@ -48,4 +50,6 @@ config CPU_CORE
|
|||||||
|
|
||||||
rsource "periph/Kconfig"
|
rsource "periph/Kconfig"
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
source "$(RIOTCPU)/riscv_common/Kconfig"
|
source "$(RIOTCPU)/riscv_common/Kconfig"
|
||||||
|
|||||||
1
cpu/gd32v/Makefile.default
Normal file
1
cpu/gd32v/Makefile.default
Normal file
@ -0,0 +1 @@
|
|||||||
|
DEFAULT_MODULE += pm_layered
|
||||||
@ -12,3 +12,9 @@ FEATURES_PROVIDED += periph_flashpage_in_address_space
|
|||||||
FEATURES_PROVIDED += periph_flashpage_pagewise
|
FEATURES_PROVIDED += periph_flashpage_pagewise
|
||||||
|
|
||||||
include $(RIOTCPU)/riscv_common/Makefile.features
|
include $(RIOTCPU)/riscv_common/Makefile.features
|
||||||
|
|
||||||
|
# This configuration enables modules that are only available when using Kconfig
|
||||||
|
# module modelling
|
||||||
|
ifeq (1, $(TEST_KCONFIG))
|
||||||
|
KCONFIG_ADD_CONFIG += $(RIOTCPU)/gd32v/gd32v.config
|
||||||
|
endif
|
||||||
|
|||||||
@ -29,6 +29,8 @@ extern void __libc_init_array(void);
|
|||||||
void cpu_init(void)
|
void cpu_init(void)
|
||||||
{
|
{
|
||||||
gd32vf103_clock_init();
|
gd32vf103_clock_init();
|
||||||
|
/* enable PMU required for pm_layered */
|
||||||
|
periph_clk_en(APB1, RCU_APB1EN_PMUEN_Msk);
|
||||||
/* Common RISC-V initialization */
|
/* Common RISC-V initialization */
|
||||||
riscv_init();
|
riscv_init();
|
||||||
early_init();
|
early_init();
|
||||||
|
|||||||
1
cpu/gd32v/gd32v.config
Normal file
1
cpu/gd32v/gd32v.config
Normal file
@ -0,0 +1 @@
|
|||||||
|
CONFIG_MODULE_PM_LAYERED=y
|
||||||
@ -33,7 +33,39 @@ extern "C" {
|
|||||||
* @name Power management configuration
|
* @name Power management configuration
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define PROVIDES_PM_SET_LOWEST
|
/**
|
||||||
|
* @brief Number of usable low power modes
|
||||||
|
*/
|
||||||
|
#define PM_NUM_MODES (3U) /**< Number of usable low power modes */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Power modes
|
||||||
|
*
|
||||||
|
* The GD32V has three power modes (terminology as defined by GigaDevice).
|
||||||
|
* - Sleep: Only the clock of the RISC-V core is switched off.
|
||||||
|
* - Deep sleep: The RISC-V core including all AHB and APB peripheralsa and all
|
||||||
|
* high speed clocks are off. The LDO is in operation and the
|
||||||
|
* SRAM is retained.
|
||||||
|
* The MCU can be woken up by external interrupts or events
|
||||||
|
* without restart.
|
||||||
|
* - Standby: The RISC-V core including all AHB and APB peripherals, all
|
||||||
|
* high-speed clocks, and the LDO are off. The SRAM is not
|
||||||
|
* retained.
|
||||||
|
* The MCU can be woken up by WKUP or the NRST pin, watchdog
|
||||||
|
* reset and RTC alarms with restart.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
GD32V_PM_STANDBY = 0, /**< STANDBY mode, */
|
||||||
|
GD32V_PM_DEEPSLEEP = 1, /**< DEEPSLEEP mode, corresponds to STOP mode of STM32 */
|
||||||
|
GD32V_PM_IDLE = 2 /**< IDLE mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wake-up pin used
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_PM_EWUP_USED
|
||||||
|
#define CONFIG_PM_EWUP_USED (0U)
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -8,3 +8,9 @@
|
|||||||
config MODULE_PERIPH
|
config MODULE_PERIPH
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config PM_EWUP_USED
|
||||||
|
bool "Use PA0/WKUP pin"
|
||||||
|
depends on MODULE_PM_LAYERED
|
||||||
|
help
|
||||||
|
If enabled, the PA0/WKUP pin can be used to wake up the MCU from standby mode.
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 Koen Zandberg
|
* Copyright 2020 Koen Zandberg
|
||||||
|
* 2023 Gunar Schorcht
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
* General Public License v2.1. See the file LICENSE in the top level
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -13,16 +14,67 @@
|
|||||||
* @brief Implementation of the CPU power management for Gigadevice GD32V
|
* @brief Implementation of the CPU power management for Gigadevice GD32V
|
||||||
*
|
*
|
||||||
* @author Koen Zandberg <koen@bergzand.net>
|
* @author Koen Zandberg <koen@bergzand.net>
|
||||||
|
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "periph/pm.h"
|
#include "periph/pm.h"
|
||||||
#include "periph/wdt.h"
|
#include "periph/wdt.h"
|
||||||
|
|
||||||
void pm_set_lowest(void)
|
#undef MCAUSE_CAUSE /* redefined in NMSIS header */
|
||||||
|
|
||||||
|
#include "core_feature_base.h"
|
||||||
|
|
||||||
|
void pm_set(unsigned mode)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("wfi");
|
bool csr_deepsleep = false; /* RISC-V sleep mode */
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case GD32V_PM_STANDBY:
|
||||||
|
csr_deepsleep = true;
|
||||||
|
/* set the STANDBY mode flag */
|
||||||
|
PMU->CTL |= PMU_CTL_WURST_Msk;
|
||||||
|
/* reset the wake up flag */
|
||||||
|
PMU->CTL |= PMU_CTL_STBMOD_Msk;
|
||||||
|
break;
|
||||||
|
case GD32V_PM_DEEPSLEEP:
|
||||||
|
csr_deepsleep = true;
|
||||||
|
/* reset the STANDBY mode flag */
|
||||||
|
PMU->CTL &= ~PMU_CTL_STBMOD_Msk;
|
||||||
|
/* use LDO low powered in deep sleep mode */
|
||||||
|
PMU->CTL |= PMU_CTL_LDOLP_Msk;
|
||||||
|
break;
|
||||||
|
case GD32V_PM_IDLE:
|
||||||
|
csr_deepsleep = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csr_deepsleep) {
|
||||||
|
/* Enable WKUP pin if used */
|
||||||
|
PMU->CS &= ~PMU_CS_WUPEN_Msk;
|
||||||
|
PMU->CS |= (CONFIG_PM_EWUP_USED) ? PMU_CS_WUPEN_Msk : 0;
|
||||||
|
/* set CSR_SLEEPVALUE bit in RISC-V system control register */
|
||||||
|
__set_wfi_sleepmode(WFI_DEEP_SLEEP);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* clear CSR_SLEEPVALUE bit in RISC-V system control register */
|
||||||
|
__set_wfi_sleepmode(WFI_SHALLOW_SLEEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* trigger sleeping, TODO wait for wake up event (__WFE) implementation */
|
||||||
|
__WFI();
|
||||||
|
|
||||||
|
if (csr_deepsleep) {
|
||||||
|
/* clear CSR_SLEEPVALUE bit in RISC-V system control register */
|
||||||
|
__set_wfi_sleepmode(WFI_SHALLOW_SLEEP);
|
||||||
|
/* after deep sleep, the IRC8M is used as clock so that a clock
|
||||||
|
* reinitialization is required */
|
||||||
|
gd32vf103_clock_init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_reboot(void)
|
void pm_reboot(void)
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "periph_cpu.h"
|
#include "periph_cpu.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "clic.h"
|
#include "clic.h"
|
||||||
|
#include "pm_layered.h"
|
||||||
|
|
||||||
#define RXENABLE (USART_CTL0_REN_Msk | USART_CTL0_RBNEIE_Msk)
|
#define RXENABLE (USART_CTL0_REN_Msk | USART_CTL0_RBNEIE_Msk)
|
||||||
|
|
||||||
@ -56,14 +57,18 @@ static inline void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb)
|
|||||||
|
|
||||||
static inline void uart_enable_clock(uart_t uart)
|
static inline void uart_enable_clock(uart_t uart)
|
||||||
{
|
{
|
||||||
/* TODO: add pm blocker */
|
if (isr_ctx[uart].rx_cb) {
|
||||||
|
pm_block(GD32V_PM_DEEPSLEEP);
|
||||||
|
}
|
||||||
periph_clk_en(uart_config[uart].bus, uart_config[uart].rcu_mask);
|
periph_clk_en(uart_config[uart].bus, uart_config[uart].rcu_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void uart_disable_clock(uart_t uart)
|
static inline void uart_disable_clock(uart_t uart)
|
||||||
{
|
{
|
||||||
periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcu_mask);
|
periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcu_mask);
|
||||||
/* TODO remove pm blocker */
|
if (isr_ctx[uart].rx_cb) {
|
||||||
|
pm_unblock(GD32V_PM_DEEPSLEEP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void uart_init_usart(uart_t uart, uint32_t baudrate)
|
static inline void uart_init_usart(uart_t uart, uint32_t baudrate)
|
||||||
|
|||||||
@ -55,6 +55,7 @@ rsource "mynewt-core/Kconfig"
|
|||||||
rsource "nanocbor/Kconfig"
|
rsource "nanocbor/Kconfig"
|
||||||
rsource "nanopb/Kconfig"
|
rsource "nanopb/Kconfig"
|
||||||
rsource "nanors/Kconfig"
|
rsource "nanors/Kconfig"
|
||||||
|
rsource "nmsis_sdk/Kconfig"
|
||||||
rsource "nrfx/Kconfig"
|
rsource "nrfx/Kconfig"
|
||||||
rsource "qcbor/Kconfig"
|
rsource "qcbor/Kconfig"
|
||||||
rsource "qdsa/Kconfig"
|
rsource "qdsa/Kconfig"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user