mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 14:03:55 +01:00
Merge pull request #5529 from kYc0o/atmega_common_unify
cpu/atmega*: unify common code for atmega CPUs
This commit is contained in:
commit
42d34e69c3
@ -28,6 +28,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Use the UART 0 for STDIO on this board
|
||||
*/
|
||||
#define UART_STDIO_DEV UART_DEV(0)
|
||||
|
||||
/**
|
||||
* @brief As the CPU is too slow to handle 115200 baud, we set the default
|
||||
* baudrate to 9600 for this board
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# define the module that is build
|
||||
MODULE = cpu
|
||||
# add a list of subdirectories, that should also be build
|
||||
DIRS = periph $(ATMEGA_COMMON)
|
||||
DIRS = $(ATMEGA_COMMON)
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -4,18 +4,9 @@ export CFLAGS += -DCOREIF_NG=1
|
||||
# tell the build system that the CPU depends on the atmega common files
|
||||
USEMODULE += atmega_common
|
||||
|
||||
# export the peripheral drivers to be linked into the final binary
|
||||
export USEMODULE += periph
|
||||
|
||||
# the atmel port uses uart_stdio
|
||||
export USEMODULE += uart_stdio
|
||||
|
||||
# define path to atmega common module, which is needed for this CPU
|
||||
export ATMEGA_COMMON = $(RIOTCPU)/atmega_common/
|
||||
|
||||
# define the linker script to use for this CPU
|
||||
#export LINKERSCRIPT = $(RIOTCPU)/$(CPU)/ldscripts/atmega2560.ld
|
||||
|
||||
# explicitly tell the linker to link the syscalls and startup code.
|
||||
# Without this the interrupt vectors will not be linked correctly!
|
||||
export UNDEF += $(BINDIR)cpu/startup.o
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#ifndef CPU_CONF_H
|
||||
#define CPU_CONF_H
|
||||
|
||||
#include "atmega2560_regs.h"
|
||||
#include "atmega_regs_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@ -21,15 +21,12 @@
|
||||
#ifndef PERIPH_CPU_H_
|
||||
#define PERIPH_CPU_H_
|
||||
|
||||
#include "periph_cpu_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Define a CPU specific GPIO pin generator macro
|
||||
*/
|
||||
#define GPIO_PIN(x, y) ((x << 4) | y)
|
||||
|
||||
/**
|
||||
* @brief Available ports on the ATmega2560 family
|
||||
*/
|
||||
@ -47,54 +44,6 @@ enum {
|
||||
PORT_L = 10 /**< port L */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SPI mode select macro
|
||||
*
|
||||
* The polarity is determined by bit 3 in the configuration register, the phase
|
||||
* by bit 2.
|
||||
*/
|
||||
#define SPI_MODE_SEL(pol, pha) ((pol << 3) | (pha << 2))
|
||||
|
||||
/**
|
||||
* @brief Override the SPI mode values
|
||||
*
|
||||
* As the mode is set in bit 3 and 2 of the configuration register, we put the
|
||||
* correct configuration there
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CONF_T
|
||||
typedef enum {
|
||||
SPI_CONF_FIRST_RISING = SPI_MODE_SEL(0, 0), /**< mode 0 */
|
||||
SPI_CONF_SECOND_RISING = SPI_MODE_SEL(0, 1), /**< mode 1 */
|
||||
SPI_CONF_FIRST_FALLING = SPI_MODE_SEL(1, 0), /**< mode 2 */
|
||||
SPI_CONF_SECOND_FALLING = SPI_MODE_SEL(1, 1) /**< mode 3 */
|
||||
} spi_conf_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SPI speed selection macro
|
||||
*
|
||||
* We encode the speed in bits 2, 1, and 0, where bit0 and bit1 hold the SPCR
|
||||
* prescaler bits, while bit2 holds the SPI2X bit.
|
||||
*/
|
||||
#define SPI_SPEED_SEL(s2x, pr1, pr0) ((s2x << 2) | (pr1 << 1) | pr0)
|
||||
|
||||
/**
|
||||
* @brief Override SPI speed values
|
||||
*
|
||||
* We assume a master clock speed of 16MHz here.
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_SPEED_T
|
||||
typedef enum {
|
||||
SPI_SPEED_100KHZ = SPI_SPEED_SEL(0, 1, 1), /**< 16/128 -> 125KHz */
|
||||
SPI_SPEED_400KHZ = SPI_SPEED_SEL(1, 1, 0), /**< 16/32 -> 500KHz */
|
||||
SPI_SPEED_1MHZ = SPI_SPEED_SEL(0, 0, 1), /**< 16/16 -> 1MHz */
|
||||
SPI_SPEED_5MHZ = SPI_SPEED_SEL(0, 0, 0), /**< 16/4 -> 4MHz */
|
||||
SPI_SPEED_10MHZ = SPI_SPEED_SEL(1, 0, 0) /**< 16/2 -> 8MHz */
|
||||
} spi_speed_t;
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
# define the module that is build
|
||||
MODULE = atmega_common
|
||||
|
||||
# add a list of subdirectories, that should also be build
|
||||
DIRS = periph
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
# Target architecture for the build. Use avr if you are unsure.
|
||||
export TARGET_ARCH ?= avr
|
||||
|
||||
# export the peripheral drivers to be linked into the final binary
|
||||
export USEMODULE += periph
|
||||
|
||||
# the atmel port uses uart_stdio
|
||||
export USEMODULE += uart_stdio
|
||||
|
||||
# include module specific includes
|
||||
export INCLUDES += -I$(RIOTCPU)/atmega_common/include -isystem$(RIOTCPU)/atmega_common/avr-libc-extra
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin
|
||||
* 2016 INRIA
|
||||
*
|
||||
* 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
|
||||
@ -7,17 +8,18 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_atmega2560
|
||||
* @ingroup cpu_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CMSIS style register definitions for the atmega2560
|
||||
* @brief CMSIS style register definitions for the atmega family
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef ATMEGA2560_REGS_H
|
||||
#define ATMEGA2560_REGS_H
|
||||
#ifndef ATMEGA_REGS_COMMON_H
|
||||
#define ATMEGA_REGS_COMMON_H
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
@ -63,14 +65,23 @@ typedef struct {
|
||||
* @{
|
||||
*/
|
||||
#define MEGA_TIMER1_BASE (uint16_t *)(&TCCR1A)
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
#define MEGA_TIMER3_BASE (uint16_t *)(&TCCR3A)
|
||||
#define MEGA_TIMER4_BASE (uint16_t *)(&TCCR4A)
|
||||
#define MEGA_TIMER5_BASE (uint16_t *)(&TCCR5A)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Base register address definitions
|
||||
* @{
|
||||
*/
|
||||
#define MEGA_UART0_BASE ((uint16_t *)(&UCSR0A))
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
#define MEGA_UART1_BASE ((uint16_t *)(&UCSR1A))
|
||||
#define MEGA_UART2_BASE ((uint16_t *)(&UCSR2A))
|
||||
#define MEGA_UART3_BASE ((uint16_t *)(&UCSR3A))
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -78,14 +89,23 @@ typedef struct {
|
||||
* @{
|
||||
*/
|
||||
#define MEGA_TIMER1 ((mega_timer_t *)MEGA_TIMER1_BASE)
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
#define MEGA_TIMER3 ((mega_timer_t *)MEGA_TIMER3_BASE)
|
||||
#define MEGA_TIMER4 ((mega_timer_t *)MEGA_TIMER4_BASE)
|
||||
#define MEGA_TIMER5 ((mega_timer_t *)MEGA_TIMER5_BASE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Peripheral instances
|
||||
* @{
|
||||
*/
|
||||
#define MEGA_UART0 ((mega_uart_t *)MEGA_UART0_BASE)
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
#define MEGA_UART1 ((mega_uart_t *)MEGA_UART1_BASE)
|
||||
#define MEGA_UART2 ((mega_uart_t *)MEGA_UART2_BASE)
|
||||
#define MEGA_UART3 ((mega_uart_t *)MEGA_UART3_BASE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
88
cpu/atmega_common/include/periph_cpu_common.h
Normal file
88
cpu/atmega_common/include/periph_cpu_common.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2015 HAW Hamburg
|
||||
* 2016 Freie Universität Berlin
|
||||
* 2016 INRIA
|
||||
*
|
||||
* 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_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CPU specific definitions for internal peripheral handling
|
||||
*
|
||||
* @author René Herthel <rene-herthel@outlook.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_COMMON_H_
|
||||
#define PERIPH_CPU_COMMON_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Define a CPU specific GPIO pin generator macro
|
||||
*/
|
||||
#define GPIO_PIN(x, y) ((x << 4) | y)
|
||||
|
||||
/**
|
||||
* @brief SPI mode select macro
|
||||
*
|
||||
* The polarity is determined by bit 3 in the configuration register, the phase
|
||||
* by bit 2.
|
||||
*/
|
||||
#define SPI_MODE_SEL(pol, pha) ((pol << 3) | (pha << 2))
|
||||
|
||||
/**
|
||||
* @brief Override the SPI mode values
|
||||
*
|
||||
* As the mode is set in bit 3 and 2 of the configuration register, we put the
|
||||
* correct configuration there
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CONF_T
|
||||
typedef enum {
|
||||
SPI_CONF_FIRST_RISING = SPI_MODE_SEL(0, 0), /**< mode 0 */
|
||||
SPI_CONF_SECOND_RISING = SPI_MODE_SEL(0, 1), /**< mode 1 */
|
||||
SPI_CONF_FIRST_FALLING = SPI_MODE_SEL(1, 0), /**< mode 2 */
|
||||
SPI_CONF_SECOND_FALLING = SPI_MODE_SEL(1, 1) /**< mode 3 */
|
||||
} spi_conf_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SPI speed selection macro
|
||||
*
|
||||
* We encode the speed in bits 2, 1, and 0, where bit0 and bit1 hold the SPCR
|
||||
* prescaler bits, while bit2 holds the SPI2X bit.
|
||||
*/
|
||||
#define SPI_SPEED_SEL(s2x, pr1, pr0) ((s2x << 2) | (pr1 << 1) | pr0)
|
||||
|
||||
/**
|
||||
* @brief Override SPI speed values
|
||||
*
|
||||
* We assume a master clock speed of 16MHz here.
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_SPEED_T
|
||||
typedef enum {
|
||||
SPI_SPEED_100KHZ = SPI_SPEED_SEL(0, 1, 1), /**< 16/128 -> 125KHz */
|
||||
SPI_SPEED_400KHZ = SPI_SPEED_SEL(1, 1, 0), /**< 16/32 -> 500KHz */
|
||||
SPI_SPEED_1MHZ = SPI_SPEED_SEL(0, 0, 1), /**< 16/16 -> 1MHz */
|
||||
SPI_SPEED_5MHZ = SPI_SPEED_SEL(0, 0, 0), /**< 16/4 -> 4MHz */
|
||||
SPI_SPEED_10MHZ = SPI_SPEED_SEL(1, 0, 0) /**< 16/2 -> 8MHz */
|
||||
} spi_speed_t;
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CPU_COMMON_H_ */
|
||||
/** @} */
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 HAW Hamburg
|
||||
* 2016 INRIA
|
||||
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
@ -12,9 +13,10 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level GPIO driver implementation for ATmega2560
|
||||
* @brief Low-level GPIO driver implementation for ATmega family
|
||||
*
|
||||
* @author René Herthel <rene-herthel@outlook.de>
|
||||
* @author Francisco Acosta <francisco.acosta@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@ -32,7 +34,16 @@
|
||||
#define GPIO_OFFSET_PORT_H (0xCB)
|
||||
#define GPIO_OFFSET_PIN_PORT (0x02)
|
||||
#define GPIO_OFFSET_PIN_PIN (0x03)
|
||||
|
||||
/*
|
||||
* @brief Define GPIO interruptions for an specific atmega CPU, by default
|
||||
* 2 (for small atmega CPUs)
|
||||
*/
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
#define GPIO_EXT_INT_NUMOF (8U)
|
||||
#else
|
||||
#define GPIO_EXT_INT_NUMOF (2U)
|
||||
#endif
|
||||
|
||||
static gpio_isr_ctx_t config[GPIO_EXT_INT_NUMOF];
|
||||
|
||||
@ -226,6 +237,7 @@ ISR(INT1_vect, ISR_BLOCK)
|
||||
irq_handler(1); /**< predefined interrupt pin */
|
||||
}
|
||||
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
ISR(INT2_vect, ISR_BLOCK)
|
||||
{
|
||||
irq_handler(2); /**< predefined interrupt pin */
|
||||
@ -255,3 +267,4 @@ ISR(INT7_vect, ISR_BLOCK)
|
||||
{
|
||||
irq_handler(7); /**< predefined interrupt pin */
|
||||
}
|
||||
#endif
|
||||
@ -24,6 +24,9 @@
|
||||
#include "mutex.h"
|
||||
#include "periph/spi.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* guard this file in case no SPI device is defined */
|
||||
#if SPI_NUMOF
|
||||
|
||||
@ -39,6 +42,7 @@ static mutex_t lock = MUTEX_INIT;
|
||||
|
||||
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
|
||||
{
|
||||
DEBUG("spi.c: conf = %d, speed = %d\n", conf, speed);
|
||||
/* make sure device is valid (there is only one...) */
|
||||
if (dev != 0) {
|
||||
return -1;
|
||||
@ -63,8 +67,10 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
|
||||
SPSR = (speed >> S2X_SHIFT);
|
||||
SPCR = ((1 << SPE) | (1 << MSTR) | conf | (speed & SPEED_MASK));
|
||||
|
||||
/* clear interrupt flag */
|
||||
/* clear interrupt flag by reading SPSR */
|
||||
(void)SPSR;
|
||||
|
||||
/* clear data register */
|
||||
(void)SPDR;
|
||||
|
||||
return 0;
|
||||
@ -28,6 +28,9 @@
|
||||
#include "periph/timer.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief All timers have three channels
|
||||
*/
|
||||
@ -60,7 +63,7 @@ typedef struct {
|
||||
* @brief Allocate memory for saving the device states
|
||||
* @{
|
||||
*/
|
||||
#if TIMER_NUMOF
|
||||
#ifdef TIMER_NUMOF
|
||||
static ctx_t ctx[] = {
|
||||
#ifdef TIMER_0
|
||||
{ TIMER_0, TIMER_0_MASK, TIMER_0_FLAG, NULL, NULL, 0, 0 },
|
||||
@ -86,6 +89,7 @@ static ctx_t *ctx[] = {{ NULL }};
|
||||
*/
|
||||
int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
|
||||
{
|
||||
DEBUG("timer.c: freq = %ld\n", freq);
|
||||
uint8_t pre = 0;
|
||||
|
||||
/* make sure given device is valid */
|
||||
@ -100,6 +104,7 @@ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
|
||||
}
|
||||
}
|
||||
if (pre == PRESCALE_NUMOF) {
|
||||
DEBUG("timer.c: prescaling failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -116,6 +121,7 @@ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg)
|
||||
|
||||
/* enable timer with calculated prescaler */
|
||||
ctx[tim].dev->CRB = (pre + 1);
|
||||
DEBUG("timer.c: prescaler set at %d\n", pre + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -175,12 +181,13 @@ void timer_irq_disable(tim_t tim)
|
||||
*ctx[tim].mask = 0;
|
||||
}
|
||||
|
||||
static inline void _isr(int num, int chan)
|
||||
#ifdef TIMER_NUMOF
|
||||
static inline void _isr(tim_t tim, int chan)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
*ctx[num].mask &= ~(1 << (chan + OCIE1A));
|
||||
ctx[num].cb(ctx[num].arg, chan);
|
||||
*ctx[tim].mask &= ~(1 << (chan + OCIE1A));
|
||||
ctx[tim].cb(ctx[tim].arg, chan);
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
@ -188,6 +195,7 @@ static inline void _isr(int num, int chan)
|
||||
|
||||
__exit_isr();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_0
|
||||
ISR(TIMER_0_ISRA, ISR_BLOCK)
|
||||
Loading…
x
Reference in New Issue
Block a user