atsam: Add support for SAM E70

Signed-off-by: Alex Maclean <monkeh@monkeh.net>
This commit is contained in:
Alex Maclean 2021-08-18 20:01:59 +01:00 committed by Kevin O'Connor
parent 99c2bf0ded
commit 8049243221
18 changed files with 440 additions and 82 deletions

View File

@ -64,6 +64,7 @@ class PrinterTemperatureMCU:
cfg_funcs = [ cfg_funcs = [
('rp2040', self.config_rp2040), ('rp2040', self.config_rp2040),
('sam3', self.config_sam3), ('sam4', self.config_sam4), ('sam3', self.config_sam3), ('sam4', self.config_sam4),
('same70', self.config_same70),
('samd21', self.config_samd21), ('samd51', self.config_samd51), ('samd21', self.config_samd21), ('samd51', self.config_samd51),
('stm32f1', self.config_stm32f1), ('stm32f2', self.config_stm32f2), ('stm32f1', self.config_stm32f1), ('stm32f2', self.config_stm32f2),
('stm32f4', self.config_stm32f4), ('stm32f4', self.config_stm32f4),
@ -100,6 +101,9 @@ class PrinterTemperatureMCU:
def config_sam4(self): def config_sam4(self):
self.slope = 3.3 / .004700 self.slope = 3.3 / .004700
self.base_temperature = self.calc_base(27., 1.44 / 3.3) self.base_temperature = self.calc_base(27., 1.44 / 3.3)
def config_same70(self):
self.slope = 3.3 / .002330
self.base_temperature = self.calc_base(25., 0.72 / 3.3)
def config_samd21(self, addr=0x00806030): def config_samd21(self, addr=0x00806030):
def get1v(val): def get1v(val):
if val & 0x80: if val & 0x80:

View File

@ -286,7 +286,7 @@ def flash_rp2040(options, binfile):
MCUTYPES = { MCUTYPES = {
'sam3': flash_atsam3, 'sam4': flash_atsam4, 'samd': flash_atsamd, 'sam3': flash_atsam3, 'sam4': flash_atsam4, 'samd': flash_atsamd,
'lpc176': flash_lpc176x, 'stm32f103': flash_stm32f1, 'same70': flash_atsam4, 'lpc176': flash_lpc176x, 'stm32f103': flash_stm32f1,
'stm32f4': flash_stm32f4, 'stm32f042': flash_stm32f4, 'stm32f4': flash_stm32f4, 'stm32f042': flash_stm32f4,
'stm32f072': flash_stm32f4, 'rp2040': flash_rp2040 'stm32f072': flash_stm32f4, 'rp2040': flash_rp2040
} }

View File

@ -14,7 +14,7 @@ choice
config MACH_AVR config MACH_AVR
bool "Atmega AVR" bool "Atmega AVR"
config MACH_ATSAM config MACH_ATSAM
bool "SAM3/SAM4 (Due and Duet)" bool "SAM3/SAM4/SAM E70 (Due and Duet)"
config MACH_ATSAMD config MACH_ATSAMD
bool "SAMD21/SAMD51" bool "SAMD21/SAMD51"
config MACH_LPC176X config MACH_LPC176X

View File

@ -9,7 +9,7 @@ config ATSAM_SELECT
select HAVE_GPIO_ADC select HAVE_GPIO_ADC
select HAVE_GPIO_I2C select HAVE_GPIO_I2C
select HAVE_GPIO_SPI select HAVE_GPIO_SPI
select HAVE_GPIO_HARD_PWM select HAVE_GPIO_HARD_PWM if !MACH_SAME70
select HAVE_GPIO_BITBANGING select HAVE_GPIO_BITBANGING
select HAVE_STRICT_TIMING select HAVE_STRICT_TIMING
select HAVE_CHIPID select HAVE_CHIPID
@ -33,6 +33,9 @@ choice
config MACH_SAM4E8E config MACH_SAM4E8E
bool "SAM4e8e (Duet Wifi/Eth)" bool "SAM4e8e (Duet Wifi/Eth)"
select MACH_SAM4E select MACH_SAM4E
config MACH_SAME70Q20B
bool "SAME70Q20B (Duet 3 6HC)"
select MACH_SAME70
endchoice endchoice
config MACH_SAM3X config MACH_SAM3X
@ -45,6 +48,8 @@ config MACH_SAM4S
config MACH_SAM4E config MACH_SAM4E
bool bool
select MACH_SAM4 select MACH_SAM4
config MACH_SAME70
bool
config MCU config MCU
string string
@ -52,15 +57,17 @@ config MCU
default "sam3x8c" if MACH_SAM3X8C default "sam3x8c" if MACH_SAM3X8C
default "sam4s8c" if MACH_SAM4S8C default "sam4s8c" if MACH_SAM4S8C
default "sam4e8e" if MACH_SAM4E8E default "sam4e8e" if MACH_SAM4E8E
default "same70q20b" if MACH_SAME70Q20B
config CLOCK_FREQ config CLOCK_FREQ
int int
default 84000000 if MACH_SAM3X default 84000000 if MACH_SAM3X
default 120000000 if MACH_SAM4 default 120000000 if MACH_SAM4
default 300000000 if MACH_SAME70
config FLASH_START config FLASH_START
hex hex
default 0x400000 if MACH_SAM4 default 0x400000 if MACH_SAM4 || MACH_SAME70
default 0x80000 default 0x80000
config FLASH_SIZE config FLASH_SIZE
@ -69,12 +76,14 @@ config FLASH_SIZE
config RAM_START config RAM_START
hex hex
default 0x20400000 if MACH_SAME70
default 0x20000000 default 0x20000000
config RAM_SIZE config RAM_SIZE
hex hex
default 0x18000 if MACH_SAM3X default 0x18000 if MACH_SAM3X
default 0x20000 if MACH_SAM4 default 0x20000 if MACH_SAM4
default 0x40000 if MACH_SAME70
config STACK_SIZE config STACK_SIZE
int int

View File

@ -7,14 +7,17 @@ dirs-y += src/atsam src/generic
dirs-$(CONFIG_MACH_SAM3X) += lib/sam3x/gcc dirs-$(CONFIG_MACH_SAM3X) += lib/sam3x/gcc
dirs-$(CONFIG_MACH_SAM4S) += lib/sam4s/gcc dirs-$(CONFIG_MACH_SAM4S) += lib/sam4s/gcc
dirs-$(CONFIG_MACH_SAM4E) += lib/sam4e/gcc dirs-$(CONFIG_MACH_SAM4E) += lib/sam4e/gcc
dirs-$(CONFIG_MACH_SAME70) += lib/same70b/gcc
MCU := $(shell echo $(CONFIG_MCU) | tr a-z A-Z) MCU := $(shell echo $(CONFIG_MCU) | tr a-z A-Z)
CFLAGS-$(CONFIG_MACH_SAM3X) += -mcpu=cortex-m3 -falign-loops=16 CFLAGS-$(CONFIG_MACH_SAM3X) += -mcpu=cortex-m3 -falign-loops=16
CFLAGS-$(CONFIG_MACH_SAM4) += -mcpu=cortex-m4 CFLAGS-$(CONFIG_MACH_SAM4) += -mcpu=cortex-m4
CFLAGS-$(CONFIG_MACH_SAME70) += -mcpu=cortex-m7
CFLAGS-$(CONFIG_MACH_SAM3X) += -Ilib/sam3x/include CFLAGS-$(CONFIG_MACH_SAM3X) += -Ilib/sam3x/include
CFLAGS-$(CONFIG_MACH_SAM4S) += -Ilib/sam4s/include CFLAGS-$(CONFIG_MACH_SAM4S) += -Ilib/sam4s/include
CFLAGS-$(CONFIG_MACH_SAM4E) += -Ilib/sam4e/include CFLAGS-$(CONFIG_MACH_SAM4E) += -Ilib/sam4e/include
CFLAGS-$(CONFIG_MACH_SAME70) += -Ilib/same70b/include
CFLAGS += $(CFLAGS-y) -D__$(MCU)__ -mthumb -Ilib/cmsis-core CFLAGS += $(CFLAGS-y) -D__$(MCU)__ -mthumb -Ilib/cmsis-core
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
@ -22,19 +25,22 @@ CFLAGS_klipper.elf += -T $(OUT)src/generic/armcm_link.ld
$(OUT)klipper.elf: $(OUT)src/generic/armcm_link.ld $(OUT)klipper.elf: $(OUT)src/generic/armcm_link.ld
# Add source files # Add source files
src-y += atsam/main.c atsam/gpio.c atsam/i2c.c atsam/spi.c atsam/hard_pwm.c src-y += atsam/main.c atsam/gpio.c atsam/i2c.c atsam/spi.c
src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_timer.c src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_timer.c
src-y += generic/crc16_ccitt.c src-y += generic/crc16_ccitt.c
usb-src-$(CONFIG_MACH_SAM3X) := atsam/sam3_usb.c usb-src-$(CONFIG_MACH_SAM3X) := atsam/sam3_usb.c
usb-src-$(CONFIG_MACH_SAM4) := atsam/sam4_usb.c usb-src-$(CONFIG_MACH_SAM4) := atsam/sam4_usb.c
usb-src-$(CONFIG_MACH_SAME70) := atsam/sam3_usb.c
src-$(CONFIG_USBSERIAL) += $(usb-src-y) atsam/chipid.c generic/usb_cdc.c src-$(CONFIG_USBSERIAL) += $(usb-src-y) atsam/chipid.c generic/usb_cdc.c
src-$(CONFIG_SERIAL) += atsam/serial.c generic/serial_irq.c src-$(CONFIG_SERIAL) += atsam/serial.c generic/serial_irq.c
src-$(CONFIG_MACH_SAM3X) += atsam/adc.c src-$(CONFIG_MACH_SAM3X) += atsam/adc.c atsam/hard_pwm.c
src-$(CONFIG_MACH_SAM4) += atsam/hard_pwm.c
src-$(CONFIG_MACH_SAM4S) += atsam/adc.c src-$(CONFIG_MACH_SAM4S) += atsam/adc.c
src-$(CONFIG_MACH_SAM4E) += atsam/sam4e_afec.c atsam/sam4_cache.c src-$(CONFIG_MACH_SAM4E) += atsam/sam4e_afec.c atsam/sam4_cache.c
src-$(CONFIG_MACH_SAM3X) += ../lib/sam3x/gcc/system_sam3xa.c src-$(CONFIG_MACH_SAM3X) += ../lib/sam3x/gcc/system_sam3xa.c
src-$(CONFIG_MACH_SAM4S) += atsam/sam4s_sysinit.c src-$(CONFIG_MACH_SAM4S) += atsam/sam4s_sysinit.c
src-$(CONFIG_MACH_SAM4E) += ../lib/sam4e/gcc/system_sam4e.c src-$(CONFIG_MACH_SAM4E) += ../lib/sam4e/gcc/system_sam4e.c
src-$(CONFIG_MACH_SAME70) += atsam/same70_sysinit.c atsam/sam4e_afec.c
# Build the additional bin output file # Build the additional bin output file
target-y += $(OUT)klipper.bin target-y += $(OUT)klipper.bin

View File

@ -11,6 +11,11 @@
#include "internal.h" // gpio_peripheral #include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown #include "sched.h" // sched_shutdown
struct gpio_info {
void *dev;
uint8_t dev_id;
};
DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 32); DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 32);
DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 0), 32); DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 0), 32);
#ifdef PIOC #ifdef PIOC
@ -23,16 +28,17 @@ DECL_ENUMERATION_RANGE("pin", "PD0", GPIO('D', 0), 32);
DECL_ENUMERATION_RANGE("pin", "PE0", GPIO('E', 0), 32); DECL_ENUMERATION_RANGE("pin", "PE0", GPIO('E', 0), 32);
#endif #endif
static Pio * const digital_regs[] = { static const struct gpio_info digital_regs[] = {
PIOA, PIOB, { PIOA, ID_PIOA },
{ PIOB, ID_PIOB },
#ifdef PIOC #ifdef PIOC
PIOC, { PIOC, ID_PIOC },
#endif #endif
#ifdef PIOD #ifdef PIOD
PIOD, { PIOD, ID_PIOD },
#endif #endif
#ifdef PIOE #ifdef PIOE
PIOE, { PIOE, ID_PIOE },
#endif #endif
}; };
@ -65,6 +71,9 @@ set_pull_up(Pio *regs, uint32_t bit, int32_t pull_up)
// Check if this pin is a "system IO pin" and disable if so // Check if this pin is a "system IO pin" and disable if so
if (regs == PIOB && (bit & 0x1cf0)) if (regs == PIOB && (bit & 0x1cf0))
MATRIX->CCFG_SYSIO |= bit; MATRIX->CCFG_SYSIO |= bit;
#elif CONFIG_MACH_SAME70
if (regs == PIOB && (bit & 0x10f0))
MATRIX->CCFG_SYSIO |= bit;
#endif #endif
} }
@ -72,7 +81,7 @@ void
gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up) gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up)
{ {
uint32_t bank = GPIO2PORT(gpio), bit = GPIO2BIT(gpio), pt = ptype - 'A'; uint32_t bank = GPIO2PORT(gpio), bit = GPIO2BIT(gpio), pt = ptype - 'A';
Pio *regs = digital_regs[bank]; Pio *regs = digital_regs[bank].dev;
#if CONFIG_MACH_SAM3X #if CONFIG_MACH_SAM3X
regs->PIO_ABSR = (regs->PIO_ABSR & ~bit) | (pt & 0x01 ? bit : 0); regs->PIO_ABSR = (regs->PIO_ABSR & ~bit) | (pt & 0x01 ? bit : 0);
@ -94,7 +103,7 @@ gpio_out_setup(uint8_t pin, uint8_t val)
{ {
if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs))
goto fail; goto fail;
Pio *regs = digital_regs[GPIO2PORT(pin)]; Pio *regs = digital_regs[GPIO2PORT(pin)].dev;
struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) };
gpio_out_reset(g, val); gpio_out_reset(g, val);
return g; return g;
@ -152,8 +161,8 @@ gpio_in_setup(uint8_t pin, int8_t pull_up)
if (CONFIG_MACH_SAM3X && pull_up < 0) if (CONFIG_MACH_SAM3X && pull_up < 0)
goto fail; goto fail;
uint32_t port = GPIO2PORT(pin); uint32_t port = GPIO2PORT(pin);
enable_pclock(ID_PIOA + port); enable_pclock(digital_regs[port].dev_id);
struct gpio_in g = { .regs=digital_regs[port], .bit=GPIO2BIT(pin) }; struct gpio_in g = { .regs=digital_regs[port].dev, .bit=GPIO2BIT(pin) };
gpio_in_reset(g, pull_up); gpio_in_reset(g, pull_up);
return g; return g;
fail: fail:

