From 04624af4e50eb59c0be7a9e5e1ef42b968a2c200 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 17 Jan 2013 20:05:25 +0100 Subject: [PATCH] f4discovery: Adapt from the "native" file and add or change code where needed - stm32_mem.py has problems with erasing the big pages, but dfu-util works - serial GDB remote server doesn't work. It neither works for the STM32F107, so maybe there is a problem with the usbd_f107_driver. --- src/platforms/f4discovery/Makefile.inc | 8 +- src/platforms/f4discovery/Readme | 17 +++ src/platforms/f4discovery/platform.c | 170 ++++++------------------ src/platforms/f4discovery/platform.h | 105 ++++++++------- src/platforms/stm32/cdcacm.c | 4 + src/platforms/stm32/f4discovery.ld | 7 +- src/platforms/stm32/usbdfu.c | 172 ++++++++++++++++++++----- 7 files changed, 264 insertions(+), 219 deletions(-) create mode 100644 src/platforms/f4discovery/Readme diff --git a/src/platforms/f4discovery/Makefile.inc b/src/platforms/f4discovery/Makefile.inc index 4c56bd6..8d9b3c1 100644 --- a/src/platforms/f4discovery/Makefile.inc +++ b/src/platforms/f4discovery/Makefile.inc @@ -3,13 +3,13 @@ CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy CFLAGS += -Istm32/include -mcpu=cortex-m3 -mthumb \ - -DSTM32F1 -DBLACKMAGIC -I../libopencm3/include + -DSTM32F4 -DF4DISCOVERY -I../libopencm3/include -LDFLAGS_BOOT = -lopencm3_stm32f1 -Wl,--defsym,_stack=0x20005000 \ - -Wl,-T,platforms/stm32/blackmagic.ld -nostartfiles -lc -lnosys \ +LDFLAGS_BOOT = -lopencm3_stm32f4 -Wl,--defsym,_stack=0x20020000 \ + -Wl,-T,platforms/stm32/f4discovery.ld -nostartfiles -lc -lnosys \ -Wl,-Map=mapfile -mthumb -mcpu=cortex-m3 -Wl,-gc-sections \ -L../libopencm3/lib -LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8002000 +LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8010000 VPATH += platforms/stm32 diff --git a/src/platforms/f4discovery/Readme b/src/platforms/f4discovery/Readme new file mode 100644 index 0000000..6035917 --- /dev/null +++ b/src/platforms/f4discovery/Readme @@ -0,0 +1,17 @@ +Application start address: +========================= + +Use 0x8010000 +- lower 3 16 k pages may be used for parameter storage +- Erasing a single 64 k Page is faster then erasing 2 16 k Pages + eventual the 64 k page + + +Internal boot loader: +==================== + +When we request invokation of a bootloader from inside the application, +we boot the device internal bootloader with the blue botton pressed. + +That way, we can easy exchange the custom bootloader via the device +internale bootloader \ No newline at end of file diff --git a/src/platforms/f4discovery/platform.c b/src/platforms/f4discovery/platform.c index 0e81ba4..4aa14a6 100644 --- a/src/platforms/f4discovery/platform.c +++ b/src/platforms/f4discovery/platform.c @@ -22,14 +22,14 @@ * implementation. */ -#include +#include #include #include #include #include #include +#include #include -#include #include "platform.h" #include "jtag_scan.h" @@ -44,64 +44,39 @@ jmp_buf fatal_error_jmpbuf; static void morse_update(void); -static void adc_init(void); - -/* Pins PB[7:5] are used to detect hardware revision. - * 000 - Original production build. - * 001 - Mini production build. - */ -int platform_hwversion(void) -{ - static int hwversion = -1; - if (hwversion == -1) { - gpio_set_mode(GPIOB, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_PULL_UPDOWN, - GPIO7 | GPIO6 | GPIO5); - gpio_clear(GPIOB, GPIO7 | GPIO6 | GPIO5); - hwversion = gpio_get(GPIOB, GPIO7 | GPIO6 | GPIO5) >> 5; - } - return hwversion; -} - int platform_init(void) { - rcc_clock_setup_in_hse_8mhz_out_72mhz(); + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]); /* Enable peripherals */ - rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); + rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN); + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); - /* Setup GPIO ports */ - gpio_clear(USB_PU_PORT, USB_PU_PIN); - gpio_set_mode(USB_PU_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, - USB_PU_PIN); - gpio_set_mode(JTAG_PORT, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, + /* Set up USB Pins and alternate function*/ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, + GPIO9 | GPIO11 | GPIO12); + gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); + + GPIOA_OSPEEDR &=~0xfc; + GPIOA_OSPEEDR |= 0xa8; + gpio_mode_setup(JTAG_PORT, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, TMS_PIN | TCK_PIN | TDI_PIN); - /* This needs some fixing... */ - /* Toggle required to sort out line drivers... */ - gpio_port_write(GPIOA, 0x8100); - gpio_port_write(GPIOB, 0x2000); + gpio_mode_setup(TDO_PORT, GPIO_MODE_INPUT, + GPIO_PUPD_NONE, + TDO_PIN); - gpio_port_write(GPIOA, 0x8180); - gpio_port_write(GPIOB, 0x2002); - - gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, - LED_UART | LED_IDLE_RUN | LED_ERROR); - - /* FIXME: This pin in intended to be input, but the TXS0108 fails - * to release the device from reset if this floats. */ - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO7); + gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, + LED_UART | LED_IDLE_RUN | LED_ERROR | LED_SPARE1); /* Setup heartbeat timer */ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); - systick_set_reload(900000); /* Interrupt us at 10 Hz */ + systick_set_reload(168000000/(10*8)); /* Interrupt us at 10 Hz */ SCB_SHPR(11) &= ~((15 << 4) & 0xff); SCB_SHPR(11) |= ((14 << 4) & 0xff); systick_interrupt_enable(); @@ -109,15 +84,7 @@ int platform_init(void) usbuart_init(); - if (platform_hwversion() > 0) { - adc_init(); - } else { - gpio_clear(GPIOB, GPIO0); - gpio_set_mode(GPIOB, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0); - } - - SCB_VTOR = 0x2000; // Relocate interrupt vector table here + SCB_VTOR = 0x10000; // Relocate interrupt vector table here cdcacm_init(); @@ -219,88 +186,23 @@ static void morse_update(void) code >>= 1; bits--; } -static void adc_init(void) -{ - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); - - gpio_set_mode(GPIOB, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_ANALOG, GPIO0); - - adc_off(ADC1); - adc_disable_scan_mode(ADC1); - adc_set_single_conversion_mode(ADC1); - adc_disable_external_trigger_regular(ADC1); - adc_set_right_aligned(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - - adc_power_on(ADC1); - - /* Wait for ADC starting up. */ - for (int i = 0; i < 800000; i++) /* Wait a bit. */ - __asm__("nop"); - - adc_reset_calibration(ADC1); - adc_calibration(ADC1); -} - const char *platform_target_voltage(void) { - if (platform_hwversion() == 0) - return gpio_get(GPIOB, GPIO0) ? "OK" : "ABSENT!"; - - static char ret[] = "0.0V"; - const u8 channel = 8; - adc_set_regular_sequence(ADC1, 1, (u8*)&channel); - - adc_on(ADC1); - - /* Wait for end of conversion. */ - while (!(ADC_SR(ADC1) & ADC_SR_EOC)); - - u32 val = ADC_DR(ADC1) * 99; /* 0-4095 */ - ret[0] = '0' + val / 81910; - ret[2] = '0' + (val / 8191) % 10; - - return ret; + return "ABSENT!"; } void assert_boot_pin(void) { - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); - gpio_clear(GPIOB, GPIO12); -} - -void exti15_10_isr(void) -{ - if (gpio_get(USB_VBUS_PORT, USB_VBUS_PIN)) { - /* Drive pull-up high if VBUS connected */ - gpio_set_mode(USB_PU_PORT, GPIO_MODE_OUTPUT_10_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, USB_PU_PIN); - } else { - /* Allow pull-up to float if VBUS disconnected */ - gpio_set_mode(USB_PU_PORT, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_FLOAT, USB_PU_PIN); + if (gpio_get(GPIOA, GPIO0)) { + /* Jump to the built in bootloader by mapping System flash */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_SYSCFGEN); + SYSCFG_MEMRM &= ~3; + SYSCFG_MEMRM |= 1; + } + else { + /* Flag Bootloader Request by mimicing a pushed USER button*/ + gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, GPIO0); + gpio_set(GPIOA, GPIO0); } - - exti_reset_request(USB_VBUS_PIN); -} - -void setup_vbus_irq(void) -{ - nvic_set_priority(USB_VBUS_IRQ, IRQ_PRI_USB_VBUS); - nvic_enable_irq(USB_VBUS_IRQ); - - gpio_set(USB_VBUS_PORT, USB_VBUS_PIN); - gpio_set(USB_PU_PORT, USB_PU_PIN); - - gpio_set_mode(USB_VBUS_PORT, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_PULL_UPDOWN, USB_VBUS_PIN); - - /* Configure EXTI for USB VBUS monitor */ - exti_select_source(USB_VBUS_PIN, USB_VBUS_PORT); - exti_set_trigger(USB_VBUS_PIN, EXTI_TRIGGER_BOTH); - exti_enable_request(USB_VBUS_PIN); - - exti15_10_isr(); } diff --git a/src/platforms/f4discovery/platform.h b/src/platforms/f4discovery/platform.h index 7d84533..6cbbc1b 100644 --- a/src/platforms/f4discovery/platform.h +++ b/src/platforms/f4discovery/platform.h @@ -24,7 +24,7 @@ #ifndef __PLATFORM_H #define __PLATFORM_H -#include +#include #include #include @@ -42,18 +42,18 @@ extern usbd_device *usbdev; /* Important pin mappings for STM32 implementation: * - * LED0 = PB2 (Yellow LED : Running) - * LED1 = PB10 (Yellow LED : Idle) - * LED2 = PB11 (Red LED : Error) + * LED0 = PD12 (Green LED : Running) + * LED1 = PD13 (Orange LED : Idle) + * LED2 = PD12 (Red LED : Error) * - * TPWR = RB0 (input) -- analogue on mini design ADC1, ch8 - * nTRST = PB1 - * SRST_OUT = PA2 - * TDI = PA3 - * TMS = PA4 (input for SWDP) - * TCK = PA5 - * TDO = PA6 (input) - * nSRST = PA7 (input) + * TPWR = XXX (input) -- analogue on mini design ADC1, ch8 + * nTRST = PD0 + * SRST_OUT = PD1 + * TDI = PA1 + * TMS = PA3 (input for SWDP) + * TCK = PA8 + * TDO = PB4 (input) + * nSRST = PD2 (input) * * USB cable pull-up: PA8 * USB VBUS detect: PB13 -- New on mini design. @@ -66,55 +66,68 @@ extern usbd_device *usbdev; #define TDI_PORT JTAG_PORT #define TMS_PORT JTAG_PORT #define TCK_PORT JTAG_PORT -#define TDO_PORT JTAG_PORT -#define TDI_PIN GPIO3 -#define TMS_PIN GPIO4 -#define TCK_PIN GPIO5 -#define TDO_PIN GPIO6 +#define TDO_PORT GPIOB +#define TDI_PIN GPIO1 +#define TMS_PIN GPIO3 +#define TCK_PIN GPIO2 +#define TDO_PIN GPIO4 #define SWDIO_PORT JTAG_PORT #define SWCLK_PORT JTAG_PORT #define SWDIO_PIN TMS_PIN #define SWCLK_PIN TCK_PIN -#define TRST_PORT GPIOB -#define TRST_PIN GPIO1 -#define SRST_PORT GPIOA -#define SRST_PIN GPIO2 +#define TRST_PORT GPIOD +#define TRST_PIN GPIO0 +#define SRST_PORT GPIOD +#define SRST_PIN GPIO1 -#define USB_PU_PORT GPIOA -#define USB_PU_PIN GPIO8 +#define LED_PORT GPIOD +#define LED_PORT_UART GPIOD +#define LED_UART GPIO12 +#define LED_IDLE_RUN GPIO13 +#define LED_ERROR GPIO14 +#define LED_SPARE1 GPIO15 -#define USB_VBUS_PORT GPIOB -#define USB_VBUS_PIN GPIO13 -#define USB_VBUS_IRQ NVIC_EXTI15_10_IRQ +#define TMS_SET_MODE() gpio_mode_setup(TMS_PORT, GPIO_MODE_OUTPUT, \ + GPIO_PUPD_NONE, TMS_PIN); +#define SWDIO_MODE_FLOAT() gpio_mode_setup(SWDIO_PORT, GPIO_MODE_INPUT, \ + GPIO_PUPD_NONE, SWDIO_PIN); -#define LED_PORT GPIOB -#define LED_PORT_UART GPIOB -#define LED_UART GPIO2 -#define LED_IDLE_RUN GPIO10 -#define LED_ERROR GPIO11 +#define SWDIO_MODE_DRIVE() gpio_mode_setup(SWDIO_PORT, GPIO_MODE_OUTPUT, \ + GPIO_PUPD_NONE, SWDIO_PIN); -#define USB_DRIVER stm32f103_usb_driver -#define USB_IRQ NVIC_USB_LP_CAN_RX0_IRQ -#define USB_ISR usb_lp_can_rx0_isr + +#define USB_DRIVER stm32f107_usb_driver +#define USB_IRQ NVIC_OTG_FS_IRQ +#define USB_ISR otg_fs_isr /* Interrupt priorities. Low numbers are high priority. * For now USART1 preempts USB which may spin while buffer is drained. * TIM3 is used for traceswo capture and must be highest priority. */ #define IRQ_PRI_USB (2 << 4) #define IRQ_PRI_USBUSART (1 << 4) -#define IRQ_PRI_USB_VBUS (14 << 4) #define IRQ_PRI_TRACE (0 << 4) -#define USBUSART USART1 -#define USBUSART_CR1 USART1_CR1 -#define USBUSART_IRQ NVIC_USART1_IRQ -#define USBUSART_APB_ENR RCC_APB2ENR -#define USBUSART_CLK_ENABLE RCC_APB2ENR_USART1EN -#define USBUSART_PORT GPIOA -#define USBUSART_TX_PIN GPIO9 -#define USBUSART_ISR usart1_isr +#define USBUSART USART3 +#define USBUSART_CR1 USART3_CR1 +#define USBUSART_IRQ NVIC_USART3_IRQ +#define USBUSART_APB_ENR RCC_APB1ENR +#define USBUSART_CLK_ENABLE RCC_APB1ENR_USART3EN +#define USBUSART_TX_PORT GPIOD +#define USBUSART_TX_PIN GPIO8 +#define USBUSART_RX_PORT GPIOD +#define USBUSART_RX_PIN GPIO9 +#define USBUSART_ISR usart3_isr + +#define UART_PIN_SETUP() do { \ + gpio_mode_setup(USBUSART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, \ + USBUSART_TX_PIN); \ + gpio_mode_setup(USBUSART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, \ + USBUSART_RX_PIN); \ + gpio_set_af(USBUSART_TX_PORT, GPIO_AF7, USBUSART_TX_PIN); \ + gpio_set_af(USBUSART_RX_PORT, GPIO_AF7, USBUSART_RX_PIN); \ + } while(0) #define TRACE_TIM TIM3 #define TRACE_TIM_CLK_EN() rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM3EN) @@ -180,7 +193,7 @@ static inline void _gpio_set(u32 gpioport, u16 gpios) static inline void _gpio_clear(u32 gpioport, u16 gpios) { - GPIO_BRR(gpioport) = gpios; + GPIO_BSRR(gpioport) = gpios<<16; } #define gpio_clear _gpio_clear @@ -193,6 +206,6 @@ static inline u16 _gpio_get(u32 gpioport, u16 gpios) #endif -#define disconnect_usb() gpio_set_mode(USB_PU_PORT, GPIO_MODE_INPUT, 0, USB_PU_PIN); +#define disconnect_usb() do {usbd_disconnect(usbdev,1); nvic_disable_irq(USB_IRQ);} while(0) void assert_boot_pin(void); -void setup_vbus_irq(void); +#define setup_vbus_irq() diff --git a/src/platforms/stm32/cdcacm.c b/src/platforms/stm32/cdcacm.c index 9799d13..0cbfc5f 100644 --- a/src/platforms/stm32/cdcacm.c +++ b/src/platforms/stm32/cdcacm.c @@ -553,7 +553,11 @@ void USB_ISR(void) static char *get_dev_unique_id(char *s) { +#if defined(STM32F4) + volatile uint32_t *unique_id_p = (volatile uint32_t *)0x1FFF7A10; +#else volatile uint32_t *unique_id_p = (volatile uint32_t *)0x1FFFF7E8; +#endif uint32_t unique_id = *unique_id_p + *(unique_id_p + 1) + *(unique_id_p + 2); diff --git a/src/platforms/stm32/f4discovery.ld b/src/platforms/stm32/f4discovery.ld index b70739c..b066426 100644 --- a/src/platforms/stm32/f4discovery.ld +++ b/src/platforms/stm32/f4discovery.ld @@ -20,9 +20,10 @@ /* Define memory regions. */ MEMORY { - rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K } /* Include the common ld script from libopenstm32. */ -INCLUDE libopencm3_stm32f1.ld +INCLUDE libopencm3_stm32f4.ld + diff --git a/src/platforms/stm32/usbdfu.c b/src/platforms/stm32/usbdfu.c index e33eddb..4535b34 100644 --- a/src/platforms/stm32/usbdfu.c +++ b/src/platforms/stm32/usbdfu.c @@ -34,8 +34,6 @@ #include #include -#define APP_ADDRESS 0x08002000 - /* Commands sent with wBlockNum == 0 as per ST implementation. */ #define CMD_SETADDR 0x21 #define CMD_ERASE 0x41 @@ -49,10 +47,60 @@ usbd_device *usbdev; /* We need a special large control buffer for this device: */ u8 usbd_control_buffer[1024]; +#if defined (STM32_CAN) +#define FLASHBLOCKSIZE 2048 +#else +#define FLASHBLOCKSIZE 1024 +#endif + #if defined(DISCOVERY_STLINK) u32 led2_state = 0; #endif +static u32 max_address; +#if defined (STM32F4) +#define APP_ADDRESS 0x08010000 +static u32 sector_addr[] = {0x8000000, 0x8004000, 0x8008000, 0x800c000, + 0x8010000, 0x8020000, 0x8040000, 0x8060000, + 0x8080000, 0x80a0000, 0x80c0000, 0x80e0000, + 0x8100000, 0}; +u16 sector_erase_time[12]= {500, 500, 500, 500, + 1100, + 2600, 2600, 2600, 2600, 2600, 2600, 2600}; +u8 sector_num = 0xff; +/* Find the sector number for a given address*/ +void get_sector_num(u32 addr) +{ + int i = 0; + while(sector_addr[i+1]) { + if (addr < sector_addr[i+1]) + break; + i++; + } + if (!sector_addr[i]) + return; + sector_num = i; +} + +void check_and_do_sector_erase(u32 addr) +{ + if(addr == sector_addr[sector_num]) { + flash_erase_sector((sector_num & 0x1f)<<3, FLASH_PROGRAM_X32); + } +} +#else +#define APP_ADDRESS 0x08002000 +static uint32_t last_erased_page=0xffffffff; +void check_and_do_sector_erase(u32 sector) +{ + sector &= (~(FLASHBLOCKSIZE-1)); + if (sector != last_erased_page) { + flash_erase_page(sector); + last_erased_page = sector; + } +} +#endif + static enum dfu_state usbdfu_state = STATE_DFU_IDLE; static char *get_dev_unique_id(char *serial_no); @@ -136,6 +184,8 @@ static const char *usb_strings[] = { "Black Magic (Upgrade) for STLink/Discovery", #elif defined(STM32_CAN) "Black Magic (Upgrade) for STM32_CAN", +#elif defined(F4DISCOVERY) + "Black Magic (Upgrade) for F4DISCOVERY", #else #warning "Unhandled board" #endif @@ -147,6 +197,8 @@ static const char *usb_strings[] = { "@Internal Flash /0x08000000/8*001Ka,56*001Kg" #elif defined(STM32_CAN) "@Internal Flash /0x08000000/4*002Ka,124*002Kg" +#elif defined(F4DISCOVERY) + "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg" #else #warning "Unhandled board" #endif @@ -157,7 +209,20 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) switch(usbdfu_state) { case STATE_DFU_DNLOAD_SYNC: usbdfu_state = STATE_DFU_DNBUSY; +#if defined(STM32F4) + /* Programming 256 word with 100 us(max) per word*/ + *bwPollTimeout = 26; + /* Erase for big pages on STM2/4 needs "long" time + Try not to hit USB timeouts*/ + if ((prog.blocknum == 0) && (prog.buf[0] == CMD_ERASE)) { + u32 addr = *(u32 *)(prog.buf + 1); + get_sector_num(addr); + if(addr == sector_addr[sector_num]) + *bwPollTimeout = sector_erase_time[sector_num]; + } +#else *bwPollTimeout = 100; +#endif return DFU_STATUS_OK; case STATE_DFU_MANIFEST_SYNC: @@ -170,13 +235,6 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -#if defined (STM32_CAN) -#define FLASHBLOCKSIZE 2048 -#else -#define FLASHBLOCKSIZE 1024 -#endif -static uint32_t last_erased_pages=0xffffffff; - static void usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req) { @@ -188,32 +246,33 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req) flash_unlock(); if(prog.blocknum == 0) { - if ((*(u32*)(prog.buf+1) < 0x8002000) || - (*(u32*)(prog.buf+1) >= 0x8020000)) { + u32 addr = *(u32 *)(prog.buf + 1); + if (addr < APP_ADDRESS || + (addr >= max_address)) { + flash_lock(); usbd_ep_stall_set(dev, 0, 1); return; } switch(prog.buf[0]) { - case CMD_ERASE: { - u32 page_start = *(u32*)(prog.buf+1); - - page_start &= (~(FLASHBLOCKSIZE-1)); - if (page_start != last_erased_pages) { - flash_erase_page(page_start); - last_erased_pages = page_start; - } - - } + case CMD_ERASE: + check_and_do_sector_erase(addr); case CMD_SETADDR: - prog.addr = *(u32*)(prog.buf+1); + prog.addr = addr; } } else { u32 baseaddr = prog.addr + ((prog.blocknum - 2) * dfu_function.wTransferSize); +#if defined (STM32F4) + for(i = 0; i < prog.len; i += 4) + flash_program_word(baseaddr + i, + *(u32*)(prog.buf+i), + FLASH_PROGRAM_X32); +#else for(i = 0; i < prog.len; i += 2) flash_program_half_word(baseaddr + i, *(u16*)(prog.buf+i)); +#endif } flash_lock(); @@ -311,14 +370,23 @@ int main(void) #elif defined (STM32_CAN) rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if(!gpio_get(GPIOA, GPIO0)) { +#elif defined (F4DISCOVERY) + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); + if(!gpio_get(GPIOA, GPIO0)) { #else rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); if(gpio_get(GPIOB, GPIO12)) { #endif /* Boot the application if it's valid */ +#if defined (STM32F4) + /* Vector table may be anywhere in 128 kByte RAM + CCM not handled*/ + if((*(volatile u32*)APP_ADDRESS & 0x2FFC0000) == 0x20000000) { +#else if((*(volatile u32*)APP_ADDRESS & 0x2FFE0000) == 0x20000000) { +#endif /* Set vector table base address */ - SCB_VTOR = APP_ADDRESS & 0xFFFF; + SCB_VTOR = APP_ADDRESS & 0x1FFFFF; /* Max 2 MByte Flash*/ /* Initialise master stack pointer */ asm volatile ("msr msp, %0"::"g" (*(volatile u32*)APP_ADDRESS)); @@ -327,6 +395,9 @@ int main(void) } } +#if defined (STM32F4) + /* don' touch option bits for now */ +#else if ((FLASH_WRPR & 0x03) != 0x00) { flash_unlock(); FLASH_CR = 0; @@ -336,6 +407,7 @@ int main(void) /* MD Device: Protect 2 bits with (4 * 1k pages each)*/ flash_program_option_bytes(FLASH_OBP_WRP10, 0x03FC); } +#endif #if defined (DISCOVERY_STLINK) /* Just in case: Disconnect USB cable by resetting USB Device @@ -348,19 +420,22 @@ int main(void) gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12); #endif +#if defined (F4DISCOVERY) + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]); +#else rcc_clock_setup_in_hse_8mhz_out_72mhz(); - - rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); +#endif #if defined(DISCOVERY_STLINK) - gpio_set_mode(GPIOA, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_ANALOG, GPIO0); +#elif defined(F4DISCOVERY) #elif defined (STM32_CAN) + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO0); #else + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO8); @@ -368,18 +443,33 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); #endif systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); - systick_set_reload(900000); + systick_set_reload(2100000); systick_interrupt_enable(); systick_counter_enable(); - gpio_set_mode(GPIOB, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_FLOAT, GPIO2 | GPIO10); - get_dev_unique_id(serial_no); #if defined(STM32_CAN) + usbdev = usbd_init(&stm32f107_usb_driver, + &dev, &config, usb_strings, 4); +#elif defined(F4DISCOVERY) + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); + gpio_clear(GPIOD, GPIO12 | GPIO13 | GPIO14 |GPIO15); + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, + GPIO12 | GPIO13 | GPIO14 |GPIO15); + + rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); + + /* Set up USB Pins and alternate function*/ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, + GPIO9 | GPIO11 | GPIO12); + gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); + usbdev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings, 4); #else + gpio_set_mode(GPIOB, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_FLOAT, GPIO2 | GPIO10); + usbdev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 4); #endif @@ -401,12 +491,28 @@ int main(void) static char *get_dev_unique_id(char *s) { - volatile uint32_t *unique_id_p = (volatile uint32_t *)0x1FFFF7E8; +#if defined(STM32F4) || defined(STM32F2) +#define UNIQUE_SERIAL_R 0x1FFF7A10 +#define FLASH_SIZE_R 0x1fff7A22 +#elif defined(STM32F3) +#define UNIQUE_SERIAL_R 0x1FFFF7AC +#define FLASH_SIZE_R 0x1fff77cc +#elif defined(STM32L1) +#define UNIQUE_SERIAL_R 0x1ff80050 +#define FLASH_SIZE_R 0x1FF8004C +#else +#define UNIQUE_SERIAL_R 0x1FFFF7E8; +#define FLASH_SIZE_R 0x1ffff7e0 +#endif + volatile uint32_t *unique_id_p = (volatile uint32_t *)UNIQUE_SERIAL_R; uint32_t unique_id = *unique_id_p + *(unique_id_p + 1) + *(unique_id_p + 2); int i; + /* Calculated the upper flash limit from the exported data + in theparameter block*/ + max_address = (*(u32 *) FLASH_SIZE_R) <<10; /* Fetch serial number from chip's unique ID */ for(i = 0; i < 8; i++) { s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0'; @@ -429,6 +535,8 @@ void sys_tick_handler() gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO9); led2_state++; +#elif defined (F4DISCOVERY) + gpio_toggle(GPIOD, GPIO12); /* Green LED on/off */ #elif defined(STM32_CAN) gpio_toggle(GPIOB, GPIO0); /* LED2 on/off */ #else