diff options
Diffstat (limited to 'src/sam4e8e')
-rw-r--r-- | src/sam4e8e/Kconfig | 30 | ||||
-rw-r--r-- | src/sam4e8e/Makefile | 41 | ||||
-rw-r--r-- | src/sam4e8e/afec.c | 206 | ||||
-rw-r--r-- | src/sam4e8e/gpio.c | 173 | ||||
-rw-r--r-- | src/sam4e8e/gpio.h | 57 | ||||
-rw-r--r-- | src/sam4e8e/i2c.c | 180 | ||||
-rw-r--r-- | src/sam4e8e/internal.h | 13 | ||||
-rw-r--r-- | src/sam4e8e/main.c | 48 | ||||
-rw-r--r-- | src/sam4e8e/sam4_cache.c | 16 | ||||
-rw-r--r-- | src/sam4e8e/serial.c | 56 | ||||
-rw-r--r-- | src/sam4e8e/spi.c | 124 | ||||
-rw-r--r-- | src/sam4e8e/timer.c | 67 |
12 files changed, 0 insertions, 1011 deletions
diff --git a/src/sam4e8e/Kconfig b/src/sam4e8e/Kconfig deleted file mode 100644 index 72e21857..00000000 --- a/src/sam4e8e/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -# Kconfig settings for SAM4e8e processors - -if MACH_SAM4E8E - -config SAM_SELECT - bool - default y - select HAVE_GPIO - select HAVE_GPIO_I2C - select HAVE_GPIO_ADC - select HAVE_GPIO_SPI - select HAVE_GPIO_BITBANGING - -config BOARD_DIRECTORY - string - default "sam4e8e" - -config CLOCK_FREQ - int - default 60000000 # 120000000/2 - -config SERIAL - bool - default y -config SERIAL_BAUD - depends on SERIAL - int "Baud rate for serial port" - default 250000 - -endif diff --git a/src/sam4e8e/Makefile b/src/sam4e8e/Makefile deleted file mode 100644 index a80741bf..00000000 --- a/src/sam4e8e/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Additional sam4e8e build rules - -# Setup the toolchain -CROSS_PREFIX=arm-none-eabi- -dirs-y += src/sam4e8e src/generic - -CFLAGS += -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -CFLAGS += -D__SAM4E8E__ - -CFLAGS_klipper.elf += -L lib/sam4e/gcc/gcc -CFLAGS_klipper.elf += -T lib/sam4e/gcc/gcc/sam4e8e_flash.ld -CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs - -dirs-y += lib/sam4e/gcc lib/sam4e/gcc/gcc -CFLAGS += -Ilib/sam4e/include -Ilib/cmsis-core -src-y += ../lib/sam4e/gcc/system_sam4e.c ../lib/sam4e/gcc/gcc/startup_sam4e.c - -src-$(CONFIG_HAVE_GPIO_SPI) += sam4e8e/spi.c -src-$(CONFIG_HAVE_GPIO_I2C) += sam4e8e/i2c.c -src-$(CONFIG_SERIAL) += sam4e8e/serial.c generic/serial_irq.c -src-$(CONFIG_HAVE_GPIO) += sam4e8e/gpio.c sam4e8e/afec.c -src-y += generic/crc16_ccitt.c generic/alloc.c -src-y += generic/armcm_irq.c generic/timer_irq.c -src-y += sam4e8e/main.c sam4e8e/sam4_cache.c sam4e8e/timer.c - -# Build the additional hex output file -target-y += $(OUT)klipper.bin - -$(OUT)klipper.bin: $(OUT)klipper.elf - @echo " Creating bin file $@" - $(Q)$(OBJCOPY) -O binary $< $@ - -# Flash rules -lib/bossac/bin/bossac: - @echo " Building bossac" - $(Q)make -C lib/bossac bin/bossac - -flash: $(OUT)klipper.bin lib/bossac/bin/bossac - @echo " Flashing $^ to $(FLASH_DEVICE) via bossac" - $(Q)if [ -z $(FLASH_DEVICE) ]; then echo "Please specify FLASH_DEVICE"; exit 1; fi - $(Q)lib/bossac/bin/bossac -U -p "$(FLASH_DEVICE)" -e -w $(OUT)klipper.bin -v -b -R diff --git a/src/sam4e8e/afec.c b/src/sam4e8e/afec.c deleted file mode 100644 index 69205c50..00000000 --- a/src/sam4e8e/afec.c +++ /dev/null @@ -1,206 +0,0 @@ -// SAM4e8e Analog Front-End Converter (AFEC) support -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#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 "sched.h" // sched_shutdown - -static const uint8_t afec_pins[] = { - //remove first channel, since it offsets the channel number: GPIO('A', 8), - 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), - GPIO('C', 31), GPIO('C', 26), GPIO('C', 27), GPIO('C',0), - // 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), -}; - -#define AFEC1_START 15 // The first 15 pins are on afec0 - -static inline struct gpio_adc -pin_to_gpio_adc(uint8_t pin) -{ - int chan; - for (chan=0; ; chan++) { - if (chan >= ARRAY_SIZE(afec_pins)) - shutdown("Not a valid ADC pin"); - if (afec_pins[chan] == pin) { - break; - } - } - return (struct gpio_adc){ .chan=chan }; -} - -static inline Afec * -gpio_adc_to_afec(struct gpio_adc g) -{ - return (g.chan >= AFEC1_START ? AFEC1 : AFEC0); -} - -static inline uint32_t -gpio_adc_to_afec_chan(struct gpio_adc g) -{ - return (g.chan >= AFEC1_START ? g.chan - AFEC1_START : g.chan); -} - -#define ADC_FREQ_MAX 6000000UL -DECL_CONSTANT(ADC_MAX, 4095); - -static int -init_afec(Afec* afec) { - - // Enable PMC - if (afec == AFEC0) - PMC->PMC_PCER0 = 1 << ID_AFEC0; - else - PMC->PMC_PCER0 = 1 << ID_AFEC1; - - // If busy, return busy - if ((afec->AFE_ISR & AFE_ISR_DRDY) == AFE_ISR_DRDY) { - return -1; - } - - // Reset - afec->AFE_CR = AFE_CR_SWRST; - - // Configure afec - afec->AFE_MR = AFE_MR_ANACH_ALLOWED | \ - AFE_MR_PRESCAL (SystemCoreClock / (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 | \ - AFE_EMR_RES_NO_AVERAGE | \ - AFE_EMR_STM; - afec->AFE_ACR = AFE_ACR_IBCTL(1); - - // Disable interrupts - afec->AFE_IDR = 0xDF00803F; - - // Disable SW triggering - uint32_t mr = afec->AFE_MR; - - mr &= ~(AFE_MR_TRGSEL_Msk | AFE_MR_TRGEN | AFE_MR_FREERUN_ON); - mr |= AFE_MR_TRGEN_DIS; - afec->AFE_MR = mr; - - return 0; -} - -void -gpio_afec_init(void) { - - while(init_afec(AFEC0) != 0) { - (void)(AFEC0->AFE_LCDR & AFE_LCDR_LDATA_Msk); - } - while(init_afec(AFEC1) != 0) { - (void)(AFEC1->AFE_LCDR & AFE_LCDR_LDATA_Msk); - } - -} -DECL_INIT(gpio_afec_init); - -struct gpio_adc -gpio_adc_setup(uint8_t pin) -{ - struct gpio_adc adc_pin = pin_to_gpio_adc(pin); - Afec *afec = gpio_adc_to_afec(adc_pin); - uint32_t afec_chan = gpio_adc_to_afec_chan(adc_pin); - - //config channel - uint32_t reg = afec->AFE_DIFFR; - reg &= ~(1u << afec_chan); - 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 - afec->AFE_CSELR = afec_chan; - afec->AFE_COCR = (0x800 & AFE_COCR_AOFF_Msk); - - // Enable and calibrate Channel - afec->AFE_CHER = 1 << afec_chan; - - reg = afec->AFE_CHSR; - afec->AFE_CDOR = reg; - afec->AFE_CR = AFE_CR_AUTOCAL; - - return adc_pin; -} - -enum { AFE_DUMMY=0xff }; -uint8_t active_channel = AFE_DUMMY; - -// Try to sample a value. Returns zero if sample ready, otherwise -// returns the number of clock ticks the caller should wait before -// retrying this function. -uint32_t -gpio_adc_sample(struct gpio_adc g) -{ - Afec *afec = gpio_adc_to_afec(g); - uint32_t afec_chan = gpio_adc_to_afec_chan(g); - if (active_channel == g.chan) { - if ((afec->AFE_ISR & AFE_ISR_DRDY) - && (afec->AFE_ISR & (1 << afec_chan))) { - // Sample now ready - return 0; - } else { - // Busy - goto need_delay; - } - } else if (active_channel != AFE_DUMMY) { - goto need_delay; - } - - afec->AFE_CHDR = 0x803F; // Disable all channels - afec->AFE_CHER = 1 << afec_chan; - - active_channel = g.chan; - - for (uint32_t chan = 0; chan < 16; ++chan) - { - if ((afec->AFE_ISR & (1 << chan)) != 0) - { - afec->AFE_CSELR = chan; - (void)(afec->AFE_CDR); - } - } - afec->AFE_CR = AFE_CR_START; - -need_delay: - return ADC_FREQ_MAX * 10000ULL / CONFIG_CLOCK_FREQ; // about 400 mcu clock cycles or 40 afec cycles -} - -// Read a value; use only after gpio_adc_sample() returns zero -uint16_t -gpio_adc_read(struct gpio_adc g) -{ - Afec *afec = gpio_adc_to_afec(g); - uint32_t afec_chan = gpio_adc_to_afec_chan(g); - active_channel = AFE_DUMMY; - afec->AFE_CSELR = afec_chan; - return afec->AFE_CDR; -} - -// Cancel a sample that may have been started with gpio_adc_sample() -void -gpio_adc_cancel_sample(struct gpio_adc g) -{ - if (active_channel == g.chan) { - active_channel = AFE_DUMMY; - } -} diff --git a/src/sam4e8e/gpio.c b/src/sam4e8e/gpio.c deleted file mode 100644 index 3e2c9796..00000000 --- a/src/sam4e8e/gpio.c +++ /dev/null @@ -1,173 +0,0 @@ -// SAM4e8e GPIO port -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "board/irq.h" // irq_save -#include "command.h" // shutdown -#include "gpio.h" // gpio_out_setup -#include "internal.h" // gpio_peripheral -#include "sam4e.h" // Pio -#include "sched.h" // sched_shutdown - -static Pio * const digital_regs[] = { - PIOA, PIOB, PIOC, PIOD, PIOE -}; - - -/**************************************************************** - * Pin multiplexing - ****************************************************************/ - -void -gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up) -{ - uint32_t bank = GPIO2PORT(gpio), bit = GPIO2BIT(gpio); - Pio *regs = digital_regs[bank]; - regs ->PIO_IDR = bit; - - // Enable peripheral for pin - uint32_t sr; - - switch (ptype) { - case 'A': - sr = regs->PIO_ABCDSR[0]; - regs->PIO_ABCDSR[0] &= (~bit & sr); - sr = regs->PIO_ABCDSR[1]; - regs->PIO_ABCDSR[1] &= (~bit & sr); - break; - case 'B': - sr = regs->PIO_ABCDSR[0]; - regs->PIO_ABCDSR[0] = (bit | sr); - sr = regs->PIO_ABCDSR[1]; - regs->PIO_ABCDSR[1] &= (~bit & sr); - break; - case 'C': - sr = regs->PIO_ABCDSR[0]; - regs->PIO_ABCDSR[0] &= (~bit & sr); - sr = regs->PIO_ABCDSR[1]; - regs->PIO_ABCDSR[1] = (bit | sr); - break; - case 'D': - sr = regs->PIO_ABCDSR[0]; - regs->PIO_ABCDSR[0] = (bit | sr); - sr = regs->PIO_ABCDSR[1]; - regs->PIO_ABCDSR[1] = (bit | sr); - break; - } - - // Disable pin in IO controller - regs->PIO_PDR = bit; - - // Set pullup - if (pull_up > 0) { - regs->PIO_PUER = bit; - } else { - regs->PIO_PUDR = bit; - } -} - - -/**************************************************************** - * General Purpose Input Output (GPIO) pins - ****************************************************************/ - -struct gpio_out -gpio_out_setup(uint8_t pin, uint8_t val) -{ - if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) - goto fail; - uint32_t port = GPIO2PORT(pin); - Pio *regs = digital_regs[port]; - uint32_t bank_id = ID_PIOA + port; - if ((PMC->PMC_PCSR0 & (1u << bank_id)) == 0) { - PMC->PMC_PCER0 = 1 << bank_id; - } - struct gpio_out g = { .regs=regs, .bit=GPIO2BIT(pin) }; - gpio_out_reset(g, val); - return g; -fail: - shutdown("Not an output pin"); -} - -void -gpio_out_reset(struct gpio_out g, uint8_t val) -{ - Pio *regs = g.regs; - irqstatus_t flag = irq_save(); - if (val) - regs->PIO_SODR = g.bit; - else - regs->PIO_CODR = g.bit; - regs->PIO_OER = g.bit; - regs->PIO_OWER = g.bit; - regs->PIO_PER = g.bit; - regs->PIO_PUDR = g.bit; - irq_restore(flag); -} - -void -gpio_out_toggle_noirq(struct gpio_out g) -{ - Pio *regs = g.regs; - regs->PIO_ODSR ^= g.bit; -} - -void -gpio_out_toggle(struct gpio_out g) -{ - irqstatus_t flag = irq_save(); - gpio_out_toggle_noirq(g); - irq_restore(flag); -} - -void -gpio_out_write(struct gpio_out g, uint8_t val) -{ - Pio *regs = g.regs; - if (val) - regs->PIO_SODR = g.bit; - else - regs->PIO_CODR = g.bit; -} - -struct gpio_in -gpio_in_setup(uint8_t pin, int8_t pull_up) -{ - if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) - goto fail; - uint32_t port = GPIO2PORT(pin); - Pio *regs = digital_regs[port]; - uint32_t bank_id = ID_PIOA + port; - if ((PMC->PMC_PCSR0 & (1u << bank_id)) == 0) { - PMC->PMC_PCER0 = 1 << bank_id; - } - struct gpio_in g = { .regs=regs, .bit=GPIO2BIT(pin) }; - gpio_in_reset(g, pull_up); - return g; -fail: - shutdown("Not an input pin"); -} - -void -gpio_in_reset(struct gpio_in g, int8_t pull_up) -{ - Pio *regs = g.regs; - irqstatus_t flag = irq_save(); - regs->PIO_IDR = g.bit; - if (pull_up) - regs->PIO_PUER = g.bit; - else - regs->PIO_PUDR = g.bit; - regs->PIO_ODR = g.bit; - regs->PIO_PER = g.bit; - irq_restore(flag); -} - -uint8_t -gpio_in_read(struct gpio_in g) -{ - Pio *regs = g.regs; - return !!(regs->PIO_PDSR & g.bit); -} diff --git a/src/sam4e8e/gpio.h b/src/sam4e8e/gpio.h deleted file mode 100644 index a32a59a7..00000000 --- a/src/sam4e8e/gpio.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __SAM4E8E_GPIO_H -#define __SAM4E8E_GPIO_H - -#include <stdint.h> - -struct gpio_out { - uint8_t pin; - void *regs; - uint32_t bit; -}; - -struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val); -void gpio_out_reset(struct gpio_out g, uint8_t val); -void gpio_out_toggle_noirq(struct gpio_out g); -void gpio_out_toggle(struct gpio_out g); -void gpio_out_write(struct gpio_out g, uint8_t val); - -struct gpio_in { - uint8_t pin; - void *regs; - uint32_t bit; -}; - -struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up); -void gpio_in_reset(struct gpio_in g, int8_t pull_up); -uint8_t gpio_in_read(struct gpio_in g); - -struct gpio_adc { - uint32_t chan; -}; - -struct gpio_adc gpio_adc_setup(uint8_t pin); -uint32_t gpio_adc_sample(struct gpio_adc g); -uint16_t gpio_adc_read(struct gpio_adc g); -void gpio_adc_cancel_sample(struct gpio_adc g); - -struct spi_config { - void *sspi; - uint32_t cfg; -}; -struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); -void spi_transfer(struct spi_config config, uint8_t receive_data - , uint8_t len, uint8_t *data); -void spi_prepare(struct spi_config config); - -struct i2c_config { - void *twi; - uint8_t addr; -}; - -struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr); -void i2c_write(struct i2c_config config, - uint8_t write_len, uint8_t *write); -void i2c_read(struct i2c_config config, - uint8_t reg_len, uint8_t *reg, - uint8_t read_len, uint8_t *read); -#endif // gpio.h diff --git a/src/sam4e8e/i2c.c b/src/sam4e8e/i2c.c deleted file mode 100644 index caf05f0a..00000000 --- a/src/sam4e8e/i2c.c +++ /dev/null @@ -1,180 +0,0 @@ -// SAM4 I2C Port -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "autoconf.h" // CONFIG_CLOCK_FREQ -#include "board/misc.h" // timer_from_us -#include "command.h" // shutdown -#include "gpio.h" // i2c_setup -#include "internal.h" // gpio_peripheral -#include "sam4e.h" // TWI0 -#include "sched.h" // sched_shutdown - -// I2C pin definitions -#define TWI0_SCL_GPIO GPIO('A', 4) -#define TWI0_SCL_PERIPH 'A' - -#define TWI0_SDA_GPIO GPIO('A', 3) -#define TWI0_SDA_PERIPH 'A' - -#define TWI1_SCL_GPIO GPIO('B', 5) -#define TWI1_SCL_PERIPH 'A' - -#define TWI1_SDA_GPIO GPIO('B', 4) -#define TWI1_SDA_PERIPH 'A' - -void -i2c_init(Twi *p_twi, uint32_t rate) -{ - uint32_t twi_id = (p_twi == TWI0) ? ID_TWI0 : ID_TWI1; - if ((PMC->PMC_PCSR0 & (1u << twi_id)) == 0) { - PMC->PMC_PCER0 = 1 << twi_id; - } - if (p_twi == TWI0) { - gpio_peripheral(TWI0_SCL_GPIO, TWI0_SCL_PERIPH, 0); - gpio_peripheral(TWI0_SDA_GPIO, TWI0_SDA_PERIPH, 0); - } else { - gpio_peripheral(TWI1_SCL_GPIO, TWI1_SCL_PERIPH, 0); - gpio_peripheral(TWI1_SDA_GPIO, TWI1_SDA_PERIPH, 0); - } - p_twi->TWI_IDR = 0xFFFFFFFF; - (void)p_twi->TWI_SR; - p_twi->TWI_CR = TWI_CR_SWRST; - (void)p_twi->TWI_RHR; - p_twi->TWI_CR = TWI_CR_MSDIS; - p_twi->TWI_CR = TWI_CR_SVDIS; - p_twi->TWI_CR = TWI_CR_MSEN; - - uint32_t cldiv = 0; - uint32_t chdiv = 0; - uint32_t ckdiv = 0; - - cldiv = CONFIG_CLOCK_FREQ / ((rate > 384000 ? 384000 : rate) * 2) - 4; - - while((cldiv > 255) && (ckdiv < 7)) { - ckdiv++; - cldiv /= 2; - } - - if (rate > 348000) { - chdiv = CONFIG_CLOCK_FREQ / ((2 * rate - 384000) * 2) - 4; - while((chdiv > 255) && (ckdiv < 7)) { - ckdiv++; - chdiv /= 2; - } - } else { - chdiv = cldiv; - } - p_twi->TWI_CWGR = TWI_CWGR_CLDIV(cldiv) | \ - TWI_CWGR_CHDIV(chdiv) | \ - TWI_CWGR_CKDIV(ckdiv); -} - -uint32_t -addr_to_u32(uint8_t addr_len, uint8_t *addr) -{ - uint32_t address = addr[0]; - if (addr_len > 1) { - address <<= 8; - address |= addr[1]; - } - if (addr_len > 2) { - address <<= 8; - address |= addr[2]; - } - if (addr_len > 3) { - shutdown("Addresses larger than 3 bytes are not supported"); - } - return address; -} - -struct i2c_config -i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr) -{ - if ((bus > 1) | (rate > 400000)) - shutdown("Invalid i2c_setup parameters!"); - Twi *p_twi = (bus == 0) ? TWI0 : TWI1; - i2c_init(p_twi, rate); - return (struct i2c_config){ .twi=p_twi, .addr=addr}; -} - -void -i2c_write(struct i2c_config config, - uint8_t write_len, uint8_t *write) -{ - Twi *p_twi = config.twi; - uint32_t status; - uint32_t bytes_to_send = write_len; - p_twi->TWI_MMR = TWI_MMR_DADR(config.addr); - for(;;) { - status = p_twi->TWI_SR; - if (status & TWI_SR_NACK) - shutdown("I2C NACK error encountered!"); - if (!(status & TWI_SR_TXRDY)) - continue; - if (!bytes_to_send) - break; - p_twi->TWI_THR = *write++; - bytes_to_send--; - } - p_twi->TWI_CR = TWI_CR_STOP; - while(!(p_twi->TWI_SR& TWI_SR_TXCOMP)) { - } -} - -static void -i2c_wait(Twi* p_twi, uint32_t bit, uint32_t timeout) -{ - for (;;) { - uint32_t flags = p_twi->TWI_SR; - if (flags & bit) - break; - if (!timer_is_before(timer_read_time(), timeout)) - shutdown("I2C timeout occured"); - } -} - -void -i2c_read(struct i2c_config config, - uint8_t reg_len, uint8_t *reg, - uint8_t read_len, uint8_t *read) -{ - Twi *p_twi = config.twi; - uint32_t status; - uint32_t bytes_to_send=read_len; - uint8_t stop = 0; - p_twi->TWI_MMR = 0; - p_twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(config.addr) | - ((reg_len << TWI_MMR_IADRSZ_Pos) & - TWI_MMR_IADRSZ_Msk); - p_twi->TWI_IADR = 0; - p_twi->TWI_IADR = addr_to_u32(reg_len, reg); - if (bytes_to_send == 1) { - p_twi->TWI_CR = TWI_CR_START | TWI_CR_STOP; - stop = 1; - } else { - p_twi->TWI_CR = TWI_CR_START; - stop = 0; - } - while (bytes_to_send > 0) { - status = p_twi->TWI_SR; - if (status & TWI_SR_NACK) { - shutdown("I2C NACK error encountered!"); - } - if (bytes_to_send == 1 && !stop) { - p_twi->TWI_CR = TWI_CR_STOP; - stop = 1; - } - i2c_wait(p_twi, TWI_SR_RXRDY, timer_read_time() + timer_from_us(5000)); - if (!(status & TWI_SR_RXRDY)) { - continue; - } - *read++ = p_twi->TWI_RHR; - bytes_to_send--; - } - while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {} - (void)p_twi->TWI_SR; -} diff --git a/src/sam4e8e/internal.h b/src/sam4e8e/internal.h deleted file mode 100644 index cf0e0f81..00000000 --- a/src/sam4e8e/internal.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __SAM4_INTERNAL_H -#define __SAM4_INTERNAL_H -// Local definitions for sam4 code - -#include <stdint.h> // uint32_t - -#define GPIO(PORT, NUM) (((PORT)-'A') * 32 + (NUM)) -#define GPIO2PORT(PIN) ((PIN) / 32) -#define GPIO2BIT(PIN) (1<<((PIN) % 32)) - -void gpio_peripheral(uint32_t gpio, char ptype, int32_t pull_up); - -#endif // internal.h diff --git a/src/sam4e8e/main.c b/src/sam4e8e/main.c deleted file mode 100644 index f3666075..00000000 --- a/src/sam4e8e/main.c +++ /dev/null @@ -1,48 +0,0 @@ -// SAM4e8e port main entry -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -// CMSIS -#include "sam4e.h" - -// Klipper -#include "command.h" // DECL_CONSTANT -#include "sched.h" // sched_main - -DECL_CONSTANT(MCU, "sam4e8e"); - -#define WDT_PASSWORD 0xA5000000 -#define WDT_SLOW_CLOCK_DIV 128 - -void -watchdog_reset(void) -{ - WDT->WDT_CR = WDT_PASSWORD | WDT_CR_WDRSTT; -} -DECL_TASK(watchdog_reset); - -void -watchdog_init(void) -{ - uint32_t timeout = 500000 / (WDT_SLOW_CLOCK_DIV * 1000000 / 32768UL); - WDT->WDT_MR = WDT_MR_WDRSTEN | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout); -} -DECL_INIT(watchdog_init); - -void -command_reset(uint32_t *args) -{ - NVIC_SystemReset(); -} -DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset"); - -// Main entry point -int -main(void) -{ - SystemInit(); - sched_main(); - return 0; -} diff --git a/src/sam4e8e/sam4_cache.c b/src/sam4e8e/sam4_cache.c deleted file mode 100644 index 75459660..00000000 --- a/src/sam4e8e/sam4_cache.c +++ /dev/null @@ -1,16 +0,0 @@ -// SAM4 cache enable -// -// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "sam4e.h" // CMCC -#include "sched.h" // DECL_INIT - -void -sam4_cache_init(void) -{ - if (!(CMCC->CMCC_SR & CMCC_SR_CSTS)) - CMCC->CMCC_CTRL = CMCC_CTRL_CEN; -} -DECL_INIT(sam4_cache_init); diff --git a/src/sam4e8e/serial.c b/src/sam4e8e/serial.c deleted file mode 100644 index c75623bc..00000000 --- a/src/sam4e8e/serial.c +++ /dev/null @@ -1,56 +0,0 @@ -// SAM4e8e serial port -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "autoconf.h" // CONFIG_SERIAL_BAUD -#include "board/serial_irq.h" // serial_rx_data -#include "internal.h" // gpio_peripheral -#include "sam4e.h" // UART0 -#include "sched.h" // DECL_INIT - -void -serial_init(void) -{ - gpio_peripheral(GPIO('A', 9), 'A', 1); - gpio_peripheral(GPIO('A', 10), 'A', 0); - - // Reset uart - PMC->PMC_PCER0 = 1 << ID_UART0; - UART0->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; - UART0->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS; - UART0->UART_IDR = 0xFFFFFFFF; - - // Enable uart - UART0->UART_MR = (US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO - | UART_MR_CHMODE_NORMAL); - UART0->UART_BRGR = SystemCoreClock / (16 * CONFIG_SERIAL_BAUD); - UART0->UART_IER = UART_IER_RXRDY; - NVIC_EnableIRQ(UART0_IRQn); - NVIC_SetPriority(UART0_IRQn, 0); - UART0->UART_CR = UART_CR_RXEN | UART_CR_TXEN; -} -DECL_INIT(serial_init); - -void __visible -UART0_Handler(void) -{ - uint32_t status = UART0->UART_SR; - if (status & UART_SR_RXRDY) - serial_rx_byte(UART0->UART_RHR); - if (status & UART_SR_TXRDY) { - uint8_t data; - int ret = serial_get_tx_byte(&data); - if (ret) - UART0->UART_IDR = UART_IDR_TXRDY; - else - UART0->UART_THR = data; - } -} - -void -serial_enable_tx_irq(void) -{ - UART0->UART_IER = UART_IDR_TXRDY; -} diff --git a/src/sam4e8e/spi.c b/src/sam4e8e/spi.c deleted file mode 100644 index 0fa9d3ca..00000000 --- a/src/sam4e8e/spi.c +++ /dev/null @@ -1,124 +0,0 @@ -// SAM4e8e SPI port -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "autoconf.h" // CONFIG_CLOCK_FREQ -#include "command.h" // shutdown -#include "gpio.h" // spi_setup -#include "internal.h" // gpio_peripheral -#include "sam4e.h" // USART0 -#include "sched.h" // sched_shutdown - -#define SSPI_USART0 0 -#define SSPI_USART1 1 -#define SSPI_SPI 2 - -struct spi_config -spi_setup(uint32_t bus, uint8_t mode, uint32_t rate) -{ - Usart *p_usart = USART0; - if (bus > 2) { - shutdown("Invalid spi_setup parameters"); - } - - if (bus == SSPI_USART0) { - // DUET_USART0_SCK as per dc42 CoreNG - gpio_peripheral(GPIO('B', 13), 'C', 0); - // DUET_USART0_MOSI as per dc42 CoreNG - gpio_peripheral(GPIO('B', 1), 'C', 0); - // DUET_USART0_MISO as per dc42 CoreNG - gpio_peripheral(GPIO('B', 0), 'C', 1); - - if ((PMC->PMC_PCSR0 & (1u << ID_USART0)) == 0) { - PMC->PMC_PCER0 = 1 << ID_USART0; - } - p_usart = USART0; - } else if (bus == SSPI_USART1) { - // DUET_USART1_SCK as per dc42 CoreNG - gpio_peripheral(GPIO('A', 23), 'A', 0); - // DUET_USART1_MOSI as per dc42 CoreNG - gpio_peripheral(GPIO('A', 22), 'A', 0); - // DUET_USART1_MISO as per dc42 CoreNG - gpio_peripheral(GPIO('A', 21), 'A', 1); - - if ((PMC->PMC_PCSR0 & (1u << ID_USART1)) == 0) { - PMC->PMC_PCER0 = 1 << ID_USART1; - } - p_usart = USART1; - } - - if (bus < 2) { - p_usart->US_MR = 0; - p_usart->US_RTOR = 0; - p_usart->US_TTGR = 0; - - p_usart->US_CR = US_CR_RSTTX | US_CR_RSTRX | US_CR_TXDIS | US_CR_RXDIS; - - uint32_t br = (CONFIG_CLOCK_FREQ + rate / 2) / rate; - p_usart-> US_BRGR = br << US_BRGR_CD_Pos; - - uint32_t reg = US_MR_CHRL_8_BIT | - US_MR_USART_MODE_SPI_MASTER | - US_MR_CLKO | - US_MR_CHMODE_NORMAL; - switch (mode) { - case 0: - reg |= US_MR_CPHA; - reg &= ~US_MR_CPOL; - break; - case 1: - reg &= ~US_MR_CPHA; - reg &= ~US_MR_CPOL; - break; - case 2: - reg |= US_MR_CPHA; - reg |= US_MR_CPOL; - break; - case 3: - reg &= ~US_MR_CPHA; - reg |= US_MR_CPOL; - break; - } - - p_usart->US_MR |= reg; - p_usart->US_CR = US_CR_RXEN | US_CR_TXEN; - return (struct spi_config){ .sspi=p_usart, .cfg=p_usart->US_MR }; - } - - // True SPI implementation still ToDo - return (struct spi_config){ .sspi = 0, .cfg=0}; -} - -void -spi_transfer(struct spi_config config, uint8_t receive_data - , uint8_t len, uint8_t *data) -{ - if ((config.sspi == USART0) || (config.sspi == USART1)) { - Usart *p_usart = config.sspi; - if (receive_data) { - for (uint32_t i = 0; i < len; ++i) { - uint32_t co = (uint32_t)*data & 0x000000FF; - while(!(p_usart->US_CSR & US_CSR_TXRDY)) {} - p_usart->US_THR = US_THR_TXCHR(co); - uint32_t ci = 0; - while(!(p_usart->US_CSR & US_CSR_RXRDY)) {} - ci = p_usart->US_RHR & US_RHR_RXCHR_Msk; - *data++ = (uint8_t)ci; - } - } else { - for (uint32_t i = 0; i < len; ++i) { - uint32_t co = (uint32_t)*data & 0x000000FF; - while(!(p_usart->US_CSR & US_CSR_TXRDY)) {} - p_usart->US_THR = US_THR_TXCHR(co); - while(!(p_usart->US_CSR & US_CSR_RXRDY)) {} - (void)(p_usart->US_RHR & US_RHR_RXCHR_Msk); - (void)*data++; - } - } - } -} - -void -spi_prepare(struct spi_config config) {} diff --git a/src/sam4e8e/timer.c b/src/sam4e8e/timer.c deleted file mode 100644 index 8115ea8a..00000000 --- a/src/sam4e8e/timer.c +++ /dev/null @@ -1,67 +0,0 @@ -// SAM4e8e timer port -// -// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net> -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -// CMSIS -#include "sam4e.h" -// Klipper -#include "board/irq.h" // irq_disable -#include "board/misc.h" // timer_read_time -#include "board/timer_irq.h" // timer_dispatch_many -#include "sched.h" // DECL_INIT - -// Set the next irq time -static void -timer_set(uint32_t value) -{ - TC0->TC_CHANNEL[0].TC_RA = value; -} - -// Return the current time (in absolute clock ticks). -uint32_t -timer_read_time(void) -{ - return TC0->TC_CHANNEL[0].TC_CV; -} - -// Activate timer dispatch as soon as possible -void -timer_kick(void) -{ - timer_set(timer_read_time() + 50); - TC0->TC_CHANNEL[0].TC_SR; -} - -void -timer_init(void) -{ - if ((PMC->PMC_PCSR0 & (1u << ID_TC0)) == 0) { - PMC->PMC_PCER0 = 1 << ID_TC0; - } - TcChannel *tc_channel = &TC0->TC_CHANNEL[0]; - tc_channel->TC_CCR = TC_CCR_CLKDIS; - tc_channel->TC_IDR = 0xFFFFFFFF; - tc_channel->TC_SR; - tc_channel->TC_CMR = TC_CMR_WAVE | TC_CMR_WAVSEL_UP | TC_CMR_TCCLKS_TIMER_CLOCK1; - tc_channel->TC_IER = TC_IER_CPAS; - NVIC_SetPriority(TC0_IRQn, 1); - NVIC_EnableIRQ(TC0_IRQn); - timer_kick(); - tc_channel->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; -} -DECL_INIT(timer_init); - -// IRQ handler -void __visible __aligned(16) // aligning helps stabilize perf benchmarks -TC0_Handler(void) -{ - irq_disable(); - uint32_t status = TC0->TC_CHANNEL[0].TC_SR; - if (likely(status & TC_SR_CPAS)) { - uint32_t next = timer_dispatch_many(); - timer_set(next); - } - irq_enable(); -} |