Skip to content

Commit

Permalink
SAMD51 builds
Browse files Browse the repository at this point in the history
  • Loading branch information
tannewt committed Oct 21, 2017
1 parent 8f78aa2 commit fc5f4d3
Show file tree
Hide file tree
Showing 16 changed files with 906 additions and 65 deletions.
16 changes: 9 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ BOARD=zero
include boards/$(BOARD)/board.mk
CC=arm-none-eabi-gcc
ifeq ($(CHIP_FAMILY), samd21)
COMMON_FLAGS = -mthumb -mcpu=cortex-m0plus -Os -g
COMMON_FLAGS = -mthumb -mcpu=cortex-m0plus -Os -g -DSAMD21
endif
ifeq ($(CHIP_FAMILY), samd51)
COMMON_FLAGS = -mthumb -mcpu=cortex-m4 -O2 -g
COMMON_FLAGS = -mthumb -mcpu=cortex-m4 -O2 -g -DSAMD51
endif
WFLAGS = \
-Wall -Wstrict-prototypes \
Expand All @@ -28,10 +28,12 @@ $(WFLAGS)

ifeq ($(CHIP_FAMILY), samd21)
LINKER_SCRIPT=./lib/samd21/samd21a/gcc/gcc/samd21j18a_flash.ld
BOOTLOADER_SIZE=8192
endif

ifeq ($(CHIP_FAMILY), samd51)
LINKER_SCRIPT=./lib/samd51/gcc/gcc/samd51j18a_flash.ld
BOOTLOADER_SIZE=16384
endif

LDFLAGS= $(COMMON_FLAGS) \
Expand All @@ -49,12 +51,12 @@ INCLUDES += -Ilib/samd21/samd21a/include/
endif

ifeq ($(CHIP_FAMILY), samd51)
INCLUDES += -I
INCLUDES += -Ilib/samd51/include/
endif

COMMON_SRC = \
src/flash.c \
src/init.c \
src/flash_$(CHIP_FAMILY).c \
src/init_$(CHIP_FAMILY).c \
src/startup_$(CHIP_FAMILY).c \
src/usart_sam_ba.c \
src/utils.c
Expand All @@ -78,7 +80,7 @@ NAME=bootloader
EXECUTABLE=$(BUILD_PATH)/$(NAME).bin
SELF_EXECUTABLE=$(BUILD_PATH)/update-$(NAME).uf2

all: dirs $(EXECUTABLE) $(SELF_EXECUTABLE)
all: dirs $(EXECUTABLE) #$(SELF_EXECUTABLE)

r: run
b: burn
Expand Down Expand Up @@ -109,7 +111,7 @@ $(EXECUTABLE): $(OBJECTS)
-Wl,-Map,$(BUILD_PATH)/$(NAME).map -o $(BUILD_PATH)/$(NAME).elf $(OBJECTS)
arm-none-eabi-objcopy -O binary $(BUILD_PATH)/$(NAME).elf $@
@echo
-@arm-none-eabi-size $(BUILD_PATH)/$(NAME).elf | awk '{ s=$$1+$$2; print } END { print ""; print "Space left: " (8192-s) }'
-@arm-none-eabi-size $(BUILD_PATH)/$(NAME).elf | awk '{ s=$$1+$$2; print } END { print ""; print "Space left: " ($(BOOTLOADER_SIZE)-s) }'
@echo


Expand Down
4 changes: 4 additions & 0 deletions boards/metro_m4/board.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CHIP_FAMILY = samd51
# We target the smallest flash/ram variants of the SAMD51 so we apply to all of
# them.
CHIP_VARIANT = SAMD51J18A
27 changes: 19 additions & 8 deletions boards/metro_m4/board_config.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H

#define __SAMD21G18A__ 1
#define __SAMD21J19A__ 1

#define VENDOR_NAME "Adafruit Industries"
#define PRODUCT_NAME "Metro M0"
#define VOLUME_LABEL "METROBOOT"
#define PRODUCT_NAME "Metro M4"
#define VOLUME_LABEL "METROM4BOOT"
#define INDEX_URL "http://adafru.it/3505"
#define BOARD_ID "SAMD21G18A-Metro-v0"
#define BOARD_ID "SAMD21G19A-Metro-v0"

#define USB_VID 0x239A
#define USB_PID 0x0013

#define LED_PIN PIN_PA17
#define LED_PIN PIN_PA21
#define LED_TX_PIN PIN_PA27
#define LED_RX_PIN PIN_PA31
#define LED_RX_PIN PIN_PB06

#define BOARD_NEOPIXEL_PIN PIN_PA30
#define BOARD_NEOPIXEL_COUNT 1
//#define BOARD_NEOPIXEL_PIN PIN_PB17
//#define BOARD_NEOPIXEL_COUNT 1

