Skip to content

Commit

Permalink
cpu/avr8: Enable PM periph to all SoC
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
nandojve committed Jul 6, 2023
1 parent a5eb891 commit 211ac40
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 49 deletions.
11 changes: 11 additions & 0 deletions cpu/atmega1281/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
11 changes: 11 additions & 0 deletions cpu/atmega1284p/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
10 changes: 10 additions & 0 deletions cpu/atmega128rfa1/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions cpu/atmega2560/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
11 changes: 11 additions & 0 deletions cpu/atmega256rfr2/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
* @{
Expand Down
11 changes: 11 additions & 0 deletions cpu/atmega328p/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
11 changes: 11 additions & 0 deletions cpu/atmega32u4/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
1 change: 0 additions & 1 deletion cpu/atxmega/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 0 additions & 3 deletions cpu/atxmega/Makefile.dep
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 0 additions & 1 deletion cpu/atxmega/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions cpu/atxmega/atxmega.config

This file was deleted.

4 changes: 4 additions & 0 deletions cpu/atxmega/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*/
/** @} */

/**
Expand Down
40 changes: 0 additions & 40 deletions cpu/atxmega/periph/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
* @}
*/

#include <avr/sleep.h>

#include "cpu_pm.h"
#include "irq.h"
#include "periph/pm.h"
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions cpu/avr8_common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cpu/avr8_common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 4 additions & 1 deletion cpu/avr8_common/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions cpu/avr8_common/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
FEATURES_PROVIDED += arch_8bit
FEATURES_PROVIDED += arch_avr8
FEATURES_PROVIDED += cpp
FEATURES_PROVIDED += periph_pm
2 changes: 2 additions & 0 deletions cpu/avr8_common/avr8_common.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# All AVR-8 based CPUs provide PM
CONFIG_MODULE_PM_LAYERED=y
9 changes: 9 additions & 0 deletions cpu/avr8_common/include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,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
* @{
Expand Down
7 changes: 7 additions & 0 deletions cpu/avr8_common/periph/Kconfig
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions cpu/avr8_common/periph/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = avr8_common_periph

include $(RIOTMAKE)/periph.mk
83 changes: 83 additions & 0 deletions cpu/avr8_common/periph/pm.c
Original file line number Diff line number Diff line change
@@ -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();
}

0 comments on commit 211ac40

Please sign in to comment.