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 = [
('rp2040', self.config_rp2040),
('sam3', self.config_sam3), ('sam4', self.config_sam4),
('same70', self.config_same70),
('samd21', self.config_samd21), ('samd51', self.config_samd51),
('stm32f1', self.config_stm32f1), ('stm32f2', self.config_stm32f2),
('stm32f4', self.config_stm32f4),
@ -100,6 +101,9 @@ class PrinterTemperatureMCU:
def config_sam4(self):
self.slope = 3.3 / .004700
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 get1v(val):
if val & 0x80:

View File

@ -286,7 +286,7 @@ def flash_rp2040(options, binfile):
MCUTYPES = {
'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,
'stm32f072': flash_stm32f4, 'rp2040': flash_rp2040
}

View File

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

View File

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

View File

@ -7,14 +7,17 @@ dirs-y += src/atsam src/generic
dirs-$(CONFIG_MACH_SAM3X) += lib/sam3x/gcc
dirs-$(CONFIG_MACH_SAM4S) += lib/sam4s/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)
CFLAGS-$(CONFIG_MACH_SAM3X) += -mcpu=cortex-m3 -falign-loops=16
CFLAGS-$(CONFIG_MACH_SAM4) += -mcpu=cortex-m4
CFLAGS-$(CONFIG_MACH_SAME70) += -mcpu=cortex-m7
CFLAGS-$(CONFIG_MACH_SAM3X) += -Ilib/sam3x/include
CFLAGS-$(CONFIG_MACH_SAM4S) += -Ilib/sam4s/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_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
# 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/crc16_ccitt.c
usb-src-$(CONFIG_MACH_SAM3X) := atsam/sam3_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_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_SAM4E) += atsam/sam4e_afec.c atsam/sam4_cache.c
src-$(CONFIG_MACH_SAM3X) += ../lib/sam3x/gcc/system_sam3xa.c
src-$(CONFIG_MACH_SAM4S) += atsam/sam4s_sysinit.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
target-y += $(OUT)klipper.bin

View File

@ -11,6 +11,11 @@
#include "internal.h" // gpio_peripheral
#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", "PB0", GPIO('B', 0), 32);
#ifdef PIOC
@ -23,16 +28,17 @@ DECL_ENUMERATION_RANGE("pin", "PD0", GPIO('D', 0), 32);
DECL_ENUMERATION_RANGE("pin", "PE0", GPIO('E', 0), 32);
#endif
static Pio * const digital_regs[] = {
PIOA, PIOB,
static const struct gpio_info digital_regs[] = {
{ PIOA, ID_PIOA },
{ PIOB, ID_PIOB },
#ifdef PIOC
PIOC,
{ PIOC, ID_PIOC },
#endif
#ifdef PIOD
PIOD,
{ PIOD, ID_PIOD },
#endif
#ifdef PIOE
PIOE,
{ PIOE, ID_PIOE },
#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
if (regs == PIOB && (bit & 0x1cf0))
MATRIX->CCFG_SYSIO |= bit;
#elif CONFIG_MACH_SAME70
if (regs == PIOB && (bit & 0x10f0))
MATRIX->CCFG_SYSIO |= bit;
#endif
}
@ -72,7 +81,7 @@ void
gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up)
{
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
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))
goto fail;
Pio *regs = digital_regs[GPIO2PORT(pin)];
Pio *regs = digital_regs[GPIO2PORT(pin)].dev;
struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) };
gpio_out_reset(g, val);
return g;
@ -152,8 +161,8 @@ gpio_in_setup(uint8_t pin, int8_t pull_up)
if (CONFIG_MACH_SAM3X && pull_up < 0)
goto fail;
uint32_t port = GPIO2PORT(pin);
enable_pclock(ID_PIOA + port);
struct gpio_in g = { .regs=digital_regs[port], .bit=GPIO2BIT(pin) };
enable_pclock(digital_regs[port].dev_id);
struct gpio_in g = { .regs=digital_regs[port].dev, .bit=GPIO2BIT(pin) };
gpio_in_reset(g, pull_up);
return g;
fail:

View File

