diff --git a/src/stm32f1/Kconfig b/src/stm32f1/Kconfig deleted file mode 100644 index c8b04e4c..00000000 --- a/src/stm32f1/Kconfig +++ /dev/null @@ -1,45 +0,0 @@ -# Kconfig settings for STM32F1 processors - -if MACH_STM32F1 - -config STM32F1_SELECT - bool - default y - select HAVE_GPIO - select HAVE_GPIO_ADC - select HAVE_GPIO_SPI - select HAVE_GPIO_BITBANGING - -config BOARD_DIRECTORY - string - default "stm32f1" - -config CLOCK_FREQ - int - default 72000000 - -choice - prompt "Bootloader offset" - config STM_FLASH_START_2000 - bool "8KiB bootloader (stm32duino)" - config STM_FLASH_START_7000 - bool "28KiB bootloader" - config STM_FLASH_START_0000 - bool "No bootloader" -endchoice - -config FLASH_START - hex - default 0x2000 if STM_FLASH_START_2000 - default 0x7000 if STM_FLASH_START_7000 - default 0x0000 - -config USBSERIAL - bool "Use USB for communication (instead of serial)" - default y -config SERIAL - depends on !USBSERIAL - bool - default y - -endif diff --git a/src/stm32f1/Makefile b/src/stm32f1/Makefile deleted file mode 100644 index 2b00b5f0..00000000 --- a/src/stm32f1/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# Additional STM32F1 build rules - -# Setup the toolchain -CROSS_PREFIX=arm-none-eabi- - -dirs-y += src/stm32f1 src/generic -dirs-y += lib/stm32f1 lib/stm32f1/gcc lib/stm32f1/hal/source - -CFLAGS += -mthumb -mcpu=cortex-m3 -CFLAGS += -Ilib/cmsis-core -CFLAGS += -Ilib/stm32f1/include -Ilib/stm32f1/hal/include -CFLAGS += -DSTM32F103xB - -# Add source files -src-y += stm32f1/main.c stm32f1/gpio.c -src-$(CONFIG_HAVE_GPIO_ADC) += stm32f1/adc.c -src-$(CONFIG_HAVE_GPIO_SPI) += stm32f1/spi.c -src-y += $(addprefix ../, $(wildcard lib/stm32f1/hal/source/stm32f1xx_ll_*.c)) -src-y += generic/crc16_ccitt.c generic/armcm_irq.c generic/armcm_timer.c -src-y += ../lib/stm32f1/system_stm32f1xx.c -src-$(CONFIG_USBSERIAL) += stm32f1/usbserial.c generic/usb_cdc.c -src-$(CONFIG_SERIAL) += stm32f1/serial.c generic/serial_irq.c - -# Add assembler build rules -$(OUT)%.o: %.s $(OUT)autoconf.h $(OUT)board-link - @echo " Assembling $@" - $(Q)$(AS) $< -o $@ - -asmsrc-y = ../lib/stm32f1/gcc/startup_stm32f103xb.s -OBJS_klipper.elf += $(patsubst %.s, $(OUT)src/%.o,$(asmsrc-y)) - -# Build the linker script -$(OUT)stm32f1.ld: src/stm32f1/stm32f1.ld $(OUT)board-link - @echo " Preprocessing $@" - $(Q)$(CPP) -P -MD -MT $@ -DFLASH_START=$(CONFIG_FLASH_START) $< -o $@ - -CFLAGS_klipper.elf += -T $(OUT)stm32f1.ld -CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs -$(OUT)klipper.elf : $(OUT)stm32f1.ld - -# Binary output file rules -target-y += $(OUT)klipper.bin - -$(OUT)klipper.bin: $(OUT)klipper.elf - @echo " Creating hex file $@" - $(Q)$(OBJCOPY) -O binary $< $@ - -flash: $(OUT)klipper.bin - @echo " Flashing $< to $(FLASH_DEVICE)" - $(Q)$(PYTHON) ./scripts/flash_usb.py -t stm32f1 -d "$(FLASH_DEVICE)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.bin - -serialflash: $(OUT)klipper.bin - @echo " Flashing $< to $(FLASH_DEVICE) via stm32flash" - $(Q)stm32flash -w $< -v -g 0 $(FLASH_DEVICE) diff --git a/src/stm32f1/adc.c b/src/stm32f1/adc.c deleted file mode 100644 index 47271d3e..00000000 --- a/src/stm32f1/adc.c +++ /dev/null @@ -1,110 +0,0 @@ -// ADC functions on STM32F1 -// -// Copyright (C) 2018 Grigori Goronzy -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include // bool -#include "board/io.h" // readb -#include "command.h" // shutdown -#include "compiler.h" // ARRAY_SIZE -#include "gpio.h" // gpio_adc_setup -#include "internal.h" // GPIO -#include "stm32f1xx_ll_adc.h" // LL_ADC_REG_ReadConversionData12 -#include "stm32f1xx_ll_gpio.h" // LL_GPIO_SetPinMode -#include "sched.h" // sched_shutdown - -DECL_CONSTANT("ADC_MAX", 4095); - -#define ADC_DELAY (240 * 8) - -static bool adc_busy; -static uint32_t adc_current_channel; - -static const uint8_t adc_pins[] = { - GPIO('A', 0), GPIO('A', 1), GPIO('A', 2), GPIO('A', 3), - GPIO('A', 4), GPIO('A', 5), GPIO('A', 6), GPIO('A', 7), - GPIO('B', 0), GPIO('B', 1), GPIO('C', 0), GPIO('C', 1), - GPIO('C', 2), GPIO('C', 3), GPIO('C', 4), GPIO('C', 5) -}; - -static const uint32_t adc_channels[] = { - LL_ADC_CHANNEL_0, - LL_ADC_CHANNEL_1, - LL_ADC_CHANNEL_2, - LL_ADC_CHANNEL_3, - LL_ADC_CHANNEL_4, - LL_ADC_CHANNEL_5, - LL_ADC_CHANNEL_6, - LL_ADC_CHANNEL_7, - LL_ADC_CHANNEL_8, - LL_ADC_CHANNEL_9, - LL_ADC_CHANNEL_10, - LL_ADC_CHANNEL_11, - LL_ADC_CHANNEL_12, - LL_ADC_CHANNEL_13, - LL_ADC_CHANNEL_14, - LL_ADC_CHANNEL_15, -}; - -struct gpio_adc -gpio_adc_setup(uint8_t pin) -{ - // Find pin in adc_pins table - int chan; - for (chan=0; ; chan++) { - if (chan >= ARRAY_SIZE(adc_pins)) - shutdown("Not a valid ADC pin"); - if (adc_pins[chan] == pin) - break; - } - - GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; - uint32_t bit = digital_pins[pin % 16]; - LL_GPIO_SetPinMode(regs, bit, LL_GPIO_MODE_ANALOG); - - return (struct gpio_adc){ .bit = adc_channels[chan] }; -} - -// 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) -{ - /* ADC not busy, start conversion */ - if (!readb(&adc_busy)) { - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, g.bit); - LL_ADC_SetChannelSamplingTime(ADC1, g.bit - , LL_ADC_SAMPLINGTIME_41CYCLES_5); - LL_ADC_REG_StartConversionSWStart(ADC1); - adc_busy = true; - adc_current_channel = g.bit; - return ADC_DELAY; - /* ADC finished conversion for this channel */ - } else if (LL_ADC_IsActiveFlag_EOS(ADC1) && - readl(&adc_current_channel) == g.bit) { - LL_ADC_ClearFlag_EOS(ADC1); - adc_busy = false; - return 0; - } - /* Wants to sample another channel, or not finished yet */ - return ADC_DELAY; -} - -// Read a value; use only after gpio_adc_sample() returns zero -uint16_t -gpio_adc_read(struct gpio_adc g) -{ - return LL_ADC_REG_ReadConversionData12(ADC1); -} - -// Cancel a sample that may have been started with gpio_adc_sample() -void -gpio_adc_cancel_sample(struct gpio_adc g) -{ - if (readb(&adc_busy) && readl(&adc_current_channel) == g.bit) { - adc_busy = false; - LL_ADC_ClearFlag_EOS(ADC1); - } -} diff --git a/src/stm32f1/gpio.c b/src/stm32f1/gpio.c deleted file mode 100644 index ced64cd1..00000000 --- a/src/stm32f1/gpio.c +++ /dev/null @@ -1,135 +0,0 @@ -// GPIO functions on STM32F1 -// -// Copyright (C) 2018 Grigori Goronzy -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "board/irq.h" // irq_save -#include "command.h" // shutdown -#include "compiler.h" // ARRAY_SIZE -#include "gpio.h" // gpio_out_setup -#include "internal.h" // GPIO -#include "stm32f1xx_ll_gpio.h" // LL_GPIO_SetPinMode -#include "sched.h" // sched_shutdown - - -/**************************************************************** - * Pin mappings - ****************************************************************/ - -DECL_ENUMERATION_RANGE("pin", "PA0", GPIO('A', 0), 16); -DECL_ENUMERATION_RANGE("pin", "PB0", GPIO('B', 0), 16); -DECL_ENUMERATION_RANGE("pin", "PC0", GPIO('C', 0), 16); -DECL_ENUMERATION_RANGE("pin", "PD0", GPIO('D', 0), 16); -DECL_ENUMERATION_RANGE("pin", "PE0", GPIO('E', 0), 16); - -GPIO_TypeDef *const digital_regs[] = { - GPIOA, GPIOB, GPIOC, GPIOD, GPIOE -}; - -uint32_t const digital_pins[] = { - LL_GPIO_PIN_0, - LL_GPIO_PIN_1, - LL_GPIO_PIN_2, - LL_GPIO_PIN_3, - LL_GPIO_PIN_4, - LL_GPIO_PIN_5, - LL_GPIO_PIN_6, - LL_GPIO_PIN_7, - LL_GPIO_PIN_8, - LL_GPIO_PIN_9, - LL_GPIO_PIN_10, - LL_GPIO_PIN_11, - LL_GPIO_PIN_12, - LL_GPIO_PIN_13, - LL_GPIO_PIN_14, - LL_GPIO_PIN_15, -}; - -/**************************************************************** - * 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; - GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; - uint32_t bit = digital_pins[pin % 16]; - struct gpio_out g = { .regs=regs, .bit=bit }; - gpio_out_reset(g, val); - return g; -fail: - shutdown("Not an output pin"); -} - -void -gpio_out_reset(struct gpio_out g, uint8_t val) -{ - irqstatus_t flag = irq_save(); - if (val) - LL_GPIO_SetOutputPin(g.regs, g.bit); - else - LL_GPIO_ResetOutputPin(g.regs, g.bit); - LL_GPIO_SetPinMode(g.regs, g.bit, LL_GPIO_MODE_OUTPUT); - irq_restore(flag); -} - -void -gpio_out_toggle_noirq(struct gpio_out g) -{ - LL_GPIO_TogglePin(g.regs, 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) -{ - if (val) - LL_GPIO_SetOutputPin(g.regs, g.bit); - else - LL_GPIO_ResetOutputPin(g.regs, g.bit); -} - - -struct gpio_in -gpio_in_setup(uint8_t pin, int8_t pull_up) -{ - if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs)) - goto fail; - GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)]; - uint32_t bit = digital_pins[pin % 16]; - struct gpio_in g = { .regs = regs, .bit = bit }; - 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) -{ - irqstatus_t flag = irq_save(); - if (pull_up) { - LL_GPIO_SetPinMode(g.regs, g.bit, LL_GPIO_MODE_INPUT); - uint32_t p = pull_up > 0 ? LL_GPIO_PULL_UP : LL_GPIO_PULL_DOWN; - LL_GPIO_SetPinPull(g.regs, g.bit, p); - } else { - LL_GPIO_SetPinMode(g.regs, g.bit, LL_GPIO_MODE_FLOATING); - } - irq_restore(flag); -} - -uint8_t -gpio_in_read(struct gpio_in g) -{ - return LL_GPIO_IsInputPinSet(g.regs, g.bit); -} diff --git a/src/stm32f1/gpio.h b/src/stm32f1/gpio.h deleted file mode 100644 index 8aba2f85..00000000 --- a/src/stm32f1/gpio.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __STM32F1_GPIO_H -#define __STM32F1_GPIO_H - -#include -#include "stm32f1xx.h" - -void gpio_peripheral(char bank, uint32_t bit, char ptype, uint32_t pull_up); - -struct gpio_out { - GPIO_TypeDef *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 { - GPIO_TypeDef *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 bit; -}; -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 { - uint32_t spi_cr1; -}; -struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate); -void spi_prepare(struct spi_config config); -void spi_transfer(struct spi_config config, uint8_t receive_data, - uint8_t len, uint8_t *data); - -#endif // gpio.h diff --git a/src/stm32f1/internal.h b/src/stm32f1/internal.h deleted file mode 100644 index 4c4394fd..00000000 --- a/src/stm32f1/internal.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __STM32F1_INTERNAL_H -#define __STM32F1_INTERNAL_H -// Local definitions for STM32F1 code - -#include "stm32f1xx.h" - -#define GPIO(PORT, NUM) (((PORT)-'A') * 16 + (NUM)) -#define GPIO2PORT(PIN) ((PIN) / 16) - -extern GPIO_TypeDef *const digital_regs[]; -extern uint32_t const digital_pins[]; - -#endif // internal.h diff --git a/src/stm32f1/main.c b/src/stm32f1/main.c deleted file mode 100644 index d9bdbb24..00000000 --- a/src/stm32f1/main.c +++ /dev/null @@ -1,148 +0,0 @@ -// Main starting point for STM32F103 boards. -// -// Copyright (C) 2018 Grigori Goronzy -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "autoconf.h" -#include "board/internal.h" // udelay -#include "board/misc.h" // timer_read_time -#include "command.h" // DECL_CONSTANT -#include "stm32f1xx.h" -#include "stm32f1xx_ll_system.h" -#include "stm32f1xx_ll_utils.h" -#include "stm32f1xx_ll_bus.h" -#include "stm32f1xx_ll_rcc.h" -#include "stm32f1xx_ll_iwdg.h" -#include "stm32f1xx_ll_gpio.h" -#include "stm32f1xx_ll_adc.h" -#include "stm32f1xx_ll_spi.h" -#include "sched.h" // sched_main - -DECL_CONSTANT_STR("MCU", "stm32f103"); - - -/**************************************************************** - * dynamic memory pool - ****************************************************************/ - -static char dynmem_pool[15 * 1024]; - -// Return the start of memory available for dynamic allocations -void * -dynmem_start(void) -{ - return dynmem_pool; -} - -// Return the end of memory available for dynamic allocations -void * -dynmem_end(void) -{ - return &dynmem_pool[sizeof(dynmem_pool)]; -} - - -/**************************************************************** - * watchdog handler - ****************************************************************/ - -void -watchdog_reset(void) -{ - LL_IWDG_ReloadCounter(IWDG); -} -DECL_TASK(watchdog_reset); - -void -watchdog_init(void) -{ - LL_IWDG_EnableWriteAccess(IWDG); - /* IWDG timer is 40 KHz, configure to trigger every seconds */ - LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_16); - LL_IWDG_SetReloadCounter(IWDG, 2500); - LL_IWDG_Enable(IWDG); - -} -DECL_INIT(watchdog_init); - - -/**************************************************************** - * misc functions - ****************************************************************/ - -void -command_reset(uint32_t *args) -{ - NVIC_SystemReset(); -} -DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset"); - -void clock_config(void) -{ - LL_RCC_HSE_Enable(); - while (!LL_RCC_HSE_IsReady()); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLL_MUL_9); - LL_RCC_PLL_Disable(); - LL_RCC_PLL_Enable(); - while (!LL_RCC_PLL_IsReady()); - LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); - LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2); - LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2); - LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_4); - LL_FLASH_SetLatency(LL_FLASH_LATENCY_2); - LL_FLASH_EnablePrefetch(); - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); - SystemCoreClockUpdate(); - LL_Init1msTick(SystemCoreClock); -} - -void adc_config(void) -{ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); - /* ADC might be in deep sleep, needs to be woken up twice in that case */ - LL_ADC_Enable(ADC1); - LL_mDelay(1); - LL_ADC_Enable(ADC1); - LL_mDelay(1); - LL_ADC_StartCalibration(ADC1); - while (LL_ADC_IsCalibrationOnGoing(ADC1)); - LL_ADC_SetSequencersScanMode(ADC1, LL_ADC_SEQ_SCAN_DISABLE); - LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE); - LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE); -} - -void spi_config(void) -{ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); -} - -void io_config(void) -{ - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOE); - /* JTAG is normally not needed, but blocks ports like PB3, PB4 */ - LL_GPIO_AF_Remap_SWJ_NOJTAG(); - /* Likewise, we don't need PB3 for TRACESWO output */ - LL_DBGMCU_SetTracePinAssignment(LL_DBGMCU_TRACE_NONE); -} - -// Main entry point -int -main(void) -{ - SystemInit(); - SCB->VTOR += CONFIG_FLASH_START; - - LL_Init1msTick(SystemCoreClock); - clock_config(); - adc_config(); - io_config(); - spi_config(); - sched_main(); - return 0; -} diff --git a/src/stm32f1/serial.c b/src/stm32f1/serial.c deleted file mode 100644 index e1699334..00000000 --- a/src/stm32f1/serial.c +++ /dev/null @@ -1,65 +0,0 @@ -// STM32F1 serial port -// -// Copyright (C) 2018 Grigori Goronzy -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include -#include "autoconf.h" // CONFIG_SERIAL_BAUD -#include "board/serial_irq.h" // serial_rx_byte -#include "sched.h" // DECL_INIT -#include "stm32f1xx.h" // UART -#include "stm32f1xx_ll_bus.h" -#include "stm32f1xx_ll_rcc.h" -#include "stm32f1xx_ll_usart.h" -#include "stm32f1xx_ll_gpio.h" - -void -serial_init(void) -{ - const uint32_t pclk = __LL_RCC_CALC_PCLK2_FREQ(SystemCoreClock - , LL_RCC_GetAPB2Prescaler()); - - LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1); - LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1); - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); - LL_USART_SetBaudRate(USART1, pclk, CONFIG_SERIAL_BAUD); - LL_USART_SetDataWidth(USART1, LL_USART_DATAWIDTH_8B); - LL_USART_SetParity(USART1, LL_USART_PARITY_NONE); - LL_USART_SetStopBitsLength(USART1, LL_USART_STOPBITS_1); - LL_USART_SetHWFlowCtrl(USART1, LL_USART_HWCONTROL_NONE); - LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX); - LL_USART_EnableIT_RXNE(USART1); - NVIC_SetPriority(USART1_IRQn, 0); - NVIC_EnableIRQ(USART1_IRQn); - LL_USART_Enable(USART1); - - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); - LL_GPIO_AF_DisableRemap_USART1(); - LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_UP); - LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_10, LL_GPIO_PULL_UP); - LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_10, LL_GPIO_MODE_INPUT); -} -DECL_INIT(serial_init); - -void __visible -USART1_IRQHandler(void) -{ - if (LL_USART_IsActiveFlag_RXNE(USART1) || LL_USART_IsActiveFlag_ORE(USART1)) - serial_rx_byte(LL_USART_ReceiveData8(USART1)); - if (LL_USART_IsActiveFlag_TXE(USART1)) { - uint8_t data; - int ret = serial_get_tx_byte(&data); - if (ret) - LL_USART_DisableIT_TXE(USART1); - else - LL_USART_TransmitData8(USART1, data); - } -} - -void -serial_enable_tx_irq(void) -{ - LL_USART_EnableIT_TXE(USART1); -} diff --git a/src/stm32f1/spi.c b/src/stm32f1/spi.c deleted file mode 100644 index 5b9ffda2..00000000 --- a/src/stm32f1/spi.c +++ /dev/null @@ -1,111 +0,0 @@ -// SPI functions on STM32F1 -// -// Copyright (C) 2018 Grigori Goronzy -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include "command.h" // shutdown -#include "gpio.h" // spi_setup -#include "sched.h" // sched_shutdown -#include "stm32f1xx_ll_gpio.h" // LL_GPIO_SetPinMode -#include "stm32f1xx_ll_rcc.h" // __LL_RCC_CALC_PCLK1_FREQ -#include "stm32f1xx_ll_spi.h" // LL_SPI_Enable - -static void spi_set_mode(SPI_TypeDef *spi, uint8_t mode) -{ - switch (mode) { - case 0: - LL_SPI_SetClockPolarity(spi, LL_SPI_POLARITY_LOW); - LL_SPI_SetClockPhase(spi, LL_SPI_PHASE_1EDGE); - break; - case 1: - LL_SPI_SetClockPolarity(spi, LL_SPI_POLARITY_LOW); - LL_SPI_SetClockPhase(spi, LL_SPI_PHASE_2EDGE); - break; - case 2: - LL_SPI_SetClockPolarity(spi, LL_SPI_POLARITY_HIGH); - LL_SPI_SetClockPhase(spi, LL_SPI_PHASE_1EDGE); - break; - case 3: - LL_SPI_SetClockPolarity(spi, LL_SPI_POLARITY_HIGH); - LL_SPI_SetClockPhase(spi, LL_SPI_PHASE_2EDGE); - break; - } -} - -static void spi_set_baudrate(SPI_TypeDef *spi, uint32_t rate) -{ - const uint32_t pclk = __LL_RCC_CALC_PCLK1_FREQ(SystemCoreClock - , LL_RCC_GetAPB1Prescaler()); - const uint32_t prescaler = pclk / rate; - - uint32_t setting = LL_SPI_BAUDRATEPRESCALER_DIV256; - if (prescaler <= 2) - setting = LL_SPI_BAUDRATEPRESCALER_DIV2; - else if (prescaler <= 4) - setting = LL_SPI_BAUDRATEPRESCALER_DIV4; - else if (prescaler <= 8) - setting = LL_SPI_BAUDRATEPRESCALER_DIV8; - else if (prescaler <= 16) - setting = LL_SPI_BAUDRATEPRESCALER_DIV16; - else if (prescaler <= 32) - setting = LL_SPI_BAUDRATEPRESCALER_DIV32; - else if (prescaler <= 64) - setting = LL_SPI_BAUDRATEPRESCALER_DIV64; - else if (prescaler <= 128) - setting = LL_SPI_BAUDRATEPRESCALER_DIV128; - - LL_SPI_SetBaudRatePrescaler(spi, setting); -} - -static void spi_init_pins(void) -{ - LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_13, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_14, LL_GPIO_MODE_INPUT); - LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_15, LL_GPIO_MODE_ALTERNATE); - LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_13, LL_GPIO_OUTPUT_PUSHPULL); - LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_14, LL_GPIO_PULL_UP); - LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_15, LL_GPIO_OUTPUT_PUSHPULL); -} - -struct spi_config -spi_setup(uint32_t bus, uint8_t mode, uint32_t rate) -{ - if (bus > 0 || !rate) - shutdown("Invalid spi_setup parameters"); - - spi_init_pins(); - SPI_TypeDef spi_hw = { }; - LL_SPI_SetNSSMode(&spi_hw, LL_SPI_NSS_SOFT); - LL_SPI_SetMode(&spi_hw, LL_SPI_MODE_MASTER); - spi_set_mode(&spi_hw, mode); - spi_set_baudrate(&spi_hw, rate); - LL_SPI_Enable(&spi_hw); - - return (struct spi_config){ .spi_cr1 = spi_hw.CR1 }; -} - -void -spi_prepare(struct spi_config config) -{ - SPI2->CR1 = config.spi_cr1; -} - -void -spi_transfer(struct spi_config config, uint8_t receive_data, - uint8_t len, uint8_t *data) -{ - while (len--) { - LL_SPI_TransmitData8(SPI2, *data); - while (!LL_SPI_IsActiveFlag_TXE(SPI2)); - while (!LL_SPI_IsActiveFlag_RXNE(SPI2)); - uint8_t rdata = LL_SPI_ReceiveData8(SPI2); - if (receive_data) { - *data = rdata; - } - data++; - } - - while (LL_SPI_IsActiveFlag_BSY(SPI2)); - LL_SPI_Disable(SPI2); -} diff --git a/src/stm32f1/stm32f1.ld b/src/stm32f1/stm32f1.ld deleted file mode 100644 index f8735437..00000000 --- a/src/stm32f1/stm32f1.ld +++ /dev/null @@ -1,109 +0,0 @@ -/* Cortex-M linker script */ - -ENTRY(Reset_Handler) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x08000000 + FLASH_START, LENGTH = 64K - FLASH_START - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K -} - -/* highest address of the user mode stack */ -_estack = 0x20005000; - -SECTIONS -{ - /* Interrupt vector table */ - .isr_vector : - { - . = ALIGN(4); - KEEP(*(.isr_vector)) - . = ALIGN(4); - } >FLASH - - /* Program code and constant data */ - .text : - { - . = ALIGN(4); - *(.text) - *(.text*) - *(.rodata) - *(.rodata*) - KEEP (*(.init)) - KEEP (*(.fini)) - . = ALIGN(4); - _etext = .; - } >FLASH - - /* Exception handling */ - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH - .ARM : { - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - } >FLASH - - /* Static constructor initialization (C++) */ - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - - - /* Initialized data, needs to be handled by startup code */ - _sidata = .; - .data : AT (_sidata) - { - . = ALIGN(4); - _sdata = . ; - _data = . ; - *(.data) - *(.data*) - *(.RAMtext) - . = ALIGN(4); - _edata = . ; - } >RAM - - /* Uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = .; - __bss_start__ = .; - _bss = .; - *(.bss) - *(.bss*) - *(COMMON) - . = ALIGN(4); - _ebss = .; - __bss_end__ = _ebss; - } >RAM - - /* Pointers to end of data for dynamic memory management */ - PROVIDE (end = _ebss); - PROVIDE (_end = _ebss); - - /* Remove debugging from standard libraries */ - /DISCARD/ : - { - libc.a (*) - libm.a (*) - libgcc.a (*) - } -} diff --git a/src/stm32f1/usbserial.c b/src/stm32f1/usbserial.c deleted file mode 100644 index 3bdf86a8..00000000 --- a/src/stm32f1/usbserial.c +++ /dev/null @@ -1,305 +0,0 @@ -// Hardware interface to "fullspeed USB controller" on stm32f1 -// -// Copyright (C) 2018 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU GPLv3 license. - -#include // NULL -#include "autoconf.h" // CONFIG_STM_FLASH_START_2000 -#include "board/armcm_timer.h" // udelay -#include "board/gpio.h" // gpio_out_setup -#include "board/io.h" // writeb -#include "board/irq.h" // irq_disable -#include "board/usb_cdc.h" // usb_notify_ep0 -#include "board/usb_cdc_ep.h" // USB_CDC_EP_BULK_IN -#include "internal.h" // GPIO -#include "sched.h" // DECL_INIT -#include "stm32f1xx.h" // USB - - -/**************************************************************** - * USB transfer memory - ****************************************************************/ - -struct ep_desc { - uint32_t addr_tx, count_tx, addr_rx, count_rx; -}; - -struct ep_mem { - struct ep_desc ep0, ep_acm, ep_bulk_out, ep_bulk_in; - uint32_t ep0_tx[USB_CDC_EP0_SIZE / 2]; - uint32_t ep0_rx[USB_CDC_EP0_SIZE / 2]; - uint32_t ep_acm_tx[USB_CDC_EP_ACM_SIZE / 2]; - uint32_t ep_bulk_out_rx[USB_CDC_EP_BULK_OUT_SIZE / 2]; - uint32_t ep_bulk_in_tx[USB_CDC_EP_BULK_IN_SIZE / 2]; -}; - -#define USB_BTABLE ((struct ep_mem *)(USB_BASE + 0x400)) - -#define CALC_ADDR(p) (((void*)(p) - (void*)USB_BTABLE) / 2) -#define CALC_SIZE(s) ((s) > 32 ? (DIV_ROUND_UP((s), 32) << 10) | 0x8000 \ - : DIV_ROUND_UP((s), 2) << 10) - -// Setup the transfer descriptors in dedicated usb memory -static void -btable_configure(void) -{ - USB_BTABLE->ep0.count_tx = 0; - USB_BTABLE->ep0.addr_tx = CALC_ADDR(USB_BTABLE->ep0_tx); - USB_BTABLE->ep0.count_rx = CALC_SIZE(USB_CDC_EP0_SIZE); - USB_BTABLE->ep0.addr_rx = CALC_ADDR(USB_BTABLE->ep0_rx); - - USB_BTABLE->ep_acm.count_tx = 0; - USB_BTABLE->ep_acm.addr_tx = CALC_ADDR(USB_BTABLE->ep_acm_tx); - - USB_BTABLE->ep_bulk_out.count_rx = CALC_SIZE(USB_CDC_EP_BULK_OUT_SIZE); - USB_BTABLE->ep_bulk_out.addr_rx = CALC_ADDR(USB_BTABLE->ep_bulk_out_rx); - - USB_BTABLE->ep_bulk_in.count_tx = 0; - USB_BTABLE->ep_bulk_in.addr_tx = CALC_ADDR(USB_BTABLE->ep_bulk_in_tx); -} - -// Read a packet stored in dedicated usb memory -static void -btable_read_packet(uint8_t *dest, uint32_t *src, int count) -{ - uint_fast8_t i; - for (i=0; i<(count/2); i++) { - uint32_t d = *src++; - *dest++ = d; - *dest++ = d >> 8; - } - if (count & 1) - *dest = *src; -} - -// Write a packet to dedicated usb memory -static void -btable_write_packet(uint32_t *dest, const uint8_t *src, int count) -{ - int i; - for (i=0; i<(count/2); i++) { - uint8_t b1 = *src++, b2 = *src++; - *dest++ = b1 | (b2 << 8); - } - if (count & 1) - *dest = *src; -} - - -/**************************************************************** - * USB endpoint register - ****************************************************************/ - -#define USB_EPR ((volatile uint32_t *)USB_BASE) - -#define EP_BULK (0 << USB_EP0R_EP_TYPE_Pos) -#define EP_CONTROL (1 << USB_EP0R_EP_TYPE_Pos) -#define EP_INTERRUPT (3 << USB_EP0R_EP_TYPE_Pos) -#define RX_STALL (1 << USB_EP0R_STAT_RX_Pos) -#define RX_NAK (2 << USB_EP0R_STAT_RX_Pos) -#define RX_VALID (3 << USB_EP0R_STAT_RX_Pos) -#define TX_STALL (1 << USB_EP0R_STAT_TX_Pos) -#define TX_NAK (2 << USB_EP0R_STAT_TX_Pos) -#define TX_VALID (3 << USB_EP0R_STAT_TX_Pos) -#define EPR_RWBITS (USB_EP0R_EA | USB_EP0R_EP_KIND | USB_EP0R_EP_TYPE) -#define EPR_RWCBITS (USB_EP0R_CTR_RX | USB_EP0R_CTR_TX) - -static uint32_t -set_stat_rx_bits(uint32_t epr, uint32_t bits) -{ - return ((epr & (EPR_RWBITS | USB_EP0R_STAT_RX_Msk)) ^ bits) | EPR_RWCBITS; -} - -static uint32_t -set_stat_tx_bits(uint32_t epr, uint32_t bits) -{ - return ((epr & (EPR_RWBITS | USB_EP0R_STAT_TX_Msk)) ^ bits) | EPR_RWCBITS; -} - -static uint32_t -set_stat_rxtx_bits(uint32_t epr, uint32_t bits) -{ - uint32_t mask = EPR_RWBITS | USB_EP0R_STAT_RX_Msk | USB_EP0R_STAT_TX_Msk; - return ((epr & mask) ^ bits) | EPR_RWCBITS; -} - - -/**************************************************************** - * USB interface - ****************************************************************/ - -int_fast8_t -usb_read_bulk_out(void *data, uint_fast8_t max_len) -{ - uint32_t epr = USB_EPR[USB_CDC_EP_BULK_OUT]; - if ((epr & USB_EP0R_STAT_RX_Msk) == RX_VALID) - // No data ready - return -1; - uint32_t count = USB_BTABLE->ep_bulk_out.count_rx & 0x3ff; - if (count > max_len) - count = max_len; - btable_read_packet(data, USB_BTABLE->ep_bulk_out_rx, count); - USB_EPR[USB_CDC_EP_BULK_OUT] = set_stat_rx_bits(epr, RX_VALID); - return count; -} - -int_fast8_t -usb_send_bulk_in(void *data, uint_fast8_t len) -{ - uint32_t epr = USB_EPR[USB_CDC_EP_BULK_IN]; - if ((epr & USB_EP0R_STAT_TX_Msk) != TX_NAK) - // No buffer space available - return -1; - btable_write_packet(USB_BTABLE->ep_bulk_in_tx, data, len); - USB_BTABLE->ep_bulk_in.count_tx = len; - USB_EPR[USB_CDC_EP_BULK_IN] = set_stat_tx_bits(epr, TX_VALID); - return len; -} - -int_fast8_t -usb_read_ep0(void *data, uint_fast8_t max_len) -{ - uint32_t epr = USB_EPR[0]; - if ((epr & USB_EP0R_STAT_RX_Msk) != RX_NAK) - // No data ready - return -1; - uint32_t count = USB_BTABLE->ep0.count_rx & 0x3ff; - if (count > max_len) - count = max_len; - btable_read_packet(data, USB_BTABLE->ep0_rx, count); - USB_EPR[0] = set_stat_rxtx_bits(epr, RX_VALID | TX_NAK); - return count; -} - -int_fast8_t -usb_read_ep0_setup(void *data, uint_fast8_t max_len) -{ - return usb_read_ep0(data, max_len); -} - -int_fast8_t -usb_send_ep0(const void *data, uint_fast8_t len) -{ - uint32_t epr = USB_EPR[0]; - if ((epr & USB_EP0R_STAT_RX_Msk) != RX_VALID) - // Transfer interrupted - return -2; - if ((epr & USB_EP0R_STAT_TX_Msk) != TX_NAK) - // No buffer space available - return -1; - btable_write_packet(USB_BTABLE->ep0_tx, data, len); - USB_BTABLE->ep0.count_tx = len; - USB_EPR[0] = set_stat_tx_bits(epr, TX_VALID); - return len; -} - -void -usb_stall_ep0(void) -{ - USB_EPR[0] = set_stat_rxtx_bits(USB_EPR[0], RX_STALL | TX_STALL); -} - -static uint8_t set_address; - -void -usb_set_address(uint_fast8_t addr) -{ - writeb(&set_address, addr | USB_DADDR_EF); - usb_send_ep0(NULL, 0); -} - -void -usb_set_configure(void) -{ -} - -void -usb_request_bootloader(void) -{ - if (!CONFIG_STM_FLASH_START_2000) - return; - // Enter "stm32duino" bootloader - irq_disable(); - RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN; - PWR->CR |= PWR_CR_DBP; - BKP->DR10 = 0x01; - PWR->CR &=~ PWR_CR_DBP; - NVIC_SystemReset(); -} - - -/**************************************************************** - * Setup and interrupts - ****************************************************************/ - -// Initialize the usb controller -void -usb_init(void) -{ - // Pull the D+ pin low briefly to signal a new connection - gpio_out_setup(GPIO('A', 12), 0); - udelay(5000); - gpio_in_setup(GPIO('A', 12), 0); - - // Setup USB packet memory - btable_configure(); - - // Enable USB clock - RCC->APB1ENR |= RCC_APB1ENR_USBEN; - - // Reset usb controller and enable interrupts - USB->CNTR = USB_CNTR_FRES; - USB->BTABLE = 0; - USB->DADDR = 0; - USB->CNTR = USB_CNTR_RESETM; - USB->ISTR = 0; - NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 1); - NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); -} -DECL_INIT(usb_init); - -// Configure interface after a USB reset event -static void -usb_reset(void) -{ - USB_EPR[0] = 0 | EP_CONTROL | RX_VALID | TX_NAK; - USB_EPR[USB_CDC_EP_ACM] = USB_CDC_EP_ACM | EP_INTERRUPT | RX_NAK | TX_NAK; - USB_EPR[USB_CDC_EP_BULK_OUT] = (USB_CDC_EP_BULK_OUT | EP_BULK - | RX_VALID | TX_NAK); - USB_EPR[USB_CDC_EP_BULK_IN] = (USB_CDC_EP_BULK_IN | EP_BULK - | RX_NAK | TX_NAK); - - USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM; - USB->DADDR = USB_DADDR_EF; -} - -// Main irq handler -void __visible -USB_LP_CAN1_RX0_IRQHandler(void) -{ - uint32_t istr = USB->ISTR; - if (istr & USB_ISTR_CTR) { - // Endpoint activity - uint32_t ep = istr & USB_ISTR_EP_ID; - uint32_t epr = USB_EPR[ep]; - USB_EPR[ep] = epr & EPR_RWBITS; - if (ep == 0) { - usb_notify_ep0(); - if (epr & USB_EP_CTR_TX && set_address) { - // Apply address after last "in" message transmitted - USB->DADDR = set_address; - set_address = 0; - } - } else if (ep == USB_CDC_EP_BULK_OUT) { - usb_notify_bulk_out(); - } else if (ep == USB_CDC_EP_BULK_IN) { - usb_notify_bulk_in(); - } - } - if (istr & USB_ISTR_RESET) { - // USB Reset - USB->ISTR = (uint16_t)~USB_ISTR_RESET; - usb_reset(); - } -}