mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +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_WDT if MODULE_PERIPH_PM && HAS_PERIPH_WDT
|
||||
select PACKAGE_NUCLEI_SDK
|
||||
select PACKAGE_NMSIS_SDK
|
||||
|
||||
menu "GD32V configuration"
|
||||
|
||||
config CPU_MODEL_GD32VF103VBT6
|
||||
bool
|
||||
@ -48,4 +50,6 @@ config CPU_CORE
|
||||
|
||||
rsource "periph/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
gd32vf103_clock_init();
|
||||
/* enable PMU required for pm_layered */
|
||||
periph_clk_en(APB1, RCU_APB1EN_PMUEN_Msk);
|
||||
/* Common RISC-V initialization */
|
||||
riscv_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
|
||||
* @{
|
||||
*/
|
||||
#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
|
||||
bool
|
||||
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
|
||||
* 2023 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -13,16 +14,67 @@
|
||||
* @brief Implementation of the CPU power management for Gigadevice GD32V
|
||||
*
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "periph/pm.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)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "periph_cpu.h"
|
||||
#include "cpu.h"
|
||||
#include "clic.h"
|
||||
#include "pm_layered.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static inline void uart_disable_clock(uart_t uart)
|
||||
{
|
||||
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)
|
||||
|
@ -55,6 +55,7 @@ rsource "mynewt-core/Kconfig"
|
||||
rsource "nanocbor/Kconfig"
|
||||
rsource "nanopb/Kconfig"
|
||||
rsource "nanors/Kconfig"
|
||||
rsource "nmsis_sdk/Kconfig"
|
||||
rsource "nrfx/Kconfig"
|
||||
rsource "qcbor/Kconfig"
|
||||
rsource "qdsa/Kconfig"
|
||||
|
Loading…
Reference in New Issue
Block a user