@ -11,35 +11,62 @@
#include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown
// I2C pin definitions
DECL_ENUMERATION_RANGE("i2c_bus", "twi0", 0, 2);
#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");
#if CONFIG_MACH_SAME70
#include "same70_i2c.h" // Fixes for upstream header changes
#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
i2c_init(Twi *p_twi, uint32_t rate)
init_pins(uint32_t bus)
{
enable_pclock(p_twi == TWI0 ? ID_TWI0 : ID_TWI1);
if (p_twi == TWI0) {
gpio_peripheral(TWI0_SCL_GPIO, 'A', 1);
gpio_peripheral(TWI0_SDA_GPIO, 'A', 1);
} else {
gpio_peripheral(TWI1_SCL_GPIO, 'A', 1);
gpio_peripheral(TWI1_SDA_GPIO, 'A', 1);
const struct twi_info *si = &twi_bus[bus];
gpio_peripheral(si->scl_pin, si->periph, 1);
gpio_peripheral(si->sda_pin, si->periph, 1);
enable_pclock(si->dev_id);
}
static void
i2c_init(uint32_t bus, uint32_t rate)
{
Twi *p_twi = twi_bus[bus].dev;
p_twi->TWI_IDR = 0xFFFFFFFF;
(void)p_twi->TWI_SR;
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_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;
cldiv = pclk / ((rate > 384000 ? 384000 : rate) * 2) - 4;
cldiv = pclk / ((rate > 384000 ? 384000 : rate) * 2) - PRD_CALC_NUM;
while ((cldiv > 255) && (ckdiv < 7)) {
ckdiv++;
@ -58,7 +85,7 @@ i2c_init(Twi *p_twi, uint32_t rate)
}
if (rate > 348000) {
chdiv = pclk / ((2 * rate - 384000) * 2) - 4;
chdiv = pclk / ((2 * rate - 384000) * 2) - PRD_CALC_NUM;
while ((chdiv > 255) && (ckdiv < 7)) {
ckdiv++;
chdiv /= 2;
@ -91,10 +118,11 @@ addr_to_u32(uint8_t addr_len, uint8_t *addr)
struct i2c_config
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!");
Twi *p_twi = (bus == 0) ? TWI0 : TWI1;
i2c_init(p_twi, rate);
Twi *p_twi = twi_bus[bus].dev;
init_pins(bus);
i2c_init(bus, rate);
return (struct i2c_config){ .twi=p_twi, .addr=addr};
}

View File

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

View File

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

View File

@ -11,6 +11,14 @@
#include "internal.h" // UOTGHS
#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 : \
((s)==32 ? UOTGHS_DEVEPTCFG_EPSIZE_32_BYTE : \
((s)==16 ? UOTGHS_DEVEPTCFG_EPSIZE_16_BYTE : \
@ -216,8 +224,7 @@ usbserial_init(void)
;
// Enable USB
UOTGHS->UOTGHS_CTRL = (UOTGHS_CTRL_UIMOD | UOTGHS_CTRL_OTGPADE
| UOTGHS_CTRL_USBE);
UOTGHS->UOTGHS_CTRL = CFG_UOTGHS_CTRL;
UOTGHS->UOTGHS_DEVCTRL = UOTGHS_DEVCTRL_SPDCONF_FORCED_FS;
// Enable interrupts

View File

@ -7,15 +7,19 @@
#include "autoconf.h" // CONFIG_CLOCK_FREQ
#include "command.h" // shutdown
#include "gpio.h" // gpio_adc_setup
#include "internal.h" // GPIO
#include "sam4e.h" // AFEC0
#include "internal.h" // GPIO, AFEC0
#include "sched.h" // sched_shutdown
#if CONFIG_MACH_SAME70
#include "same70_afec.h" // Fixes for upstream header changes
#endif
#define ADC_TEMPERATURE_PIN 0xfe
DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN);
static const uint8_t afec_pins[] = {
//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', 20), GPIO('B', 0), GPIO('B', 1), GPIO('C', 13),
GPIO('C', 15), GPIO('C', 12), GPIO('C', 29), GPIO('C', 30),
@ -24,9 +28,40 @@ static const uint8_t afec_pins[] = {
// AFEC1
GPIO('B', 2), GPIO('B', 3), GPIO('A', 21), GPIO('A', 22),
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 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
pin_to_gpio_adc(uint8_t pin)
@ -73,19 +108,14 @@ init_afec(Afec* afec) {
// Configure afec
uint32_t pclk = get_pclock_frequency(afec == AFEC0 ? ID_AFEC0 : ID_AFEC1);
afec->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;
afec->AFE_MR = CFG_AFE_MR;
afec->AFE_EMR = AFE_EMR_TAG | \
AFE_EMR_RES_NO_AVERAGE | \
AFE_EMR_STM;
afec->AFE_ACR = AFE_ACR_IBCTL(1);
afec->AFE_ACR = CFG_AFE_MR;
// Disable interrupts
afec->AFE_IDR = 0xDF00803F;
afec->AFE_IDR = CFG_AFE_IDR;
// Disable SW triggering
uint32_t mr = afec->AFE_MR;
@ -123,23 +153,25 @@ gpio_adc_setup(uint8_t pin)
afec->AFE_DIFFR = reg;
reg = afec->AFE_CGR;
reg &= ~(0x03u << (2 * afec_chan));
reg |= 1 << (2 * afec_chan);
afec->AFE_CGR = reg;
// Configure channel
// afec_ch_get_config_defaults(&ch_cfg);
// afec_ch_set_config(afec, afec_chan, &ch_cfg);
// 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_COCR = (0x800 & AFE_COCR_AOFF_Msk);
afec->AFE_COCR = CFG_AFE_COCR;
// Enable and calibrate Channel
afec->AFE_CHER = 1 << afec_chan;
#if CONFIG_MACH_SAM4E
reg = afec->AFE_CHSR;
afec->AFE_CDOR = reg;
afec->AFE_CR = AFE_CR_AUTOCAL;
#endif
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 const uint32_t Pmc_id = ID_UART;
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");
#elif CONFIG_MACH_SAM4S
#define UARTx_IRQn UART1_IRQn
static Uart * const Port = 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 char uart_periph = 'A';
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PB2,PB3");
#elif CONFIG_MACH_SAM4E
#define UARTx_IRQn UART0_IRQn
static Uart * const Port = 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 char uart_periph = 'A';
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
void
@ -57,8 +67,8 @@ serial_enable_tx_irq(void)
void
serial_init(void)
{
gpio_peripheral(rx_pin, 'A', 1);
gpio_peripheral(tx_pin, 'A', 0);
gpio_peripheral(rx_pin, uart_periph, 1);
gpio_peripheral(tx_pin, uart_periph, 0);
// Reset uart
enable_pclock(Pmc_id);

View File

@ -11,6 +11,11 @@
#include "internal.h" // gpio_peripheral
#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
@ -19,7 +24,7 @@
struct spi_info {
void *dev;
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
@ -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_usart0", "PB0,PB1,PB13");
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
static const struct spi_info spi_bus[] = {
#if CONFIG_MACH_SAM3X
{ SPI0, ID_SPI0, GPIO('A', 25), GPIO('A', 26), GPIO('A', 27), 'A', 'A' },
{ USART0, ID_USART0, GPIO('A', 10), GPIO('A', 11), GPIO('A', 17), 'A', 'B'},
{ USART1, ID_USART1, GPIO('A', 12), GPIO('A', 13), GPIO('A', 16), 'A', 'A'},
{ USART2, ID_USART2, GPIO('B', 21), GPIO('B', 20), GPIO('B', 24), 'A', 'A'},
{ SPI0, ID_SPI0,
GPIO('A', 25), GPIO('A', 26), GPIO('A', 27), 'A', 'A', 'A'},
{ USART0, ID_USART0,
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
{ SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' },
{ USART0, ID_USART0, GPIO('A', 5), GPIO('A', 6), GPIO('A', 2), 'A', 'B' },
{ USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'},
{ SPI, ID_SPI,
GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', '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
{ SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' },
{ USART0, ID_USART0, GPIO('B', 0), GPIO('B', 1), GPIO('B', 13), 'C', 'C' },
{ USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'},
{ SPI, ID_SPI,
GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', '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
};
@ -65,6 +98,8 @@ is_spihw(void *dev)
{
#if CONFIG_MACH_SAM3X
return dev == SPI0;
#elif CONFIG_MACH_SAME70
return (dev == SPI0) || (dev == SPI1);
#else
return dev == SPI;
#endif
@ -75,8 +110,8 @@ init_pins(uint32_t bus)
{
const struct spi_info *si = &spi_bus[bus];
gpio_peripheral(si->sck_pin, si->sck_periph, 0);
gpio_peripheral(si->miso_pin, si->rxtx_periph, 1);
gpio_peripheral(si->mosi_pin, si->rxtx_periph, 0);
gpio_peripheral(si->miso_pin, si->rx_periph, 1);
gpio_peripheral(si->mosi_pin, si->tx_periph, 0);
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