board: add support for arduino-leonardo

This commit is contained in:
Thomas Perrot 2017-07-03 19:23:28 +02:00 committed by Marian Buschsieweke
parent 44803ea4fd
commit b63121c588
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F
18 changed files with 306 additions and 92 deletions

View File

@ -0,0 +1,5 @@
MODULE = board
DIRS = $(RIOTBOARD)/common/arduino-atmega
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,3 @@
include $(RIOTBOARD)/common/arduino-atmega/Makefile.features
include $(RIOTCPU)/atmega32u4/Makefile.features

View File

@ -0,0 +1,17 @@
# define the cpu used by the arduino uno board
export CPU = atmega32u4
# export needed for flash rule
PORT_LINUX ?= /dev/ttyUSB0
AVRDUDE_PORT ?= /dev/ttyACM0
PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbmodem*)))
BAUD ?= 9600
# PROGRAMMER defaults to avr109 which is the internal flasher via USB. Can be
# overridden for debugging (which requires changes that require to use an ISP)
PROGRAMMER ?= avr109
BOOTLOADER_SIZE ?= 4K
ROM_RESERVED ?= $(BOOTLOADER_SIZE)
include $(RIOTBOARD)/common/arduino-atmega/Makefile.include

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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_arduino-leonardo
* @{
*
* @file
* @brief Board specific initialization for Arduino Leonardo
*
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*
* @}
*/
#include "board.h"
#include "cpu.h"
#include "irq.h"
#include "periph/gpio.h"
#ifndef CPU_ATMEGA_CLK_SCALE_INIT
#define CPU_ATMEGA_CLK_SCALE_INIT CPU_ATMEGA_CLK_SCALE_DIV1
#endif
void led_init(void);
void board_init(void)
{
/* disable usb interrupt */
PRR1 |= 1<<PRUSB;
atmega_set_prescaler(CPU_ATMEGA_CLK_SCALE_INIT);
atmega_stdio_init();
cpu_init();
led_init();
irq_enable();
}

View File