View File

@ -11,35 +11,62 @@
#include "internal.h" // gpio_peripheral #include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown #include "sched.h" // sched_shutdown
// I2C pin definitions #if CONFIG_MACH_SAME70
DECL_ENUMERATION_RANGE("i2c_bus", "twi0", 0, 2); #include "same70_i2c.h" // Fixes for upstream header changes
#if CONFIG_MACH_SAM3X
#define TWI0_SCL_GPIO GPIO('A', 18)
#define TWI0_SDA_GPIO GPIO('A', 17)
#define TWI1_SCL_GPIO GPIO('B', 13)
#define TWI1_SDA_GPIO GPIO('B', 12)
DECL_CONSTANT_STR("BUS_PINS_twi0", "PA18,PA17");
DECL_CONSTANT_STR("BUS_PINS_twi1", "PB13,PB12");
#elif CONFIG_MACH_SAM4
#define TWI0_SCL_GPIO GPIO('A', 4)
#define TWI0_SDA_GPIO GPIO('A', 3)
#define TWI1_SCL_GPIO GPIO('B', 5)
#define TWI1_SDA_GPIO GPIO('B', 4)
DECL_CONSTANT_STR("BUS_PINS_twi0", "PA4,PA3");
DECL_CONSTANT_STR("BUS_PINS_twi1", "PB5,PB4");
#endif #endif
struct twi_info {
void *dev;
uint32_t dev_id;
uint8_t scl_pin, sda_pin, periph;
};
// I2C pin definitions
#if CONFIG_MACH_SAM3X
DECL_ENUMERATION_RANGE("i2c_bus", "twi0", 0, 2);
DECL_CONSTANT_STR("BUS_PINS_twi0", "PA18,PA17");
DECL_CONSTANT_STR("BUS_PINS_twi1", "PB13,PB12");
#define PRD_CALC_NUM 4
#elif CONFIG_MACH_SAM4
DECL_ENUMERATION_RANGE("i2c_bus", "twi0", 0, 2);
DECL_CONSTANT_STR("BUS_PINS_twi0", "PA4,PA3");
DECL_CONSTANT_STR("BUS_PINS_twi1", "PB5,PB4");
#define PRD_CALC_NUM 4
#elif CONFIG_MACH_SAME70
DECL_ENUMERATION_RANGE("i2c_bus", "twihs0", 0,3);
DECL_CONSTANT_STR("BUS_PINS_twihs0", "PA4,PA3");
DECL_CONSTANT_STR("BUS_PINS_twihs1", "PB5,PB4");
DECL_CONSTANT_STR("BUS_PINS_twihs2", "PD28,PD27");
#define PRD_CALC_NUM 3
#endif
static const struct twi_info twi_bus[] = {
#if CONFIG_MACH_SAM3X
{ TWI0, ID_TWI0, GPIO('A', 18), GPIO('A', 17), 'A'},
{ TWI1, ID_TWI1, GPIO('B', 13), GPIO('B', 12), 'A'},
#elif CONFIG_MACH_SAM4
{ TWI0, ID_TWI0, GPIO('A', 4), GPIO('A', 3), 'A'},
{ TWI1, ID_TWI1, GPIO('B', 5), GPIO('B', 4), 'A'},
#elif CONFIG_MACH_SAME70
{ TWIHS0, ID_TWIHS0, GPIO('A', 4), GPIO('A', 3), 'A'},
{ TWIHS1, ID_TWIHS1, GPIO('B', 5), GPIO('B', 4), 'A'},
{ TWIHS2, ID_TWIHS2, GPIO('D', 28), GPIO('D', 27), 'C'},
#endif
};
static void static void
i2c_init(Twi *p_twi, uint32_t rate) init_pins(uint32_t bus)
{ {
enable_pclock(p_twi == TWI0 ? ID_TWI0 : ID_TWI1); const struct twi_info *si = &twi_bus[bus];
if (p_twi == TWI0) { gpio_peripheral(si->scl_pin, si->periph, 1);
gpio_peripheral(TWI0_SCL_GPIO, 'A', 1); gpio_peripheral(si->sda_pin, si->periph, 1);
gpio_peripheral(TWI0_SDA_GPIO, 'A', 1); enable_pclock(si->dev_id);
} else { }
gpio_peripheral(TWI1_SCL_GPIO, 'A', 1);
gpio_peripheral(TWI1_SDA_GPIO, 'A', 1); static void
} i2c_init(uint32_t bus, uint32_t rate)
{
Twi *p_twi = twi_bus[bus].dev;
p_twi->TWI_IDR = 0xFFFFFFFF; p_twi->TWI_IDR = 0xFFFFFFFF;
(void)p_twi->TWI_SR; (void)p_twi->TWI_SR;
p_twi->TWI_CR = TWI_CR_SWRST; p_twi->TWI_CR = TWI_CR_SWRST;
@ -48,9 +75,9 @@ i2c_init(Twi *p_twi, uint32_t rate)
p_twi->TWI_CR = TWI_CR_SVDIS; p_twi->TWI_CR = TWI_CR_SVDIS;
p_twi->TWI_CR = TWI_CR_MSEN; p_twi->TWI_CR = TWI_CR_MSEN;
uint32_t pclk = get_pclock_frequency(p_twi == TWI0 ? ID_TWI0 : ID_TWI1); uint32_t pclk = get_pclock_frequency(twi_bus[bus].dev_id);
uint32_t cldiv = 0, chdiv = 0, ckdiv = 0; uint32_t cldiv = 0, chdiv = 0, ckdiv = 0;
cldiv = pclk / ((rate > 384000 ? 384000 : rate) * 2) - 4; cldiv = pclk / ((rate > 384000 ? 384000 : rate) * 2) - PRD_CALC_NUM;
while ((cldiv > 255) && (ckdiv < 7)) { while ((cldiv > 255) && (ckdiv < 7)) {
ckdiv++; ckdiv++;
@ -58,7 +85,7 @@ i2c_init(Twi *p_twi, uint32_t rate)
} }
if (rate > 348000) { if (rate > 348000) {
chdiv = pclk / ((2 * rate - 384000) * 2) - 4; chdiv = pclk / ((2 * rate - 384000) * 2) - PRD_CALC_NUM;
while ((chdiv > 255) && (ckdiv < 7)) { while ((chdiv > 255) && (ckdiv < 7)) {
ckdiv++; ckdiv++;
chdiv /= 2; chdiv /= 2;
@ -91,10 +118,11 @@ addr_to_u32(uint8_t addr_len, uint8_t *addr)
struct i2c_config struct i2c_config
i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr) i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
{ {
if (bus > 1 || rate > 400000) if (bus >= ARRAY_SIZE(twi_bus) || rate > 400000)
shutdown("Invalid i2c_setup parameters!"); shutdown("Invalid i2c_setup parameters!");
Twi *p_twi = (bus == 0) ? TWI0 : TWI1; Twi *p_twi = twi_bus[bus].dev;
i2c_init(p_twi, rate); init_pins(bus);
i2c_init(bus, rate);
return (struct i2c_config){ .twi=p_twi, .addr=addr}; return (struct i2c_config){ .twi=p_twi, .addr=addr};
} }

View File

@ -11,6 +11,8 @@
#include "sam4s.h" #include "sam4s.h"
#elif CONFIG_MACH_SAM4E #elif CONFIG_MACH_SAM4E
#include "sam4e.h" #include "sam4e.h"
#elif CONFIG_MACH_SAME70
#include "sam.h"
#endif #endif
#define GPIO(PORT, NUM) (((PORT)-'A') * 32 + (NUM)) #define GPIO(PORT, NUM) (((PORT)-'A') * 32 + (NUM))

View File

@ -11,6 +11,8 @@
#include "internal.h" // WDT #include "internal.h" // WDT
#include "sched.h" // sched_main #include "sched.h" // sched_main
#define FREQ_PERIPH_DIV (CONFIG_MACH_SAME70 ? 2 : 1)
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / FREQ_PERIPH_DIV)
/**************************************************************** /****************************************************************
* watchdog handler * watchdog handler
@ -60,7 +62,7 @@ enable_pclock(uint32_t id)
uint32_t uint32_t
get_pclock_frequency(uint32_t id) get_pclock_frequency(uint32_t id)
{ {
return CONFIG_CLOCK_FREQ; return FREQ_PERIPH;
} }
@ -68,12 +70,18 @@ get_pclock_frequency(uint32_t id)
* Resets * Resets
****************************************************************/ ****************************************************************/
#if CONFIG_MACH_SAME70
#define RST_PARAMS ((0xA5 << RSTC_CR_KEY_Pos) | RSTC_CR_PROCRST)
#else
#define RST_PARAMS ((0xA5 << RSTC_CR_KEY_Pos) | RSTC_CR_PROCRST \
| RSTC_CR_PERRST)
#endif
void void
command_reset(uint32_t *args) command_reset(uint32_t *args)
{ {
irq_disable(); irq_disable();
RSTC->RSTC_CR = ((0xA5 << RSTC_CR_KEY_Pos) | RSTC_CR_PROCRST RSTC->RSTC_CR = RST_PARAMS;
| RSTC_CR_PERRST);
for (;;) for (;;)
; ;
} }
@ -81,7 +89,7 @@ DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset");
#if CONFIG_MACH_SAM3X || CONFIG_MACH_SAM4S #if CONFIG_MACH_SAM3X || CONFIG_MACH_SAM4S
#define EFC_HW EFC0 #define EFC_HW EFC0
#elif CONFIG_MACH_SAM4E #elif CONFIG_MACH_SAM4E || CONFIG_MACH_SAME70
#define EFC_HW EFC #define EFC_HW EFC
#endif #endif
@ -97,8 +105,7 @@ usb_request_bootloader(void)
while ((EFC_HW->EEFC_FSR & EEFC_FSR_FRDY) == 0) while ((EFC_HW->EEFC_FSR & EEFC_FSR_FRDY) == 0)
; ;
// Reboot // Reboot
RSTC->RSTC_CR = ((0xA5 << RSTC_CR_KEY_Pos) | RSTC_CR_PROCRST RSTC->RSTC_CR = RST_PARAMS;
| RSTC_CR_PERRST);
for (;;) for (;;)
; ;
} }

View File

@ -11,6 +11,14 @@
#include "internal.h" // UOTGHS #include "internal.h" // UOTGHS
#include "sched.h" // DECL_INIT #include "sched.h" // DECL_INIT
#if CONFIG_MACH_SAME70
#include "same70_usb.h" // Fixes for upstream header changes
#define CFG_UOTGHS_CTRL (UOTGHS_CTRL_UIMOD | UOTGHS_CTRL_USBE)
#else
#define CFG_UOTGHS_CTRL (UOTGHS_CTRL_UIMOD | UOTGHS_CTRL_OTGPADE | \
UOTGHS_CTRL_USBE)
#endif
#define EP_SIZE(s) ((s)==64 ? UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE : \ #define EP_SIZE(s) ((s)==64 ? UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE : \
((s)==32 ? UOTGHS_DEVEPTCFG_EPSIZE_32_BYTE : \ ((s)==32 ? UOTGHS_DEVEPTCFG_EPSIZE_32_BYTE : \
((s)==16 ? UOTGHS_DEVEPTCFG_EPSIZE_16_BYTE : \ ((s)==16 ? UOTGHS_DEVEPTCFG_EPSIZE_16_BYTE : \
@ -216,8 +224,7 @@ usbserial_init(void)
; ;
// Enable USB // Enable USB
UOTGHS->UOTGHS_CTRL = (UOTGHS_CTRL_UIMOD | UOTGHS_CTRL_OTGPADE UOTGHS->UOTGHS_CTRL = CFG_UOTGHS_CTRL;
| UOTGHS_CTRL_USBE);
UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS; UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS;
// Enable interrupts // Enable interrupts

View File

@ -7,15 +7,19 @@
#include "autoconf.h" // CONFIG_CLOCK_FREQ #include "autoconf.h" // CONFIG_CLOCK_FREQ
#include "command.h" // shutdown #include "command.h" // shutdown
#include "gpio.h" // gpio_adc_setup #include "gpio.h" // gpio_adc_setup
#include "internal.h" // GPIO #include "internal.h" // GPIO, AFEC0
#include "sam4e.h" // AFEC0
#include "sched.h" // sched_shutdown #include "sched.h" // sched_shutdown
#if CONFIG_MACH_SAME70
#include "same70_afec.h" // Fixes for upstream header changes
#endif
#define ADC_TEMPERATURE_PIN 0xfe #define ADC_TEMPERATURE_PIN 0xfe
DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN); DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN);
static const uint8_t afec_pins[] = { static const uint8_t afec_pins[] = {
//remove first channel, since it offsets the channel number: GPIO('A', 8), //remove first channel, since it offsets the channel number: GPIO('A', 8),
#if CONFIG_MACH_SAM4E
GPIO('A', 17), GPIO('A', 18), GPIO('A', 19), GPIO('A', 17), GPIO('A', 18), GPIO('A', 19),
GPIO('A', 20), GPIO('B', 0), GPIO('B', 1), GPIO('C', 13), GPIO('A', 20), GPIO('B', 0), GPIO('B', 1), GPIO('C', 13),
GPIO('C', 15), GPIO('C', 12), GPIO('C', 29), GPIO('C', 30), GPIO('C', 15), GPIO('C', 12), GPIO('C', 29), GPIO('C', 30),
@ -24,9 +28,40 @@ static const uint8_t afec_pins[] = {
// AFEC1 // AFEC1
GPIO('B', 2), GPIO('B', 3), GPIO('A', 21), GPIO('A', 22), GPIO('B', 2), GPIO('B', 3), GPIO('A', 21), GPIO('A', 22),
GPIO('C', 1), GPIO('C', 2), GPIO('C', 3), GPIO('C', 4), GPIO('C', 1), GPIO('C', 2), GPIO('C', 3), GPIO('C', 4),
#elif CONFIG_MACH_SAME70
GPIO('D', 30), GPIO('A', 21), GPIO('B', 3), GPIO('E', 5),
GPIO('E', 4), GPIO('B', 2), GPIO('A', 17), GPIO('A', 18),
GPIO('A', 19), GPIO('A', 20), GPIO('B', 0),
ADC_TEMPERATURE_PIN,
// AFEC1
GPIO('B', 1), GPIO('C', 13), GPIO('C', 15), GPIO('C', 12),
GPIO('C', 29), GPIO('C', 30), GPIO('C', 31), GPIO('C', 26),
GPIO('C', 27), GPIO('C', 0), GPIO('E', 3), GPIO('E', 0),
#endif
}; };
#if CONFIG_MACH_SAM4E
#define AFEC1_START 16 // The first 16 pins are on afec0 #define AFEC1_START 16 // The first 16 pins are on afec0
#define CFG_AFE_MR (AFE_MR_ANACH_ALLOWED | \
AFE_MR_PRESCAL(pclk / (2 * ADC_FREQ_MAX) - 1) | \
AFE_MR_SETTLING_AST3 | \
AFE_MR_TRACKTIM(2) | \
AFE_MR_TRANSFER(1) | \
AFE_MR_STARTUP_SUT64)
#define CFG_AFE_ACR AFE_ACR_IBCTL(1)
#define CFG_AFE_IDR 0xDF00FFFF
#define CFG_AFE_COCR (0x800 & AFE_COCR_AOFF_Msk)
#elif CONFIG_MACH_SAME70
#define AFEC1_START 12 // The first 12 pins are on afec0
#define CFG_AFE_MR (AFEC_MR_ONE | \
AFE_MR_PRESCAL (pclk / (ADC_FREQ_MAX) -1) | \
AFE_MR_TRANSFER(2) | \
AFE_MR_STARTUP_SUT64)
#define CFG_AFE_ACR (AFE_ACR_IBCTL(1) | AFEC_ACR_PGA0EN | AFEC_ACR_PGA1EN)
#define CFG_AFE_IDR 0x47000FFF
#define CFG_AFE_COCR (0x200 & AFE_COCR_AOFF_Msk)
#endif
static inline struct gpio_adc static inline struct gpio_adc
pin_to_gpio_adc(uint8_t pin) pin_to_gpio_adc(uint8_t pin)
@ -73,19 +108,14 @@ init_afec(Afec* afec) {
// Configure afec // Configure afec
uint32_t pclk = get_pclock_frequency(afec == AFEC0 ? ID_AFEC0 : ID_AFEC1); uint32_t pclk = get_pclock_frequency(afec == AFEC0 ? ID_AFEC0 : ID_AFEC1);
afec->AFE_MR = AFE_MR_ANACH_ALLOWED | \ afec->AFE_MR = CFG_AFE_MR;
AFE_MR_PRESCAL(pclk / (2 * ADC_FREQ_MAX) - 1) | \
AFE_MR_SETTLING_AST3 | \
AFE_MR_TRACKTIM(2) | \
AFE_MR_TRANSFER(1) | \
AFE_MR_STARTUP_SUT64;
afec->AFE_EMR = AFE_EMR_TAG | \ afec->AFE_EMR = AFE_EMR_TAG | \
AFE_EMR_RES_NO_AVERAGE | \ AFE_EMR_RES_NO_AVERAGE | \
AFE_EMR_STM; AFE_EMR_STM;
afec->AFE_ACR = AFE_ACR_IBCTL(1); afec->AFE_ACR = CFG_AFE_MR;
// Disable interrupts // Disable interrupts
afec->AFE_IDR = 0xDF00803F; afec->AFE_IDR = CFG_AFE_IDR;
// Disable SW triggering // Disable SW triggering
uint32_t mr = afec->AFE_MR; uint32_t mr = afec->AFE_MR;
@ -123,23 +153,25 @@ gpio_adc_setup(uint8_t pin)
afec->AFE_DIFFR = reg; afec->AFE_DIFFR = reg;
reg = afec->AFE_CGR; reg = afec->AFE_CGR;
reg &= ~(0x03u << (2 * afec_chan)); reg &= ~(0x03u << (2 * afec_chan));
reg |= 1 << (2 * afec_chan);
afec->AFE_CGR = reg; afec->AFE_CGR = reg;
// Configure channel // Configure channel
// afec_ch_get_config_defaults(&ch_cfg); // afec_ch_get_config_defaults(&ch_cfg);
// afec_ch_set_config(afec, afec_chan, &ch_cfg); // afec_ch_set_config(afec, afec_chan, &ch_cfg);
// Remove default internal offset from channel // Remove default internal offset from channel
// See Atmel Appnote AT03078 Section 1.5 // See Atmel Appnote AT03078 Section 1.5 for SAM4E,
// datasheet section 52.6.11 for SAME70
afec->AFE_CSELR = afec_chan; afec->AFE_CSELR = afec_chan;
afec->AFE_COCR = (0x800 & AFE_COCR_AOFF_Msk); afec->AFE_COCR = CFG_AFE_COCR;
// Enable and calibrate Channel // Enable and calibrate Channel
afec->AFE_CHER = 1 << afec_chan; afec->AFE_CHER = 1 << afec_chan;
#if CONFIG_MACH_SAM4E
reg = afec->AFE_CHSR; reg = afec->AFE_CHSR;
afec->AFE_CDOR = reg; afec->AFE_CDOR = reg;
afec->AFE_CR = AFE_CR_AUTOCAL; afec->AFE_CR = AFE_CR_AUTOCAL;
#endif
return adc_pin; return adc_pin;
} }

