1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/avr8: Enable PM periph to all SoC

This refactor the current xmega PM peripheral to avr8 common and extend
PM to cpus families.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
Gerson Fernando Budke 2022-10-20 18:50:22 +02:00 committed by Marian Buschsieweke
parent 834e2a5fe4
commit 3b9368a99e
No known key found for this signature in database
GPG Key ID: 77AA882EC78084E6
23 changed files with 202 additions and 49 deletions

View File

@ -29,6 +29,17 @@ extern "C" {
#include "periph_cpu_common.h"
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Available ports on the ATmega1281 family
*/

View File

@ -29,6 +29,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Define a CPU specific GPIO pin generator macro
*/

View File

@ -26,6 +26,16 @@
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @name Available ports on the ATmega128rfa1 MCU

View File

@ -27,6 +27,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Available ports on the ATmega2560 family
*/

View File

@ -27,6 +27,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @name Available ports on the ATmega256rfr family
* @{

View File

@ -27,6 +27,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Define a CPU specific GPIO pin generator macro
*/

View File

@ -26,6 +26,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Available ports on the ATmega32u4 family
*/

View File

@ -29,6 +29,17 @@
extern "C" {
#endif
/**
* @name Power management configuration
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_ADC /**< Sleep ADC low noise */
/** @} */
/**
* @brief Define a CPU specific GPIO pin generator macro
*/

View File

@ -19,7 +19,6 @@ config CPU_COMMON_ATXMEGA
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_NVM
select HAS_PERIPH_PM
select HAS_PERIPH_TIMER
select HAS_PERIPH_TIMER_PERIODIC

View File

@ -1,9 +1,6 @@
# peripheral drivers are linked into the final binary
USEMODULE += atxmega_periph
# All ATxmega based CPUs provide PM
USEMODULE += pm_layered
ifneq (,$(filter periph_cpuid,$(USEMODULE)))
USEMODULE += periph_nvm
endif

View File

@ -11,7 +11,6 @@ FEATURES_PROVIDED += cpu_core_atxmega
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_nvm
FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_timer periph_timer_periodic
# Add atxmega configurations. This configuration enables modules that are only available when

View File

@ -1,2 +0,0 @@
# All ATxmega based CPUs provide PM
CONFIG_MODULE_PM_LAYERED=y

View File

@ -96,6 +96,10 @@ enum {
* @{
*/
#define PM_NUM_MODES (5)
#define AVR8_PM_SLEEP_MODE_0 SLEEP_MODE_PWR_DOWN /**< Power Down */
#define AVR8_PM_SLEEP_MODE_1 SLEEP_MODE_PWR_SAVE /**< Power Save */
#define AVR8_PM_SLEEP_MODE_2 SLEEP_MODE_STANDBY /**< Standby */
#define AVR8_PM_SLEEP_MODE_3 SLEEP_MODE_EXT_STANDBY /**< Extended Standby*/
/** @} */
/**

View File

@ -19,8 +19,6 @@
* @}
*/
#include <avr/sleep.h>
#include "cpu_pm.h"
#include "irq.h"
#include "periph/pm.h"
@ -73,44 +71,6 @@ void pm_reboot(void)
while (1) {}
}
/*
* DEBUG may affect this routine.
*
* --- Do NOT add DEBUG macro here ---
*
*/
void pm_set(unsigned mode)
{
unsigned irq_state = irq_disable();
if (avr8_is_uart_tx_pending() && mode < 4) {
irq_restore(irq_state);
return;
}
switch (mode) {
case 0:
set_sleep_mode(SLEEP_SMODE_PDOWN_gc);
break;
case 1:
set_sleep_mode(SLEEP_SMODE_PSAVE_gc);
break;
case 2:
set_sleep_mode(SLEEP_SMODE_STDBY_gc);
break;
case 3:
set_sleep_mode(SLEEP_SMODE_ESTDBY_gc);
break;
default:
set_sleep_mode(SLEEP_SMODE_IDLE_gc);
}
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
irq_restore(irq_state);
}
void pm_periph_enable(pwr_reduction_t pwr)
{
uint8_t mask = _device_mask(pwr);

View File

@ -10,6 +10,7 @@ config CPU_ARCH_AVR8
bool
select HAS_ARCH_8BIT
select HAS_ARCH_AVR8
select HAS_PERIPH_PM
select MODULE_MALLOC_THREAD_SAFE if TEST_KCONFIG
select MODULE_TINY_STRERROR_AS_STRERROR if TEST_KCONFIG

View File

@ -2,6 +2,6 @@
MODULE = avr8_common
# add a list of subdirectories, that should also be build
DIRS = avr_libc_extra
DIRS = periph avr_libc_extra
include $(RIOTBASE)/Makefile.base

View File

@ -2,7 +2,10 @@
USEMODULE += avr_libc_extra
# tell the build system to build the avr8 common files
USEMODULE += avr8_common
USEMODULE += avr8_common avr8_common_periph
# All avr8 CPUs provide PM
USEMODULE += pm_layered
# The AVR-libc provides no thread safe malloc implementation and has no hooks
# to inject. Use malloc_thread_safe to link calls to malloc to safe wrappers

View File

@ -1,3 +1,4 @@
FEATURES_PROVIDED += arch_8bit
FEATURES_PROVIDED += arch_avr8
FEATURES_PROVIDED += cpp
FEATURES_PROVIDED += periph_pm

View File

@ -0,0 +1,2 @@
# All AVR-8 based CPUs provide PM
CONFIG_MODULE_PM_LAYERED=y

View File

@ -48,6 +48,15 @@ extern "C"
{
#endif
/**
* @name BOD monitoring when CPU is on sleep
* @{
*/
#ifndef AVR8_PM_DISABLE_BOD_ON_SLEEP
#define AVR8_PM_DISABLE_BOD_ON_SLEEP 0 /**< BOD is active on sleep */
#endif
/** @} */
/**
* @name Use shared I2C functions
* @{

View File

@ -0,0 +1,7 @@
config MODULE_AVR8_COMMON_PERIPH
bool
depends on TEST_KCONFIG
depends on CPU_COMMON_ATXMEGA
default y
help
AVR8 common peripheral drivers.

View File

@ -0,0 +1,3 @@
MODULE = avr8_common_periph
include $(RIOTMAKE)/periph.mk

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2022-2023 Gerson Fernando Budke <nandojve@gmail.com>
*
* 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
* directory for more details.
*/
/**
* @ingroup cpu_avr8_common
* @ingroup cpu_avr8_common_periph
* @{
*
* @file
* @brief Low-level PM driver implementation
*
* @author Gerson Fernando Budke <nandojve@gmail.com>
*
* @}
*/
#include <avr/sleep.h>
#include "irq.h"
#include "periph_cpu.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/**
* @note: The pm_set assumes that interrupts are disable and there is no reason
* to save SREG here.
*
* @note: DEBUG affects this routine.
*/
void pm_set(unsigned mode)
{
DEBUG("pm_set(%d)\n", mode);
if (avr8_is_uart_tx_pending()) {
mode = PM_NUM_MODES - 1;
}
switch (mode) {
case 0:
set_sleep_mode(AVR8_PM_SLEEP_MODE_0);
break;
#if PM_NUM_MODES > 1
case 1:
set_sleep_mode(AVR8_PM_SLEEP_MODE_1);
break;
#endif
#if PM_NUM_MODES > 2
case 2:
set_sleep_mode(AVR8_PM_SLEEP_MODE_2);
break;
#endif
#if PM_NUM_MODES > 3
case 3:
set_sleep_mode(AVR8_PM_SLEEP_MODE_3);
break;
#endif
default:
set_sleep_mode(SLEEP_MODE_IDLE);
break;
}
DEBUG("mode selected: %d\n", mode);
/*
* Critical Section to correct enable SLEEP instruction on RIOT-OS
*/
#if (AVR8_PM_DISABLE_BOD_ON_SLEEP == 1)
#ifdef sleep_bod_disable
sleep_bod_disable();
#endif
#endif
sleep_enable();
sei();
sleep_cpu();
cli();
sleep_disable();
}