From 9081a3b7c77711ecb6b1f16f7eb763e78ec2a53e Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Wed, 3 Feb 2021 21:58:24 -0300 Subject: [PATCH 01/18] cpu/avr8_common/include/cpu.h: Increase number of uart The ATxmega can have up to 8 UARTs. This increase from 2 up to 7 to keep avr8_state flags with 8 bits wide. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/include/cpu.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/cpu/avr8_common/include/cpu.h b/cpu/avr8_common/include/cpu.h index 42cfd34354..3e221584d6 100644 --- a/cpu/avr8_common/include/cpu.h +++ b/cpu/avr8_common/include/cpu.h @@ -63,6 +63,11 @@ extern "C" #define AVR8_STATE_FLAG_ISR (0x80U) /**< In ISR */ #define AVR8_STATE_FLAG_UART0_TX (0x01U) /**< TX pending for UART 0 */ #define AVR8_STATE_FLAG_UART1_TX (0x02U) /**< TX pending for UART 1 */ +#define AVR8_STATE_FLAG_UART2_TX (0x04U) /**< TX pending for UART 2 */ +#define AVR8_STATE_FLAG_UART3_TX (0x08U) /**< TX pending for UART 3 */ +#define AVR8_STATE_FLAG_UART4_TX (0x10U) /**< TX pending for UART 4 */ +#define AVR8_STATE_FLAG_UART5_TX (0x20U) /**< TX pending for UART 5 */ +#define AVR8_STATE_FLAG_UART6_TX (0x40U) /**< TX pending for UART 6 */ #define AVR8_STATE_FLAG_UART_TX(x) (0x01U << x) /**< TX pending for UART x */ /** @} */ @@ -77,14 +82,18 @@ extern "C" * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * 7 6 5 4 3 2 1 0 * +---+---+---+---+---+---+---+---+ - * |IRQ| unused |TX1|TX0| + * |IRQ|TX6|TX5|TX4|TX3|TX2|TX1|TX0| * +---+---+---+---+---+---+---+---+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * | Label | Description | * |:-------|:--------------------------------------------------------------| * | IRQ | This bit is set when in IRQ context | - * | unused | This bits are currently not used | + * | TX6 | This bit is set when on UART6 TX is pending | + * | TX5 | This bit is set when on UART5 TX is pending | + * | TX4 | This bit is set when on UART4 TX is pending | + * | TX3 | This bit is set when on UART3 TX is pending | + * | TX2 | This bit is set when on UART2 TX is pending | * | TX1 | This bit is set when on UART1 TX is pending | * | TX0 | This bit is set when on UART0 TX is pending | */ @@ -138,7 +147,13 @@ static inline void avr8_enter_isr(void) static inline int avr8_is_uart_tx_pending(void) { uint8_t state = avr8_get_state(); - return (state & (AVR8_STATE_FLAG_UART0_TX | AVR8_STATE_FLAG_UART1_TX)); + return (state & (AVR8_STATE_FLAG_UART0_TX + | AVR8_STATE_FLAG_UART1_TX + | AVR8_STATE_FLAG_UART2_TX + | AVR8_STATE_FLAG_UART3_TX + | AVR8_STATE_FLAG_UART4_TX + | AVR8_STATE_FLAG_UART5_TX + | AVR8_STATE_FLAG_UART6_TX)); } /** From d041199825a5dc8874c062dbdf11abe228cb4332 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Wed, 3 Feb 2021 22:09:58 -0300 Subject: [PATCH 02/18] cpu/avr8_common: Move irq_enable from board to cpu Some mega boards enabling global irq at board_init. This moves that responsability to cpu/avr8_common to create a common point to all variants. Signed-off-by: Gerson Fernando Budke --- boards/arduino-leonardo/board.c | 2 -- boards/common/atmega/board.c | 2 -- boards/waspmote-pro/board.c | 2 -- cpu/avr8_common/avr8_cpu.c | 3 +++ 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/boards/arduino-leonardo/board.c b/boards/arduino-leonardo/board.c index 9825132215..35b5adb315 100644 --- a/boards/arduino-leonardo/board.c +++ b/boards/arduino-leonardo/board.c @@ -20,7 +20,6 @@ #include "board.h" #include "cpu.h" -#include "irq.h" #include "periph/gpio.h" #ifndef CPU_ATMEGA_CLK_SCALE_INIT @@ -38,5 +37,4 @@ void board_init(void) avr8_stdio_init(); cpu_init(); led_init(); - irq_enable(); } diff --git a/boards/common/atmega/board.c b/boards/common/atmega/board.c index 7e7ae676c9..7c05383965 100644 --- a/boards/common/atmega/board.c +++ b/boards/common/atmega/board.c @@ -20,7 +20,6 @@ #include "board.h" #include "cpu.h" -#include "irq.h" #include "periph/gpio.h" #ifndef CPU_ATMEGA_CLK_SCALE_INIT @@ -42,5 +41,4 @@ void __attribute__((weak)) board_init(void) #ifdef LED0_ON led_init(); #endif - irq_enable(); } diff --git a/boards/waspmote-pro/board.c b/boards/waspmote-pro/board.c index 6130b0131a..1fdd0376e0 100644 --- a/boards/waspmote-pro/board.c +++ b/boards/waspmote-pro/board.c @@ -24,7 +24,6 @@ #include "board.h" #include "cpu.h" -#include "irq.h" /** * @brief Initialize the boards on-board LEDs (green and red) @@ -61,5 +60,4 @@ void board_init(void) cpu_init(); led_init(); - irq_enable(); } diff --git a/cpu/avr8_common/avr8_cpu.c b/cpu/avr8_common/avr8_cpu.c index bdcfb12ec1..c451306fed 100644 --- a/cpu/avr8_common/avr8_cpu.c +++ b/cpu/avr8_common/avr8_cpu.c @@ -32,6 +32,7 @@ #include "cpu.h" #include "board.h" +#include "irq.h" #include "periph/init.h" #include "panic.h" @@ -95,6 +96,8 @@ void cpu_init(void) /* rtc_init */ /* hwrng_init */ periph_init(); + + irq_enable(); } struct __freelist { From 1a88f0bad612e276cda1906f9d3ed979f0229560 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Thu, 7 Jan 2021 13:05:50 -0300 Subject: [PATCH 03/18] cpu: Introduce Atmel xmega cpu Add ATxmega common files and cpu definitions. This works was originally developed by @Josar. The 2018 version were port to 2021 mainline. This version changes original port to have only the atxmega CPU definition. With that, all family can be accomodated. Signed-off-by: Gerson Fernando Budke --- cpu/atxmega/Kconfig | 82 +++++ cpu/atxmega/Kconfig.XMEGAA | 105 ++++++ cpu/atxmega/Kconfig.XMEGAB | 25 ++ cpu/atxmega/Kconfig.XMEGAC | 45 +++ cpu/atxmega/Kconfig.XMEGAD | 55 ++++ cpu/atxmega/Kconfig.XMEGAE | 17 + cpu/atxmega/Makefile | 7 + cpu/atxmega/Makefile.dep | 11 + cpu/atxmega/Makefile.features | 11 + cpu/atxmega/Makefile.include | 38 +++ cpu/atxmega/atxmega_cpu.c | 132 ++++++++ cpu/atxmega/doc.txt | 10 + cpu/atxmega/include/cpu_clock.h | 75 +++++ cpu/atxmega/include/cpu_conf.h | 76 +++++ cpu/atxmega/include/cpu_nvm.h | 65 ++++ cpu/atxmega/include/periph_cpu.h | 247 ++++++++++++++ cpu/atxmega/periph/Makefile | 3 + cpu/atxmega/periph/cpuid.c | 64 ++++ cpu/atxmega/periph/gpio.c | 546 +++++++++++++++++++++++++++++++ cpu/atxmega/periph/nvm.c | 78 +++++ cpu/atxmega/periph/pm.c | 80 +++++ cpu/atxmega/periph/timer.c | 533 ++++++++++++++++++++++++++++++ cpu/atxmega/periph/uart.c | 425 ++++++++++++++++++++++++ 23 files changed, 2730 insertions(+) create mode 100644 cpu/atxmega/Kconfig create mode 100644 cpu/atxmega/Kconfig.XMEGAA create mode 100644 cpu/atxmega/Kconfig.XMEGAB create mode 100644 cpu/atxmega/Kconfig.XMEGAC create mode 100644 cpu/atxmega/Kconfig.XMEGAD create mode 100644 cpu/atxmega/Kconfig.XMEGAE create mode 100644 cpu/atxmega/Makefile create mode 100644 cpu/atxmega/Makefile.dep create mode 100644 cpu/atxmega/Makefile.features create mode 100644 cpu/atxmega/Makefile.include create mode 100644 cpu/atxmega/atxmega_cpu.c create mode 100644 cpu/atxmega/doc.txt create mode 100644 cpu/atxmega/include/cpu_clock.h create mode 100644 cpu/atxmega/include/cpu_conf.h create mode 100644 cpu/atxmega/include/cpu_nvm.h create mode 100644 cpu/atxmega/include/periph_cpu.h create mode 100644 cpu/atxmega/periph/Makefile create mode 100644 cpu/atxmega/periph/cpuid.c create mode 100644 cpu/atxmega/periph/gpio.c create mode 100644 cpu/atxmega/periph/nvm.c create mode 100644 cpu/atxmega/periph/pm.c create mode 100644 cpu/atxmega/periph/timer.c create mode 100644 cpu/atxmega/periph/uart.c diff --git a/cpu/atxmega/Kconfig b/cpu/atxmega/Kconfig new file mode 100644 index 0000000000..450978477f --- /dev/null +++ b/cpu/atxmega/Kconfig @@ -0,0 +1,82 @@ +# Copyright (c) 2020 HAW Hamburg +# Copyright (c) 2021 Gerson Fernando Budke +# +# 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. +# + +config CPU_COMMON_ATXMEGA + bool + select CPU_ARCH_AVR8 + select CPU_CORE_AVR + select HAS_CPU_ATXMEGA + select HAS_CPP + select HAS_PERIPH_CPUID + 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 + select HAS_PERIPH_UART + +config CPU_CORE_ATXMEGA_A1 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_A3 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_A4 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_B1 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_B3 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_C3 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_C4 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_D3 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_D4 + bool + select CPU_COMMON_ATXMEGA + +config CPU_CORE_ATXMEGA_E5 + bool + select CPU_COMMON_ATXMEGA + +config CPU + default "atxmega" if CPU_COMMON_ATXMEGA + +source "$(RIOTCPU)/atxmega/Kconfig.XMEGAA" +source "$(RIOTCPU)/atxmega/Kconfig.XMEGAB" +source "$(RIOTCPU)/atxmega/Kconfig.XMEGAC" +source "$(RIOTCPU)/atxmega/Kconfig.XMEGAD" +source "$(RIOTCPU)/atxmega/Kconfig.XMEGAE" + +## Declaration of specific features +config HAS_CPU_ATXMEGA + bool + +config HAS_PERIPH_NVM + bool + help + Indicates that the Non Volatile Memory controller is present. + +source "$(RIOTCPU)/avr8_common/Kconfig" diff --git a/cpu/atxmega/Kconfig.XMEGAA b/cpu/atxmega/Kconfig.XMEGAA new file mode 100644 index 0000000000..0fb05fc837 --- /dev/null +++ b/cpu/atxmega/Kconfig.XMEGAA @@ -0,0 +1,105 @@ +## CPU Models +# XMEGA - A1/A1U +config CPU_MODEL_XMEGA64A1 + bool + select CPU_CORE_ATXMEGA_A1 + +config CPU_MODEL_XMEGA128A1 + bool + select CPU_CORE_ATXMEGA_A1 + +config CPU_MODEL_XMEGA64A1U + bool + select CPU_CORE_ATXMEGA_A1 + +config CPU_MODEL_XMEGA128A1U + bool + select CPU_CORE_ATXMEGA_A1 + +# XMEGA - A3/A3U/A3BU +config CPU_MODEL_XMEGA64A3 + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA128A3 + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA192A3 + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA256A3 + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA64A3U + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA128A3U + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA192A3U + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA256A3U + bool + select CPU_CORE_ATXMEGA_A3 + +config CPU_MODEL_XMEGA256A3BU + bool + select CPU_CORE_ATXMEGA_A3 + +# XMEGA - A4/A4U +config CPU_MODEL_XMEGA16A4 + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL_XMEGA32A4 + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL_XMEGA16A4U + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL_XMEGA32A4U + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL_XMEGA64A4U + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL_XMEGA128A4U + bool + select CPU_CORE_ATXMEGA_A4 + +config CPU_MODEL + string + default "atxmega64a1" if CPU_MODEL_XMEGA64A1 + default "atxmega128a1" if CPU_MODEL_XMEGA128A1 + default "atxmega192a1" if CPU_MODEL_XMEGA192A1 + default "atxmega256a1" if CPU_MODEL_XMEGA256A1 + default "atxmega64a1u" if CPU_MODEL_XMEGA64A1U + default "atxmega128a1u" if CPU_MODEL_XMEGA128A1U + + default "atxmega64a3" if CPU_MODEL_XMEGA64A3 + default "atxmega128a3" if CPU_MODEL_XMEGA128A3 + default "atxmega192a3" if CPU_MODEL_XMEGA192A3 + default "atxmega256a3" if CPU_MODEL_XMEGA256A3 + default "atxmega64a3u" if CPU_MODEL_XMEGA64A3U + default "atxmega128a3u" if CPU_MODEL_XMEGA128A3U + default "atxmega192a3u" if CPU_MODEL_XMEGA192A3U + default "atxmega256a3u" if CPU_MODEL_XMEGA256A3U + default "atxmega256a3bu" if CPU_MODEL_XMEGA256A3BU + + default "atxmega16a4" if CPU_MODEL_XMEGA16A4 + default "atxmega32a4" if CPU_MODEL_XMEGA32A4 + default "atxmega16a4u" if CPU_MODEL_XMEGA16A4U + default "atxmega32a4u" if CPU_MODEL_XMEGA32A4U + default "atxmega64a4u" if CPU_MODEL_XMEGA64A4U + default "atxmega128a4u" if CPU_MODEL_XMEGA128A4U diff --git a/cpu/atxmega/Kconfig.XMEGAB b/cpu/atxmega/Kconfig.XMEGAB new file mode 100644 index 0000000000..8070567dfb --- /dev/null +++ b/cpu/atxmega/Kconfig.XMEGAB @@ -0,0 +1,25 @@ +## CPU Models +# XMEGA - B1 +config CPU_MODEL_XMEGA64B1 + bool + select CPU_CORE_ATXMEGA_B1 + +config CPU_MODEL_XMEGA128B1 + bool + select CPU_CORE_ATXMEGA_B1 + +# XMEGA - B3 +config CPU_MODEL_XMEGA64B3 + bool + select CPU_CORE_ATXMEGA_B3 + +config CPU_MODEL_XMEGA128B3 + bool + select CPU_CORE_ATXMEGA_B3 + +config CPU_MODEL + default "atxmega64b3" if CPU_MODEL_XMEGA64B3 + default "atxmega128b3" if CPU_MODEL_XMEGA128B3 + + default "atxmega64b1" if CPU_MODEL_XMEGA64B1 + default "atxmega128b1" if CPU_MODEL_XMEGA128B1 diff --git a/cpu/atxmega/Kconfig.XMEGAC b/cpu/atxmega/Kconfig.XMEGAC new file mode 100644 index 0000000000..d6fa5e7a34 --- /dev/null +++ b/cpu/atxmega/Kconfig.XMEGAC @@ -0,0 +1,45 @@ +## CPU Models +# XMEGA - C3 +config CPU_MODEL_XMEGA32C3 + bool + select CPU_CORE_ATXMEGA_C3 + +config CPU_MODEL_XMEGA64C3 + bool + select CPU_CORE_ATXMEGA_C3 + +config CPU_MODEL_XMEGC128C3 + bool + select CPU_CORE_ATXMEGA_C3 + +config CPU_MODEL_XMEGC192C3 + bool + select CPU_CORE_ATXMEGA_C3 + +config CPU_MODEL_XMEGA256C3 + bool + select CPU_CORE_ATXMEGA_C3 + +config CPU_MODEL_XMEGA384C3 + bool + select CPU_CORE_ATXMEGA_C3 + +# XMEGA - C4 +config CPU_MODEL_XMEGA16C4 + bool + select CPU_CORE_ATXMEGA_C4 + +config CPU_MODEL_XMEGA32C4 + bool + select CPU_CORE_ATXMEGA_C4 + +config CPU_MODEL + default "atxmega32c3" if CPU_MODEL_XMEGA32C3 + default "atxmega64c3" if CPU_MODEL_XMEGA64C3 + default "atxmega128c3" if CPU_MODEL_XMEGC128C3 + default "atxmega192c3" if CPU_MODEL_XMEGC192C3 + default "atxmega256c3" if CPU_MODEL_XMEGA256C3 + default "atxmega384c3" if CPU_MODEL_XMEGA384C3 + + default "atxmega16c4" if CPU_MODEL_XMEGA16C4 + default "atxmega32c4" if CPU_MODEL_XMEGA32C4 diff --git a/cpu/atxmega/Kconfig.XMEGAD b/cpu/atxmega/Kconfig.XMEGAD new file mode 100644 index 0000000000..af0dcf12d5 --- /dev/null +++ b/cpu/atxmega/Kconfig.XMEGAD @@ -0,0 +1,55 @@ +## CPU Models +# XMEGA - D3 +config CPU_MODEL_XMEGA32D3 + bool + select CPU_CORE_ATXMEGA_D3 + +config CPU_MODEL_XMEGA64D3 + bool + select CPU_CORE_ATXMEGA_D3 + +config CPU_MODEL_XMEGC128D3 + bool + select CPU_CORE_ATXMEGA_D3 + +config CPU_MODEL_XMEGC192D3 + bool + select CPU_CORE_ATXMEGA_D3 + +config CPU_MODEL_XMEGA256D3 + bool + select CPU_CORE_ATXMEGA_D3 + +config CPU_MODEL_XMEGA384D3 + bool + select CPU_CORE_ATXMEGA_D3 + +# XMEGA - D4 +config CPU_MODEL_XMEGA16D4 + bool + select CPU_CORE_ATXMEGA_D4 + +config CPU_MODEL_XMEGA32D4 + bool + select CPU_CORE_ATXMEGA_D4 + +config CPU_MODEL_XMEGA64D4 + bool + select CPU_CORE_ATXMEGA_D4 + +config CPU_MODEL_XMEGA128D4 + bool + select CPU_CORE_ATXMEGA_D4 + +config CPU_MODEL + default "atxmega32d3" if CPU_MODEL_XMEGA32D3 + default "atxmega64d3" if CPU_MODEL_XMEGA64D3 + default "atxmega128d3" if CPU_MODEL_XMEGC128D3 + default "atxmega192d3" if CPU_MODEL_XMEGC192D3 + default "atxmega256d3" if CPU_MODEL_XMEGA256D3 + default "atxmega384d3" if CPU_MODEL_XMEGA384D3 + + default "atxmega16d4" if CPU_MODEL_XMEGA16D4 + default "atxmega32d4" if CPU_MODEL_XMEGA32D4 + default "atxmega64d4" if CPU_MODEL_XMEGA64D4 + default "atxmega128d4" if CPU_MODEL_XMEGA128D4 diff --git a/cpu/atxmega/Kconfig.XMEGAE b/cpu/atxmega/Kconfig.XMEGAE new file mode 100644 index 0000000000..6363d632f3 --- /dev/null +++ b/cpu/atxmega/Kconfig.XMEGAE @@ -0,0 +1,17 @@ +## CPU Models +config CPU_MODEL_XMEGA8E5 + bool + select CPU_CORE_ATXMEGA_E5 + +config CPU_MODEL_XMEGA16E5 + bool + select CPU_CORE_ATXMEGA_E5 + +config CPU_MODEL_XMEGA32E5 + bool + select CPU_CORE_ATXMEGA_E5 + +config CPU_MODEL + default "atxmega8e5" if CPU_MODEL_XMEGA8E5 + default "atxmega16e5" if CPU_MODEL_XMEGA16E5 + default "atxmega32e5" if CPU_MODEL_XMEGA32E5 diff --git a/cpu/atxmega/Makefile b/cpu/atxmega/Makefile new file mode 100644 index 0000000000..4e5fcf7a8c --- /dev/null +++ b/cpu/atxmega/Makefile @@ -0,0 +1,7 @@ +# define the module that is build +MODULE = cpu + +# add a list of subdirectories, that should also be build +DIRS = periph $(RIOTCPU)/avr8_common/ + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/atxmega/Makefile.dep b/cpu/atxmega/Makefile.dep new file mode 100644 index 0000000000..562b7c960d --- /dev/null +++ b/cpu/atxmega/Makefile.dep @@ -0,0 +1,11 @@ +# peripheral drivers are linked into the final binary +USEMODULE += atxmega_periph + +# All ATxmega based CPUs provide PM +USEMODULE += pm_layered + +ifeq (,$(filter cpuid,$(USEMODULE))) + USEMODULE += periph_nvm +endif + +include $(RIOTCPU)/avr8_common/Makefile.dep diff --git a/cpu/atxmega/Makefile.features b/cpu/atxmega/Makefile.features new file mode 100644 index 0000000000..c20ff1a9dd --- /dev/null +++ b/cpu/atxmega/Makefile.features @@ -0,0 +1,11 @@ +include $(RIOTCPU)/avr8_common/Makefile.features + +# common feature are defined in avr8_common/Makefile.features +# Only add Additional features + +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 +FEATURES_PROVIDED += periph_uart diff --git a/cpu/atxmega/Makefile.include b/cpu/atxmega/Makefile.include new file mode 100644 index 0000000000..e8365a18e4 --- /dev/null +++ b/cpu/atxmega/Makefile.include @@ -0,0 +1,38 @@ +export CPU_ATXMEGA 1 + +# CPU ROM/RAM +ifneq (,$(findstring atxmega8,$(CPU_MODEL))) + RAM_LEN = 1K + ROM_LEN = 8K +endif +ifneq (,$(findstring atxmega16,$(CPU_MODEL))) + RAM_LEN = 2K + ROM_LEN = 16K +endif +ifneq (,$(findstring atxmega32,$(CPU_MODEL))) + RAM_LEN = 4K + ROM_LEN = 32K +endif +ifneq (,$(findstring atxmega64,$(CPU_MODEL))) + RAM_LEN ?= 4K + ROM_LEN = 64K +endif +#ifneq (,$(findstring atxmega128,$(CPU_MODEL))) + RAM_LEN ?= 8K + ROM_LEN = 128K +#endif +ifneq (,$(findstring atxmega192,$(CPU_MODEL))) + RAM_LEN = 16K + ROM_LEN = 192K +endif +ifneq (,$(findstring atxmega256,$(CPU_MODEL))) + RAM_LEN = 16K + ROM_LEN = 256K +endif +ifneq (,$(findstring atxmega384,$(CPU_MODEL))) + RAM_LEN = 32K + ROM_LEN = 384K +endif + +# CPU depends on the avr8 common module, so include it +include $(RIOTCPU)/avr8_common/Makefile.include diff --git a/cpu/atxmega/atxmega_cpu.c b/cpu/atxmega/atxmega_cpu.c new file mode 100644 index 0000000000..433b0f7f18 --- /dev/null +++ b/cpu/atxmega/atxmega_cpu.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @{ + * + * @file + * @brief Implementation of the CPU initialization + * + * @author Gerson Fernando Budke + + * @} + */ + +#include + +#include "cpu.h" +#include "cpu_clock.h" +#include "panic.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +#ifndef CPU_ATXMEGA_CLK_SCALE_INIT +#define CPU_ATXMEGA_CLK_SCALE_INIT CPU_ATXMEGA_CLK_SCALE_DIV1 +#endif +#ifndef CPU_ATXMEGA_BUS_SCALE_INIT +#define CPU_ATXMEGA_BUS_SCALE_INIT CPU_ATXMEGA_BUS_SCALE_DIV1_1 +#endif + +extern uint8_t mcusr_mirror; + +void avr8_reset_cause(void) +{ + if (mcusr_mirror & (1 << RST_PORF_bp)) { + DEBUG("Power-on reset.\n"); + } + if (mcusr_mirror & (1 << RST_EXTRF_bp)) { + DEBUG("External reset!\n"); + } + if (mcusr_mirror & (1 << RST_BORF_bp)) { + DEBUG("Brown-out reset!\n"); + } + if (mcusr_mirror & (1 << RST_WDRF_bp)) { + DEBUG("Watchdog reset!\n"); + } + if (mcusr_mirror & (1 << RST_PDIRF_bp)) { + DEBUG("Programming and Debug Interface reset!\n"); + } + if (mcusr_mirror & (1 << RST_SRF_bp)) { + DEBUG("Software reset!\n"); + } + if (mcusr_mirror & (1 << RST_SDRF_bp)) { + DEBUG("Spike Detection reset!\n"); + } +} + +void __attribute__((weak)) avr8_clk_init(void) +{ + volatile uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= 7; i++) { + reg[i] = 0xff; + } + + /* Turn on all peripheral clocks that can be turned on. */ + for (i = 0; i <= 7; i++) { + reg[i] = 0x00; + } + + /* XMEGA A3U [DATASHEET] p.23 After reset, the device starts up running + * from the 2MHz internal oscillator. The other clock sources, DFLLs + * and PLL, are turned off by default. + * + * Configure clock to 32MHz with calibration + * application note AVR1003 + * + * From errata http://www.avrfreaks.net/forum/xmega-dfll-does-it-work + * In order to use the automatic runtime calibration for the 2 MHz or + * the 32 MHz internal oscillators, the DFLL for both oscillators and + * both oscillators has to be enabled for one to work. + */ + OSC.PLLCTRL = 0; + + /* Enable the internal PLL & 32MHz & 32KHz oscillators */ + OSC.CTRL |= OSC_PLLEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm; + + /* Wait for 32Khz and 32MHz oscillator to stabilize */ + while ((OSC.STATUS & (OSC_RC32KRDY_bm | OSC_RC32MRDY_bm)) + != (OSC_RC32KRDY_bm | OSC_RC32MRDY_bm)) {} + + /* Enable DFLL - defaults to calibrate against internal 32Khz clock */ + DFLLRC32M.CTRL = DFLL_ENABLE_bm; + + /* Enable DFLL - defaults to calibrate against internal 32Khz clock */ + DFLLRC2M.CTRL = DFLL_ENABLE_bm; + + atxmega_set_prescaler(CPU_ATXMEGA_CLK_SCALE_INIT, + CPU_ATXMEGA_BUS_SCALE_INIT); + + /* Disable CCP for Protected IO register and set new value*/ + /* Switch to 32MHz clock */ + _PROTECTED_WRITE(CLK.CTRL, CLK_SCLKSEL_RC32M_gc); +} + +/* This is a vector which is aliased to __vector_default, + * the vector executed when an ISR fires with no accompanying + * ISR handler. This may be used along with the ISR() macro to + * create a catch-all for undefined but used ISRs for debugging + * purposes. + */ +ISR(BADISR_vect) +{ + avr8_reset_cause(); + +#ifdef LED_PANIC + /* Use LED light to signal ERROR. */ + LED_PANIC; +#endif + + core_panic(PANIC_GENERAL_ERROR, + PSTR("FATAL ERROR: BADISR_vect called, unprocessed Interrupt.\n" + "STOP Execution.\n")); +} diff --git a/cpu/atxmega/doc.txt b/cpu/atxmega/doc.txt new file mode 100644 index 0000000000..8da7e0301c --- /dev/null +++ b/cpu/atxmega/doc.txt @@ -0,0 +1,10 @@ +/** + * @defgroup cpu_atxmega Atmel ATxmega MCU + * @ingroup cpu + * @brief Implementation of Atmel's ATxmega MCU + */ + +/** + * @defgroup cpu_atxmega_periph Atmel ATxmega MCU Peripherals + * @ingroup cpu_atxmega + */ diff --git a/cpu/atxmega/include/cpu_clock.h b/cpu/atxmega/include/cpu_clock.h new file mode 100644 index 0000000000..f65100c9cf --- /dev/null +++ b/cpu/atxmega/include/cpu_clock.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @brief Common implementations and headers for ATxmega family based micro-controllers + * @{ + * + * @file + * @brief Basic definitions for the ATxmega common clock module + * + * When ever you want to do something hardware related, that is accessing MCUs registers directly, + * just include this file. It will then make sure that the MCU specific headers are included. + * + * @author Gerson Fernando Budke + * + */ + +#ifndef CPU_CLOCK_H +#define CPU_CLOCK_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ATxmega system clock prescaler settings + * + * Some CPUs may not support the highest prescaler settings + */ +enum { + CPU_ATXMEGA_CLK_SCALE_DIV1 = 0, + CPU_ATXMEGA_CLK_SCALE_DIV2 = 1, + CPU_ATXMEGA_CLK_SCALE_DIV4 = 3, + CPU_ATXMEGA_CLK_SCALE_DIV8 = 5, + CPU_ATXMEGA_CLK_SCALE_DIV16 = 7, + CPU_ATXMEGA_CLK_SCALE_DIV32 = 9, + CPU_ATXMEGA_CLK_SCALE_DIV64 = 11, + CPU_ATXMEGA_CLK_SCALE_DIV128 = 13, + CPU_ATXMEGA_CLK_SCALE_DIV256 = 15, + CPU_ATXMEGA_CLK_SCALE_DIV512 = 17, +}; + +enum { + CPU_ATXMEGA_BUS_SCALE_DIV1_1 = 0, + CPU_ATXMEGA_BUS_SCALE_DIV1_2 = 1, + CPU_ATXMEGA_BUS_SCALE_DIV4_1 = 2, + CPU_ATXMEGA_BUS_SCALE_DIV2_2 = 3, +}; + +/** + * @brief Initializes system clock prescaler + */ +static inline void atxmega_set_prescaler(uint8_t clk_scale, uint8_t bus_scale) +{ + /* Disable CCP for Protected IO register and set new value + * Set system clock prescalers to zero. PSCTRL contains A Prescaler + * Value and one value for and B and C Prescaler + */ + _PROTECTED_WRITE(CLK.PSCTRL, clk_scale | bus_scale); +} + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CLOCK_H */ +/** @} */ diff --git a/cpu/atxmega/include/cpu_conf.h b/cpu/atxmega/include/cpu_conf.h new file mode 100644 index 0000000000..132d149bf5 --- /dev/null +++ b/cpu/atxmega/include/cpu_conf.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @{ + * + * @file + * @brief Implementation specific CPU configuration options + * + * @author Gerson Fernando Budke + */ + +#ifndef CPU_CONF_H +#define CPU_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define THREAD_EXTRA_STACKSIZE_PRINTF (128) + +/** + * @name Kernel configuration + * + * Since printf seems to get memory allocated by the + * linker/avr-libc the stack size tested successfully + * even with pretty small stacks. + * @{ + */ +#ifndef THREAD_STACKSIZE_DEFAULT +#define THREAD_STACKSIZE_DEFAULT (512) +#endif + +/* keep THREAD_STACKSIZE_IDLE > THREAD_EXTRA_STACKSIZE_PRINTF + * to avoid not printing of debug in interrupts + */ +#ifndef THREAD_STACKSIZE_IDLE +#ifdef MODULE_XTIMER +/* xtimer's 64 bit arithmetic doesn't perform well on 8 bit archs. In order to + * prevent a stack overflow when an timer triggers while the idle thread is + * running, we have to increase the stack size then + */ +#define THREAD_STACKSIZE_IDLE (384) +#else +#define THREAD_STACKSIZE_IDLE (192) +#endif +#endif +/** @} */ + +/** + * @brief Declare the heap_stats function as available + */ +#define HAVE_HEAP_STATS + +/** + * @brief This arch uses the inlined IRQ API. + */ +#define IRQ_API_INLINED (1) + +/** + * @brief This arch require special clock initialization. + */ +#define CPU_AVR8_HAS_CLOCK_INIT 1 + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CONF_H */ +/** @} */ diff --git a/cpu/atxmega/include/cpu_nvm.h b/cpu/atxmega/include/cpu_nvm.h new file mode 100644 index 0000000000..f3fb592ff4 --- /dev/null +++ b/cpu/atxmega/include/cpu_nvm.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @brief Non Volatile Memory (NVM) internal API + * @{ + * + * @author Gerson Fernando Budke + * + */ + +#ifndef CPU_NVM_H +#define CPU_NVM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get offset of calibration bytes in the production signature row + * + * @note In some distributions may require most recent vendor headers, even + * more recent than the upstream avr-libc. The headers can be download + * directly from Microchip web site. In general, Microchip have a + * dedicated page at Tools and Software / AVR and SAM Downloads Archive. + * The most recent version is AVR 8-bit Toolchain (3.4.4) 6.2.0.334. + * http://ww1.microchip.com/downloads/archive/avr8-headers-6.2.0.334.zip + * + * The official RIOT-OS docker container, Debian and Ubuntu are + * distributions that already had updated versions of those files. + * + * @param regname Name of register within the production signature row + * @retval Offset of register into the production signature row + */ +#define nvm_get_production_signature_row_offset(regname) \ + offsetof(NVM_PROD_SIGNATURES_t, regname) + +/** + * @brief Read one byte from the production signature row + * + * This function reads one byte from the production signature row of the device + * at the given address. + * + * @note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * @param address Byte offset into the signature row + */ +uint8_t nvm_read_production_signature_row(uint8_t address); + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_NVM_H */ +/** @} */ diff --git a/cpu/atxmega/include/periph_cpu.h b/cpu/atxmega/include/periph_cpu.h new file mode 100644 index 0000000000..2597917d18 --- /dev/null +++ b/cpu/atxmega/include/periph_cpu.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Gerson Fernando Budke + */ + +#ifndef PERIPH_CPU_H +#define PERIPH_CPU_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Length of the CPU_ID in octets + * @{ + */ +#define CPUID_LEN (11U) +/** @} */ + +/** + * @name Interrupt level used to control nested interrupts + * @{ + */ +typedef enum { + CPU_INT_LVL_OFF, /**< Interrupt Disabled */ + CPU_INT_LVL_LOW, /**< Interrupt Low Level */ + CPU_INT_LVL_MID, /**< Interrupt Medium Level */ + CPU_INT_LVL_HIGH, /**< Interrupt High Level */ +} cpu_int_lvl_t; +/** @} */ + +/** + * @brief Available ports on the ATxmega family + */ +enum { + PORT_A, /**< port A - 600 - 0 */ + PORT_B, /**< port B - 620 - 1 */ + PORT_C, /**< port C - 640 - 2 */ + PORT_D, /**< port D - 660 - 3 */ + PORT_E, /**< port E - 680 - 4 */ + PORT_F, /**< port F - 6A0 - 5 */ + PORT_G, /**< port G - 6C0 - 6 */ + PORT_H, /**< port H - 6E0 - 7 */ + PORT_J, /**< port J - 700 - 8 */ + PORT_K, /**< port K - 720 - 9 */ + PORT_L, /**< port L - 740 - A */ + PORT_M, /**< port M - 760 - B */ + PORT_N, /**< port N - 780 - C */ + PORT_P, /**< port P - 7A0 - D */ + PORT_Q, /**< port Q - 7C0 - E */ + PORT_R, /**< port R - 7E0 - F */ + /* ... */ + PORT_MAX, +}; + +/** + * @name Power management configuration + * @{ + */ +#define PM_NUM_MODES (4) +/** @} */ + +/** + * @brief Define the number of GPIO interrupts vectors for ATxmega CPU. + * @{ + */ +#define GPIO_EXT_INT_NUMOF (2 * PORT_MAX) +/** @} */ + +/** + * @brief Override GPIO type + * @{ + */ +#define HAVE_GPIO_T +typedef uint16_t gpio_t; +/** @} */ + +/** + * @brief Definition of a fitting UNDEF value + */ +#define GPIO_UNDEF (0xffff) + +/** + * @brief Define a CPU specific GPIO pin generator macro + * + * The ATxmega internally uses pin mask to manipulate all gpio functions. + * This allows simultaneous pin actions at any method call. ATxmega specific + * applications can use ATXMEGA_GPIO_PIN macro to define pins and generic + * RIOT-OS application should continue to use GPIO_PIN API for compatibility. + * + * @{ + */ +#define ATXMEGA_GPIO_PIN(x, y) (((x & 0x0f) << 8) | (y & 0xff)) +#define GPIO_PIN(x, y) ATXMEGA_GPIO_PIN(x, (1U << (y & 0x07))) +/** @} */ + +/** + * @brief Available pin modes + * + * Generally, a pin can be configured to be input or output. In output mode, a + * pin can further be put into push-pull or open drain configuration. Though + * this is supported by most platforms, this is not always the case, so driver + * implementations may return an error code if a mode is not supported. + * @{ + */ +#define HAVE_GPIO_MODE_T +typedef enum GPIO_MODE { + GPIO_SLEW_RATE = (1 << 7), /**< enable slew rate */ + GPIO_INVERTED = (1 << 6), /**< enable inverted signal */ + + GPIO_OPC_TOTEN = (0 << 3), /**< select no pull resistor (TOTEM) */ + GPIO_OPC_BSKPR = (1 << 3), /**< push-pull mode (BUSKEEPER) */ + GPIO_OPC_PD = (2 << 3), /**< pull-down resistor */ + GPIO_OPC_PU = (3 << 3), /**< pull-up resistor */ + GPIO_OPC_WRD_OR = (4 << 3), /**< enable wired OR */ + GPIO_OPC_WRD_AND = (5 << 3), /**< enable wired AND */ + GPIO_OPC_WRD_OR_PULL = (6 << 3), /**< enable wired OR and pull-down resistor */ + GPIO_OPC_WRD_AND_PULL = (7 << 3), /**< enable wired AND and pull-up resistor */ + + GPIO_ANALOG = (1 << 1), /**< select GPIO for analog function */ + + GPIO_IN = (0 << 0), /**< select GPIO MASK as input */ + GPIO_OUT = (1 << 0), /**< select GPIO MASK as output */ + + /* Compatibility Mode */ + GPIO_IN_PU = GPIO_IN | GPIO_OPC_PU, + GPIO_IN_PD = GPIO_IN | GPIO_OPC_PD, + GPIO_OD = GPIO_OUT | GPIO_OPC_WRD_OR, + GPIO_OD_PU = GPIO_OUT | GPIO_OPC_WRD_OR_PULL, +} gpio_mode_t; +/** @} */ + +/** + * @brief Definition of possible active flanks for external interrupt mode + * @{ + */ +#define HAVE_GPIO_FLANK_T +typedef enum { + GPIO_ISC_BOTH = (0 << 4), /**< emit interrupt on both flanks (default) */ + GPIO_ISC_RISING = (1 << 4), /**< emit interrupt on rising flank */ + GPIO_ISC_FALLING = (2 << 4), /**< emit interrupt on falling flank */ + GPIO_ISC_LOW_LEVEL = (3 << 4), /**< emit interrupt on low level */ + + GPIO_INT_DISABLED_ALL = (1 << 3), /**< disable all interrupts */ + + GPIO_INT0_VCT = (0 << 2), /**< enable interrupt on Vector 0 (default) */ + GPIO_INT1_VCT = (1 << 2), /**< enable interrupt on Vector 1 */ + + GPIO_LVL_OFF = (0 << 0), /**< interrupt disabled (default) */ + GPIO_LVL_LOW = (1 << 0), /**< interrupt low level */ + GPIO_LVL_MID = (2 << 0), /**< interrupt medium level */ + GPIO_LVL_HIGH = (3 << 0), /**< interrupt higher */ + + /* Compatibility Mode */ + GPIO_FALLING = GPIO_ISC_FALLING | GPIO_LVL_LOW, + GPIO_RISING = GPIO_ISC_RISING | GPIO_LVL_LOW, + GPIO_BOTH = GPIO_ISC_BOTH | GPIO_LVL_LOW, +} gpio_flank_t; +/** @} */ + +/** + * @brief Max number of available UARTs + */ +#define UART_MAX_NUMOF (7) + +/** + * @brief Size of the UART TX buffer for non-blocking mode. + */ +#ifndef UART_TXBUF_SIZE +#define UART_TXBUF_SIZE (64) +#endif + +/** + * @brief UART device configuration + */ +typedef struct { + USART_t *dev; /**< pointer to the used UART device */ + gpio_t rx_pin; /**< pin used for RX */ + gpio_t tx_pin; /**< pin used for TX */ +#ifdef MODULE_PERIPH_UART_HW_FC + gpio_t rts_pin; /**< RTS pin */ + gpio_t cts_pin; /**< CTS pin */ +#endif + cpu_int_lvl_t rx_int_lvl; /**< RX Complete Interrupt Level */ + cpu_int_lvl_t tx_int_lvl; /**< TX Complete Interrupt Level */ + cpu_int_lvl_t dre_int_lvl; /**< Data Registry Empty Interrupt Level */ +} uart_conf_t; + +/** + * @brief Max number of available timer channels + */ +#define TIMER_CH_MAX_NUMOF (4) + +/** + * @brief A low-level timer_set() implementation is provided + */ +#define PERIPH_TIMER_PROVIDES_SET + +/** + * @brief Timer Type + * + * Timer Type 1 is equal to Type 0 (two channels instead four) + * Timer Type 2 is Type 0 configured as two 8 bit timers instead one 16 bit + * Timer Type 2 won't be available as a standard timer + * Timer Type 5 is equal to Type 4 (two channels instead four) + */ +typedef enum { + TC_TYPE_0 = 0, + TC_TYPE_1 = 1, + TC_TYPE_2 = 2, + TC_TYPE_4 = 4, + TC_TYPE_5 = 5, +} timer_type_t; + +/** + * @brief Timer device configuration + * + * All timers can be derived from TC0_t struct. Need check at runtime the + * type and number of channels to perform all operations. + */ +typedef struct { + TC0_t *dev; /**< Pointer to the used as Timer device */ + timer_type_t type; /**< Timer Type */ + cpu_int_lvl_t int_lvl[TIMER_CH_MAX_NUMOF]; /**< Interrupt channels level */ +} timer_conf_t; + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_H */ +/** @} */ diff --git a/cpu/atxmega/periph/Makefile b/cpu/atxmega/periph/Makefile new file mode 100644 index 0000000000..f71f88d5c1 --- /dev/null +++ b/cpu/atxmega/periph/Makefile @@ -0,0 +1,3 @@ +MODULE = atxmega_periph + +include $(RIOTMAKE)/periph.mk diff --git a/cpu/atxmega/periph/cpuid.c b/cpu/atxmega/periph/cpuid.c new file mode 100644 index 0000000000..0e15a0420b --- /dev/null +++ b/cpu/atxmega/periph/cpuid.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level CPUID driver implementation + * + * @author Gerson Fernando Budke + * + * @} + */ + +#include "periph_cpu.h" +#include "cpu_nvm.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +void cpuid_get(void *id) +{ + uint8_t *addr = id; + + addr[0x0] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM0)); + addr[0x1] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM1)); + addr[0x2] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM2)); + addr[0x3] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM3)); + addr[0x4] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM4)); + addr[0x5] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM5)); + + addr[0x6] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(WAFNUM)); + + addr[0x7] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX0)); + addr[0x8] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX1)); + addr[0x9] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY0)); + addr[0xa] = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY1)); + + if (IS_ACTIVE(ENABLE_DEBUG)) { + DEBUG("CPUID: "); + for (uint8_t i = 0; i < CPUID_LEN; i++) { + DEBUG("%02x ", addr[i]); + } + DEBUG("\n"); + } +} diff --git a/cpu/atxmega/periph/gpio.c b/cpu/atxmega/periph/gpio.c new file mode 100644 index 0000000000..ffe92209d4 --- /dev/null +++ b/cpu/atxmega/periph/gpio.c @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level GPIO driver implementation + * + * @author Gerson Fernando Budke + * + * @} + */ + +#include +#include + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "bitarithm.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +/** + * @brief GPIO port base + * + * GPIO_PORT_BASE resides in the IO address space and must be 16 bits. + */ +#define GPIO_PORT_BASE ((uint16_t)&PORTA) + +/** + * @brief GPIO port structure offset + * + * The PORT_t struct it is not complete filled and it is necessary define the + * address offset manually. + */ +#define GPIO_PORT_OFFSET (0x20) + +static gpio_isr_ctx_t config_ctx[GPIO_EXT_INT_NUMOF]; +static uint8_t config_irq[GPIO_EXT_INT_NUMOF]; + +/** + * @brief Extract the pin number of the given pin + */ +static inline uint8_t _pin_mask(gpio_t pin) +{ + return (pin & 0xff); +} + +/** + * @brief Extract the port number of the given pin + */ +static inline uint8_t _port_num(gpio_t pin) +{ + return (pin >> 8) & 0x0f; +} + +/** + * @brief Generate the PORTx address of the give pin in the IO address space + */ +static inline PORT_t *_port_addr(gpio_t pin) +{ + uint8_t port_num = _port_num(pin); + uint16_t port_addr = GPIO_PORT_BASE + (port_num * GPIO_PORT_OFFSET); + + return (PORT_t *) port_addr; +} + +static inline void _print_config(gpio_t pin) +{ + PORT_t *port = _port_addr(pin); + uint8_t pin_mask = _pin_mask(pin); + volatile uint8_t *pin_ctrl = &port->PIN0CTRL; + + DEBUG("PORT: 0x%04x, PIN: 0x%02x\n", (uint16_t)port, pin_mask); + DEBUG("DIR: 0x%02x, IN: 0x%02x, OUT: 0x%02x\n", port->DIR, port->IN, port->OUT); + DEBUG("INTCTRL: 0x%02x\nINTFLAGS: 0x%02x\n", port->INTCTRL, port->INTFLAGS); + DEBUG("INT0MASK: 0x%02x\nINT1MASK: 0x%02x\n", port->INT0MASK, port->INT1MASK); + + for (uint8_t p = 0; p < 8; p++) { + DEBUG("PIN%dCTRL: 0x%02x\n", p, pin_ctrl[p]); + } +} + +static inline void _gpio_pinctrl_set(gpio_t pin, gpio_mode_t mode, + gpio_flank_t flank, gpio_cb_t cb, + void *arg) +{ + uint8_t pin_mask = _pin_mask(pin); + uint8_t port_num = _port_num(pin); + PORT_t *port = _port_addr(pin); + volatile uint8_t *pin_ctrl = &port->PIN0CTRL; + uint8_t irq_state; + uint8_t in_sense_cfg; + uint8_t pins; + uint8_t pin_idx; + + in_sense_cfg = (mode & ~PORT_ISC_gm); + in_sense_cfg |= (mode & GPIO_ANALOG) + ? PORT_ISC_INPUT_DISABLE_gc + : ((flank >> 4) & PORT_ISC_gm); + + pins = pin_mask; + pin_idx = 0; + + if (mode & GPIO_OUT) { + port->DIRSET = pin_mask; + } + else { + port->DIRCLR = pin_mask; + } + + irq_state = irq_disable(); + + while (pins) { + pins = bitarithm_test_and_clear(pins, &pin_idx); + pin_ctrl[pin_idx] = in_sense_cfg; + } + + if (flank & GPIO_INT_DISABLED_ALL) { + config_ctx[port_num + PORT_MAX].cb = NULL; + config_ctx[port_num + PORT_MAX].arg = NULL; + config_irq[port_num + PORT_MAX] = 0; + config_ctx[port_num].cb = NULL; + config_ctx[port_num].arg = NULL; + config_irq[port_num] = 0; + + port->INTCTRL = 0; + port->INT1MASK = 0; + port->INT0MASK = 0; + port->INTFLAGS = PORT_INT1IF_bm | PORT_INT0IF_bm; + } + else if (flank & GPIO_INT1_VCT) { + config_ctx[port_num + PORT_MAX].cb = cb; + config_ctx[port_num + PORT_MAX].arg = arg; + config_irq[port_num + PORT_MAX] = (flank & GPIO_LVL_HIGH) + << PORT_INT1LVL_gp; + + if ((flank & GPIO_LVL_HIGH) == GPIO_LVL_OFF) { + port->INT1MASK &= ~pin_mask; + } + else { + port->INT1MASK |= pin_mask; + } + + port->INTFLAGS = PORT_INT1IF_bm; + + /* Get mask from INT 0 and apply new INT 1 mask */ + port->INTCTRL = (port->INTCTRL & PORT_INT0LVL_gm) + | config_irq[port_num + PORT_MAX]; + } + else { + config_ctx[port_num].cb = cb; + config_ctx[port_num].arg = arg; + config_irq[port_num] = (flank & GPIO_LVL_HIGH) + << PORT_INT0LVL_gp; + + if ((flank & GPIO_LVL_HIGH) == GPIO_LVL_OFF) { + port->INT0MASK &= ~pin_mask; + } + else { + port->INT0MASK |= pin_mask; + } + + port->INTFLAGS = PORT_INT0IF_bm; + + /* Get mask from INT 1 and apply new INT 0 mask */ + port->INTCTRL = (port->INTCTRL & PORT_INT1LVL_gm) + | config_irq[port_num]; + } + + irq_restore(irq_state); +} + +int gpio_init(gpio_t pin, gpio_mode_t mode) +{ + DEBUG("gpio_init pin = 0x%02x mode = 0x%02x\n", pin, mode); + + _gpio_pinctrl_set(pin, mode, GPIO_INT_DISABLED_ALL, NULL, NULL); + + return 0; +} + +int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, + gpio_cb_t cb, void *arg) +{ + DEBUG("gpio_init_int pin = 0x%02x mode = 0x%02x flank = 0x%02x\n", pin, + mode, flank); + + if (mode & GPIO_ANALOG) { + DEBUG("Pin can't be ANALOG (input buffer disabled) and INT at same time.\n"); + return -1; + } + + _gpio_pinctrl_set(pin, mode, flank, cb, arg); + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } + + return 0; +} + +void gpio_irq_enable(gpio_t pin) +{ + DEBUG("gpio_irq_enable pin = 0x%04x \n", pin); + + uint8_t pin_mask = _pin_mask(pin); + uint8_t port_num = _port_num(pin); + PORT_t *port = _port_addr(pin); + + if (port->INT1MASK & pin_mask) { + port->INTFLAGS = PORT_INT1IF_bm; + port->INTCTRL |= config_irq[port_num + PORT_MAX]; + } + if (port->INT0MASK & pin_mask) { + port->INTFLAGS = PORT_INT0IF_bm; + port->INTCTRL |= config_irq[port_num]; + } + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } +} + +void gpio_irq_disable(gpio_t pin) +{ + DEBUG("gpio_irq_disable pin = 0x%04x \n", pin); + + uint8_t pin_mask = _pin_mask(pin); + PORT_t *port = _port_addr(pin); + + if (port->INT1MASK & pin_mask) { + port->INTCTRL &= ~PORT_INT1LVL_gm; + } + if (port->INT0MASK & pin_mask) { + port->INTCTRL &= ~PORT_INT0LVL_gm; + } + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } +} + +int gpio_read(gpio_t pin) +{ + PORT_t *port = _port_addr(pin); + uint8_t pin_mask = _pin_mask(pin); + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } + + return port->IN & pin_mask; +} + +void gpio_set(gpio_t pin) +{ + DEBUG("gpio_set pin = 0x%04x \n", pin); + + PORT_t *port = _port_addr(pin); + uint8_t pin_mask = _pin_mask(pin); + + port->OUTSET = pin_mask; + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } +} + +void gpio_clear(gpio_t pin) +{ + DEBUG("gpio_clear pin = 0x%04x \n", pin); + + PORT_t *port = _port_addr(pin); + uint8_t pin_mask = _pin_mask(pin); + + port->OUTCLR = pin_mask; + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } +} + +void gpio_toggle(gpio_t pin) +{ + DEBUG("gpio_toggle pin = 0x%04x \n", pin); + + PORT_t *port = _port_addr(pin); + uint8_t pin_mask = _pin_mask(pin); + + port->OUTTGL = pin_mask; + + if (IS_ACTIVE(ENABLE_DEBUG)) { + _print_config(pin); + } +} + +void gpio_write(gpio_t pin, int value) +{ + DEBUG("gpio_write pin = 0x%04x, value = 0x%02x \n", pin, value); + + if (value) { + gpio_set(pin); + } + else { + gpio_clear(pin); + } +} + +static inline void irq_handler(uint8_t port_num, uint8_t isr_vct_num) +{ + avr8_enter_isr(); + + DEBUG("irq_handler port = 0x%02x, vct_num = %d \n", port_num, isr_vct_num); + + if (isr_vct_num) { + port_num += PORT_MAX; + } + + if (config_ctx[port_num].cb) { + config_ctx[port_num].cb(config_ctx[port_num].arg); + } + else { + DEBUG("WARNING! irq_handler without callback\n"); + } + + avr8_exit_isr(); +} + +#if defined(PORTA_INT0_vect) +ISR(PORTA_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_A, 0); +} +#endif +#if defined(PORTA_INT1_vect) +ISR(PORTA_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_A, 1); +} +#endif + +#if defined(PORTB_INT0_vect) +ISR(PORTB_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_B, 0); +} +#endif +#if defined(PORTB_INT1_vect) +ISR(PORTB_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_B, 1); +} +#endif + +#if defined(PORTC_INT0_vect) +ISR(PORTC_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_C, 0); +} +#endif +#if defined(PORTC_INT1_vect) +ISR(PORTC_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_C, 1); +} +#endif + +#if defined(PORTD_INT0_vect) +ISR(PORTD_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_D, 0); +} +#endif +#if defined(PORTD_INT1_vect) +ISR(PORTD_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_D, 1); +} +#endif + +#if defined(PORTE_INT0_vect) +ISR(PORTE_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_E, 0); +} +#endif +#if defined(PORTE_INT1_vect) +ISR(PORTE_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_E, 1); +} +#endif + +#if defined(PORTF_INT0_vect) +ISR(PORTF_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_F, 0); +} +#endif +#if defined(PORTF_INT1_vect) +ISR(PORTF_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_F, 1); +} +#endif + +#if defined(PORTG_INT0_vect) +ISR(PORTG_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_G, 0); +} +#endif +#if defined(PORTG_INT1_vect) +ISR(PORTG_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_G, 1); +} +#endif + +#if defined(PORTH_INT0_vect) +ISR(PORTH_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_H, 0); +} +#endif +#if defined(PORTH_INT1_vect) +ISR(PORTH_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_H, 1); +} +#endif + +#if defined(PORTJ_INT0_vect) +ISR(PORTJ_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_J, 0); +} +#endif +#if defined(PORTJ_INT1_vect) +ISR(PORTJ_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_J, 1); +} +#endif + +#if defined(PORTK_INT0_vect) +ISR(PORTK_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_K, 0); +} +#endif +#if defined(PORTK_INT1_vect) +ISR(PORTK_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_K, 1); +} +#endif + +#if defined(PORTL_INT0_vect) +ISR(PORTL_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_L, 0); +} +#endif +#if defined(PORTL_INT1_vect) +ISR(PORTL_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_L, 1); +} +#endif + +#if defined(PORTM_INT0_vect) +ISR(PORTM_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_M, 0); +} +#endif +#if defined(PORTM_INT1_vect) +ISR(PORTM_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_M, 1); +} +#endif + +#if defined(PORTN_INT0_vect) +ISR(PORTN_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_N, 0); +} +#endif +#if defined(PORTN_INT1_vect) +ISR(PORTN_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_N, 1); +} +#endif + +#if defined(PORTP_INT0_vect) +ISR(PORTP_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_P, 0); +} +#endif +#if defined(PORTP_INT1_vect) +ISR(PORTP_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_P, 1); +} +#endif + +#if defined(PORTQ_INT0_vect) +ISR(PORTQ_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_Q, 0); +} +#endif +#if defined(PORTQ_INT1_vect) +ISR(PORTQ_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_Q, 1); +} +#endif + +#if defined(PORTR_INT0_vect) +ISR(PORTR_INT0_vect, ISR_BLOCK) +{ + irq_handler(PORT_R, 0); +} +#endif +#if defined(PORTR_INT1_vect) +ISR(PORTR_INT1_vect, ISR_BLOCK) +{ + irq_handler(PORT_R, 1); +} +#endif diff --git a/cpu/atxmega/periph/nvm.c b/cpu/atxmega/periph/nvm.c new file mode 100644 index 0000000000..88dc389e4c --- /dev/null +++ b/cpu/atxmega/periph/nvm.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level NVM driver implementation + * + * @author Gerson Fernando Budke + * + * @} + */ +#include + +#include "cpu_nvm.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +/** + * @brief Read one byte using the Load Program Memory (LPM) instruction + * @internal + * + * This function sets the specified NVM_CMD, reads one byte using at the + * specified byte address with the LPM instruction. NVM_CMD is restored after + * use. + * + * @note This will disable interrupts during execution. + * + * @param nvm_cmd NVM command to load before running LPM + * @param address Byte offset into the signature row + */ +static inline uint8_t _nvm_read_byte(uint8_t nvm_cmd, uint16_t address) +{ + uint8_t result; + + __asm__ volatile ( + "in __tmp_reg__, __SREG__ \n\t" + "cli \n\t" + "lds __zero_reg__, %3 \n\t" + "sts %3, %1 \n\t" + "lpm %0, %a2 \n\t" + "sts %3, __zero_reg__ \n\t" + "clr __zero_reg__ \n\t" + "out __SREG__, __tmp_reg__ \n\t" + : + "=&r" (result) + : + "r" (nvm_cmd), "e" (address), "m" (NVM_CMD) + : /* no clobbers */ + ); + + return result; +} + +/** + * @brief Read one byte from the production signature row + * + * This function reads one byte from the production signature row of the device + * at the given address. + * + * @note The execution can take some time. It is recommended not call this + * inside an interrupt service routine. + * + * @param address Byte offset into the signature row + */ +uint8_t nvm_read_production_signature_row(uint8_t address) +{ + return _nvm_read_byte(NVM_CMD_READ_CALIB_ROW_gc, address); +} diff --git a/cpu/atxmega/periph/pm.c b/cpu/atxmega/periph/pm.c new file mode 100644 index 0000000000..08875134e4 --- /dev/null +++ b/cpu/atxmega/periph/pm.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level PM driver implementation + * + * @author Gerson Fernando Budke + * + * @} + */ + +#include + +#include "periph_conf.h" +#include "periph/pm.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +void pm_reboot(void) +{ + DEBUG("Reboot Software Reset\n" ); + + /* XMEGA AU [MANUAL] p. 116 CTRL->Control register + * page 13 3.12.1 Sequence for write operation to protected I/O registers + * page 15 3.14.1 CCP – Configuration Change Protection register + */ + + /* Disable CCP for Protected IO registerand set new value*/ + _PROTECTED_WRITE(RST_CTRL, RST_SWRST_bm); + 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); +} diff --git a/cpu/atxmega/periph/timer.c b/cpu/atxmega/periph/timer.c new file mode 100644 index 0000000000..f49fbfd510 --- /dev/null +++ b/cpu/atxmega/periph/timer.c @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level TIMER driver implementation + * + * @author Gerson Fernando Budke + * + * @} + */ + +#include + +#include + +#include "cpu.h" +#include "thread.h" + +#include "periph/timer.h" + +#include "board.h" +#include "periph_conf.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +/** + * @brief We have 7 possible prescaler values + */ +#define PRESCALE_NUMOF (7U) + +/** + * @brief Possible prescaler values, encoded as 2 ^ val + */ +static const uint8_t prescalers[] = { 0, 1, 2, 3, 6, 8, 10 }; + +/** + * @brief Timer state context + */ +typedef struct { + timer_cb_t cb; /**< interrupt callback */ + void *arg; /**< interrupt callback argument */ + uint8_t prescaler; /**< remember the prescaler value */ + uint8_t channels; /**< number of channels */ +} ctx_t; + +/** + * @brief Allocate memory for saving the device states + * @{ + */ +#ifdef TIMER_NUMOF +static ctx_t ctx[TIMER_NUMOF] = { { NULL } }; +#else +/* fallback if no timer is configured */ +static ctx_t *ctx[] = { { NULL } }; +#endif +/** @} */ + +static uint32_t _oneshot; + +static inline void set_oneshot(tim_t tim, int chan) +{ + _oneshot |= (1 << chan) << (TIMER_CH_MAX_NUMOF * tim); +} + +static inline void clear_oneshot(tim_t tim, int chan) +{ + _oneshot &= ~((1 << chan) << (TIMER_CH_MAX_NUMOF * tim)); +} + +static inline bool is_oneshot(tim_t tim, int chan) +{ + return _oneshot & ((1 << chan) << (TIMER_CH_MAX_NUMOF * tim)); +} + +/** + * @brief Setup the given timer + */ +int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) +{ + DEBUG("timer.c: freq = %ld, Core Clock = %ld\n", freq, CLOCK_CORECLOCK); + + TC0_t *dev; + uint8_t pre; + uint8_t ch; + + assert(TIMER_CH_MAX_NUMOF * TIMER_NUMOF < 32); + + /* make sure given device is valid */ + if (tim >= TIMER_NUMOF) { + return -1; + } + + /* figure out if freq is applicable */ + for (pre = 0; pre < PRESCALE_NUMOF; pre++) { + if ((CLOCK_CORECLOCK >> prescalers[pre]) == freq) { + break; + } + } + if (pre == PRESCALE_NUMOF) { + DEBUG("timer.c: prescaling failed!\n"); + return -1; + } + + dev = timer_config[tim].dev; + + /* stop and reset timer */ + dev->CTRLA = 0; /* Stop */ + dev->CTRLFSET = TC_CMD_RESET_gc; /* Force Reset */ + + /* save interrupt context and timer Prescaler */ + ctx[tim].cb = cb; + ctx[tim].arg = arg; + ctx[tim].prescaler = (0x07 & (pre + 1)); + + /* Check enabled channels */ + ctx[tim].channels = 0; + for (ch = 0; ch < TIMER_CH_MAX_NUMOF; ch++) { + if (timer_config[tim].int_lvl[ch] != CPU_INT_LVL_OFF) { + ctx[tim].channels++; + } + } + + if (timer_config[tim].type != TC_TYPE_0 + && timer_config[tim].type != TC_TYPE_4) { + if (ctx[tim].channels > 2) { + DEBUG("timer.c: wrong number of channels. max value is 2.\n"); + return -1; + } + } + + if (timer_config[tim].type == TC_TYPE_2) { + DEBUG("timer.c: Timer version %d is current not supported.\n", + timer_config[tim].type); + return -1; + } + + /* Normal Counter with rollover */ + dev->CTRLB = TC_WGMODE_NORMAL_gc; + + /* Compare or Capture disable all channels */ + dev->INTCTRLB = 0; + + /* Free running counter */ + dev->PER = 0xFFFF; + + DEBUG("timer.c: prescaler set to %d \n", ctx[tim].prescaler); + dev->CTRLA = ctx[tim].prescaler; + + return 0; +} + +int timer_set_absolute(tim_t tim, int channel, unsigned int value) +{ + if (tim >= TIMER_NUMOF) { + return -1; + } + + if (channel >= ctx[tim].channels) { + return -1; + } + + DEBUG("Setting timer %i channel %i to %04x\n", tim, channel, value); + + TC0_t *dev = timer_config[tim].dev; + + dev->INTCTRLB &= ~(TC0_CCAINTLVL_gm << (channel * 2)); + dev->INTFLAGS |= TC0_CCAIF_bm << channel; + + uint8_t irq_state = irq_disable(); + + *(((uint16_t *)(&dev->CCA)) + channel) = (uint16_t)value; + + irq_restore(irq_state); + set_oneshot(tim, channel); + + dev->INTCTRLB |= (timer_config[tim].int_lvl[channel] << (channel * 2)); + + return 0; +} + +int timer_set_periodic(tim_t tim, int channel, unsigned int value, uint8_t flags) +{ + (void)flags; + + if (tim >= TIMER_NUMOF) { + return -1; + } + + if (channel > 0 || ctx[tim].channels != 1) { + DEBUG("Only channel 0 can be set as periodic and channels must be 1\n"); + + return -1; + } + + DEBUG("Setting timer %i channel 0 to %i and flags %i (repeating)\n", + tim, value, flags); + + TC0_t *dev = timer_config[tim].dev; + uint8_t irq_state = irq_disable(); + + dev->CTRLA = 0; + dev->CTRLFSET = TC_CMD_RESET_gc; + dev->CTRLB = TC_WGMODE_FRQ_gc; + dev->INTCTRLB = 0; + dev->INTFLAGS |= TC0_CCAIF_bm; + dev->CCA = (uint16_t)value; + dev->INTCTRLB = timer_config[tim].int_lvl[0]; + dev->CTRLA = ctx[tim].prescaler; + + clear_oneshot(tim, channel); + irq_restore(irq_state); + + return 0; +} + +int timer_clear(tim_t tim, int channel) +{ + if (tim >= TIMER_NUMOF) { + return -1; + } + + if (channel >= ctx[tim].channels) { + return -1; + } + + DEBUG("timer_clear channel %d\n", channel ); + + TC0_t *dev = timer_config[tim].dev; + + /* Compare or Capture Disable */ + dev->INTCTRLB &= ~(TC0_CCAINTLVL_gm << (channel * 2)); + + /* Clear Interrupt Flag + * The CCxIF is automatically cleared when the corresponding + * interrupt vector is executed.*/ + dev->INTFLAGS |= TC0_CCAIF_bm << channel; + + return 0; +} + +int timer_set(tim_t tim, int channel, unsigned int timeout) +{ + if (tim >= TIMER_NUMOF) { + return -1; + } + + if (channel >= ctx[tim].channels) { + return -1; + } + + TC0_t *dev = timer_config[tim].dev; + + /* Compare or Capture Disable */ + dev->INTCTRLB &= ~(TC0_CCAINTLVL_gm << (channel * 2)); + + /* Clear Interrupt Flag */ + dev->INTFLAGS |= TC0_CCAIF_bm << channel; + + uint8_t irq_state = irq_disable(); + + /* set value to compare with rollover */ + uint16_t absolute = dev->CNT + timeout; + *(((uint16_t *)(&dev->CCA)) + channel) = absolute; + + irq_restore(irq_state); + set_oneshot(tim, channel); + + /* Compare or Capture Enable */ + dev->INTCTRLB |= (timer_config[tim].int_lvl[channel] << (channel * 2)); + + return 0; +} + +unsigned int timer_read(tim_t tim) +{ + if (tim >= TIMER_NUMOF) { + return -1; + } + + DEBUG("timer_read\n"); + return (unsigned int)timer_config[tim].dev->CNT; +} + +void timer_stop(tim_t tim) +{ + if (tim >= TIMER_NUMOF) { + return; + } + + DEBUG("timer_stop\n"); + timer_config[tim].dev->CTRLA = 0; + timer_config[tim].dev->CTRLFSET = TC_CMD_RESTART_gc; +} + +void timer_start(tim_t tim) +{ + if (tim >= TIMER_NUMOF) { + return; + } + + DEBUG("timer_start\n"); + timer_config[tim].dev->CTRLA = ctx[tim].prescaler; +} + +#ifdef TIMER_NUMOF +static inline void _isr(tim_t tim, int channel) +{ + avr8_enter_isr(); + + DEBUG("timer %d _isr channel %d\n", tim, channel); + + if (is_oneshot(tim, channel)) { + timer_config[tim].dev->INTCTRLB &= ~(TC0_CCAINTLVL_gm << (channel * 2)); + } + + if (ctx[tim].cb) { + ctx[tim].cb(ctx[tim].arg, channel); + } + + avr8_exit_isr(); +} +#endif + +#ifdef TIMER_0_ISRA +ISR(TIMER_0_ISRA, ISR_BLOCK) +{ + _isr(0, 0); +} +#endif +#ifdef TIMER_0_ISRB +ISR(TIMER_0_ISRB, ISR_BLOCK) +{ + _isr(0, 1); +} +#endif +#ifdef TIMER_0_ISRC +ISR(TIMER_0_ISRC, ISR_BLOCK) +{ + _isr(0, 2); +} +#endif +#ifdef TIMER_0_ISRD +ISR(TIMER_0_ISRD, ISR_BLOCK) +{ + _isr(0, 3); +} +#endif /* TIMER_0 */ + +#ifdef TIMER_1_ISRA +ISR(TIMER_1_ISRA, ISR_BLOCK) +{ + _isr(1, 0); +} +#endif +#ifdef TIMER_1_ISRB +ISR(TIMER_1_ISRB, ISR_BLOCK) +{ + _isr(1, 1); +} +#endif +#ifdef TIMER_1_ISRC +ISR(TIMER_1_ISRC, ISR_BLOCK) +{ + _isr(1, 2); +} +#endif +#ifdef TIMER_1_ISRD +ISR(TIMER_1_ISRD, ISR_BLOCK) +{ + _isr(1, 3); +} +#endif /* TIMER_1 */ + +#ifdef TIMER_2_ISRA +ISR(TIMER_2_ISRA, ISR_BLOCK) +{ + _isr(2, 0); +} +#endif +#ifdef TIMER_2_ISRB +ISR(TIMER_2_ISRB, ISR_BLOCK) +{ + _isr(2, 1); +} +#endif +#ifdef TIMER_2_ISRC +ISR(TIMER_2_ISRC, ISR_BLOCK) +{ + _isr(2, 2); +} +#endif +#ifdef TIMER_2_ISRD +ISR(TIMER_2_ISRD, ISR_BLOCK) +{ + _isr(2, 3); +} +#endif /* TIMER_2 */ + +#ifdef TIMER_3_ISRA +ISR(TIMER_3_ISRA, ISR_BLOCK) +{ + _isr(3, 0); +} +#endif +#ifdef TIMER_3_ISRB +ISR(TIMER_3_ISRB, ISR_BLOCK) +{ + _isr(3, 1); +} +#endif +#ifdef TIMER_3_ISRC +ISR(TIMER_3_ISRC, ISR_BLOCK) +{ + _isr(3, 2); +} +#endif +#ifdef TIMER_3_ISRD +ISR(TIMER_3_ISRD, ISR_BLOCK) +{ + _isr(3, 3); +} +#endif /* TIMER_3 */ + +#ifdef TIMER_4_ISRA +ISR(TIMER_4_ISRA, ISR_BLOCK) +{ + _isr(4, 0); +} +#endif +#ifdef TIMER_4_ISRB +ISR(TIMER_4_ISRB, ISR_BLOCK) +{ + _isr(4, 1); +} +#endif +#ifdef TIMER_4_ISRC +ISR(TIMER_4_ISRC, ISR_BLOCK) +{ + _isr(4, 2); +} +#endif +#ifdef TIMER_4_ISRD +ISR(TIMER_4_ISRD, ISR_BLOCK) +{ + _isr(4, 3); +} +#endif /* TIMER_4 */ + +#ifdef TIMER_5_ISRA +ISR(TIMER_5_ISRA, ISR_BLOCK) +{ + _isr(5, 0); +} +#endif +#ifdef TIMER_5_ISRB +ISR(TIMER_5_ISRB, ISR_BLOCK) +{ + _isr(5, 1); +} +#endif +#ifdef TIMER_5_ISRC +ISR(TIMER_5_ISRC, ISR_BLOCK) +{ + _isr(5, 2); +} +#endif +#ifdef TIMER_5_ISRD +ISR(TIMER_5_ISRD, ISR_BLOCK) +{ + _isr(5, 3); +} +#endif /* TIMER_5 */ + +#ifdef TIMER_6_ISRA +ISR(TIMER_6_ISRA, ISR_BLOCK) +{ + _isr(6, 0); +} +#endif +#ifdef TIMER_6_ISRB +ISR(TIMER_6_ISRB, ISR_BLOCK) +{ + _isr(6, 1); +} +#endif +#ifdef TIMER_6_ISRC +ISR(TIMER_6_ISRC, ISR_BLOCK) +{ + _isr(6, 2); +} +#endif +#ifdef TIMER_6_ISRD +ISR(TIMER_6_ISRD, ISR_BLOCK) +{ + _isr(6, 3); +} +#endif /* TIMER_6 */ + +#ifdef TIMER_7_ISRA +ISR(TIMER_7_ISRA, ISR_BLOCK) +{ + _isr(7, 0); +} +#endif +#ifdef TIMER_7_ISRB +ISR(TIMER_7_ISRB, ISR_BLOCK) +{ + _isr(7, 1); +} +#endif +#ifdef TIMER_7_ISRC +ISR(TIMER_7_ISRC, ISR_BLOCK) +{ + _isr(7, 2); +} +#endif +#ifdef TIMER_7_ISRB +ISR(TIMER_7_ISRD, ISR_BLOCK) +{ + _isr(7, 3); +} +#endif /* TIMER_7 */ diff --git a/cpu/atxmega/periph/uart.c b/cpu/atxmega/periph/uart.c new file mode 100644 index 0000000000..aeaebcda3b --- /dev/null +++ b/cpu/atxmega/periph/uart.c @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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_atxmega + * @ingroup cpu_atxmega_periph + * @{ + * + * @file + * @brief Low-level UART driver implementation + * + * @author Gerson Fernando Budke + * + * + * Supports runtime calculation of the BSEL and BSCALE register values. + * Supports reconfiguring UART after a clock change. + * + * @} + */ +#include + +#include +#include + +#include "board.h" +#include "cpu.h" +#include "sched.h" +#include "thread.h" +#include "periph/uart.h" +#include "periph/gpio.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +/** + * @brief UART Baudrate Tolerance + * + * The tolerance is expressed as baud rate percentage multiplied by 100. + * For bigger tolerances UART double frequency can be avoided, thus saving + * power. + * + * The default baud tolerance is 2%. + */ +#ifndef BAUD_TOL +#define BAUD_TOL 2 * 100 +#endif + +/** + * @brief Allocate memory to store the callback functions. + */ +static uart_isr_ctx_t isr_ctx[UART_NUMOF]; + +/** + * @brief Get the pointer to the base register of the given USART device + * + * @param[in] dev USART device identifier + * + * @return base register address + */ +static inline USART_t *dev(uart_t dev) +{ + return uart_config[dev].dev; +} + +static inline int8_t _check_bsel(uint32_t baud, uint32_t calcbaud, + int16_t *precision) +{ + /* Avoid negative values and with precision of two positions + * after the decimal point for the deviation in percent + * + * result is the absolute deviation eg. 10 001 + * + * MAX BAUD fper/2 = 16MHz a shift of 8 can be used to increase + * accuracy + */ + uint16_t pre; + + if (baud < calcbaud) { + pre = (uint16_t)((calcbaud * 10000ULL) / baud); + } + else { + pre = (uint16_t)((baud * 10000ULL) / calcbaud); + } + + if (pre < ((uint16_t)*precision)) { + *precision = pre; + return 1; + } + + return 0; +} + +static inline int16_t _xmega_bsel_bscale(uint32_t *fper, uint32_t *baud, + uint8_t clk2x, uint16_t *bsel, + int8_t *bscale) +{ + uint32_t calcbaud = 0; + uint32_t deno = 0; + int16_t precision = UINT_MAX; + uint16_t loc_bsel = 0; + int8_t loc_bscale; + + /* Some explanation for equation transformation + * bsel = ( (fper / (2^bscale*16*baud) ) - 1 ) + * = ( (fper / (2^bscale*(16-8*clk2x)*baud) ) - 1 ) + * = ( fper - (2^bscale*(16-8*clk2x)*baud) ) + * / (2^bscale*(16-8*clk2x)*baud) + * + * deno = ( baud * (16-8*clk2x) * 2^bscale ) + * = ( baud * (1<<(4-clk2x)) * (1<= 4095) { + continue; + } + + /* Omit division by 16 get higher accuracy at small baudrates*/ + calcbaud = (*fper >> loc_bscale) / ((loc_bsel + 1) << (4 - clk2x)); + + if (_check_bsel(*baud, calcbaud, &precision)) { + *bsel = loc_bsel; + *bscale = loc_bscale; + } + } + + /* More math for the negative equation + * bscale is negative so 1/2^bscale = 2^|bscale| which is a factor and + * not a division again runding the result before division with + * 0.5 * denominator + * + * bsel = 1/2^bscale *( fcpu / ( (16*baud)-1) ) + * = ( fcpu*2^|bscale| - (16*baud)*2^|bscale| )/(16*baud) + * = ( fcpu*2^|bscale| - (16*baud)*2^|bscale| + 0.5*(16*baud) )/(16*baud) + * + * deno = (16/2*baud) = (baud<<(3-clk2x)) + * + * bsel = ( (fcpu - (deno<<(1))<<|bscale|) + deno )/(deno<<1) + * + * Baud = (fper*1/2^bscale)/ (16*(bsel+1/2^bscale)) + */ + for (loc_bscale = -1; loc_bscale >= -7; loc_bscale--) { + uint32_t num = 0; + + deno = (*baud << (3 - clk2x)); + num = ((*fper - (deno << 1)) << (-loc_bscale)) + deno; + num = (num / (deno << 1)); + + if (num >= 4095) { + break; + } + + loc_bsel = (uint16_t)(num & 0xFFF); + + /* Omit division by 16 get higher accuracy at small baudrates */ + calcbaud = (*fper << (-loc_bscale)) + / ((loc_bsel + (1 << (-loc_bscale))) << (4 - clk2x)); + + if (_check_bsel(*baud, calcbaud, &precision)) { + *bsel = loc_bsel; + *bscale = loc_bscale; + } + } + + return precision; +} + +/** + * @brief Calculates bsel and bscale for a given periphery clock and baudrate. + * Limitation are the periphery clock maximum is 32MHz, unsigned int + * overflows if clock is bigger. And the periphery clock has to be not + * smaller then 1 when divided by 128. + * + * fper/128 !=0 must be divide able by 128 + * fper*128 != uint23_max => 32MHz max fper + */ +static inline int16_t _xmega_calculate_bsel_bscale(uint32_t fcpu, uint32_t baud, + uint8_t *clk2x, + uint16_t *bsel, + int8_t *bscale) +{ + int16_t precision = 0; + + precision = _xmega_bsel_bscale(&fcpu, &baud, 0, bsel, bscale ); + + /* default 2% precision, required precision is at least 2% */ + if (precision <= (10000 + BAUD_TOL)) { + return (precision - 10000); + } + + /* Precision goal was not met calculate baudrate with uart frequency doubled */ + precision = _xmega_bsel_bscale(&fcpu, &baud, 1, bsel, bscale ); + *clk2x = 1; + + return (precision - 10000); +} + +static inline void _configure_pins(uart_t uart) +{ + /* configure RX pin */ + if (gpio_is_valid(uart_config[uart].rx_pin)) { + gpio_init(uart_config[uart].rx_pin, GPIO_IN); + } + + /* configure TX pin */ + if (gpio_is_valid(uart_config[uart].tx_pin)) { + gpio_set(uart_config[uart].tx_pin); + gpio_init(uart_config[uart].tx_pin, GPIO_OUT); + } + +#ifdef MODULE_PERIPH_UART_HW_FC + /* TODO */ +#endif +} + +int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) +{ + int8_t bscale; + uint8_t clk2x; + uint16_t bsel; + + /* make sure the given device is valid */ + if (uart >= UART_NUMOF) { + return UART_NODEV; + } + + uint16_t count = UINT16_MAX; + while (avr8_is_uart_tx_pending() && count--) {} + + /* register interrupt context */ + isr_ctx[uart].rx_cb = rx_cb; + isr_ctx[uart].arg = arg; + + /* disable and reset UART */ + dev(uart)->CTRLA = 0; + dev(uart)->CTRLB = 0; + dev(uart)->CTRLC = 0; + + _configure_pins(uart); + + /* configure UART to 8N1 mode */ + dev(uart)->CTRLC = USART_CMODE_ASYNCHRONOUS_gc + | USART_PMODE_DISABLED_gc + | USART_CHSIZE_8BIT_gc; + + /* set clock divider */ + _xmega_calculate_bsel_bscale(CLOCK_CORECLOCK, baudrate, &clk2x, + &bsel, &bscale); + + dev(uart)->BAUDCTRLA = (uint8_t)(bsel & 0x00ff); + dev(uart)->BAUDCTRLB = (bscale << USART_BSCALE_gp) + | ((uint8_t)((bsel & 0x0fff) >> 8)); + if (clk2x == 1) { + dev(uart)->CTRLB |= USART_CLK2X_bm; + } + + /* enable RX and TX Interrupts and set level*/ + if (rx_cb) { + dev(uart)->CTRLA = (uart_config[uart].rx_int_lvl << USART_RXCINTLVL_gp) + | (uart_config[uart].tx_int_lvl << USART_TXCINTLVL_gp) + | (uart_config[uart].dre_int_lvl << USART_DREINTLVL_gp); + dev(uart)->CTRLB = USART_RXEN_bm | USART_TXEN_bm; + } + else { + /* only transmit */ + dev(uart)->CTRLB = USART_TXEN_bm; + } + + DEBUG("Set clk2x %" PRIu8 " bsel %" PRIu16 "bscale %" PRIi8 "\n", + clk2x, bsel, bscale); + + return UART_OK; +} + +void uart_write(uart_t uart, const uint8_t *data, size_t len) +{ + for (size_t i = 0; i < len; i++) { + while (!(dev(uart)->STATUS & USART_DREIF_bm)) {} + + /* start of TX won't finish until no data in DATAn and transmit shift + register is empty */ + uint8_t irq_state = irq_disable(); + avr8_state |= AVR8_STATE_FLAG_UART_TX(uart); + irq_restore(irq_state); + + dev(uart)->DATA = data[i]; + } +} + +void uart_poweron(uart_t uart) +{ + (void)uart; + /* not implemented (yet) */ +} + +void uart_poweroff(uart_t uart) +{ + (void)uart; + /* not implemented (yet) */ +} + +static inline void _rx_isr_handler(int num) +{ + avr8_enter_isr(); + + if (isr_ctx[num].rx_cb) { + isr_ctx[num].rx_cb(isr_ctx[num].arg, dev(num)->DATA); + } + + avr8_exit_isr(); +} + +static inline void _tx_isr_handler(int num) +{ + avr8_enter_isr(); + + /* entire frame in the Transmit Shift Register has been shifted out and + there are no new data currently present in the transmit buffer */ + avr8_state &= ~AVR8_STATE_FLAG_UART_TX(num); + + avr8_exit_isr(); +} + +#ifdef UART_0_RXC_ISR +ISR(UART_0_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(0); +} +ISR(UART_0_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(0); +} +#endif /* UART_0_ISR */ + +#ifdef UART_1_RXC_ISR +ISR(UART_1_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(1); +} +ISR(UART_1_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(1); +} +#endif /* UART_1_ISR */ + +#ifdef UART_2_RXC_ISR +ISR(UART_2_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(2); +} +ISR(UART_2_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(2); +} +#endif /* UART_2_ISR */ + +#ifdef UART_3_RXC_ISR +ISR(UART_3_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(3); +} +ISR(UART_3_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(3); +} +#endif /* UART_3_ISR */ + +#ifdef UART_4_RXC_ISR +ISR(UART_4_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(4); +} +ISR(UART_4_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(4); +} +#endif /* UART_4_ISR */ + +#ifdef UART_5_RXC_ISR +ISR(UART_5_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(5); +} +ISR(UART_5_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(5); +} +#endif /* UART_5_ISR */ + +#ifdef UART_6_RXC_ISR +ISR(UART_6_RXC_ISR, ISR_BLOCK) +{ + _rx_isr_handler(6); +} +ISR(UART_6_TXC_ISR, ISR_BLOCK) +{ + _tx_isr_handler(6); +} +#endif /* UART_6_ISR */ From 8c1203c64689b66fe4addc0a3f8b056587eae8ac Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 2 Jan 2021 15:22:11 -0300 Subject: [PATCH 04/18] cpu/avr8_common: Add xmega reset cause register Add missing ATxmega reset cause register. This shares same definitions from ATmega CPU. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/avr8_cpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cpu/avr8_common/avr8_cpu.c b/cpu/avr8_common/avr8_cpu.c index c451306fed..afa8b044b1 100644 --- a/cpu/avr8_common/avr8_cpu.c +++ b/cpu/avr8_common/avr8_cpu.c @@ -39,12 +39,17 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#ifdef RST +/* In ATxmega there is a special register to get reset cause */ +#define MCUSR RST.STATUS +#else #ifndef MCUSR /* In older ATmegas the MCUSR register was still named MCUCSR. Current avrlibc * versions provide the MCUSR macro for those as well, but adding a fallback * here doesn't hurt*/ #define MCUSR MCUCSR #endif /* !MCUSR */ +#endif /* RST */ /* * Since atmega MCUs do not feature a software reset, the watchdog timer From facede13fda186e07d141ec04d798130656801b4 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 2 Jan 2021 18:59:47 -0300 Subject: [PATCH 05/18] cpu/avr8_common: Rework and add xmega registers The current context switch and thread stack init don't have a generic way to save/restore registers for all AVR-8 variations. This add defines to check flash/data sizes and rework: - thread_stack_init - avr8_context_save - avr8_context_restore The new implementation add missing RAMP D/X/Y registers that are used by XMEGA variations. The rules to add EIND, RAMP(D,X,Y,Z) register are: - EIND must be added if device have more than 128k flash. This means, device can access more than 64k words in flash. - RAMP D/X/Y must be added if device have or can address more than 64k data. - RAMPZ must be added if device can address more than 64k bytes of flash or data. With above rules there is no necessity to check by device because it is mandatory the registers for those MCU variations. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/thread_arch.c | 277 ++++++++++++++++++++-------------- 1 file changed, 167 insertions(+), 110 deletions(-) diff --git a/cpu/avr8_common/thread_arch.c b/cpu/avr8_common/thread_arch.c index 9ea1cd66af..d07d6448b1 100644 --- a/cpu/avr8_common/thread_arch.c +++ b/cpu/avr8_common/thread_arch.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen * 2017 Thomas Perrot * 2018 RWTH Aachen, Josua Arndt - * 2021 Gerson Fernando Budke + * 2021 Gerson Fernando Budke * * 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 @@ -14,7 +14,8 @@ * @{ * * @file - * @brief Implementation of the kernel's architecture dependent thread interface + * @brief Implementation of the kernel's architecture dependent thread + * interface * * @author Hinnerk van Bruinehsen * @author Thomas Perrot @@ -31,14 +32,31 @@ #include "irq.h" #include "cpu.h" #include "board.h" +#include "macros/xtstr.h" + +#define CHECK_EIND_REG FLASHEND > 0x1ffff + +#if defined(DATAMEM_SIZE) +#define CHECK_RAMPZ_REG DATAMEM_SIZE > 0xffff || FLASHEND > 0xffff +#define CHECK_RAMPDXY_REG DATAMEM_SIZE > 0xffff +#else +#define CHECK_RAMPZ_REG FLASHEND > 0xffff +#define CHECK_RAMPDXY_REG 0 +#endif + +#if (CHECK_EIND_REG) +#ifndef __EIND__ +#define __EIND__ 0x3C +#endif +#endif static void avr8_context_save(void); static void avr8_context_restore(void); static void avr8_enter_thread_mode(void); /** - * @brief Since AVR doesn't support direct manipulation of the program counter we - * model a stack like it would be left by avr8_context_save(). + * @brief Since AVR doesn't support direct manipulation of the program counter + * we model a stack like it would be left by avr8_context_save(). * The resulting layout in memory is the following: * ---------------thread_t (not created by thread_stack_init) ---------- * local variables (a temporary value and the stackpointer) @@ -46,18 +64,18 @@ static void avr8_enter_thread_mode(void); * a marker (AFFE) - for debugging purposes (helps finding the stack * ----------------------------------------------------------------------- * a 16 Bit pointer to sched_task_exit - * (Optional 17 bit (bit is set to zero) for devices with > 128kb FLASH) + * (Optional EIND bits are set to zero for devices with > 128kb FLASH) * ----------------------------------------------------------------------- * a 16 Bit pointer to task_func * this is placed exactly at the place where the program counter would be * stored normally and thus can be returned to when avr8_context_restore() * has been run - * (Optional 17 bit (bit is set to zero) for devices with > 128kb FLASH) + * (Optional EIND bits are set to zero for devices with > 128kb FLASH) * ----------------------------------------------------------------------- * saved registers from context: * r0 * status register - * (Optional EIND and RAMPZ registers) + * (Optional EIND, RAMPZ, RAMPX, RAMPY, RAMPD registers) * r1 - r23 * pointer to arg in r24 and r25 * r26 - r31 @@ -91,8 +109,9 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, tmp_adress >>= 8; *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); -#if FLASHEND > 0x1ffff - /* Devices with more than 128kb FLASH use a 17 bit PC, we set whole the top byte forcibly to 0 */ +#if (CHECK_EIND_REG) + /* Devices with more than 128kb FLASH use a PC with more than 16bits, we + * set whole the top byte forcibly to 0 */ stk--; *stk = (uint8_t)0x00; #endif @@ -105,8 +124,9 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, tmp_adress >>= 8; *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); -#if FLASHEND > 0x1ffff - /* Devices with more than 128kb FLASH use a 17 bit PC, we set whole the top byte forcibly to 0 */ +#if (CHECK_EIND_REG) + /* Devices with more than 128kb FLASH use a PC with more than 16bits, we + * set whole the top byte forcibly to 0 */ stk--; *stk = (uint8_t)0x00; #endif @@ -119,13 +139,23 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, stk--; *stk = (uint8_t)0x80; -#if defined(EIND) +#if (CHECK_RAMPZ_REG) stk--; - *stk = (uint8_t)0x00; + *stk = (uint8_t)0x00; /* RAMPZ */ #endif -#if defined(RAMPZ) && !defined(__AVR_ATmega32U4__) + +#if (CHECK_RAMPDXY_REG) stk--; - *stk = (uint8_t)0x00; + *stk = (uint8_t)0x00; /* RAMPY */ + stk--; + *stk = (uint8_t)0x00; /* RAMPX */ + stk--; + *stk = (uint8_t)0x00; /* RAMPD */ +#endif + +#if (CHECK_EIND_REG) + stk--; + *stk = (uint8_t)0x00; /* EIND */ #endif /* r1 - has always to be 0 */ @@ -210,7 +240,8 @@ extern char * __malloc_heap_end; extern char *__brkval; /** - * @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it + * @brief Set the MCU into Thread-Mode and load the initial task from the + * stack and run it */ void NORETURN avr8_enter_thread_mode(void) { @@ -223,6 +254,7 @@ void NORETURN avr8_enter_thread_mode(void) * thread-mode. Therefore, it can be considered as the top of the heap. */ __malloc_heap_end = STACK_POINTER - __malloc_margin; + /* __brkval has to be initialized if necessary */ if (__brkval == NULL) { __brkval = __malloc_heap_start; @@ -250,8 +282,10 @@ void thread_yield_higher(void) void avr8_exit_isr(void) { avr8_state &= ~AVR8_STATE_FLAG_ISR; + /* Force access to avr8_state to take place */ __asm__ volatile ("" : : : "memory"); + if (sched_context_switch_request) { avr8_context_save(); sched_run(); @@ -263,108 +297,131 @@ void avr8_exit_isr(void) __attribute__((always_inline)) static inline void avr8_context_save(void) { __asm__ volatile ( - "push __tmp_reg__ \n\t" - "in __tmp_reg__, __SREG__ \n\t" - "cli \n\t" - "push __tmp_reg__ \n\t" -#if defined(RAMPZ) && !defined(__AVR_ATmega32U4__) - "in __tmp_reg__, __RAMPZ__ \n\t" - "push __tmp_reg__ \n\t" + "push __tmp_reg__ \n\t" + "in __tmp_reg__, __SREG__ \n\t" + "cli \n\t" + "push __tmp_reg__ \n\t" + +#if (CHECK_RAMPZ_REG) + "in __tmp_reg__, __RAMPZ__ \n\t" + "push __tmp_reg__ \n\t" #endif -#if defined(EIND) - "in __tmp_reg__, 0x3c \n\t" - "push __tmp_reg__ \n\t" + +#if (CHECK_RAMPDXY_REG) + "in __tmp_reg__, __RAMPY__ \n\t" + "push __tmp_reg__ \n\t" + "in __tmp_reg__, __RAMPX__ \n\t" + "push __tmp_reg__ \n\t" + "in __tmp_reg__, __RAMPD__ \n\t" + "push __tmp_reg__ \n\t" #endif - "push r1 \n\t" - "clr r1 \n\t" - "push r2 \n\t" - "push r3 \n\t" - "push r4 \n\t" - "push r5 \n\t" - "push r6 \n\t" - "push r7 \n\t" - "push r8 \n\t" - "push r9 \n\t" - "push r10 \n\t" - "push r11 \n\t" - "push r12 \n\t" - "push r13 \n\t" - "push r14 \n\t" - "push r15 \n\t" - "push r16 \n\t" - "push r17 \n\t" - "push r18 \n\t" - "push r19 \n\t" - "push r20 \n\t" - "push r21 \n\t" - "push r22 \n\t" - "push r23 \n\t" - "push r24 \n\t" - "push r25 \n\t" - "push r26 \n\t" - "push r27 \n\t" - "push r28 \n\t" - "push r29 \n\t" - "push r30 \n\t" - "push r31 \n\t" - "lds r26, sched_active_thread \n\t" - "lds r27, sched_active_thread + 1 \n\t" - "in __tmp_reg__, __SP_L__ \n\t" - "st x+, __tmp_reg__ \n\t" - "in __tmp_reg__, __SP_H__ \n\t" - "st x+, __tmp_reg__ \n\t"); + +#if (CHECK_EIND_REG) + "in __tmp_reg__, " XTSTR(__EIND__) " \n\t" + "push __tmp_reg__ \n\t" +#endif + + "push r1 \n\t" + "clr r1 \n\t" + "push r2 \n\t" + "push r3 \n\t" + "push r4 \n\t" + "push r5 \n\t" + "push r6 \n\t" + "push r7 \n\t" + "push r8 \n\t" + "push r9 \n\t" + "push r10 \n\t" + "push r11 \n\t" + "push r12 \n\t" + "push r13 \n\t" + "push r14 \n\t" + "push r15 \n\t" + "push r16 \n\t" + "push r17 \n\t" + "push r18 \n\t" + "push r19 \n\t" + "push r20 \n\t" + "push r21 \n\t" + "push r22 \n\t" + "push r23 \n\t" + "push r24 \n\t" + "push r25 \n\t" + "push r26 \n\t" + "push r27 \n\t" + "push r28 \n\t" + "push r29 \n\t" + "push r30 \n\t" + "push r31 \n\t" + "lds r26, sched_active_thread \n\t" + "lds r27, sched_active_thread + 1 \n\t" + "in __tmp_reg__, __SP_L__ \n\t" + "st x+, __tmp_reg__ \n\t" + "in __tmp_reg__, __SP_H__ \n\t" + "st x+, __tmp_reg__ \n\t"); } __attribute__((always_inline)) static inline void avr8_context_restore(void) { __asm__ volatile ( - "lds r26, sched_active_thread \n\t" - "lds r27, sched_active_thread + 1 \n\t" - "ld r28, x+ \n\t" - "out __SP_L__, r28 \n\t" - "ld r29, x+ \n\t" - "out __SP_H__, r29 \n\t" - "pop r31 \n\t" - "pop r30 \n\t" - "pop r29 \n\t" - "pop r28 \n\t" - "pop r27 \n\t" - "pop r26 \n\t" - "pop r25 \n\t" - "pop r24 \n\t" - "pop r23 \n\t" - "pop r22 \n\t" - "pop r21 \n\t" - "pop r20 \n\t" - "pop r19 \n\t" - "pop r18 \n\t" - "pop r17 \n\t" - "pop r16 \n\t" - "pop r15 \n\t" - "pop r14 \n\t" - "pop r13 \n\t" - "pop r12 \n\t" - "pop r11 \n\t" - "pop r10 \n\t" - "pop r9 \n\t" - "pop r8 \n\t" - "pop r7 \n\t" - "pop r6 \n\t" - "pop r5 \n\t" - "pop r4 \n\t" - "pop r3 \n\t" - "pop r2 \n\t" - "pop r1 \n\t" -#if defined(EIND) - "pop __tmp_reg__ \n\t" - "out 0x3c, __tmp_reg__ \n\t" + "lds r26, sched_active_thread \n\t" + "lds r27, sched_active_thread + 1 \n\t" + "ld r28, x+ \n\t" + "out __SP_L__, r28 \n\t" + "ld r29, x+ \n\t" + "out __SP_H__, r29 \n\t" + "pop r31 \n\t" + "pop r30 \n\t" + "pop r29 \n\t" + "pop r28 \n\t" + "pop r27 \n\t" + "pop r26 \n\t" + "pop r25 \n\t" + "pop r24 \n\t" + "pop r23 \n\t" + "pop r22 \n\t" + "pop r21 \n\t" + "pop r20 \n\t" + "pop r19 \n\t" + "pop r18 \n\t" + "pop r17 \n\t" + "pop r16 \n\t" + "pop r15 \n\t" + "pop r14 \n\t" + "pop r13 \n\t" + "pop r12 \n\t" + "pop r11 \n\t" + "pop r10 \n\t" + "pop r9 \n\t" + "pop r8 \n\t" + "pop r7 \n\t" + "pop r6 \n\t" + "pop r5 \n\t" + "pop r4 \n\t" + "pop r3 \n\t" + "pop r2 \n\t" + "pop r1 \n\t" + +#if (CHECK_EIND_REG) + "pop __tmp_reg__ \n\t" + "out " XTSTR(__EIND__) ", __tmp_reg__ \n\t" #endif -#if defined(RAMPZ) && !defined(__AVR_ATmega32U4__) - "pop __tmp_reg__ \n\t" - "out __RAMPZ__, __tmp_reg__ \n\t" +#if (CHECK_RAMPDXY_REG) + "pop __tmp_reg__ \n\t" + "out __RAMPD__, __tmp_reg__ \n\t" + "pop __tmp_reg__ \n\t" + "out __RAMPX__, __tmp_reg__ \n\t" + "pop __tmp_reg__ \n\t" + "out __RAMPY__, __tmp_reg__ \n\t" #endif - "pop __tmp_reg__ \n\t" - "out __SREG__, __tmp_reg__ \n\t" - "pop __tmp_reg__ \n\t"); + +#if (CHECK_RAMPZ_REG) + "pop __tmp_reg__ \n\t" + "out __RAMPZ__, __tmp_reg__ \n\t" +#endif + + "pop __tmp_reg__ \n\t" + "out __SREG__, __tmp_reg__ \n\t" + "pop __tmp_reg__ \n\t"); } From 70c597620fb9ec997ec97c88d7a68df21416c8fa Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Fri, 5 Feb 2021 19:09:29 -0300 Subject: [PATCH 06/18] cpu/avr8_common: Differentiate avr8 cpu cores Current there is no way to split code between ATmega and ATxmega in drivers. This differentiate AVR8 cores into MEGAs and XMEGAs. Signed-off-by: Gerson Fernando Budke --- cpu/atmega_common/Kconfig | 9 +++++++-- cpu/atmega_common/Makefile.features | 1 + cpu/atxmega/Kconfig | 7 +++++-- cpu/atxmega/Makefile.features | 1 + cpu/avr8_common/Kconfig | 5 +---- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/cpu/atmega_common/Kconfig b/cpu/atmega_common/Kconfig index c49d8fe1b8..599b319719 100644 --- a/cpu/atmega_common/Kconfig +++ b/cpu/atmega_common/Kconfig @@ -4,11 +4,16 @@ # General Public License v2.1. See the file LICENSE in the top level # directory for more details. # + +config HAS_CPU_CORE_ATMEGA + bool + select CPU_ARCH_AVR8 + select HAS_CPP + config CPU_COMMON_ATMEGA bool - select CPU_CORE_AVR + select HAS_CPU_CORE_ATMEGA select HAS_ATMEGA_PCINT0 - select HAS_CPP select HAS_DBGPIN select HAS_PERIPH_CPUID select HAS_PERIPH_EEPROM diff --git a/cpu/atmega_common/Makefile.features b/cpu/atmega_common/Makefile.features index 8287eba643..7b58b012bd 100644 --- a/cpu/atmega_common/Makefile.features +++ b/cpu/atmega_common/Makefile.features @@ -3,6 +3,7 @@ include $(RIOTCPU)/avr8_common/Makefile.features # common feature are defined in avr8_common/Makefile.features # Only add Additional features +FEATURES_PROVIDED += cpu_core_atmega FEATURES_PROVIDED += atmega_pcint0 FEATURES_PROVIDED += dbgpin FEATURES_PROVIDED += periph_cpuid diff --git a/cpu/atxmega/Kconfig b/cpu/atxmega/Kconfig index 450978477f..88cd7174aa 100644 --- a/cpu/atxmega/Kconfig +++ b/cpu/atxmega/Kconfig @@ -6,12 +6,15 @@ # directory for more details. # -config CPU_COMMON_ATXMEGA +config HAS_CPU_CORE_ATXMEGA bool select CPU_ARCH_AVR8 - select CPU_CORE_AVR select HAS_CPU_ATXMEGA select HAS_CPP + +config CPU_COMMON_ATXMEGA + bool + select HAS_CPU_CORE_ATXMEGA select HAS_PERIPH_CPUID select HAS_PERIPH_GPIO select HAS_PERIPH_GPIO_IRQ diff --git a/cpu/atxmega/Makefile.features b/cpu/atxmega/Makefile.features index c20ff1a9dd..a08cfd24e2 100644 --- a/cpu/atxmega/Makefile.features +++ b/cpu/atxmega/Makefile.features @@ -3,6 +3,7 @@ include $(RIOTCPU)/avr8_common/Makefile.features # common feature are defined in avr8_common/Makefile.features # Only add Additional features +FEATURES_PROVIDED += cpu_core_atxmega FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_gpio periph_gpio_irq FEATURES_PROVIDED += periph_nvm diff --git a/cpu/avr8_common/Kconfig b/cpu/avr8_common/Kconfig index 334b69b788..1c5ab86dd7 100644 --- a/cpu/avr8_common/Kconfig +++ b/cpu/avr8_common/Kconfig @@ -5,15 +5,12 @@ # General Public License v2.1. See the file LICENSE in the top level # directory for more details. # + config CPU_ARCH_AVR8 bool select HAS_ARCH_8BIT select HAS_ARCH_AVR8 -config CPU_CORE_AVR - bool - select CPU_ARCH_AVR8 - ## Common CPU symbols config CPU_ARCH default "avr8" if CPU_ARCH_AVR8 From f1eaa4caf3c7525f9b0c8780822b000f70eec580 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 11 Jan 2021 20:02:48 -0300 Subject: [PATCH 07/18] cpu/avr8_common/avr8_cpu: Enable xmega pmic The XMEGA CPU have a Programmable Multilevel Interrupt Controller. This enables all three PMIC levels. By default, all interrupts are preconfigured as LOW Level without Round Robin queue. This works as any MCU with interrupt enabled. In order to get benefit from Multilevel Interrupts user need increase the interrupt level by own. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/avr8_cpu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cpu/avr8_common/avr8_cpu.c b/cpu/avr8_common/avr8_cpu.c index afa8b044b1..951d1fd25c 100644 --- a/cpu/avr8_common/avr8_cpu.c +++ b/cpu/avr8_common/avr8_cpu.c @@ -102,6 +102,13 @@ void cpu_init(void) /* hwrng_init */ periph_init(); +#ifdef CPU_ATXMEGA + /* Enable Multilevel Interrupt Controller */ + PMIC.CTRL |= PMIC_HILVLEN_bm + | PMIC_MEDLVLEN_bm + | PMIC_LOLVLEN_bm; +#endif + irq_enable(); } From aa3af4e2fa1836ff78eea67470bea621a27a0339 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Wed, 3 Feb 2021 22:03:29 -0300 Subject: [PATCH 08/18] cpu/avr8_common/avr8_cpu: Add xmega clock ATxmega have many clock options. This introduce clk_init into cpu_init to allow user select between a default configuration or perform fine clock tune. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/avr8_cpu.c | 8 ++++++++ cpu/avr8_common/include/cpu.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/cpu/avr8_common/avr8_cpu.c b/cpu/avr8_common/avr8_cpu.c index 951d1fd25c..992c782c05 100644 --- a/cpu/avr8_common/avr8_cpu.c +++ b/cpu/avr8_common/avr8_cpu.c @@ -31,10 +31,14 @@ #include #include "cpu.h" +#ifdef CPU_AVR8_HAS_CLOCK_INIT +#include "cpu_clock.h" +#endif #include "board.h" #include "irq.h" #include "periph/init.h" #include "panic.h" +#include "kernel_defines.h" #define ENABLE_DEBUG 0 #include "debug.h" @@ -92,6 +96,10 @@ void cpu_init(void) wdt_reset(); /* should not be nececessary as done in bootloader */ wdt_disable(); /* but when used without bootloader this is needed */ +#ifdef CPU_AVR8_HAS_CLOCK_INIT + avr8_clk_init(); +#endif + /* Initialize stdio before periph_init() to allow use of DEBUG() there */ #ifdef MODULE_AVR_LIBC_EXTRA avr8_stdio_init(); diff --git a/cpu/avr8_common/include/cpu.h b/cpu/avr8_common/include/cpu.h index 3e221584d6..5f74717753 100644 --- a/cpu/avr8_common/include/cpu.h +++ b/cpu/avr8_common/include/cpu.h @@ -166,6 +166,11 @@ void avr8_exit_isr(void); */ void cpu_init(void); +/** + * @brief Initialization of the CPU clock + */ +void avr8_clk_init(void); + /** * @brief Print the last instruction's address */ From 699248c65f0fb238f4198aa0034083ca4f3c5c0f Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 7 Mar 2021 17:35:19 -0300 Subject: [PATCH 09/18] makefiles/arch/atmega.inc.mk: Rename to avr8.inc.mk Atmel AVR-8 CPU was reworked to accomodate variants like ATxmega. This rename to atmega.inc.mk to avr8.inc.mk to be compliant with new directory structure. Signed-off-by: Gerson Fernando Budke --- cpu/avr8_common/Makefile.include | 2 +- makefiles/arch/{atmega.inc.mk => avr8.inc.mk} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename makefiles/arch/{atmega.inc.mk => avr8.inc.mk} (100%) diff --git a/cpu/avr8_common/Makefile.include b/cpu/avr8_common/Makefile.include index 73ea0cc84d..c762770d65 100644 --- a/cpu/avr8_common/Makefile.include +++ b/cpu/avr8_common/Makefile.include @@ -3,4 +3,4 @@ INCLUDES += -I$(RIOTCPU)/avr8_common/include \ -isystem$(RIOTCPU)/avr8_common/avr_libc_extra/include \ -isystem$(RIOTCPU)/avr8_common/avr_libc_extra/include/vendor -include $(RIOTMAKE)/arch/atmega.inc.mk +include $(RIOTMAKE)/arch/avr8.inc.mk diff --git a/makefiles/arch/atmega.inc.mk b/makefiles/arch/avr8.inc.mk similarity index 100% rename from makefiles/arch/atmega.inc.mk rename to makefiles/arch/avr8.inc.mk From 4b2bcd560b4cd08c7e4898d9756b94ff5263bdff Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 2 Jan 2021 15:29:08 -0300 Subject: [PATCH 10/18] makefiles/arch/avr8: Add xmega linker conditions The current script doesn't allow change script path and name. Add LDSCRIPT_COMPAT_PATH and LDSCRIPT_COMPAT_NAME default values to allow a unique path inside atxmega folder. Signed-off-by: Gerson Fernando Budke --- makefiles/arch/avr8.inc.mk | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/makefiles/arch/avr8.inc.mk b/makefiles/arch/avr8.inc.mk index 98c7d83c25..ed1616f251 100644 --- a/makefiles/arch/avr8.inc.mk +++ b/makefiles/arch/avr8.inc.mk @@ -2,7 +2,14 @@ TARGET_ARCH_AVR ?= avr TARGET_ARCH ?= $(TARGET_ARCH_AVR) -CFLAGS_CPU = -mmcu=$(CPU) $(CFLAGS_FPU) +ifeq (atxmega,$(CPU)) + ifeq (,$(CPU_MODEL)) + $(error CPU_MODEL must have been defined by the board Makefile.features) + endif + CFLAGS_CPU ?= -mmcu=$(CPU_MODEL) $(CFLAGS_FPU) +else + CFLAGS_CPU ?= -mmcu=$(CPU) $(CFLAGS_FPU) +endif CFLAGS_LINK = -ffunction-sections -fdata-sections -fno-builtin -fshort-enums CFLAGS_DBG ?= -ggdb -g3 CFLAGS_OPT ?= -Os From 1d55c85f24fcfdc6a34a3bf01e36a9f716e82c03 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 2 Jan 2021 15:32:51 -0300 Subject: [PATCH 11/18] makefiles/tools/avrdude: Add xmega cpu conditions The current script don't allow change debug protocol and not allows set proper part name for xmega. This make DEBUGPROTO optional with JTAG as default protocol. It add a filter for atxmega to add proper AVRDUDE_PROGRAMMER_FLAGS. Signed-off-by: Gerson Fernando Budke --- makefiles/tools/avrdude.inc.mk | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/makefiles/tools/avrdude.inc.mk b/makefiles/tools/avrdude.inc.mk index 29f9371f10..80337be76c 100644 --- a/makefiles/tools/avrdude.inc.mk +++ b/makefiles/tools/avrdude.inc.mk @@ -12,14 +12,18 @@ ifneq (,$(filter $(CPU),atmega328p)) # Use debugWIRE as protocol for debugging (ATmega328P does not support JTAG) DEBUGPROTO := -w else - # Use JTAG as protocol for debugging - DEBUGPROTO := -j $(AVR_DEBUGINTERFACE) + # Use JTAG as protocol for debugging as default + DEBUGPROTO ?= -j $(AVR_DEBUGINTERFACE) endif DEBUGSERVER_FLAGS ?= "$(AVR_DEBUGDEVICE) $(DEBUGPROTO) :$(DEBUGSERVER_PORT)" DEBUGGER_FLAGS ?= "-x $(AVARICE_PATH)/gdb.conf $(ELFFILE)" DEBUGGER = "$(AVARICE_PATH)/debug.sh" $(DEBUGSERVER_FLAGS) $(AVARICE_PATH) $(DEBUGSERVER_PORT) -AVRDUDE_PROGRAMMER_FLAGS = -p $(subst atmega,m,$(CPU)) +ifeq (atxmega,$(CPU)) + AVRDUDE_PROGRAMMER_FLAGS ?= -p $(subst atxmega,x,$(CPU_MODEL)) +else + AVRDUDE_PROGRAMMER_FLAGS = -p $(subst atmega,m,$(CPU)) +endif # Set flasher port only for programmers that require it ifneq (,$(filter $(AVRDUDE_PROGRAMMER),arduino avr109 buspirate stk500v1 stk500v2 wiring)) From 85fcba0ce92caabd4e9a5e28c980c483f433a82e Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 11 Jan 2021 20:18:40 -0300 Subject: [PATCH 12/18] boards/common: Introduce Atmel xmega common Add atxmega common board definitions. This works is a port from @josar with few modifications. Signed-off-by: Gerson Fernando Budke --- boards/common/atxmega/Makefile | 3 + boards/common/atxmega/Makefile.features | 1 + boards/common/atxmega/Makefile.include | 38 +++++++ boards/common/atxmega/board.c | 38 +++++++ boards/common/atxmega/doc.txt | 5 + .../atxmega/include/periph_conf_common.h | 100 ++++++++++++++++++ 6 files changed, 185 insertions(+) create mode 100644 boards/common/atxmega/Makefile create mode 100644 boards/common/atxmega/Makefile.features create mode 100644 boards/common/atxmega/Makefile.include create mode 100644 boards/common/atxmega/board.c create mode 100644 boards/common/atxmega/doc.txt create mode 100644 boards/common/atxmega/include/periph_conf_common.h diff --git a/boards/common/atxmega/Makefile b/boards/common/atxmega/Makefile new file mode 100644 index 0000000000..ed318b9cf8 --- /dev/null +++ b/boards/common/atxmega/Makefile @@ -0,0 +1,3 @@ +MODULE = boards_common_atxmega + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/atxmega/Makefile.features b/boards/common/atxmega/Makefile.features new file mode 100644 index 0000000000..c0e6270d49 --- /dev/null +++ b/boards/common/atxmega/Makefile.features @@ -0,0 +1 @@ +CPU = atxmega diff --git a/boards/common/atxmega/Makefile.include b/boards/common/atxmega/Makefile.include new file mode 100644 index 0000000000..a6371859e2 --- /dev/null +++ b/boards/common/atxmega/Makefile.include @@ -0,0 +1,38 @@ +INCLUDES += -I$(RIOTBOARD)/common/atxmega/include + +# Use JTAG as default protocol for debugging +DEBUGPROTO ?= -x +FLASHFILE ?= $(ELFFILE) + +# Use avrdude programmer with Atmel ICE as default flash/debug system +PROGRAMMER ?= avrdude +AVRDUDE_PROGRAMMER ?= atmelice + +ifneq (,$(filter flash%,$(MAKECMDGOALS))) + FFLAGS_EXTRA ?= -e +endif + +# If avrdude specific programmer is not set, set it based on the bootloader used +ifeq (,$(AVRDUDE_PROGRAMMER)) + FLASHFILE ?= $(BINFILE) + + ifeq (stk500v2,$(BOOTLOADER)) + AVRDUDE_PROGRAMMER = stk500v2 + BOOTLOADER_SIZE ?= 4K + # Disable auto erase; erasing the flash is done implicitly by the bootloader + # and explicit erase is not supported + FFLAGS_EXTRA += -D + endif + + ifeq (avr109,$(BOOTLOADER)) + AVRDUDE_PROGRAMMER = avr109 + BOOTLOADER_SIZE ?= 4K + endif + + ifneq (,$(BOOTLOADER_BAUD)) + FFLAGS_EXTRA += -b $(BOOTLOADER_BAUD) + endif +endif + +BOOTLOADER_SIZE ?= 0 +ROM_RESERVED ?= $(BOOTLOADER_SIZE) diff --git a/boards/common/atxmega/board.c b/boards/common/atxmega/board.c new file mode 100644 index 0000000000..e2db598884 --- /dev/null +++ b/boards/common/atxmega/board.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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 boards_common + * @{ + * + * @file + * @brief Common implementations for ATxmega boards + * + * @author Gerson Fernando Budke + * + * @} + */ + +#include "board.h" +#include "cpu.h" + +#ifdef LED_PORT +void __attribute__((weak)) led_init(void) +{ + LED_PORT.DIR = LED_PORT_MASK; + LED_PORT.OUT = LED_PORT_MASK; +} +#endif + +void __attribute__((weak)) board_init(void) +{ + cpu_init(); +#ifdef LED_PORT + led_init(); +#endif +} diff --git a/boards/common/atxmega/doc.txt b/boards/common/atxmega/doc.txt new file mode 100644 index 0000000000..73b19e8380 --- /dev/null +++ b/boards/common/atxmega/doc.txt @@ -0,0 +1,5 @@ +/** +@defgroup boards_common_atxmega ATxmega common +@ingroup boards +@brief Shared files and configuration for ATxmega-based boards + */ \ No newline at end of file diff --git a/boards/common/atxmega/include/periph_conf_common.h b/boards/common/atxmega/include/periph_conf_common.h new file mode 100644 index 0000000000..95f54717ea --- /dev/null +++ b/boards/common/atxmega/include/periph_conf_common.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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 boards_common_atxmega + * @{ + * + * @file + * @brief Common configuration of MCU periphery for ATxmega boards + * + * @author Gerson Fernando Budke + */ + +#ifndef PERIPH_CONF_COMMON_H +#define PERIPH_CONF_COMMON_H + +#include "periph_cpu.h" +#include "macros/units.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Clock configuration + * @{ + */ +#ifndef CLOCK_CORECLOCK +#define CLOCK_CORECLOCK MHZ(32) +#endif /* CLOCK_CORECLOCK */ +/** @} */ + +/** + * @name ADC Configuration + * + * @{ + */ +#ifndef ADC_NUMOF +#define ADC_NUMOF (0U) +#endif /* ADC_NUMOF */ +/** @} */ + +/** + * @name I2C configuration + * @{ + */ +#ifndef I2C_NUMOF +#define I2C_NUMOF (0U) +#endif /* I2C_NUMOF */ +/** @} */ + +/** + * @name PWM configuration + * + * @{ + */ +#ifndef PWM_NUMOF +#define PWM_NUMOF (0U) +#endif /* PWM_NUMOF */ +/** @} */ + +/** + * @name SPI configuration + * + * The SS pin must be configured as output for the SPI device to work as + * master correctly, though we do not use it for now (as we handle the chip + * select externally for now) + * + * @{ + */ +#ifndef SPI_NUMOF +#define SPI_NUMOF (0U) +#endif /* SPI_NUMOF */ +/** @} */ + +/** + * @name UART configuration + * + * The UART devices have fixed pin mappings, so all we need to do, is to specify + * which devices we would like to use and their corresponding RX interrupts. See + * the reference manual for the fixed pin mapping. + * + * @{ + */ +#ifndef UART_NUMOF +#define UART_NUMOF (0U) +#endif /* UART_NUMOF */ +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_COMMON_H */ +/** @} */ From b843cfb5c2eca0160b6ba2c56022f48501efc75b Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 11 Jan 2021 20:21:06 -0300 Subject: [PATCH 13/18] boards: Introduce atxmega-a1u-xpro board Add initial version. Signed-off-by: Gerson Fernando Budke --- boards/atxmega-a1u-xpro/Kconfig | 24 ++++ boards/atxmega-a1u-xpro/Makefile | 5 + boards/atxmega-a1u-xpro/Makefile.dep | 5 + boards/atxmega-a1u-xpro/Makefile.features | 3 + boards/atxmega-a1u-xpro/Makefile.include | 4 + boards/atxmega-a1u-xpro/doc.txt | 66 +++++++++++ boards/atxmega-a1u-xpro/include/board.h | 104 ++++++++++++++++++ boards/atxmega-a1u-xpro/include/gpio_params.h | 53 +++++++++ boards/atxmega-a1u-xpro/include/periph_conf.h | 99 +++++++++++++++++ 9 files changed, 363 insertions(+) create mode 100644 boards/atxmega-a1u-xpro/Kconfig create mode 100644 boards/atxmega-a1u-xpro/Makefile create mode 100644 boards/atxmega-a1u-xpro/Makefile.dep create mode 100644 boards/atxmega-a1u-xpro/Makefile.features create mode 100644 boards/atxmega-a1u-xpro/Makefile.include create mode 100644 boards/atxmega-a1u-xpro/doc.txt create mode 100644 boards/atxmega-a1u-xpro/include/board.h create mode 100644 boards/atxmega-a1u-xpro/include/gpio_params.h create mode 100644 boards/atxmega-a1u-xpro/include/periph_conf.h diff --git a/boards/atxmega-a1u-xpro/Kconfig b/boards/atxmega-a1u-xpro/Kconfig new file mode 100644 index 0000000000..efb90396a0 --- /dev/null +++ b/boards/atxmega-a1u-xpro/Kconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2020 HAW Hamburg +# Copyright (c) 2021 Gerson Fernando Budle +# +# 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. + +config BOARD + default "atxmega-a1u-xpro" if BOARD_ATXMEGA_A1U_XPRO + +config BOARD_ATXMEGA_A1U_XPRO + bool + default y + select CPU_MODEL_XMEGA128A1U + select HAS_PERIPH_CPUID + 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 + select HAS_PERIPH_UART + + select HAVE_SAUL_GPIO diff --git a/boards/atxmega-a1u-xpro/Makefile b/boards/atxmega-a1u-xpro/Makefile new file mode 100644 index 0000000000..1db5601cf3 --- /dev/null +++ b/boards/atxmega-a1u-xpro/Makefile @@ -0,0 +1,5 @@ +MODULE = board + +DIRS = $(RIOTBOARD)/common/atxmega + +include $(RIOTBASE)/Makefile.base diff --git a/boards/atxmega-a1u-xpro/Makefile.dep b/boards/atxmega-a1u-xpro/Makefile.dep new file mode 100644 index 0000000000..c469a40b90 --- /dev/null +++ b/boards/atxmega-a1u-xpro/Makefile.dep @@ -0,0 +1,5 @@ +USEMODULE += boards_common_atxmega + +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += saul_gpio +endif diff --git a/boards/atxmega-a1u-xpro/Makefile.features b/boards/atxmega-a1u-xpro/Makefile.features new file mode 100644 index 0000000000..729c41ce6b --- /dev/null +++ b/boards/atxmega-a1u-xpro/Makefile.features @@ -0,0 +1,3 @@ +CPU_MODEL = atxmega128a1u + +include $(RIOTBOARD)/common/atxmega/Makefile.features diff --git a/boards/atxmega-a1u-xpro/Makefile.include b/boards/atxmega-a1u-xpro/Makefile.include new file mode 100644 index 0000000000..f5bff7abc8 --- /dev/null +++ b/boards/atxmega-a1u-xpro/Makefile.include @@ -0,0 +1,4 @@ +AVRDUDE_PROGRAMMER = xplainedpro_pdi +DEBUGPROTO = -X + +include $(RIOTBOARD)/common/atxmega/Makefile.include diff --git a/boards/atxmega-a1u-xpro/doc.txt b/boards/atxmega-a1u-xpro/doc.txt new file mode 100644 index 0000000000..cab6b2fd38 --- /dev/null +++ b/boards/atxmega-a1u-xpro/doc.txt @@ -0,0 +1,66 @@ +/** +@defgroup boards_atxmega-a1u-xpro ATxmega-A1U Xplained Pro board +@ingroup boards +@brief Support for the ATxmega-A1U Xplained Pro board + +## Overview + +The ATxmega-A1U Xplained Pro is the reference to develop with XMEGA's. + +### MCU +| MCU | ATxmega128A1U | +|:------------- |:--------------------------------------------- | +| Family | AVR/ATxmega | +| Vendor | Microchip (previously Atmel) | +| Flash | 128KiB | +| RAM | 8KiB | +| EBI | 16MiB SRAM, 128MiB SDRAM | +| EEPROM | 2KiB | +| Frequency | up to 32MHz | +| Timers | 8 16bit (32 bit combining 2 x 16 bit) | +| ACs | 4 Analog Comparators | +| ADCs | 2 - 16 channels - 12 bit - 2msps | +| ADCs | 2 - 2 channels - 12 bit - 1msps | +| UARTs | 8 (can be used in SPI mode) with 1 IrDA | +| SPIs | 4 | +| I2Cs | 4 (called TWI) | +| USB | 1 port | +| DMA | 4 Channels | +| Event System | 8 Channels | +| Ext. INT | All GPIOs | +| Crypto | AES/DES, CRC-16, CRC-32 | +| Vcc | 1.6V - 3.6V | +| Datasheet | [Datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/ATxmega128A1U-64A1U-Data-Sheet-DS40002058A.pdf) | +| Xmega Manual | [Manual](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf) | +| Guide | [User Guide](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42211-XMEGA-A1U-Xplained-Pro_User-Guide.pdf) | +| Design Files | [Files](https://ww1.microchip.com/downloads/en/DeviceDoc/XMEGA-A1U-Xplained-Pro_Design-Documentation.zip) | + +## Flashing the Device + +The ATxmega-A1U Xplained Pro came with a full EDBG + CDC-ACM. The EDBG works +with default avrdude tool. However, the below programmer must have at +/etc/avrdude.conf file: + +programmer + id = "xplainedpro_pdi"; + desc = "Atmel AVR XplainedPro in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2111; +; + +In order to flash the ATxmega128A1U, simple run: + + make BOARD=atxmega-a1u-xpro flash + +## Serial Terminal + +The CDC-ACM will enumerate a /dev/ttyACM device. + + make BOARD=atxmega-a1u-xpro term + +## On-Chip Debugging (OCD) + + make debug + + */ diff --git a/boards/atxmega-a1u-xpro/include/board.h b/boards/atxmega-a1u-xpro/include/board.h new file mode 100644 index 0000000000..2314adc6ce --- /dev/null +++ b/boards/atxmega-a1u-xpro/include/board.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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 boards_atxmega-a1u-xpro + * @{ + * + * @file + * @brief Board specific definitions for the ATxmegaA1U Xplained Pro board. + * + * @author Gerson Fernando Budke + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" +#include "macros/units.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Clock configuration + */ +#define CLOCK_CORECLOCK MHZ(32) + +/** + * @name Baudrate for STDIO terminal + * + * The standard configuration for STDIO in cpu/atxmega/periph/uart.c + * is to use double speed. + * + * For 32MHz F_CPU following Baudrate have good error rates + * 115200 + * + * Matches this with BAUD in Board/Makefile.include + * + * @{ + */ +#ifndef STDIO_UART_BAUDRATE +#define STDIO_UART_BAUDRATE (115200U) +#endif +/** @} */ + +/** + * @name LED pin definitions and handlers + * @{ + */ +#define LED_PORT PORTQ + +#define LED0_PIN GPIO_PIN(PORT_Q, 3) +#define LED0_MODE GPIO_OUT +#define LED0_MASK (PIN3_bm) +#define LED0_ON (LED_PORT.OUTCLR = LED0_MASK) +#define LED0_OFF (LED_PORT.OUTSET = LED0_MASK) +#define LED0_TOGGLE (LED_PORT.OUTTGL = LED0_MASK) + +#define LED_PORT_MASK (LED0_MASK) +/** @} */ + +/** + * @name Button pin configuration + * @{ + */ +#define BTN0_PIN GPIO_PIN(PORT_Q, 2) +#define BTN0_MODE (GPIO_IN | GPIO_OPC_PU | GPIO_SLEW_RATE) +#define BTN0_INT_FLANK (GPIO_ISC_FALLING | GPIO_LVL_LOW) +/** @} */ + +/** + * @name xtimer configuration values + * if XTIMER_HZ > 1MHz then (XTIMER_HZ != (1000000ul << XTIMER_SHIFT)) + * if XTIMER_HZ < 1MHz then ((XTIMER_HZ << XTIMER_SHIFT) != 1000000ul) + * + * 32MHz Core Clock + * XTIMER_HZ 4000000 (clkdiv 8 ) XTIMER_SHIFT 2 + * XTIMER_HZ 1000000 () XTIMER_SHIFT 0 + * XTIMER_HZ 500000 (clkdiv 64) XTIMER_SHIFT 1 + * XTIMER_HZ 250000 (clkdiv 128) XTIMER_SHIFT 2 + * XTIMER_HZ 31250 (clkdiv 1024) XTIMER_SHIFT 5 + * + * @{ + */ + +#define XTIMER_DEV TIMER_DEV(0) +#define XTIMER_CHAN (0) +#define XTIMER_WIDTH (16) +#define XTIMER_HZ KHZ(500) +#define XTIMER_BACKOFF (150) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/atxmega-a1u-xpro/include/gpio_params.h b/boards/atxmega-a1u-xpro/include/gpio_params.h new file mode 100644 index 0000000000..c206dc3abc --- /dev/null +++ b/boards/atxmega-a1u-xpro/include/gpio_params.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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 boards_atxmega-a1u-xpro + * @{ + * + * @file + * @brief Configuration of SAUL mapped GPIO pins + * + * @author Gerson Fernando Budke + */ + +#ifndef GPIO_PARAMS_H +#define GPIO_PARAMS_H + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief GPIO configuration + */ +static const saul_gpio_params_t saul_gpio_params[] = +{ + { + .name = "SW0", + .pin = BTN0_PIN, + .mode = BTN0_MODE, + .flags = SAUL_GPIO_INVERTED, + }, + { + .name = "LED0 (Yellow)", + .pin = LED0_PIN, + .mode = LED0_MODE, + .flags = SAUL_GPIO_INVERTED, + }, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_PARAMS_H */ +/** @} */ diff --git a/boards/atxmega-a1u-xpro/include/periph_conf.h b/boards/atxmega-a1u-xpro/include/periph_conf.h new file mode 100644 index 0000000000..5f04556799 --- /dev/null +++ b/boards/atxmega-a1u-xpro/include/periph_conf.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 Gerson Fernando Budke + * + * 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 boards_atxmega-a1u-xpro + * @{ + * + * @file + * @brief Peripheral MCU configuration for the ATxmegaA1U Xplained Pro board. + * + * @author Gerson Fernando Budke + */ +#include "mutex.h" + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "periph_cpu.h" + +/** + * @name Timer peripheral configuration + * @{ + */ +static const timer_conf_t timer_config[] = { + { + .dev = (void *)&TCC1, + .type = TC_TYPE_1, + .int_lvl = { CPU_INT_LVL_LOW, + CPU_INT_LVL_OFF, + CPU_INT_LVL_OFF, + CPU_INT_LVL_OFF }, + }, + { + .dev = (void *)&TCC0, + .type = TC_TYPE_0, + .int_lvl = { CPU_INT_LVL_LOW, + CPU_INT_LVL_LOW, + CPU_INT_LVL_LOW, + CPU_INT_LVL_LOW }, + } +}; + +#define TIMER_0_ISRA TCC1_CCA_vect + +#define TIMER_1_ISRA TCC0_CCA_vect +#define TIMER_1_ISRB TCC0_CCB_vect +#define TIMER_1_ISRC TCC0_CCC_vect +#define TIMER_1_ISRD TCC0_CCD_vect + +#define TIMER_NUMOF ARRAY_SIZE(timer_config) +/** @} */ + +/** + * @name UART configuration + * @{ + */ +static const uart_conf_t uart_config[] = { + { /* CDC-ACM */ + .dev = &USARTE0, + .rx_pin = GPIO_PIN(PORT_E, 2), + .tx_pin = GPIO_PIN(PORT_E, 3), +#ifdef MODULE_PERIPH_UART_HW_FC + .rts_pin = GPIO_UNDEF, + .cts_pin = GPIO_UNDEF, +#endif + .rx_int_lvl = CPU_INT_LVL_LOW, + .tx_int_lvl = CPU_INT_LVL_LOW, + .dre_int_lvl = CPU_INT_LVL_OFF, + }, +}; + +/* interrupt function name mapping */ +#define UART_0_RXC_ISR USARTE0_RXC_vect /* Reception Complete Interrupt */ +#define UART_0_DRE_ISR USARTE0_DRE_vect /* Data Register Empty Interrupt */ +#define UART_0_TXC_ISR USARTE0_TXC_vect /* Transmission Complete Interrupt */ + +#define UART_NUMOF ARRAY_SIZE(uart_config) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include "periph_conf_common.h" + +#endif /* PERIPH_CONF_H */ +/** @} */ From 9cbe8bceeb711d690931abc2239662507952cc7d Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Fri, 5 Feb 2021 19:16:51 -0300 Subject: [PATCH 14/18] drivers/ws281x/Kconfig: Select mega cpu by cpu_core The current MODULE_WS281X_ATMEGA only supports ATmega core. This update Kconfig to select MODULE_WS281X_ATMEGA module by CPU_CORE_AVR_MEGA instead HAS_ARCH_AVR8. Signed-off-by: Gerson Fernando Budke --- drivers/ws281x/Kconfig | 6 +++--- drivers/ws281x/Makefile.dep | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ws281x/Kconfig b/drivers/ws281x/Kconfig index c30dc7d467..fa59466733 100644 --- a/drivers/ws281x/Kconfig +++ b/drivers/ws281x/Kconfig @@ -7,16 +7,16 @@ config MODULE_WS281X bool "WS2812/SK6812 RGB LED (NeoPixel)" - depends on HAS_ARCH_AVR8 || HAS_ARCH_ESP32 || HAS_ARCH_NATIVE + depends on HAS_CPU_CORE_ATMEGA || HAS_ARCH_ESP32 || HAS_ARCH_NATIVE depends on TEST_KCONFIG select MODULE_XTIMER - select MODULE_WS281X_ATMEGA if HAS_ARCH_AVR8 + select MODULE_WS281X_ATMEGA if HAS_CPU_CORE_ATMEGA select MODULE_WS281X_VT100 if HAS_ARCH_NATIVE select MODULE_WS281X_ESP32 if HAS_ARCH_ESP32 config MODULE_WS281X_ATMEGA bool - depends on HAS_ARCH_AVR8 + depends on HAS_CPU_CORE_ATMEGA config MODULE_WS281X_VT100 bool diff --git a/drivers/ws281x/Makefile.dep b/drivers/ws281x/Makefile.dep index 021c9b42dd..641cde00b2 100644 --- a/drivers/ws281x/Makefile.dep +++ b/drivers/ws281x/Makefile.dep @@ -1,7 +1,7 @@ -FEATURES_REQUIRED_ANY += arch_avr8|arch_esp32|arch_native +FEATURES_REQUIRED_ANY += cpu_core_atmega|arch_esp32|arch_native ifeq (,$(filter ws281x_%,$(USEMODULE))) - ifneq (,$(filter arch_avr8,$(FEATURES_USED))) + ifneq (,$(filter cpu_core_atmega,$(FEATURES_USED))) USEMODULE += ws281x_atmega endif ifneq (,$(filter arch_native,$(FEATURES_USED))) @@ -13,7 +13,7 @@ ifeq (,$(filter ws281x_%,$(USEMODULE))) endif ifneq (,$(filter ws281x_atmega,$(USEMODULE))) - FEATURES_REQUIRED += arch_avr8 + FEATURES_REQUIRED += cpu_core_atmega endif USEMODULE += xtimer From 553e968a00712f92fba0fa11d9ccc7db5e6818f8 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 27 Feb 2021 19:53:49 -0300 Subject: [PATCH 15/18] tests/periph_timer/Makefile: Add xmega 500kHz board Atmel XMEGA CPU don't have a timer prescaler div16 and div32 option. This means that at full speed (32MHz) it is not possible have a 1MHz clock tick. Define default tick to 500kHz and add atxmega-a1u-xpro boards to test list. Signed-off-by: Gerson Fernando Budke --- tests/periph_timer/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/periph_timer/Makefile b/tests/periph_timer/Makefile index 452cbbb164..4d7e648b18 100644 --- a/tests/periph_timer/Makefile +++ b/tests/periph_timer/Makefile @@ -2,6 +2,10 @@ include ../Makefile.tests_common FEATURES_REQUIRED = periph_timer +BOARDS_TIMER_500kHz := \ + atxmega-a1u-xpro \ + # + BOARDS_TIMER_250kHz := \ arduino-duemilanove \ arduino-leonardo \ @@ -39,7 +43,9 @@ BOARDS_TIMER_CLOCK_CORECLOCK := \ waspmote-pro \ # -ifneq (,$(filter $(BOARDS_TIMER_250kHz),$(BOARD))) +ifneq (,$(filter $(BOARDS_TIMER_500kHz),$(BOARD))) + TIMER_SPEED ?= 500000 +else ifneq (,$(filter $(BOARDS_TIMER_250kHz),$(BOARD))) TIMER_SPEED ?= 250000 else ifneq (,$(filter $(BOARDS_TIMER_32kHz),$(BOARD))) TIMER_SPEED ?= 32768 From 64756202906499815690ac071bd0d8bf7de70605 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 28 Feb 2021 20:03:57 -0300 Subject: [PATCH 16/18] tests: Exclude atxmega-a1u-xpro board due low mem Add atxmega-a1u-xpro board to BOARD_INSUFFICIENT_MEMORY list to exclude test since boards don't have enough data memory. Signed-off-by: Gerson Fernando Budke --- tests/bench_xtimer/Makefile.ci | 1 + tests/driver_at/Makefile.ci | 1 + tests/driver_dose/Makefile.ci | 1 + tests/driver_netdev_common/Makefile.ci | 1 + tests/driver_xbee/Makefile.ci | 1 + tests/emcute/Makefile.ci | 1 + tests/gnrc_dhcpv6_client/Makefile.ci | 1 + tests/gnrc_dhcpv6_client_6lbr/Makefile.ci | 1 + tests/gnrc_ipv6_ext/Makefile.ci | 1 + tests/gnrc_ipv6_ext_frag/Makefile.ci | 1 + tests/gnrc_ipv6_ext_opt/Makefile.ci | 1 + tests/gnrc_ipv6_fwd_w_sub/Makefile.ci | 1 + tests/gnrc_ipv6_nib/Makefile.ci | 1 + tests/gnrc_ipv6_nib_6ln/Makefile.ci | 1 + tests/gnrc_ipv6_nib_dns/Makefile.ci | 1 + tests/gnrc_mac_timeout/Makefile.ci | 1 + tests/gnrc_ndp/Makefile.ci | 1 + tests/gnrc_netif/Makefile.ci | 1 + tests/gnrc_rpl_p2p/Makefile.ci | 1 + tests/gnrc_rpl_srh/Makefile.ci | 1 + tests/gnrc_sixlowpan/Makefile.ci | 1 + tests/gnrc_sixlowpan_frag_minfwd/Makefile.ci | 1 + tests/gnrc_sixlowpan_frag_sfr/Makefile.ci | 1 + tests/gnrc_sixlowpan_iphc_w_vrb/Makefile.ci | 1 + tests/gnrc_sock_dns/Makefile.ci | 1 + tests/gnrc_sock_udp/Makefile.ci | 1 + tests/gnrc_tcp/Makefile.ci | 1 + tests/gnrc_tx_sync/Makefile.ci | 1 + tests/gnrc_udp/Makefile.ci | 1 + tests/ieee802154_security/Makefile.ci | 1 + tests/nanocoap_cli/Makefile.ci | 1 + tests/netstats_neighbor/Makefile.ci | 1 + tests/pkg_emlearn/Makefile.ci | 1 + tests/pkg_littlefs2/Makefile.ci | 1 + tests/pkg_microcoap/Makefile.ci | 1 + tests/pkg_nanopb/Makefile.ci | 1 + tests/pkg_relic/Makefile.ci | 1 + tests/pkg_ucglib/Makefile.ci | 1 + tests/slip/Makefile.ci | 1 + tests/sntp/Makefile.ci | 1 + tests/sock_udp_aux/Makefile.ci | 1 + tests/sys_crypto/Makefile.ci | 1 + 42 files changed, 42 insertions(+) diff --git a/tests/bench_xtimer/Makefile.ci b/tests/bench_xtimer/Makefile.ci index 956f7aab66..9bb7254724 100644 --- a/tests/bench_xtimer/Makefile.ci +++ b/tests/bench_xtimer/Makefile.ci @@ -3,6 +3,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ im880b \ nucleo-l011k4 \ diff --git a/tests/driver_at/Makefile.ci b/tests/driver_at/Makefile.ci index d641f80c17..6c4cd7c480 100644 --- a/tests/driver_at/Makefile.ci +++ b/tests/driver_at/Makefile.ci @@ -4,6 +4,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ nucleo-f031k6 \ nucleo-l011k4 \ samd10-xmini \ diff --git a/tests/driver_dose/Makefile.ci b/tests/driver_dose/Makefile.ci index 2935b7da31..cd0210b975 100644 --- a/tests/driver_dose/Makefile.ci +++ b/tests/driver_dose/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/driver_netdev_common/Makefile.ci b/tests/driver_netdev_common/Makefile.ci index c881c6a742..7f3451c29b 100644 --- a/tests/driver_netdev_common/Makefile.ci +++ b/tests/driver_netdev_common/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/driver_xbee/Makefile.ci b/tests/driver_xbee/Makefile.ci index aeb0f934d1..309c8ed3d1 100644 --- a/tests/driver_xbee/Makefile.ci +++ b/tests/driver_xbee/Makefile.ci @@ -4,6 +4,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ nucleo-f030r8 \ nucleo-f031k6 \ nucleo-f042k6 \ diff --git a/tests/emcute/Makefile.ci b/tests/emcute/Makefile.ci index 15d84681d7..5ff5c98c42 100644 --- a/tests/emcute/Makefile.ci +++ b/tests/emcute/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ b-l072z-lrwan1 \ blackpill \ blackpill-128kib \ diff --git a/tests/gnrc_dhcpv6_client/Makefile.ci b/tests/gnrc_dhcpv6_client/Makefile.ci index 9def9a0d47..983e5260dc 100644 --- a/tests/gnrc_dhcpv6_client/Makefile.ci +++ b/tests/gnrc_dhcpv6_client/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_dhcpv6_client_6lbr/Makefile.ci b/tests/gnrc_dhcpv6_client_6lbr/Makefile.ci index 5cc0dd7d55..b0c4f3d79b 100644 --- a/tests/gnrc_dhcpv6_client_6lbr/Makefile.ci +++ b/tests/gnrc_dhcpv6_client_6lbr/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ b-l072z-lrwan1 \ blackpill \ blackpill-128kib \ diff --git a/tests/gnrc_ipv6_ext/Makefile.ci b/tests/gnrc_ipv6_ext/Makefile.ci index a4dc8aa7e3..46b06ddf79 100644 --- a/tests/gnrc_ipv6_ext/Makefile.ci +++ b/tests/gnrc_ipv6_ext/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_ipv6_ext_frag/Makefile.ci b/tests/gnrc_ipv6_ext_frag/Makefile.ci index 11a24eb1c3..436b8a70da 100644 --- a/tests/gnrc_ipv6_ext_frag/Makefile.ci +++ b/tests/gnrc_ipv6_ext_frag/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ blackpill \ bluepill \ bluepill-stm32f030c8 \ diff --git a/tests/gnrc_ipv6_ext_opt/Makefile.ci b/tests/gnrc_ipv6_ext_opt/Makefile.ci index 2367f942d9..1c0aff4dfe 100644 --- a/tests/gnrc_ipv6_ext_opt/Makefile.ci +++ b/tests/gnrc_ipv6_ext_opt/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/tests/gnrc_ipv6_fwd_w_sub/Makefile.ci b/tests/gnrc_ipv6_fwd_w_sub/Makefile.ci index 6fa1bf6872..9ab24d6b9b 100644 --- a/tests/gnrc_ipv6_fwd_w_sub/Makefile.ci +++ b/tests/gnrc_ipv6_fwd_w_sub/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/gnrc_ipv6_nib/Makefile.ci b/tests/gnrc_ipv6_nib/Makefile.ci index 10e1400b38..2f5c8d1336 100644 --- a/tests/gnrc_ipv6_nib/Makefile.ci +++ b/tests/gnrc_ipv6_nib/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ msb-430 \ msb-430h \ nucleo-f031k6 \ diff --git a/tests/gnrc_ipv6_nib_6ln/Makefile.ci b/tests/gnrc_ipv6_nib_6ln/Makefile.ci index 6fa1bf6872..9ab24d6b9b 100644 --- a/tests/gnrc_ipv6_nib_6ln/Makefile.ci +++ b/tests/gnrc_ipv6_nib_6ln/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/gnrc_ipv6_nib_dns/Makefile.ci b/tests/gnrc_ipv6_nib_dns/Makefile.ci index c6fa0feee9..9b897fd09d 100644 --- a/tests/gnrc_ipv6_nib_dns/Makefile.ci +++ b/tests/gnrc_ipv6_nib_dns/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/tests/gnrc_mac_timeout/Makefile.ci b/tests/gnrc_mac_timeout/Makefile.ci index c881c6a742..7f3451c29b 100644 --- a/tests/gnrc_mac_timeout/Makefile.ci +++ b/tests/gnrc_mac_timeout/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/gnrc_ndp/Makefile.ci b/tests/gnrc_ndp/Makefile.ci index b3a990cb42..2c7829ddbe 100644 --- a/tests/gnrc_ndp/Makefile.ci +++ b/tests/gnrc_ndp/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ i-nucleo-lrwan1 \ msb-430 \ msb-430h \ diff --git a/tests/gnrc_netif/Makefile.ci b/tests/gnrc_netif/Makefile.ci index 5e0e938fc2..0539cb9a19 100644 --- a/tests/gnrc_netif/Makefile.ci +++ b/tests/gnrc_netif/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ b-l072z-lrwan1 \ blackpill \ blackpill-128kib \ diff --git a/tests/gnrc_rpl_p2p/Makefile.ci b/tests/gnrc_rpl_p2p/Makefile.ci index ad86168921..3c4f5cc61f 100644 --- a/tests/gnrc_rpl_p2p/Makefile.ci +++ b/tests/gnrc_rpl_p2p/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/gnrc_rpl_srh/Makefile.ci b/tests/gnrc_rpl_srh/Makefile.ci index a4dc8aa7e3..46b06ddf79 100644 --- a/tests/gnrc_rpl_srh/Makefile.ci +++ b/tests/gnrc_rpl_srh/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_sixlowpan/Makefile.ci b/tests/gnrc_sixlowpan/Makefile.ci index 92760ff33b..0c6a6f6de1 100644 --- a/tests/gnrc_sixlowpan/Makefile.ci +++ b/tests/gnrc_sixlowpan/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ hifive1 \ hifive1b \ diff --git a/tests/gnrc_sixlowpan_frag_minfwd/Makefile.ci b/tests/gnrc_sixlowpan_frag_minfwd/Makefile.ci index 9def9a0d47..983e5260dc 100644 --- a/tests/gnrc_sixlowpan_frag_minfwd/Makefile.ci +++ b/tests/gnrc_sixlowpan_frag_minfwd/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_sixlowpan_frag_sfr/Makefile.ci b/tests/gnrc_sixlowpan_frag_sfr/Makefile.ci index 11a24eb1c3..436b8a70da 100644 --- a/tests/gnrc_sixlowpan_frag_sfr/Makefile.ci +++ b/tests/gnrc_sixlowpan_frag_sfr/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ blackpill \ bluepill \ bluepill-stm32f030c8 \ diff --git a/tests/gnrc_sixlowpan_iphc_w_vrb/Makefile.ci b/tests/gnrc_sixlowpan_iphc_w_vrb/Makefile.ci index 6fa1bf6872..9ab24d6b9b 100644 --- a/tests/gnrc_sixlowpan_iphc_w_vrb/Makefile.ci +++ b/tests/gnrc_sixlowpan_iphc_w_vrb/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/gnrc_sock_dns/Makefile.ci b/tests/gnrc_sock_dns/Makefile.ci index 2a0eb4480a..1952e5c642 100644 --- a/tests/gnrc_sock_dns/Makefile.ci +++ b/tests/gnrc_sock_dns/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_sock_udp/Makefile.ci b/tests/gnrc_sock_udp/Makefile.ci index 4f3b86ea28..c27314bd5c 100644 --- a/tests/gnrc_sock_udp/Makefile.ci +++ b/tests/gnrc_sock_udp/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ msb-430 \ msb-430h \ nucleo-f031k6 \ diff --git a/tests/gnrc_tcp/Makefile.ci b/tests/gnrc_tcp/Makefile.ci index 9def9a0d47..983e5260dc 100644 --- a/tests/gnrc_tcp/Makefile.ci +++ b/tests/gnrc_tcp/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/tests/gnrc_tx_sync/Makefile.ci b/tests/gnrc_tx_sync/Makefile.ci index 2da69afbe9..b33507233e 100644 --- a/tests/gnrc_tx_sync/Makefile.ci +++ b/tests/gnrc_tx_sync/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega328p \ atmega1281 \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/gnrc_udp/Makefile.ci b/tests/gnrc_udp/Makefile.ci index 2ca8b5eb50..5b339b2e9d 100644 --- a/tests/gnrc_udp/Makefile.ci +++ b/tests/gnrc_udp/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ blackpill \ bluepill \ bluepill-stm32f030c8 \ diff --git a/tests/ieee802154_security/Makefile.ci b/tests/ieee802154_security/Makefile.ci index 880744d5f3..c497891006 100644 --- a/tests/ieee802154_security/Makefile.ci +++ b/tests/ieee802154_security/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/nanocoap_cli/Makefile.ci b/tests/nanocoap_cli/Makefile.ci index 7e4833544b..b3b49b460f 100644 --- a/tests/nanocoap_cli/Makefile.ci +++ b/tests/nanocoap_cli/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ mega-xplained \ diff --git a/tests/netstats_neighbor/Makefile.ci b/tests/netstats_neighbor/Makefile.ci index c881c6a742..7f3451c29b 100644 --- a/tests/netstats_neighbor/Makefile.ci +++ b/tests/netstats_neighbor/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/pkg_emlearn/Makefile.ci b/tests/pkg_emlearn/Makefile.ci index 6e186e1e23..53faf0451c 100644 --- a/tests/pkg_emlearn/Makefile.ci +++ b/tests/pkg_emlearn/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ blackpill \ bluepill \ derfmega128 \ diff --git a/tests/pkg_littlefs2/Makefile.ci b/tests/pkg_littlefs2/Makefile.ci index 65d505229b..eb1a2f8ff5 100644 --- a/tests/pkg_littlefs2/Makefile.ci +++ b/tests/pkg_littlefs2/Makefile.ci @@ -4,6 +4,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/pkg_microcoap/Makefile.ci b/tests/pkg_microcoap/Makefile.ci index a9d30bd77d..c82e432a53 100644 --- a/tests/pkg_microcoap/Makefile.ci +++ b/tests/pkg_microcoap/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/tests/pkg_nanopb/Makefile.ci b/tests/pkg_nanopb/Makefile.ci index 518b330a9e..62a63b0a33 100644 --- a/tests/pkg_nanopb/Makefile.ci +++ b/tests/pkg_nanopb/Makefile.ci @@ -1,3 +1,4 @@ BOARD_INSUFFICIENT_MEMORY := \ + atxmega-a1u-xpro \ stm32f030f4-demo \ # diff --git a/tests/pkg_relic/Makefile.ci b/tests/pkg_relic/Makefile.ci index 9ce5ee7362..8f37a984bf 100644 --- a/tests/pkg_relic/Makefile.ci +++ b/tests/pkg_relic/Makefile.ci @@ -1,4 +1,5 @@ BOARD_INSUFFICIENT_MEMORY := \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ nucleo-f030r8 \ diff --git a/tests/pkg_ucglib/Makefile.ci b/tests/pkg_ucglib/Makefile.ci index 9eb89940f6..f8ff01402d 100644 --- a/tests/pkg_ucglib/Makefile.ci +++ b/tests/pkg_ucglib/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ nucleo-l011k4 \ samd10-xmini \ stk3200 \ diff --git a/tests/slip/Makefile.ci b/tests/slip/Makefile.ci index 2935b7da31..cd0210b975 100644 --- a/tests/slip/Makefile.ci +++ b/tests/slip/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ i-nucleo-lrwan1 \ msb-430 \ diff --git a/tests/sntp/Makefile.ci b/tests/sntp/Makefile.ci index e9c4be39f6..60552bdba3 100644 --- a/tests/sntp/Makefile.ci +++ b/tests/sntp/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/tests/sock_udp_aux/Makefile.ci b/tests/sock_udp_aux/Makefile.ci index 5490b419fa..7194285f07 100644 --- a/tests/sock_udp_aux/Makefile.ci +++ b/tests/sock_udp_aux/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ calliope-mini \ derfmega128 \ diff --git a/tests/sys_crypto/Makefile.ci b/tests/sys_crypto/Makefile.ci index 10e1400b38..2f5c8d1336 100644 --- a/tests/sys_crypto/Makefile.ci +++ b/tests/sys_crypto/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ msb-430 \ msb-430h \ nucleo-f031k6 \ From d23b139938aadd04906c2364535f3fbfb35f9f31 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 28 Feb 2021 20:06:52 -0300 Subject: [PATCH 17/18] examples: Exclude atxmega-a1u-xpro board due low mem Add atxmega-a1u-xpro board to BOARD_INSUFFICIENT_MEMORY list to exclude examples since board don't have enough data memory. Signed-off-by: Gerson Fernando Budke --- examples/asymcute_mqttsn/Makefile.ci | 1 + examples/cord_ep/Makefile.ci | 1 + examples/cord_epsim/Makefile.ci | 1 + examples/cord_lc/Makefile.ci | 1 + examples/emcute_mqttsn/Makefile.ci | 1 + examples/gcoap/Makefile.ci | 1 + examples/gnrc_border_router/Makefile.ci | 1 + examples/gnrc_networking/Makefile.ci | 1 + examples/nanocoap_server/Makefile.ci | 1 + examples/ndn-ping/Makefile.ci | 1 + examples/posix_select/Makefile.ci | 1 + examples/posix_sockets/Makefile.ci | 1 + 12 files changed, 12 insertions(+) diff --git a/examples/asymcute_mqttsn/Makefile.ci b/examples/asymcute_mqttsn/Makefile.ci index bb4df0c045..8d25161d60 100644 --- a/examples/asymcute_mqttsn/Makefile.ci +++ b/examples/asymcute_mqttsn/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/examples/cord_ep/Makefile.ci b/examples/cord_ep/Makefile.ci index 3f986b00ea..7494151873 100644 --- a/examples/cord_ep/Makefile.ci +++ b/examples/cord_ep/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/examples/cord_epsim/Makefile.ci b/examples/cord_epsim/Makefile.ci index 15678f4aa6..e214957014 100644 --- a/examples/cord_epsim/Makefile.ci +++ b/examples/cord_epsim/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ hifive1 \ hifive1b \ diff --git a/examples/cord_lc/Makefile.ci b/examples/cord_lc/Makefile.ci index 0e62926ff6..9d45eefc5b 100644 --- a/examples/cord_lc/Makefile.ci +++ b/examples/cord_lc/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ chronos \ derfmega128 \ diff --git a/examples/emcute_mqttsn/Makefile.ci b/examples/emcute_mqttsn/Makefile.ci index 4aabd5890a..de4cc77da5 100644 --- a/examples/emcute_mqttsn/Makefile.ci +++ b/examples/emcute_mqttsn/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ hifive1 \ diff --git a/examples/gcoap/Makefile.ci b/examples/gcoap/Makefile.ci index 2367f942d9..1c0aff4dfe 100644 --- a/examples/gcoap/Makefile.ci +++ b/examples/gcoap/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/examples/gnrc_border_router/Makefile.ci b/examples/gnrc_border_router/Makefile.ci index d7a6cb158a..ebac138623 100644 --- a/examples/gnrc_border_router/Makefile.ci +++ b/examples/gnrc_border_router/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ b-l072z-lrwan1 \ blackpill \ blackpill-128kib \ diff --git a/examples/gnrc_networking/Makefile.ci b/examples/gnrc_networking/Makefile.ci index 1cc1032506..efc037d283 100644 --- a/examples/gnrc_networking/Makefile.ci +++ b/examples/gnrc_networking/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ blackpill \ bluepill \ bluepill-stm32f030c8 \ diff --git a/examples/nanocoap_server/Makefile.ci b/examples/nanocoap_server/Makefile.ci index f32b7015d8..1a15209270 100644 --- a/examples/nanocoap_server/Makefile.ci +++ b/examples/nanocoap_server/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/examples/ndn-ping/Makefile.ci b/examples/ndn-ping/Makefile.ci index ad6863e046..bc6014acb0 100644 --- a/examples/ndn-ping/Makefile.ci +++ b/examples/ndn-ping/Makefile.ci @@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ diff --git a/examples/posix_select/Makefile.ci b/examples/posix_select/Makefile.ci index b076927dcd..378b08f3b0 100644 --- a/examples/posix_select/Makefile.ci +++ b/examples/posix_select/Makefile.ci @@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-nano \ arduino-uno \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ chronos \ i-nucleo-lrwan1 \ diff --git a/examples/posix_sockets/Makefile.ci b/examples/posix_sockets/Makefile.ci index fe5ff3602f..960e1e7860 100644 --- a/examples/posix_sockets/Makefile.ci +++ b/examples/posix_sockets/Makefile.ci @@ -7,6 +7,7 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega1284p \ atmega328p \ + atxmega-a1u-xpro \ bluepill-stm32f030c8 \ derfmega128 \ i-nucleo-lrwan1 \ From 0bd55def91d45c90b88f79d41f7cf09b0cc95a10 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sun, 7 Mar 2021 18:20:08 -0300 Subject: [PATCH 18/18] CODEOWNERS: Add nandojve for xmega things Fix missing entry for avr8_common that was created when moving code from atmega_common at #15712. As complement add myself as code owner for xmega related things. Signed-off-by: Gerson Fernando Budke --- CODEOWNERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index 1f57994c27..5ad69b5f02 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -9,6 +9,7 @@ /.murdock @kaspar030 +/boards/common/atxmega/ @nandojve /boards/common/esp*/ @gschorcht /boards/common/nrf*/ @aabadie @haukepetersen /boards/common/nucleo*/ @aabadie @@ -34,11 +35,14 @@ /boards/stk3*00/ @basilfx /boards/openmote*/ @MrKevinWeiss /boards/cc1352p-launchpad @luisan00 +/boards/atxmega*/ @nandojve /core/ @kaspar030 /cpu/arm7_common/ @kaspar030 @maribu +/cpu/avr8_common/ @kYc0o @roberthartung @maribu @nandojve /cpu/atmega*/ @kYc0o @roberthartung @maribu +/cpu/atxmega/ @nandojve /cpu/cc2538/ @hexluthor @smlng @fjmolinas /cpu/cc26x0/ @hexluthor @smlng /cpu/cc26x2_cc13x2/ @hexluthor @smlng