38
src/atsam/same70_afec.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __SAME70_AFEC_H
#define __SAME70_AFEC_H
// A series of redefinitions as upstream changed the name of the peripheral
#define AFE_ACR AFEC_ACR
#define AFE_ACR_IBCTL AFEC_ACR_IBCTL
#define AFE_CDR AFEC_CDR
#define AFE_CGR AFEC_CGR
#define AFE_CHDR AFEC_CHDR
#define AFE_CHER AFEC_CHER
#define AFE_COCR AFEC_COCR
#define AFE_COCR_AOFF_Msk AFEC_COCR_AOFF_Msk
#define AFE_CR AFEC_CR
#define AFE_CR_START AFEC_CR_START
#define AFE_CR_SWRST AFEC_CR_SWRST
#define AFE_DIFFR AFEC_DIFFR
#define AFE_DUMMY AFEC_DUMMY
#define AFE_EMR AFEC_EMR
#define AFE_EMR_RES_NO_AVERAGE AFEC_EMR_RES_NO_AVERAGE
#define AFE_EMR_STM AFEC_EMR_STM
#define AFE_EMR_TAG AFEC_EMR_TAG
#define AFE_IDR AFEC_IDR
#define AFE_ISR AFEC_ISR
#define AFE_LCDR AFEC_LCDR
#define AFE_LCDR_LDATA_Msk AFEC_LCDR_LDATA_Msk
#define AFE_MR_FREERUN_ON AFEC_MR_FREERUN_ON
#define AFE_MR_PRESCAL AFEC_MR_PRESCAL
#define AFE_MR_STARTUP_SUT64 AFEC_MR_STARTUP_SUT64
#define AFE_MR_TRANSFER AFEC_MR_TRANSFER
#define AFE_MR_TRGEN AFEC_MR_TRGEN
#define AFE_MR_TRGEN_DIS AFEC_MR_TRGEN_DIS
#define AFE_MR_TRGSEL_Msk AFEC_MR_TRGSEL_Msk
#define AFE_ISR_DRDY AFEC_ISR_DRDY
#define AFE_MR AFEC_MR
#define AFE_CSELR AFEC_CSELR
#define AFE_CHSR AFEC_CHSR
#endif // same70_afec.h