@ -0,0 +1,62 @@
/**
@defgroup boards_arduino-leonardo Arduino Leonardo
@ingroup boards
@brief Support for the Arduino Leonardo board
## Overview
The Arduino Leonardo is a microcontroller board based on the ATmega32u4.
Similar to an Arduino UNO, can be recognized by computer as a mouse or keyboard.
Otherwise it's the same. Brief descriptions of both boards are available at
the official [Arduino web site.](https://www.arduino.cc/en/Main/Boards)
It has 20 digital input/output pins (of which 7 can be used as PWM outputs and
12 as analog inputs), a 16 MHz crystal oscillator, a micro USB connection, a
power jack, an ICSP header, and a reset button. It contains everything needed
to support the microcontroller; simply connect it to a computer with a USB
cable or power it with a AC-to-DC adapter or battery to get started.
For details, please look at the [Leonardo page.](@ref boards_arduino-leonardo)
## Using the shell
The shell is using the TTL (5V) serial because the USB (CDC) communication is
not currently supported.
The TTL serial cable must be connected as described below:
- FTDI RX goes to PIN1 (TX)
- FTDI TX goes to PIN0 (RX)
- FTDI GND goes to GND
Keep in mind that the Arduino Leonardo is not automatically restarted upon
`make BOARD=arduino-leonardo`, so you'll need to hit the reset button. Please
be patient, as the bootloader waits a few seconds before starting your code.
## Flashing the device
Flashing RIOT on the Arduino Leonardo is bit different compared to the other
Arduinos, as the device cannot be restarted automatically to enter the
bootloader. Therefore, you'll need to press the reset button in time to allow
avrdude (the tool used to flash the firmware) to connect to the bootloader.
### On a Fast Host
1. Type `make BOARD=arduino-leonardo flash` but do not hit enter yet
2. Press the reset button on the Arduino Leonardo
3. Hit enter
In case the compilation takes longer than the bootloader waits before starting
the user program, flashing will fail. See below to work arround
### On a Slow Host
1. Run `make BOARD=arduino-leonardo`
2. Type `make BOARD=arduino-leonardo flash-only` without hitting enter yet
3. Press the reset button on the Arduino Leonardo
4. Hit enter
## Mac Users
Mac Users have export the environment variable both `PORT` and `AVRDUDE_PORT`
to point to the device file of the TTL adapter (`PORT`) and the device file of
the Arduino Leonardo (`AVRDUDE_PORT`).
*/

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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.
*/
/**
* @defgroup boards_arduino-leonardo Arduino Leonardo
* @ingroup boards
* @brief Support for the Arduino Leonardo board
* @{
*
* @file
* @brief Board specific definitions for the Arduino Leonardo board
*
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*/
#ifndef BOARD_H
#define BOARD_H
#include "board_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H */
/** @} */

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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_arduino-leonardo
* @{
*
* @file
* @brief Board specific led initialization for Arduino Leonardo
*
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*
* @}
*/
#include "board.h"
#include "cpu.h"
#include "periph/gpio.h"
void led_init(void)
{
/* initialize the on-board LEDs */
gpio_init(LED0_PIN, GPIO_OUT);
LED0_OFF;
gpio_init(LED1_PIN, GPIO_OUT);
LED2_OFF;
gpio_init(LED2_PIN, GPIO_OUT);
LED2_OFF;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
* 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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
@ -15,6 +16,7 @@
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Laurent Navet <laurent.navet@gmail.com>
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*/
#ifndef ARDUINO_BOARD_H
@ -55,18 +57,24 @@ static const gpio_t arduino_pinmap[] = {
ARDUINO_PIN_17,
ARDUINO_PIN_18,
ARDUINO_PIN_19,
#ifdef CPU_ATMEGA2560
#if defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA32U4)
ARDUINO_PIN_20,
ARDUINO_PIN_21,
ARDUINO_PIN_22,
ARDUINO_PIN_23,
#endif
#ifdef CPU_ATMEGA2560
ARDUINO_PIN_24,
ARDUINO_PIN_25,
ARDUINO_PIN_26,
ARDUINO_PIN_27,
ARDUINO_PIN_28,
ARDUINO_PIN_29,
#endif
#if defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA32U4)
ARDUINO_PIN_30,
#endif
#ifdef CPU_ATMEGA2560
ARDUINO_PIN_31,
ARDUINO_PIN_32,
ARDUINO_PIN_33,

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* 2016 Laurent Navet <laurent.navet@gmail.com>
* 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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
@ -20,6 +21,7 @@
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Daniel Nordahl <nordahl.d@gmail.com>
* @author Laurent Navet <laurent.navet@gmail.com>
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*/
#ifndef ARDUINO_PINMAP_H
@ -71,6 +73,51 @@ extern "C" {
#define ARDUINO_PIN_A5 ARDUINO_PIN_19
#endif
#ifdef CPU_ATMEGA32U4
/* Digital pins */
#define ARDUINO_PIN_0 GPIO_PIN(PORT_D, 2)
#define ARDUINO_PIN_1 GPIO_PIN(PORT_D, 3)
#define ARDUINO_PIN_2 GPIO_PIN(PORT_D, 1)
#define ARDUINO_PIN_3 GPIO_PIN(PORT_D, 0)
#define ARDUINO_PIN_5 GPIO_PIN(PORT_C, 6)
#define ARDUINO_PIN_7 GPIO_PIN(PORT_E, 6)
#define ARDUINO_PIN_11 GPIO_PIN(PORT_B, 7)
#define ARDUINO_PIN_13 GPIO_PIN(PORT_C, 7)
#define ARDUINO_PIN_14 GPIO_PIN(PORT_B, 3)
#define ARDUINO_PIN_15 GPIO_PIN(PORT_B, 1)
#define ARDUINO_PIN_16 GPIO_PIN(PORT_B, 2)
#define ARDUINO_PIN_17 GPIO_PIN(PORT_B, 0)
#define ARDUINO_PIN_30 GPIO_PIN(PORT_D, 5)
/* Analog pins */
#define ARDUINO_PIN_4 GPIO_PIN(PORT_D, 4)
#define ARDUINO_PIN_6 GPIO_PIN(PORT_D, 7)
#define ARDUINO_PIN_8 GPIO_PIN(PORT_B, 4)
#define ARDUINO_PIN_9 GPIO_PIN(PORT_B, 5)
#define ARDUINO_PIN_10 GPIO_PIN(PORT_B, 6)
#define ARDUINO_PIN_12 GPIO_PIN(PORT_D, 6)
#define ARDUINO_PIN_18 GPIO_PIN(PORT_F, 7)
#define ARDUINO_PIN_19 GPIO_PIN(PORT_F, 6)
#define ARDUINO_PIN_20 GPIO_PIN(PORT_F, 5)
#define ARDUINO_PIN_21 GPIO_PIN(PORT_F, 4)
#define ARDUINO_PIN_22 GPIO_PIN(PORT_F, 3)
#define ARDUINO_PIN_23 GPIO_PIN(PORT_F, 2)
/* Analog input */
#define ARDUINO_PIN_A0 ARDUINO_PIN_18
#define ARDUINO_PIN_A1 ARDUINO_PIN_19
#define ARDUINO_PIN_A2 ARDUINO_PIN_20
#define ARDUINO_PIN_A3 ARDUINO_PIN_21
#define ARDUINO_PIN_A4 ARDUINO_PIN_22
#define ARDUINO_PIN_A5 ARDUINO_PIN_23
#define ARDUINO_PIN_A6 ARDUINO_PIN_4
#define ARDUINO_PIN_A7 ARDUINO_PIN_6
#define ARDUINO_PIN_A8 ARDUINO_PIN_8
#define ARDUINO_PIN_A9 ARDUINO_PIN_9
#define ARDUINO_PIN_A10 ARDUINO_PIN_10
#define ARDUINO_PIN_A11 ARDUINO_PIN_12
#endif
#ifdef CPU_ATMEGA2560
#define ARDUINO_PIN_0 GPIO_PIN(PORT_E, 0)
#define ARDUINO_PIN_1 GPIO_PIN(PORT_E, 1)

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
* 2016 Laurent Navet <laurent.navet@gmail.com>
* 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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
@ -18,6 +19,7 @@
*
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
* @author Laurent Navet <laurent.navet@gmail.com>
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*/
#ifndef BOARD_COMMON_H
@ -49,14 +51,35 @@ extern "C" {
#define LED0_MASK (1 << DDB5)
#endif
#ifdef CPU_ATMEGA32U4
#define LED0_PIN GPIO_PIN(2, 7) /**< BUILTIN LED */
#define LED0_MASK (1 << DDC7)
#define LED1_PIN GPIO_PIN(1, 0) /**< RX LED */
#define LED1_MASK (1 << DDB0)
#define LED2_PIN GPIO_PIN(3, 5) /**< TX LED */
#define LED2_MASK (1 << DDD5)
#endif
#ifdef CPU_ATMEGA2560
#define LED0_PIN GPIO_PIN(1, 7)
#define LED0_MASK (1 << DDB7)
#endif
#define LED0_ON (PORTB |= LED0_MASK)
#define LED0_OFF (PORTB &= ~LED0_MASK)
#define LED0_TOGGLE (PORTB ^= LED0_MASK)
#ifdef CPU_ATMEGA32U4
#define LED0_ON (PORTC |= LED0_MASK) /**< BUILTIN LED */
#define LED0_OFF (PORTC &= ~LED0_MASK)
#define LED0_TOGGLE (PORTC ^= LED0_MASK)
#define LED1_OFF (PORTB |= LED1_MASK) /**< RX LED */
#define LED1_ON (PORTB &= ~LED1_MASK)
#define LED1_TOGGLE (PORTB ^= LED1_MASK)
#define LED2_OFF (PORTD |= LED2_MASK) /**< TX LED */
#define LED2_ON (PORTD &= ~LED2_MASK)
#define LED2_TOGGLE (PORTD ^= LED2_MASK)
#else
#define LED0_ON (PORTD |= LED0_MASK)
#define LED0_OFF (PORTD &= ~LED0_MASK)
#define LED0_TOGGLE (PORTD ^= LED0_MASK)
#endif
/** @} */
/**

View File

@ -31,6 +31,10 @@ void led_init(void);
void board_init(void)
{
#ifdef CPU_ATMEGA32U4
/* disable usb interrupt on Atmega32U4 */
PRR1 |= 1<<PRUSB;
#endif
atmega_set_prescaler(CPU_ATMEGA_CLK_SCALE_INIT);

View File

@ -104,7 +104,24 @@ extern "C" {
* @{
*/
#ifndef TIMER_NUMOF
#if defined(CPU_ATMEGA256RFR2)
#if defined(CPU_ATMEGA32U4)
#define TIMER_NUMOF (2U)
#define TIMER_CHANNELS (3)
#define TIMER_0 MEGA_TIMER1
#define TIMER_0_MASK &TIMSK1
#define TIMER_0_FLAG &TIFR1
#define TIMER_0_ISRA TIMER1_COMPA_vect
#define TIMER_0_ISRB TIMER1_COMPB_vect
#define TIMER_0_ISRC TIMER1_COMPC_vect
#define TIMER_1 MEGA_TIMER3
#define TIMER_1_MASK &TIMSK3
#define TIMER_1_FLAG &TIFR3
#define TIMER_1_ISRA TIMER3_COMPA_vect
#define TIMER_1_ISRB TIMER3_COMPB_vect
#define TIMER_1_ISRC TIMER3_COMPC_vect
#elif defined(CPU_ATMEGA256RFR2)
#define TIMER_NUMOF (3U)
#define TIMER_CHANNELS (3)
@ -137,7 +154,7 @@ extern "C" {
#define TIMER_0_FLAG &TIFR1
#define TIMER_0_ISRA TIMER1_COMPA_vect
#define TIMER_0_ISRB TIMER1_COMPB_vect
#elif defined(CPU_ATMEGA1284P) || defined(CPU_ATMEGA32U4)
#elif defined(CPU_ATMEGA1284P)
#define TIMER_NUMOF (2U)
#define TIMER_CHANNELS (2)
@ -146,18 +163,12 @@ extern "C" {
#define TIMER_0_FLAG &TIFR1
#define TIMER_0_ISRA TIMER1_COMPA_vect
#define TIMER_0_ISRB TIMER1_COMPB_vect
#ifdef CPU_ATMEGA32U4
#define TIMER_0_ISRC TIMER1_COMPC_vect
#endif
#define TIMER_1 MEGA_TIMER3
#define TIMER_1_MASK &TIMSK3
#define TIMER_1_FLAG &TIFR3
#define TIMER_1_ISRA TIMER3_COMPA_vect
#define TIMER_1_ISRB TIMER3_COMPB_vect
#ifdef CPU_ATMEGA32U4
#define TIMER_1_ISRC TIMER3_COMPC_vect
#endif
#elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA1281)
#define TIMER_NUMOF (2U)
#define TIMER_CHANNELS (3)

View File

@ -10,9 +10,5 @@ export ATMEGA_COMMON = $(RIOTCPU)/atmega_common/
RAM_LEN = 2560
ROM_LEN = 32K
# 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
# CPU depends on the atmega common module, so include it
include $(ATMEGA_COMMON)Makefile.include

View File

@ -1,73 +0,0 @@
/*
* Copyright (C) 2017 Thomas Perrot <thomas.perrot@tupi.fr>
*
* 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_atmega32u4
* @{
*
* @file
* @brief Startup code and interrupt vector definition
*
* @author Thomas Perrot <thomas.perrot@tupi.fr>
*
* @}
*/
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
/* For Catchall-Loop */
#include "board.h"
/**
* @brief functions for initializing the board, std-lib and kernel
*/
extern void board_init(void);
extern void kernel_init(void);
extern void __libc_init_array(void);
/**
* @brief This pair of functions hook circumvent the call to main
*
* avr-libc normally uses the .init9 section for a call to main. This call
* seems to be not replaceable without hacking inside the library. We
* circumvent the call to main by using section .init7 to call the function
* reset_handler which therefore is the real entry point and section .init8
* which should never be reached but just in case jumps to exit.
* This way there should be no way to call main directly.
*/
void init7_ovr(void) __attribute__((section(".init7")));
void init8_ovr(void) __attribute__((section(".init8")));
__attribute__((used,naked)) void init7_ovr(void)
{
__asm__("call reset_handler");
}
__attribute__((used,naked)) void init8_ovr(void)
{
__asm__("jmp exit");
}
/**
* @brief This function is the entry point after a system reset
*
* After a system reset, the following steps are necessary and carried out:
* 1. initialize the board (sync clock, setup std-IO)
* 2. initialize and start RIOTs kernel
*/
__attribute__((used)) void reset_handler(void)
{
/* initialize the board and startup the kernel */
board_init();
/* startup the kernel */
kernel_init();
}

View File

@ -0,0 +1 @@
SUBSYSTEM=="usb", ATTR{idVendor}=="2341", ATTR{idProduct}=="0036", MODE="0666", OWNER="vagrant"

View File

@ -31,7 +31,6 @@ QUIET ?= 1
# Modules to include:
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
# include and auto-initialize all available sensors
USEMODULE += saul_default

View File

@ -9,7 +9,7 @@ DEBUGGER = $(DIST_PATH)/debug.sh $(DEBUGSERVER_FLAGS) $(DIST_PATH) $(DEBUGSERVER
PROGRAMMER_FLAGS = -p $(subst atmega,m,$(CPU))
# Set flasher port only for programmers that require it
ifneq (,$(filter $(PROGRAMMER),arduino buspirate stk500v1 stk500v2 wiring))
ifneq (,$(filter $(PROGRAMMER),arduino avr109 buspirate stk500v1 stk500v2 wiring))
# make the flasher port configurable (e.g. with atmelice the port is usb)
# defaults to terminal's serial port if not configured
AVRDUDE_PORT ?= $(PORT)

View File

@ -25,7 +25,7 @@
* @}
*/
#if defined(MCU_ATMEGA2560) || defined(MCU_ATMEGA1281) || defined(MCU_ATMEGA328P) || defined(MCU_ATMEGA32U4)
#if defined(MCU_ATMEGA2560) || defined(MCU_ATMEGA1281) || defined(MCU_ATMEGA328P)
#include <stdlib.h>
#else
#include <malloc.h>