#define BOOT_USART_MODULE SERCOM0
#define BOOT_USART_MASK APBAMASK
#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBAMASK_SERCOM0
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2
#define BOOT_USART_PAD3 PINMUX_UNUSED
#define BOOT_USART_PAD2 PINMUX_UNUSED
#define BOOT_USART_PAD1 PINMUX_PA10C_SERCOM0_PAD2
#define BOOT_USART_PAD0 PINMUX_PA11C_SERCOM0_PAD3
#define BOOT_GCLK_ID_CORE SERCOM0_GCLK_ID_CORE
#define BOOT_GCLK_ID_SLOW SERCOM0_GCLK_ID_SLOW

#endif
4 changes: 3 additions & 1 deletion inc/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@

#define FLASH_WAIT_STATES 1

#ifndef BOOT_USART_MODULE
#define BOOT_USART_MODULE SERCOM3
#define BOOT_USART_MUX_SETTINGS UART_RX_PAD1_TX_PAD0
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD1_TX_PAD0
#define BOOT_USART_PAD3 PINMUX_UNUSED
#define BOOT_USART_PAD2 PINMUX_UNUSED
#define BOOT_USART_PAD1 PINMUX_PA23C_SERCOM3_PAD1
#define BOOT_USART_PAD0 PINMUX_PA22C_SERCOM3_PAD0
#endif

#endif // _MAIN_H_
4 changes: 2 additions & 2 deletions inc/uart_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#ifndef UART_DRIVER_H
#define UART_DRIVER_H
#include "samd21.h"
#include "sam.h"
#include <stdbool.h>
#include <stdio.h>

Expand Down Expand Up @@ -104,4 +104,4 @@ void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);
*/
void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length);

#endif
#endif
11 changes: 9 additions & 2 deletions inc/uf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "board_config.h"

#include "samd21.h"
#include "sam.h"
#define UF2_DEFINE_HANDOVER 1 // for testing
#include "uf2format.h"
#include "uf2hid.h"
Expand Down Expand Up @@ -188,7 +188,7 @@ void panic(int code);

extern volatile bool b_sam_ba_interface_usart;
void flash_write_row(uint32_t *dst, uint32_t *src);
void flash_erase_row(uint32_t *dst);
void flash_erase_to_end(uint32_t *start_address);
void flash_write_words(uint32_t *dst, uint32_t *src, uint32_t n_words);
void copy_words(uint32_t *dst, uint32_t *src, uint32_t n_words);

Expand Down Expand Up @@ -217,7 +217,12 @@ void padded_memcpy(char *dst, const char *src, int len);
// Unlike for ordinary applications, our link script doesn't place the stack at the bottom
// of the RAM, but instead after all allocated BSS.
// In other words, this word should survive reset.
#ifdef SAMD21
#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))
#endif
#ifdef SAMD51
#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))
#endif
#define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef

Expand Down Expand Up @@ -252,9 +257,11 @@ void handoverPrep(void);
#define CONCAT_0(a, b) CONCAT_1(a, b)
#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }

#ifdef SAMD21
STATIC_ASSERT(FLASH_ROW_SIZE == FLASH_PAGE_SIZE * 4);
STATIC_ASSERT(FLASH_ROW_SIZE == NVMCTRL_ROW_SIZE);
STATIC_ASSERT(FLASH_NUM_ROWS * 4 == FLASH_NB_OF_PAGES);
#endif

extern const char infoUf2File[];

Expand Down
16 changes: 8 additions & 8 deletions scripts/gendata.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ s += "const uint16_t bootloader_crcs[] = {" + crcs + "};\n"
let selfdata = "#include <stdint.h>\n" + s
fs.writeFileSync(buildPath + "/selfdata.c", selfdata)