33
src/atsam/same70_i2c.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef __SAME70_I2C_H
#define __SAME70_I2C_H
// A series of redefinitions as upstream changed the name of the peripheral
#define Twi Twihs
#define TWI_CR TWIHS_CR
#define TWI_CR_MSDIS TWIHS_CR_MSDIS
#define TWI_CR_MSEN TWIHS_CR_MSEN
#define TWI_CR_START TWIHS_CR_START
#define TWI_CR_STOP TWIHS_CR_STOP
#define TWI_CR_SVDIS TWIHS_CR_SVDIS
#define TWI_CR_SWRST TWIHS_CR_SWRST
#define TWI_CWGR TWIHS_CWGR
#define TWI_CWGR_CHDIV TWIHS_CWGR_CHDIV
#define TWI_CWGR_CKDIV TWIHS_CWGR_CKDIV
#define TWI_CWGR_CLDIV TWIHS_CWGR_CLDIV
#define TWI_IADR TWIHS_IADR
#define TWI_IDR TWIHS_IDR
#define TWI_MMR TWIHS_MMR
#define TWI_MMR_DADR TWIHS_MMR_DADR
#define TWI_MMR_IADRSZ_Msk TWIHS_MMR_IADRSZ_Msk
#define TWI_MMR_IADRSZ_Pos TWIHS_MMR_IADRSZ_Pos
#define TWI_MMR_MREAD TWIHS_MMR_MREAD
#define TWI_RHR TWIHS_RHR
#define TWI_SR TWIHS_SR
#define TWI_SR_NAC TWIHS_SR_NACK
#define TWI_SR_NACK TWIHS_SR_NACK
#define TWI_SR_RXRDY TWIHS_SR_RXRDY
#define TWI_SR_TXCOMP TWIHS_SR_TXCOMP
#define TWI_SR_TXRDY TWIHS_SR_TXRDY
#define TWI_THR TWIHS_THR
#endif // same70_i2c.h

