Skip to content

Bootloader rework #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Nov 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 166 additions & 21 deletions bootloaders/zero/Makefile
Original file line number Diff line number Diff line change
@@ -1,29 +1,174 @@
IDE_PATH="../../../../.."
ARM_GCC_PATH=$(IDE_PATH)/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin
CC=$(ARM_GCC_PATH)/arm-none-eabi-gcc
CFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -c -g -Os -w -std=gnu99 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
LDFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
BLD_EXTA_FLAGS=-D__SAMD21G18A__
# Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved.
# Copyright (c) 2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

# -----------------------------------------------------------------------------
# Paths
ifeq ($(OS),Windows_NT)

# Are we using mingw/msys/msys2/cygwin?
ifeq ($(TERM),xterm)
# this is the path coming with night build
# T=$(shell cygpath -u $(LOCALAPPDATA))
# this is the path till 1.6.5 r5
T=$(shell cygpath -u $(APPDATA))
MODULE_PATH?=$(T)/Arduino15/packages/arduino
ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-
RM=rm
SEP=/
else
# this is the path coming with night build
# MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino
# this is the path till 1.6.5 r5
MODULE_PATH?=$(APPDATA)/Arduino15/packages/arduino
ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-
RM=rm
SEP=\\
endif
else
UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Linux)
MODULE_PATH?=$HOME/.arduino15/packages/arduino
ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-
RM=rm
SEP=/
endif

ifeq ($(UNAME_S),Darwin)
MODULE_PATH?=$HOME/Library/Arduino15/packages/arduino/
ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-
RM=rm
SEP=/
endif
endif

BUILD_PATH=build
INCLUDES=-I$(IDE_PATH)/hardware/tools/CMSIS/CMSIS/Include/ -I$(IDE_PATH)/hardware/tools/CMSIS/Device/ATMEL/ -I./drivers/ -I./utils/ -I./utils/preprocessor/ -I./utils/interrupt
SOURCES=main.c sam_ba_monitor.c startup_samd21.c usart_sam_ba.c drivers/cdc_enumerate.c drivers/uart_driver.c utils/interrupt/interrupt_sam_nvic.c

# -----------------------------------------------------------------------------
# Tools
CC=$(ARM_GCC_PATH)gcc
OBJCOPY=$(ARM_GCC_PATH)objcopy
NM=$(ARM_GCC_PATH)nm
SIZE=$(ARM_GCC_PATH)size

# -----------------------------------------------------------------------------
# Compiler options
CFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -c -std=gnu99 -ffunction-sections -fdata-sections -nostdlib -nostartfiles --param max-inline-insns-single=500
ifdef DEBUG
CFLAGS+=-g3 -O1 -DDEBUG=1
else
CFLAGS+=-Os -DDEBUG=0
endif
CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_LOW=0x4D -DUSB_PID_HIGH=0x00
INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/Device/ATMEL/"

# -----------------------------------------------------------------------------
# Linker options
LDFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all
LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols --specs=nano.specs --specs=nosys.specs

# -----------------------------------------------------------------------------
# Source files and objects
SOURCES= \
board_driver_led.c \
board_driver_serial.c \
board_driver_usb.c \
board_init.c \
board_startup.c \
main.c \
sam_ba_usb.c \
sam_ba_cdc.c \
sam_ba_monitor.c \
sam_ba_serial.c

OBJECTS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.o))
DEPS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.d))

NAME=samd21_sam_ba
EXECUTABLE=$(NAME).bin
ELF=$(NAME).elf
BIN=$(NAME).bin
HEX=$(NAME).hex

SLASH=/
BSLASH=$(EMPTY)\$(EMPTY)
ifneq "test$(AVRSTUDIO_EXE_PATH)" "test"
AS_BUILD=copy_for_atmel_studio
AS_CLEAN=clean_for_atmel_studio
else
AS_BUILD=
AS_CLEAN=
endif

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
$(CC) -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tsamd21j18a_flash.ld -Wl,-Map,$(BUILD_PATH)/$(NAME).map --specs=nano.specs --specs=nosys.specs -o $(BUILD_PATH)/$(NAME).elf $(OBJECTS) -Wl,--start-group -lm -Wl,--end-group
$(ARM_GCC_PATH)/arm-none-eabi-objcopy -O binary $(BUILD_PATH)/$(NAME).elf $@

all: print_info $(SOURCES) $(BIN) $(HEX) $(AS_BUILD)

$(ELF): Makefile $(BUILD_PATH) $(OBJECTS)
@echo ----------------------------------------------------------
@echo Creating ELF binary
"$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tbootloader_samd21x18.ld -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group
"$(NM)" "$(BUILD_PATH)/$(ELF)" >"$(BUILD_PATH)/$(NAME)_symbols.txt"
"$(SIZE)" --format=sysv -t -x $(BUILD_PATH)/$(ELF)

$(BIN): $(ELF)
@echo ----------------------------------------------------------
@echo Creating flash binary
"$(OBJCOPY)" -O binary $(BUILD_PATH)/$< $@

$(HEX): $(ELF)
@echo ----------------------------------------------------------
@echo Creating flash binary
"$(OBJCOPY)" -O ihex $(BUILD_PATH)/$< $@

$(BUILD_PATH)/%.o: %.c
-@mkdir -p $(@D)
$(CC) $(CFLAGS) $(BLD_EXTA_FLAGS) $(INCLUDES) $< -o $@