let sketch = fs.readFileSync("src/sketch.cpp", "utf8")
let instr =`//
// Bootloader update sketch. Paste into Arduino IDE and upload to the device
// to update bootloader. It will blink a few times and then start pulsing.
// Your OS will then detect a USB mass storage device.
//
`;
fs.writeFileSync(buildPath + "/update-bootloader.ino", instr + s + "\n" + sketch)
// let sketch = fs.readFileSync("src/sketch.cpp", "utf8")
// let instr =`//
// // Bootloader update sketch. Paste into Arduino IDE and upload to the device
// // to update bootloader. It will blink a few times and then start pulsing.
// // Your OS will then detect a USB mass storage device.
// //
// `;
// fs.writeFileSync(buildPath + "/update-bootloader.ino", instr + s + "\n" + sketch)
54 changes: 33 additions & 21 deletions src/cdc_enumerate.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,21 +440,39 @@ void AT91F_InitUSB(void) {
uint32_t pad_transn, pad_transp, pad_trim;

/* Enable USB clock */
PM->APBBMASK.reg |= PM_APBBMASK_USB;
#ifdef SAMD21
PM->APBBMASK.bit.USB = true;
#define DM_PIN PIN_PA24G_USB_DM
#define DM_MUX MUX_PA24G_USB_DM
#define DP_PIN PIN_PA25G_USB_DP
#define DP_MUX MUX_PA25G_USB_DP
#endif
#ifdef SAMD51
#define DM_PIN PIN_PA24H_USB_DM
#define DM_MUX MUX_PA24H_USB_DM
#define DP_PIN PIN_PA25H_USB_DP
#define DP_MUX MUX_PA25H_USB_DP
#endif

/* Set up the USB DP/DN pins */
PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA24G_USB_DM / 2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u)));
PORT->Group[0].PMUX[PIN_PA24G_USB_DM / 2].reg |= MUX_PA24G_USB_DM
<< (4 * (PIN_PA24G_USB_DM & 0x01u));
PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA25G_USB_DP / 2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u)));
PORT->Group[0].PMUX[PIN_PA25G_USB_DP / 2].reg |= MUX_PA25G_USB_DP
<< (4 * (PIN_PA25G_USB_DP & 0x01u));

PORT->Group[0].PINCFG[DM_PIN].bit.PMUXEN = 1;
PORT->Group[0].PMUX[DM_PIN / 2].reg &= ~(0xF << (4 * (DM_PIN & 0x01u)));
PORT->Group[0].PMUX[DM_PIN / 2].reg |= DM_MUX << (4 * (DM_PIN & 0x01u));
PORT->Group[0].PINCFG[DP_PIN].bit.PMUXEN = 1;
PORT->Group[0].PMUX[DP_PIN / 2].reg &= ~(0xF << (4 * (DP_PIN & 0x01u)));
PORT->Group[0].PMUX[DP_PIN / 2].reg |= DP_MUX << (4 * (DP_PIN & 0x01u));

#ifdef SAMD21
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN;
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY)
;
while (GCLK->STATUS.bit.SYNCBUSY) {}
#endif
#ifdef SAMD51
GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
MCLK->AHBMASK.bit.USB_ = true;
MCLK->APBBMASK.bit.USB_ = true;

while(GCLK->SYNCBUSY.bit.GENCTRL0) {}
#endif

/* Reset */
USB->HOST.CTRLA.bit.SWRST = 1;
Expand All @@ -463,28 +481,22 @@ void AT91F_InitUSB(void) {
}

/* Load Pad Calibration */
pad_transn = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRANSN_POS / 32)) >>
(NVM_USB_PAD_TRANSN_POS % 32)) &
((1 << NVM_USB_PAD_TRANSN_SIZE) - 1);
pad_transn = ((*((uint32_t*) USB_FUSES_TRANSN_ADDR)) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos;

if (pad_transn == 0x1F) {
pad_transn = 5;
}

USB->HOST.PADCAL.bit.TRANSN = pad_transn;

pad_transp = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRANSP_POS / 32)) >>
(NVM_USB_PAD_TRANSP_POS % 32)) &
((1 << NVM_USB_PAD_TRANSP_SIZE) - 1);
pad_transp = ((*((uint32_t*) USB_FUSES_TRANSP_ADDR)) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos;

if (pad_transp == 0x1F) {
pad_transp = 29;
}

USB->HOST.PADCAL.bit.TRANSP = pad_transp;
pad_trim = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRIM_POS / 32)) >>
(NVM_USB_PAD_TRIM_POS % 32)) &
((1 << NVM_USB_PAD_TRIM_SIZE) - 1);
pad_trim = ((*((uint32_t*) USB_FUSES_TRIM_ADDR)) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos;

if (pad_trim == 0x7) {
pad_trim = 3;
Expand Down
15 changes: 15 additions & 0 deletions src/flash.c → src/flash_samd21.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ void flash_erase_row(uint32_t *dst) {
wait_ready();
}

void flash_erase_to_end(uint32_t *start_address) {
// Note: the flash memory is erased in ROWS, that is in
// block of 4 pages.
// Even if the starting address is the last byte
// of a ROW the entire
// ROW is erased anyway.

uint32_t dst_addr = (uint32_t) start_address; // starting address

while (dst_addr < FLASH_SIZE) {
flash_erase_row((void *)dst_addr);
dst_addr += FLASH_ROW_SIZE;
}
}

void copy_words(uint32_t *dst, uint32_t *src, uint32_t n_words) {
while (n_words--)
*dst++ = *src++;
Expand Down
Loading

0 comments on commit fc5f4d3

Please sign in to comment.