View File

@ -0,0 +1,74 @@
// This code is from lib/sam4e/gcc/system_sam4e.c and modified for the SAM E70
#include "internal.h"
/* Clock Settings (300MHz) */
#define SYS_BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8U))
#define SYS_BOARD_PLLAR (CKGR_PLLAR_ONE \
| CKGR_PLLAR_MULA(0x18U) \
| CKGR_PLLAR_PLLACOUNT(0x3fU) \
| CKGR_PLLAR_DIVA_BYPASS)
#define SYS_BOARD_MCKR (PMC_MCKR_MDIV_PCK_DIV2 | PMC_MCKR_CSS_PLLA_CLK)
/* Key to unlock MOR register */
#define SYS_CKGR_MOR_KEY_VALUE CKGR_MOR_KEY(0x37)
uint32_t SystemCoreClock = CHIP_FREQ_MAINCK_RC_12MHZ;
void SystemInit( void )
{
/* Set FWS according to SYS_BOARD_MCKR configuration */
EFC->EEFC_FMR = EEFC_FMR_FWS(6) | EEFC_FMR_CLOE;
/* Initialize main oscillator */
if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
{
PMC->CKGR_MOR = (SYS_CKGR_MOR_KEY_VALUE | SYS_BOARD_OSCOUNT
| CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN);
while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) )
{
}
}
/* Switch to 3-20MHz Xtal oscillator */
PMC->CKGR_MOR = (SYS_CKGR_MOR_KEY_VALUE | SYS_BOARD_OSCOUNT
| CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN
| CKGR_MOR_MOSCSEL);
while ( !(PMC->PMC_SR & PMC_SR_MOSCSELS) )
{
}
PMC->PMC_MCKR = ((PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk)
| PMC_MCKR_CSS_MAIN_CLK);
while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) )
{
}
/* Initialize PLLA */
PMC->CKGR_PLLAR = SYS_BOARD_PLLAR;
while ( !(PMC->PMC_SR & PMC_SR_LOCKA) )
{
}
/* Switch to main clock */
PMC->PMC_MCKR = ((SYS_BOARD_MCKR & ~PMC_MCKR_CSS_Msk)
| PMC_MCKR_CSS_MAIN_CLK);
while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) )
{
}
/* Switch to PLLA */
PMC->PMC_MCKR = SYS_BOARD_MCKR;
while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) )
{
}
SystemCoreClock = CHIP_FREQ_CPU_MAX;
// Configure PCK6 for TC use
PMC->PMC_PCK[6] = PMC_PCK_CSS_MCK | PMC_PCK_PRES(2);
PMC->PMC_SCER = PMC_SCER_PCK6;
}

