From e8327a4a9a3a51a8ee9416fee0d0a872ff52330b Mon Sep 17 00:00:00 2001 From: Hugues Larrive Date: Thu, 22 Jun 2023 11:25:38 +0200 Subject: [PATCH] boards/atmega8: new board --- boards/atmega8/Kconfig | 25 +++++ boards/atmega8/Makefile | 5 + boards/atmega8/Makefile.dep | 1 + boards/atmega8/Makefile.features | 9 ++ boards/atmega8/Makefile.include | 16 +++ boards/atmega8/doc.txt | 99 +++++++++++++++++++ boards/atmega8/include/board.h | 63 ++++++++++++ boards/atmega8/include/periph_conf.h | 45 +++++++++ .../include/periph_conf_atmega_common.h | 25 ++++- 9 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 boards/atmega8/Kconfig create mode 100644 boards/atmega8/Makefile create mode 100644 boards/atmega8/Makefile.dep create mode 100644 boards/atmega8/Makefile.features create mode 100644 boards/atmega8/Makefile.include create mode 100644 boards/atmega8/doc.txt create mode 100644 boards/atmega8/include/board.h create mode 100644 boards/atmega8/include/periph_conf.h diff --git a/boards/atmega8/Kconfig b/boards/atmega8/Kconfig new file mode 100644 index 0000000000..420dc81857 --- /dev/null +++ b/boards/atmega8/Kconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2020 HAW Hamburg +# +# 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 "atmega8" if BOARD_ATMEGA8 + +config BOARD_ATMEGA8 + bool + default y + select CPU_MODEL_ATMEGA8 + # Put defined MCU peripherals here (in alphabetical order) + select HAS_PERIPH_ADC + select HAS_PERIPH_GPIO + select HAS_PERIPH_I2C + select HAS_PERIPH_PWM + select HAS_PERIPH_SPI + select HAS_PERIPH_TIMER + select HAS_PERIPH_UART + # Various other features (if any) + select MODULE_BOARDS_COMMON_ATMEGA if TEST_KCONFIG + +source "$(RIOTBOARD)/common/atmega/Kconfig" diff --git a/boards/atmega8/Makefile b/boards/atmega8/Makefile new file mode 100644 index 0000000000..3134740b39 --- /dev/null +++ b/boards/atmega8/Makefile @@ -0,0 +1,5 @@ +MODULE = board + +DIRS = $(RIOTBOARD)/common/atmega + +include $(RIOTBASE)/Makefile.base diff --git a/boards/atmega8/Makefile.dep b/boards/atmega8/Makefile.dep new file mode 100644 index 0000000000..3d1c295b9b --- /dev/null +++ b/boards/atmega8/Makefile.dep @@ -0,0 +1 @@ +USEMODULE += boards_common_atmega diff --git a/boards/atmega8/Makefile.features b/boards/atmega8/Makefile.features new file mode 100644 index 0000000000..da674867d9 --- /dev/null +++ b/boards/atmega8/Makefile.features @@ -0,0 +1,9 @@ +CPU = atmega8 + +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_pwm +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_timer +FEATURES_PROVIDED += periph_uart diff --git a/boards/atmega8/Makefile.include b/boards/atmega8/Makefile.include new file mode 100644 index 0000000000..df08c470af --- /dev/null +++ b/boards/atmega8/Makefile.include @@ -0,0 +1,16 @@ +# configure the terminal program +PORT_LINUX ?= /dev/ttyUSB0 +PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbmodem*))) +BAUD ?= 9600 +ATMEGA8_CLOCK ?= + +# Allow overwriting programmer via env variables without affecting other boards +PROGRAMMER_BOARD_ATMEGA8 ?= usbasp +# ICSP programmer to use for avrdude +AVRDUDE_PROGRAMMER ?= $(PROGRAMMER_BOARD_ATMEGA8) + +ifneq (,$(ATMEGA8_CLOCK)) + CFLAGS += -DCLOCK_CORECLOCK=$(ATMEGA8_CLOCK) +endif + +include $(RIOTBOARD)/common/atmega/Makefile.include diff --git a/boards/atmega8/doc.txt b/boards/atmega8/doc.txt new file mode 100644 index 0000000000..13acb87ad7 --- /dev/null +++ b/boards/atmega8/doc.txt @@ -0,0 +1,99 @@ +/** +@defgroup boards_atmega8 Standalone ATmega8 +@ingroup boards +@brief Support for using the ATmega8 as standalone board + +## Overview + +As the ATmega8 can run from the internal oscillator, placing it on a breadboard, +connecting an USB-UART adapter and power is enough to run RIOT on it. (An ISP +programmer will be needed to program it; or to program a bootloader to +subsequently allow programming via UART.) + +### MCU +| MCU | ATmega8 | +|:------------- |:--------------------------------------------- | +| Family | AVR/ATmega | +| Vendor | Microchip (previously Atmel) | +| RAM | 1KiB | +| Flash | 8KiB | +| EEPROM | 512B | +| Frequency | 1MHz/8MHz (up to 16MHz with external clock) | +| Timers | 3 (2x 8bit, 1x 16bit) | +| ADCs | 6 analog input pins | +| UARTs | 1 | +| SPIs | 1 | +| I2Cs | 1 (called TWI) | +| Vcc | 4.5V - 5.5V (ATmega8), 2.7V - 5.5V (ATmega8L) | +| Datasheet | [Official datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf) | + +### Pinout + +\htmlonly\endhtmlonly +@image html "https://camo.githubusercontent.com/c55beef2f138da61fe671a1e4a307ff4ffbc318d/68747470733a2f2f692e696d6775722e636f6d2f715849456368542e6a7067" "Pinout of the ATmega328p"
+ +All credit for above pinout image goes to https://github.com/MCUdude/MiniCore#pinout + +### Clock Frequency + +The ATmega8 has an internal oscillators clocked at 1MHz that allow it to be +operated without any external clock source or crystal. By default the fuses are +configured to use the internal oscillator and an operating mode resulting in a +clock speed of 1MHz. By setting the `CKSEL` fuses to 0100 the clock will operate +at 8MHz without an external clock source. This can be done like this: + + avrdude -c usbasp -p m8 -B 32 -U lfuse:w:0xe4:m + +(Replace `usbasp` with the ISP programmer you are using. The `-B 32` might +be needed on some ISP programmers to communicate with slow ATmega MCUs. It will +not be needed anymore after the clock device has been disabled.) + +This "board" is configured to use 8MHz as core clock, so that the ATmega8 +runs at the highest frequency possible without external clock sources. + +By setting the environment variable `ATMEGA8_CLOCK` to a custom frequency in +Hz (e.g. `1000000` for 1MHz), this core clock can be changed easily. Refer to +the datasheet on how to configure the ATmega8 to use an external crystal, an +external clock source or the clock divider. + +### Relation Between Supply Voltage, Clock Frequency and Power Consumption + +A higher supply voltage results in a higher current drawn. Thus, lower power +consumption can be achieved by using a lower supply voltage. However, higher +clock frequencies require higher supply voltages for reliable operation. + +The lowest possible supply voltage at 8 MHz is 2.7V (Atmega8L) or +4.5V (Atmega8). + +## Flashing the Device + +In order to flash the ATmega8 without a bootloader, an ISP programmer is +needed. Connect the programmer as follows: + +| ISP pin | ATmega8 pin | +|:-------- |:-------------- | +| MISO | 18/PB4/MISO | +| VCC | 7/VCC | +| SCK | 19/PB5/SCK | +| MOSI | 17/PB3/MOSI | +| RESET | 1/RESET | +| Ground | 22/GND | + +The tool `avrdude` needs to be installed. When using the `usbasp` running + + make BOARD=atmega8 flash + +will take care of everything. To use the programmer `` instead, run + + make BOARD=atmega8 PROGRAMMER= flash + +## Serial Terminal + +Connect a TTL adapter with pins 2/RXD and 3/TXD an run + + make BOARD=atmega8 term + +Please note that the supply voltage should be compatible with the logic level of +the TTL adapter. Usually everything between 3.3 V and 5 V should work. + + */ diff --git a/boards/atmega8/include/board.h b/boards/atmega8/include/board.h new file mode 100644 index 0000000000..965e444881 --- /dev/null +++ b/boards/atmega8/include/board.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen + * 2016 Laurent Navet + * 2019 Otto-von-Guericke-Universität Magdeburg + * 2023 Hugues Larrive + * + * 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_atmega8 + * @{ + * + * @file + * @brief Board specific definitions for the standalone ATmega8 "board" + * + * @author Marian Buschsieweke + * @author Hinnerk van Bruinehsen + * @author Laurent Navet + * @author Hugues Larrive + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" +#include "periph_conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name STDIO configuration + * + * As the CPU is too slow to handle 115200 baud, we set the default + * baudrate to 9600 for this board + * @{ + */ +#define STDIO_UART_BAUDRATE (9600U) +/** @} */ + +/** + * @name xtimer configuration values + * @{ + */ +#define XTIMER_WIDTH (16) +#if CLOCK_CORECLOCK > 4000000UL +#define XTIMER_HZ (CLOCK_CORECLOCK / 64) +#else +#define XTIMER_HZ (CLOCK_CORECLOCK / 8) +#endif +#define XTIMER_BACKOFF (40) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/atmega8/include/periph_conf.h b/boards/atmega8/include/periph_conf.h new file mode 100644 index 0000000000..ba64fb3669 --- /dev/null +++ b/boards/atmega8/include/periph_conf.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2019 Otto-von-Guericke-Universität Magdeburg + * 2023 Hugues Larrive + * + * 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_atmega8 + * @{ + * + * @file + * @brief Peripheral MCU configuration for the ATmega8 standalone "board" + * + * @author Marian Buschsieweke + * @author Hugues Larrive + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Clock configuration + * @{ + */ +#ifndef CLOCK_CORECLOCK +/* Using 8MHz internal oscillator as default clock source */ +#define CLOCK_CORECLOCK (8000000UL) +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#include "periph_conf_atmega_common.h" + +#endif /* PERIPH_CONF_H */ +/** @} */ diff --git a/boards/common/atmega/include/periph_conf_atmega_common.h b/boards/common/atmega/include/periph_conf_atmega_common.h index c2779b1410..8ba78f5c63 100644 --- a/boards/common/atmega/include/periph_conf_atmega_common.h +++ b/boards/common/atmega/include/periph_conf_atmega_common.h @@ -6,6 +6,7 @@ * 2017 HAW Hamburg, Dimitri Nahm * 2018 Matthew Blue * 2019 Otto-von-Guericke-Universität Magdeburg + * 2023 Hugues Larrive * * 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 @@ -28,6 +29,7 @@ * @author Matthew Blue * @author Francisco Acosta * @author Marian Buschsieweke + * @author Hugues Larrive */ #ifndef PERIPH_CONF_ATMEGA_COMMON_H @@ -71,6 +73,12 @@ extern "C" { #define UART_1 MEGA_UART1 #define UART_1_ISR USART1_RX_vect #define UART_1_ISR_TX USART1_TX_vect +#elif defined(CPU_ATMEGA8) + #define UART_NUMOF (1U) + + #define UART_0 MEGA_UART + #define UART_0_ISR USART_RXC_vect + #define UART_0_ISR_TX USART_TXC_vect #elif defined(CPU_ATMEGA328P) #define UART_NUMOF (1U) @@ -156,7 +164,8 @@ extern "C" { */ #ifndef ADC_NUMOF #if defined(CPU_ATMEGA128RFA1) || defined(CPU_ATMEGA256RFR2) || defined(CPU_ATMEGA328P) || \ - defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4) + defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4) || \ + defined(CPU_ATMEGA8) #define ADC_NUMOF (8U) #elif defined (CPU_ATMEGA2560) #define ADC_NUMOF (16U) @@ -180,7 +189,9 @@ extern "C" { * @{ */ #ifndef PWM_NUMOF -#if defined(CPU_ATMEGA328P) +#if defined(CPU_ATMEGA8) + #define PWM_PINS_CH0 { GPIO_PIN(PORT_B, 3), GPIO_UNDEF } +#elif defined(CPU_ATMEGA328P) #define PWM_PINS_CH0 { GPIO_PIN(PORT_D, 6), GPIO_PIN(PORT_D, 5) } #define PWM_PINS_CH1 { GPIO_PIN(PORT_B, 3), GPIO_PIN(PORT_D, 3) } #elif defined(CPU_ATMEGA1281) @@ -200,8 +211,9 @@ extern "C" { #if defined(CPU_ATMEGA32U4) || defined(CPU_ATMEGA328P) || \ defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P) || \ - defined(CPU_ATMEGA2560) + defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA8) static const pwm_conf_t pwm_conf[] = { +#ifndef CPU_ATMEGA8 { .dev = MINI_TIMER0, .pin_ch = PWM_PINS_CH0, @@ -213,6 +225,13 @@ extern "C" { .pin_ch = PWM_PINS_CH1, .div = MINI_TIMER2_DIV, } +#endif +#else /* CPU_ATMEGA8 */ + { + .dev = MINI_TIMER2, + .pin_ch = PWM_PINS_CH0, + .div = MINI_TIMER2_DIV, + }, #endif };