Skip to content

Commit

Permalink
Merge pull request #5529 from kYc0o/atmega_common_unify
Browse files Browse the repository at this point in the history
cpu/atmega*: unify common code for atmega CPUs
  • Loading branch information
aabadie committed Jun 22, 2016
2 parents 9a0f3a9 + abba25e commit 42d34e6
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 76 deletions.
5 changes: 5 additions & 0 deletions boards/arduino-mega2560/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cpu/atmega2560/Makefile
Original file line number Diff line number Diff line change
@@ -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
9 changes: 0 additions & 9 deletions cpu/atmega2560/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cpu/atmega2560/include/cpu_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand Down
55 changes: 2 additions & 53 deletions cpu/atmega2560/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions cpu/atmega_common/Makefile
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions cpu/atmega_common/Makefile.include
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
/*
* 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
* directory for more details.
*/

/**
* @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>

Expand Down Expand Up @@ -63,29 +65,47 @@ 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
/** @} */

/**
* @brief Peripheral instances
* @{
*/
#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
Expand Down
88 changes: 88 additions & 0 deletions cpu/atmega_common/include/periph_cpu_common.h
Original file line number Diff line number Diff line change
@@ -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_ */
/** @} */
File renamed without changes.
15 changes: 14 additions & 1 deletion cpu/atmega2560/periph/gpio.c → cpu/atmega_common/periph/gpio.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 HAW Hamburg
* 2016 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser
Expand All @@ -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>
*
* @}
*/
Expand All @@ -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];

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -255,3 +267,4 @@ ISR(INT7_vect, ISR_BLOCK)
{
irq_handler(7); /**< predefined interrupt pin */
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 42d34e6

Please sign in to comment.