61
src/atsam/same70_usb.h Normal file
View File

@ -0,0 +1,61 @@
#ifndef __SAME70_USB_H
#define __SAME70_USB_H
// Missing in upstream headers
#define USBHS_RAM_ADDR 0xa0100000u
// A series of redefinitions as upstream changed the name of the peripheral
#define UOTGHS USBHS
#define UOTGHS_RAM_ADDR USBHS_RAM_ADDR
#define ID_UOTGHS ID_USBHS
#define UOTGHS_IRQn USBHS_IRQn
#define UOTGHS_CTRL USBHS_CTRL
#define UOTGHS_CTRL_UIMOD USBHS_CTRL_UIMOD
#define UOTGHS_CTRL_USBE USBHS_CTRL_USBE
#define UOTGHS_DEVCTRL USBHS_DEVCTRL
#define UOTGHS_DEVCTRL_ADDEN USBHS_DEVCTRL_ADDEN
#define UOTGHS_DEVCTRL_SPDCONF_FORCED_FS USBHS_DEVCTRL_SPDCONF_FORCED_FS
#define UOTGHS_DEVEPT USBHS_DEVEPT
#define UOTGHS_DEVEPT_EPEN0 USBHS_DEVEPT_EPEN0
#define UOTGHS_DEVEPTCFG USBHS_DEVEPTCFG
#define UOTGHS_DEVEPTCFG_ALLOC USBHS_DEVEPTCFG_ALLOC
#define UOTGHS_DEVEPTCFG_EPBK_1_BANK USBHS_DEVEPTCFG_EPBK_1_BANK
#define UOTGHS_DEVEPTCFG_EPBK_2_BANK USBHS_DEVEPTCFG_EPBK_2_BANK
#define UOTGHS_DEVEPTCFG_EPDIR_IN USBHS_DEVEPTCFG_EPDIR_IN
#define UOTGHS_DEVEPTCFG_EPSIZE_8_BYTE USBHS_DEVEPTCFG_EPSIZE_8_BYTE
#define UOTGHS_DEVEPTCFG_EPSIZE_16_BYTE USBHS_DEVEPTCFG_EPSIZE_16_BYTE
#define UOTGHS_DEVEPTCFG_EPSIZE_32_BYTE USBHS_DEVEPTCFG_EPSIZE_32_BYTE
#define UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE USBHS_DEVEPTCFG_EPSIZE_64_BYTE
#define UOTGHS_DEVEPTCFG_EPTYPE_BLK USBHS_DEVEPTCFG_EPTYPE_BLK
#define UOTGHS_DEVEPTCFG_EPTYPE_CTRL USBHS_DEVEPTCFG_EPTYPE_CTRL
#define UOTGHS_DEVEPTCFG_EPTYPE_INTRPT USBHS_DEVEPTCFG_EPTYPE_INTRPT
#define UOTGHS_DEVEPTICR USBHS_DEVEPTICR
#define UOTGHS_DEVEPTICR_RXOUTIC USBHS_DEVEPTICR_RXOUTIC
#define UOTGHS_DEVEPTICR_RXSTPIC USBHS_DEVEPTICR_RXSTPIC
#define UOTGHS_DEVEPTICR_TXINIC USBHS_DEVEPTICR_TXINIC
#define UOTGHS_DEVEPTIDR USBHS_DEVEPTIDR
#define UOTGHS_DEVEPTIDR_FIFOCONC USBHS_DEVEPTIDR_FIFOCONC
#define UOTGHS_DEVEPTIDR_RXOUTEC USBHS_DEVEPTIDR_RXOUTEC
#define UOTGHS_DEVEPTIDR_TXINEC USBHS_DEVEPTIDR_TXINEC
#define UOTGHS_DEVEPTIER USBHS_DEVEPTIER
#define UOTGHS_DEVEPTIER_RXOUTES USBHS_DEVEPTIER_RXOUTES
#define UOTGHS_DEVEPTIER_RXSTPES USBHS_DEVEPTIER_RXSTPES
#define UOTGHS_DEVEPTIER_STALLRQS USBHS_DEVEPTIER_STALLRQS
#define UOTGHS_DEVEPTIER_TXINES USBHS_DEVEPTIER_TXINES
#define UOTGHS_DEVEPTISR USBHS_DEVEPTISR
#define UOTGHS_DEVEPTISR_BYCT_Msk USBHS_DEVEPTISR_BYCT_Msk
#define UOTGHS_DEVEPTISR_BYCT_Pos USBHS_DEVEPTISR_BYCT_Pos
#define UOTGHS_DEVEPTISR_RXOUTI USBHS_DEVEPTISR_RXOUTI
#define UOTGHS_DEVEPTISR_RXSTPI USBHS_DEVEPTISR_RXSTPI
#define UOTGHS_DEVEPTISR_TXINI USBHS_DEVEPTISR_TXINI
#define UOTGHS_DEVICR USBHS_DEVICR
#define UOTGHS_DEVICR_EORSTC USBHS_DEVICR_EORSTC
#define UOTGHS_DEVIDR USBHS_DEVIDR
#define UOTGHS_DEVIER USBHS_DEVIER
#define UOTGHS_DEVIER_EORSTES USBHS_DEVIER_EORSTES
#define UOTGHS_DEVIER_PEP_0 USBHS_DEVIER_PEP_0
#define UOTGHS_DEVISR USBHS_DEVISR
#define UOTGHS_DEVISR_EORST USBHS_DEVISR_EORST
#define UOTGHS_DEVISR_PEP_0 USBHS_DEVISR_PEP_0
#endif // same70_usb.h