clean:
del $(EXECUTABLE) $(subst /,\,$(OBJECTS)) $(subst /,\,$(BUILD_PATH)/$(NAME).*)
@echo ----------------------------------------------------------
@echo Compiling $< to $@
"$(CC)" $(CFLAGS) $(CFLAGS_EXTRA) $(INCLUDES) $< -o $@
@echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

$(BUILD_PATH):
@echo ----------------------------------------------------------
@echo Creating build folder
-mkdir $(BUILD_PATH)

print_info:
@echo ----------------------------------------------------------
@echo Compiling bootloader using
@echo BASE PATH = $(MODULE_PATH)
@echo GCC PATH = $(ARM_GCC_PATH)
# @echo OS = $(OS)
# @echo SHELL = $(SHELL)
# @echo TERM = $(TERM)
# "$(CC)" -v
# env

copy_for_atmel_studio: $(BIN) $(HEX)
@echo ----------------------------------------------------------
@echo Atmel Studio detected, copying ELF to project root for debug
cp $(BUILD_PATH)/$(ELF) .

clean_for_atmel_studio:
@echo ----------------------------------------------------------
@echo Atmel Studio detected, cleaning ELF from project root
-$(RM) ./$(ELF)

clean: $(AS_CLEAN)
@echo ----------------------------------------------------------
@echo Cleaning project
-$(RM) $(BIN)
-$(RM) $(HEX)
-$(RM) $(BUILD_PATH)/*.*
-rmdir $(BUILD_PATH)

.phony: print_info $(BUILD_PATH)
75 changes: 75 additions & 0 deletions bootloaders/zero/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Arduino Zero Bootloader

## 1- Prerequisites

The project build is based on Makefile system.
Makefile is present at project root and try to handle multi-platform cases.

Multi-plaform GCC is provided by ARM here: https://launchpad.net/gcc-arm-embedded/+download

Atmel Studio contains both make and ARM GCC toolchain. You don't need to install them in this specific use case.

### Windows

* Native command line
Make binary can be obtained here: http://gnuwin32.sourceforge.net/packages/make.htm

* Cygwin/MSys/MSys2/Babun/etc...
It is available natively in all distributions.

* Atmel Studio
An Atmel Studio **7** Makefile-based project is present at project root, just open samd21_sam_ba.atsln file in AS7.

### Linux

Make is usually available by default.

### OS X

Make is available through XCode package.


## 2- Selecting available SAM-BA interfaces

By default both USB and UART are made available, but this parameter can be modified in sam_ba_monitor.h, line 31:

Set the define SAM_BA_INTERFACE to
* SAM_BA_UART_ONLY for only UART interface
* SAM_BA_USBCDC_ONLY for only USB CDC interface
* SAM_BA_BOTH_INTERFACES for enabling both the interfaces

## 3- Behaviour

This bootloader implements the double-tap on Reset button.
By quickly pressing this button two times, the board will reset and stay in bootloader, waiting for communication on either USB or USART.

The USB port in use is the USB Native port, close to the Reset button.
The USART in use is the one available on pins D0/D1, labelled respectively RX/TX. Communication parameters are a baudrate at 115200, 8bits of data, no parity and 1 stop bit (8N1).

## 4- Description

**Pinmap**

The following pins are used by the program :
PA25 : input/output (USB DP)
PA24 : input/output (USB DM)
PA11 : input (USART RX)
PA10 : output (USART TX)

The application board shall avoid driving the PA25, PA24, PB23 and PB22 signals while the boot program is running (after a POR for example).

**Clock system**

CPU runs at 48MHz from Generic Clock Generator 0 on DFLL48M.

Generic Clock Generator 1 is using external 32kHz oscillator and is the source of DFLL48M.

USB and USART are using Generic Clock Generator 0 also.

**Memory Mapping**

Bootloader code will be located at 0x0 and executed before any applicative code.

Applications compiled to be executed along with the bootloader will start at 0x2000 (see linker script bootloader_samd21x18.ld).

Before jumping to the application, the bootloader changes the VTOR register to use the interrupt vectors of the application @0x2000.<- not required as application code is taking care of this.
72 changes: 72 additions & 0 deletions bootloaders/zero/board_definitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _BOARD_DEFINITIONS_H_
#define _BOARD_DEFINITIONS_H_

/*
* If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
* quickly tapping two times on the reset button.
* BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not
* be touched from the loaded application.
*/
#define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul)
#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

/*
* If BOOT_LOAD_PIN is defined the bootloader is started if the selected
* pin is tied LOW.
*/
//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7
//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5
#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f))

#define CPU_FREQUENCY (48000000ul)

#define BOOT_USART_MODULE SERCOM0
#define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0
#define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2
#define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3
#define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2
#define BOOT_USART_PAD1 PINMUX_UNUSED
#define BOOT_USART_PAD0 PINMUX_UNUSED

/* Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)

/* Master clock frequency */
#define VARIANT_MCK CPU_FREQUENCY

#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58)
#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64)

/*
* LEDs definitions
*/
#define BOARD_LED_PORT (0)
#define BOARD_LED_PIN (17)

#define BOARD_LEDRX_PORT (1)
#define BOARD_LEDRX_PIN (3)

#define BOARD_LEDTX_PORT (0)
#define BOARD_LEDTX_PIN (27)

#endif // _BOARD_DEFINITIONS_H_
22 changes: 22 additions & 0 deletions bootloaders/zero/board_driver_led.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright (c) 2015 Arduino LLC. All right reserved.
Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "board_driver_led.h"


Loading