View File

@ -17,19 +17,29 @@
static Uart * const Port = UART; static Uart * const Port = UART;
static const uint32_t Pmc_id = ID_UART; static const uint32_t Pmc_id = ID_UART;
static const uint32_t rx_pin = GPIO('A', 8), tx_pin = GPIO('A', 9); static const uint32_t rx_pin = GPIO('A', 8), tx_pin = GPIO('A', 9);
static const char uart_periph = 'A';
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA8,PA9"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA8,PA9");
#elif CONFIG_MACH_SAM4S #elif CONFIG_MACH_SAM4S
#define UARTx_IRQn UART1_IRQn #define UARTx_IRQn UART1_IRQn
static Uart * const Port = UART1; static Uart * const Port = UART1;
static const uint32_t Pmc_id = ID_UART1; static const uint32_t Pmc_id = ID_UART1;
static const uint32_t rx_pin = GPIO('B', 2), tx_pin = GPIO('B', 3); static const uint32_t rx_pin = GPIO('B', 2), tx_pin = GPIO('B', 3);
static const char uart_periph = 'A';
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB2,PB3"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB2,PB3");
#elif CONFIG_MACH_SAM4E #elif CONFIG_MACH_SAM4E
#define UARTx_IRQn UART0_IRQn #define UARTx_IRQn UART0_IRQn
static Uart * const Port = UART0; static Uart * const Port = UART0;
static const uint32_t Pmc_id = ID_UART0; static const uint32_t Pmc_id = ID_UART0;
static const uint32_t rx_pin = GPIO('A', 9), tx_pin = GPIO('A', 10); static const uint32_t rx_pin = GPIO('A', 9), tx_pin = GPIO('A', 10);
static const char uart_periph = 'A';
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA9,PA10"); DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA9,PA10");
#elif CONFIG_MACH_SAME70
#define UARTx_IRQn UART2_IRQn
static Uart * const Port = UART2;
static const uint32_t Pmc_id = ID_UART2;
static const uint32_t rx_pin = GPIO('D', 25), tx_pin = GPIO('D', 26);
static const char uart_periph = 'C';
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PD25,PD26");
#endif #endif
void void
@ -57,8 +67,8 @@ serial_enable_tx_irq(void)
void void
serial_init(void) serial_init(void)
{ {
gpio_peripheral(rx_pin, 'A', 1); gpio_peripheral(rx_pin, uart_periph, 1);
gpio_peripheral(tx_pin, 'A', 0); gpio_peripheral(tx_pin, uart_periph, 0);
// Reset uart // Reset uart
enable_pclock(Pmc_id); enable_pclock(Pmc_id);

View File

@ -11,6 +11,11 @@
#include "internal.h" // gpio_peripheral #include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown #include "sched.h" // sched_shutdown
#if CONFIG_MACH_SAME70 // Fixes for upstream header changes
#define US_MR_CHMODE_NORMAL US_MR_USART_CHMODE_NORMAL
#define US_MR_CPHA US_MR_SPI_CPHA
#define US_MR_CPOL US_MR_SPI_CPOL
#endif
/**************************************************************** /****************************************************************
* SPI/USART buses and pins * SPI/USART buses and pins
@ -19,7 +24,7 @@
struct spi_info { struct spi_info {
void *dev; void *dev;
uint32_t dev_id; uint32_t dev_id;
uint8_t miso_pin, mosi_pin, sck_pin, rxtx_periph, sck_periph; uint8_t miso_pin, mosi_pin, sck_pin, rx_periph, tx_periph, sck_periph;
}; };
#if CONFIG_MACH_SAM3X #if CONFIG_MACH_SAM3X
@ -41,22 +46,50 @@ DECL_ENUMERATION_RANGE("spi_bus", "usart0", 1, 2);
DECL_CONSTANT_STR("BUS_PINS_spi", "PA12,PA13,PA14"); DECL_CONSTANT_STR("BUS_PINS_spi", "PA12,PA13,PA14");
DECL_CONSTANT_STR("BUS_PINS_usart0", "PB0,PB1,PB13"); DECL_CONSTANT_STR("BUS_PINS_usart0", "PB0,PB1,PB13");
DECL_CONSTANT_STR("BUS_PINS_usart1", "PA21,PA22,PA23"); DECL_CONSTANT_STR("BUS_PINS_usart1", "PA21,PA22,PA23");
#elif CONFIG_MACH_SAME70
DECL_ENUMERATION_RANGE("spi_bus", "spi0", 0, 2);
DECL_ENUMERATION_RANGE("spi_bus", "usart0", 2, 3);
DECL_CONSTANT_STR("BUS_PINS_spi0", "PD20,PD21,PD22");
DECL_CONSTANT_STR("BUS_PINS_usart0", "PB0,PB1,PB13");
DECL_CONSTANT_STR("BUS_PINS_usart1", "PA21,PB4,PA23");
DECL_CONSTANT_STR("BUS_PINS_usart2", "PD15,PD16,PD17");
#endif #endif
static const struct spi_info spi_bus[] = { static const struct spi_info spi_bus[] = {
#if CONFIG_MACH_SAM3X #if CONFIG_MACH_SAM3X
{ SPI0, ID_SPI0, GPIO('A', 25), GPIO('A', 26), GPIO('A', 27), 'A', 'A' }, { SPI0, ID_SPI0,
{ USART0, ID_USART0, GPIO('A', 10), GPIO('A', 11), GPIO('A', 17), 'A', 'B'}, GPIO('A', 25), GPIO('A', 26), GPIO('A', 27), 'A', 'A', 'A'},
{ USART1, ID_USART1, GPIO('A', 12), GPIO('A', 13), GPIO('A', 16), 'A', 'A'}, { USART0, ID_USART0,
{ USART2, ID_USART2, GPIO('B', 21), GPIO('B', 20), GPIO('B', 24), 'A', 'A'}, GPIO('A', 10), GPIO('A', 11), GPIO('A', 17), 'A', 'A', 'B'},
{ USART1, ID_USART1,
GPIO('A', 12), GPIO('A', 13), GPIO('A', 16), 'A', 'A', 'A'},
{ USART2, ID_USART2,
GPIO('B', 21), GPIO('B', 20), GPIO('B', 24), 'A', 'A', 'A'},
#elif CONFIG_MACH_SAM4S #elif CONFIG_MACH_SAM4S
{ SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' }, { SPI, ID_SPI,
{ USART0, ID_USART0, GPIO('A', 5), GPIO('A', 6), GPIO('A', 2), 'A', 'B' }, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A', 'A'},
{ USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'}, { USART0, ID_USART0,
GPIO('A', 5), GPIO('A', 6), GPIO('A', 2), 'A', 'A', 'B'},
{ USART1, ID_USART1,
GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A', 'A'},
#elif CONFIG_MACH_SAM4E #elif CONFIG_MACH_SAM4E
{ SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' }, { SPI, ID_SPI,
{ USART0, ID_USART0, GPIO('B', 0), GPIO('B', 1), GPIO('B', 13), 'C', 'C' }, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A', 'A'},
{ USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'}, { USART0, ID_USART0,
GPIO('B', 0), GPIO('B', 1), GPIO('B', 13), 'C', 'C', 'C'},
{ USART1, ID_USART1,
GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A', 'A'},
#elif CONFIG_MACH_SAME70
{ SPI0, ID_SPI0,
GPIO('D', 20), GPIO('D', 21), GPIO('D', 22), 'B', 'B', 'B'},
{ SPI1, ID_SPI1,
GPIO('C', 26), GPIO('C', 27), GPIO('C', 24), 'C', 'C', 'C'},
{ USART0, ID_USART0,
GPIO('B', 0), GPIO('B', 1), GPIO('B', 13), 'C', 'C', 'C'},
{ USART1, ID_USART1,
GPIO('A', 21), GPIO('B', 4), GPIO('A', 23), 'A', 'D', 'A'},
{ USART2, ID_USART2,
GPIO('D', 15), GPIO('D', 16), GPIO('D', 17), 'B', 'B', 'B'},
#endif #endif
}; };
@ -65,6 +98,8 @@ is_spihw(void *dev)
{ {
#if CONFIG_MACH_SAM3X #if CONFIG_MACH_SAM3X
return dev == SPI0; return dev == SPI0;
#elif CONFIG_MACH_SAME70
return (dev == SPI0) || (dev == SPI1);
#else #else
return dev == SPI; return dev == SPI;
#endif #endif
@ -75,8 +110,8 @@ init_pins(uint32_t bus)
{ {
const struct spi_info *si = &spi_bus[bus]; const struct spi_info *si = &spi_bus[bus];
gpio_peripheral(si->sck_pin, si->sck_periph, 0); gpio_peripheral(si->sck_pin, si->sck_periph, 0);
gpio_peripheral(si->miso_pin, si->rxtx_periph, 1); gpio_peripheral(si->miso_pin, si->rx_periph, 1);
gpio_peripheral(si->mosi_pin, si->rxtx_periph, 0); gpio_peripheral(si->mosi_pin, si->tx_periph, 0);
enable_pclock(si->dev_id); enable_pclock(si->dev_id);
} }

View File

@ -0,0 +1,3 @@
# Base config file for Atmel SAME70Q20B ARM processor
CONFIG_MACH_ATSAM=y
CONFIG_MACH_SAME70Q20B=y