Further split-up of DFU bootloader.

This commit is contained in:
Gareth McMullin 2013-03-12 15:00:15 +13:00
parent 14e5e8b0b6
commit 55f161208d
15 changed files with 327 additions and 226 deletions

View File

@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic.bin: blackmagic blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
blackmagic_dfu: usbdfu.o blackmagic_dfu: usbdfu.o dfucore.o dfu_f4.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT) $(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu blackmagic_dfu.bin: blackmagic_dfu

View File

@ -36,7 +36,9 @@
#define CDCACM_PACKET_SIZE 64 #define CDCACM_PACKET_SIZE 64
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define BOARD_IDENT "Black Magic Probe (F4Discovery), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")" #define BOARD_IDENT "Black Magic Probe (F4Discovery), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for F4Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (F4Discovery" #define DFU_IDENT "Black Magic Firmware Upgrade (F4Discovery"
#define IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
extern usbd_device *usbdev; extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1 #define CDCACM_GDB_ENDPOINT 1

View File

@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic.bin: blackmagic blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
blackmagic_dfu: usbdfu.o blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT) $(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu blackmagic_dfu.bin: blackmagic_dfu

View File

@ -36,7 +36,9 @@
#define CDCACM_PACKET_SIZE 64 #define CDCACM_PACKET_SIZE 64
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define BOARD_IDENT "Black Magic Probe, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")" #define BOARD_IDENT "Black Magic Probe, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic Probe (Upgrade), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade" #define DFU_IDENT "Black Magic Firmware Upgrade"
#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,120*001Kg"
extern usbd_device *usbdev; extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1 #define CDCACM_GDB_ENDPOINT 1

View File

@ -21,7 +21,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic.bin: blackmagic blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
blackmagic_dfu: usbdfu.o blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT) $(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu blackmagic_dfu.bin: blackmagic_dfu

View File

@ -35,7 +35,9 @@
#define INLINE_GPIO #define INLINE_GPIO
#define CDCACM_PACKET_SIZE 64 #define CDCACM_PACKET_SIZE 64
#define BOARD_IDENT "Black Magic Probe (STLINK), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")" #define BOARD_IDENT "Black Magic Probe (STLINK), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for STLink/Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (STLINK)" #define DFU_IDENT "Black Magic Firmware Upgrade (STLINK)"
#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg"
extern usbd_device *usbdev; extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1 #define CDCACM_GDB_ENDPOINT 1

View File

@ -0,0 +1,88 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2013 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/cm3/scb.h>
#include "usbdfu.h"
#define FLASH_OBP_RDP 0x1FFFF800
#define FLASH_OBP_WRP10 0x1FFFF808
#define FLASH_OBP_RDP_KEY 0x5aa5
#if defined (STM32_CAN)
# define FLASHBLOCKSIZE 2048
#else
# define FLASHBLOCKSIZE 1024
#endif
static uint32_t last_erased_page = 0xffffffff;
void dfu_check_and_do_sector_erase(uint32_t sector)
{
sector &= (~(FLASHBLOCKSIZE - 1));
if (sector != last_erased_page) {
flash_erase_page(sector);
last_erased_page = sector;
}
}
void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len)
{
for(int i = 0; i < len; i += 2)
flash_program_half_word(baseaddr + i,
*(u16*)(buf+i));
}
uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum)
{
(void)cmd;
(void)addr;
(void)blocknum;
return 100;
}
void dfu_protect_enable(void)
{
if ((FLASH_WRPR & 0x03) != 0x00) {
flash_unlock();
FLASH_CR = 0;
flash_erase_option_bytes();
flash_program_option_bytes(FLASH_OBP_RDP, FLASH_OBP_RDP_KEY);
/* CL Device: Protect 2 bits with (2 * 2k pages each)*/
/* MD Device: Protect 2 bits with (4 * 1k pages each)*/
flash_program_option_bytes(FLASH_OBP_WRP10, 0x03FC);
}
}
void dfu_jump_app_if_valid(void)
{
/* Boot the application if it's valid */
if((*(volatile u32*)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
/* Set vector table base address */
SCB_VTOR = APP_ADDRESS & 0x1FFFFF; /* Max 2 MByte Flash*/
/* Initialise master stack pointer */
asm volatile ("msr msp, %0"::"g"
(*(volatile u32*)APP_ADDRESS));
/* Jump to application */
(*(void(**)())(APP_ADDRESS + 4))();
}
}

View File

@ -0,0 +1,103 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2013 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(STM32F2)
# include <libopencm3/stm32/f2/flash.h>
#elif defined(STM32F4)
# include <libopencm3/stm32/f4/flash.h>
#endif
#include "usbdfu.h"
static u32 sector_addr[] = {0x8000000, 0x8004000, 0x8008000, 0x800c000,
0x8010000, 0x8020000, 0x8040000, 0x8060000,
0x8080000, 0x80a0000, 0x80c0000, 0x80e0000,
0x8100000, 0};
static u16 sector_erase_time[12]= {500, 500, 500, 500,
1100,
2600, 2600, 2600, 2600, 2600, 2600, 2600};
static u8 sector_num = 0xff;
/* Find the sector number for a given address*/
static 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 dfu_check_and_do_sector_erase(uint32_t addr)
{
if(addr == sector_addr[sector_num]) {
flash_erase_sector((sector_num & 0x1f)<<3, FLASH_PROGRAM_X32);
}
}
void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len)
{
for(int i = 0; i < len; i += 4)
flash_program_word(baseaddr + i,
*(u32*)(buf+i),
FLASH_PROGRAM_X32);
}
uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum)
{
/* Erase for big pages on STM2/4 needs "long" time
Try not to hit USB timeouts*/
if ((blocknum == 0) && (cmd == CMD_ERASE)) {
get_sector_num(addr);
if(addr == sector_addr[sector_num])
return sector_erase_time[sector_num];
}
/* Programming 256 word with 100 us(max) per word*/
return 26;
}
void dfu_protect_enable(void)
{
if ((FLASH_OPTCR & 0x10000) != 0) {
flash_program_option_bytes(FLASH_OPTCR & ~0x10000);
flash_lock_option_bytes();
}
}
void dfu_jump_app_if_valid(void)
{
/* Boot the application if it's valid */
/* Vector table may be anywhere in 128 kByte RAM
CCM not handled*/
if((*(volatile u32*)APP_ADDRESS & 0x2FFC0000) == 0x20000000) {
/* Set vector table base address */
SCB_VTOR = APP_ADDRESS & 0x1FFFFF; /* Max 2 MByte Flash*/
/* Initialise master stack pointer */
asm volatile ("msr msp, %0"::"g"
(*(volatile u32*)APP_ADDRESS));
/* Jump to application */
(*(void(**)())(APP_ADDRESS + 4))();
}
}

View File

@ -17,10 +17,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "platform.h"
#include <string.h> #include <string.h>
#if defined(STM32F1)
# include <libopencm3/stm32/f1/flash.h>
#elif defined(STM32F2)
# include <libopencm3/stm32/f2/flash.h>
#elif defined(STM32F4)
# include <libopencm3/stm32/f4/flash.h>
#endif
#include <libopencm3/usb/usbd.h> #include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/dfu.h> #include <libopencm3/usb/dfu.h>
#include "usbdfu.h"
/* Commands sent with wBlockNum == 0 as per ST implementation. */ /* Commands sent with wBlockNum == 0 as per ST implementation. */
#define CMD_SETADDR 0x21 #define CMD_SETADDR 0x21
#define CMD_ERASE 0x41 #define CMD_ERASE 0x41
@ -29,6 +40,8 @@ usbd_device *usbdev;
/* We need a special large control buffer for this device: */ /* We need a special large control buffer for this device: */
u8 usbd_control_buffer[1024]; u8 usbd_control_buffer[1024];
static u32 max_address;
static enum dfu_state usbdfu_state = STATE_DFU_IDLE; static enum dfu_state usbdfu_state = STATE_DFU_IDLE;
static char *get_dev_unique_id(char *serial_no); static char *get_dev_unique_id(char *serial_no);
@ -106,10 +119,10 @@ static char serial_no[9];
static const char *usb_strings[] = { static const char *usb_strings[] = {
"Black Sphere Technologies", "Black Sphere Technologies",
PRODUCT_STRING, BOARD_IDENT_DFU,
serial_no, serial_no,
/* This string is used by ST Microelectronics' DfuSe utility */ /* This string is used by ST Microelectronics' DfuSe utility */
IFACE_STRING, DFU_IFACE_STRING,
}; };
static u8 usbdfu_getstatus(u32 *bwPollTimeout) static u8 usbdfu_getstatus(u32 *bwPollTimeout)
@ -117,7 +130,7 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
switch(usbdfu_state) { switch(usbdfu_state) {
case STATE_DFU_DNLOAD_SYNC: case STATE_DFU_DNLOAD_SYNC:
usbdfu_state = STATE_DFU_DNBUSY; usbdfu_state = STATE_DFU_DNBUSY;
*bwPollTimeout = poll_timeout(prog.buf[0], *bwPollTimeout = dfu_poll_timeout(prog.buf[0],
*(u32 *)(prog.buf + 1), *(u32 *)(prog.buf + 1),
prog.blocknum); prog.blocknum);
return DFU_STATUS_OK; return DFU_STATUS_OK;
@ -151,7 +164,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
} }
switch(prog.buf[0]) { switch(prog.buf[0]) {
case CMD_ERASE: case CMD_ERASE:
check_and_do_sector_erase(addr); dfu_check_and_do_sector_erase(addr);
case CMD_SETADDR: case CMD_SETADDR:
prog.addr = addr; prog.addr = addr;
} }
@ -159,7 +172,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
u32 baseaddr = prog.addr + u32 baseaddr = prog.addr +
((prog.blocknum - 2) * ((prog.blocknum - 2) *
dfu_function.wTransferSize); dfu_function.wTransferSize);
flash_program_buffer(baseaddr, prog.buf, prog.len); dfu_flash_program_buffer(baseaddr, prog.buf, prog.len);
} }
flash_lock(); flash_lock();
@ -170,7 +183,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
return; return;
case STATE_DFU_MANIFEST: case STATE_DFU_MANIFEST:
detach(); dfu_detach();
return; /* Will never return */ return; /* Will never return */
default: default:
return; return;
@ -236,3 +249,56 @@ static int usbdfu_control_request(usbd_device *dev,
return 0; return 0;
} }
void dfu_init(const usbd_driver *driver)
{
get_dev_unique_id(serial_no);
usbdev = usbd_init(driver, &dev, &config, usb_strings, 4);
usbd_set_control_buffer_size(usbdev, sizeof(usbd_control_buffer));
usbd_register_control_callback(usbdev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
}
void dfu_main(void)
{
while (1)
usbd_poll(usbdev);
}
static char *get_dev_unique_id(char *s)
{
#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';
}
for(i = 0; i < 8; i++)
if(s[i] > '9')
s[i] += 'A' - '9' - 1;
s[8] = 0;
return s;
}

View File

@ -21,27 +21,9 @@
#include <libopencm3/cm3/systick.h> #include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/rcc.h> #include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h> #include <libopencm3/stm32/gpio.h>
#if defined(STM32F1)
#include <libopencm3/stm32/f1/flash.h>
#elif defined(STM32F2)
#include <libopencm3/stm32/f2/flash.h>
#elif defined(STM32F4)
#include <libopencm3/stm32/f4/flash.h>
#else
#warning "Unhandled STM32 family"
#endif
#include <libopencm3/cm3/scb.h> #include <libopencm3/cm3/scb.h>
#define FLASH_OBP_RDP 0x1FFFF800 #include "usbdfu.h"
#define FLASH_OBP_WRP10 0x1FFFF808
#define FLASH_OBP_RDP_KEY 0x5aa5
#if defined (STM32_CAN)
#define FLASHBLOCKSIZE 2048
#else
#define FLASHBLOCKSIZE 1024
#endif
#if defined(DISCOVERY_STLINK) #if defined(DISCOVERY_STLINK)
uint8_t rev; uint8_t rev;
@ -86,119 +68,7 @@ int stlink_test_nrst(void) {
} }
#endif #endif
static u32 max_address; void dfu_detach(void)
#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
#if defined(BLACKMAGIC)
# define PRODUCT_STRING \
"Black Magic Probe (Upgrade), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#elif defined(DISCOVERY_STLINK)
# define PRODUCT_STRING \
"Black Magic (Upgrade) for STLink/Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#elif defined(STM32_CAN)
# define PRODUCT_STRING \
"Black Magic (Upgrade) for STM32_CAN, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#elif defined(F4DISCOVERY)
# define PRODUCT_STRING \
"Black Magic (Upgrade) for F4Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#elif defined(USPS_F407)
# define PRODUCT_STRING \
"Black Magic (Upgrade) for USPS_F407, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#else
# warning "Unhandled board"
#endif
/* This string is used by ST Microelectronics' DfuSe utility */
#if defined(BLACKMAGIC)
# define IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,120*001Kg"
#elif defined(DISCOVERY_STLINK)
# define IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg"
#elif defined(STM32_CAN)
# define IFACE_STRING "@Internal Flash /0x08000000/4*002Ka,124*002Kg"
#elif defined(F4DISCOVERY) || defined(USPS_F407)
# define IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
#else
# warning "Unhandled board"
#endif
static u32 poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum)
{
#if defined(STM32F4)
/* Erase for big pages on STM2/4 needs "long" time
Try not to hit USB timeouts*/
if ((blocknum == 0) && (cmd == CMD_ERASE)) {
get_sector_num(addr);
if(addr == sector_addr[sector_num])
return sector_erase_time[sector_num];
}
/* Programming 256 word with 100 us(max) per word*/
return 26;
#else
(void)cmd;
(void)addr;
(void)blocknum;
return 100;
#endif
}
static void flash_program_buffer(uint32_t baseaddr, void *buf, int len)
{
int i;
#if defined (STM32F4)
for(i = 0; i < len; i += 4)
flash_program_word(baseaddr + i,
*(u32*)(buf+i),
FLASH_PROGRAM_X32);
#else
for(i = 0; i < len; i += 2)
flash_program_half_word(baseaddr + i,
*(u16*)(buf+i));
#endif
}
static void detach(void)
{ {
#if defined (DISCOVERY_STLINK) #if defined (DISCOVERY_STLINK)
/* Disconnect USB cable by resetting USB Device /* Disconnect USB cable by resetting USB Device
@ -216,8 +86,6 @@ static void detach(void)
scb_reset_system(); scb_reset_system();
} }
#include "dfucore.c"
int main(void) int main(void)
{ {
/* Check the force bootloader pin*/ /* Check the force bootloader pin*/
@ -247,40 +115,10 @@ int main(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
if(gpio_get(GPIOB, GPIO12)) { if(gpio_get(GPIOB, GPIO12)) {
#endif #endif
/* Boot the application if it's valid */ dfu_jump_app_if_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 & 0x1FFFFF; /* Max 2 MByte Flash*/
/* Initialise master stack pointer */
asm volatile ("msr msp, %0"::"g"
(*(volatile u32*)APP_ADDRESS));
/* Jump to application */
(*(void(**)())(APP_ADDRESS + 4))();
}
} }
#if defined (STM32F4) dfu_protect_enable();
if ((FLASH_OPTCR & 0x10000) != 0) {
flash_program_option_bytes(FLASH_OPTCR & ~0x10000);
flash_lock_option_bytes();
}
#else
if ((FLASH_WRPR & 0x03) != 0x00) {
flash_unlock();
FLASH_CR = 0;
flash_erase_option_bytes();
flash_program_option_bytes(FLASH_OBP_RDP, FLASH_OBP_RDP_KEY);
/* CL Device: Protect 2 bits with (2 * 2k pages each)*/
/* MD Device: Protect 2 bits with (4 * 1k pages each)*/
flash_program_option_bytes(FLASH_OBP_WRP10, 0x03FC);
}
#endif
/* Set up clock*/ /* Set up clock*/
#if defined (F4DISCOVERY) || defined(USPS_F407) #if defined (F4DISCOVERY) || defined(USPS_F407)
@ -316,7 +154,6 @@ int main(void)
#endif #endif
systick_interrupt_enable(); systick_interrupt_enable();
systick_counter_enable(); systick_counter_enable();
get_dev_unique_id(serial_no);
/* Handle LEDs */ /* Handle LEDs */
#if defined(F4DISCOVERY) #if defined(F4DISCOVERY)
@ -345,8 +182,7 @@ int main(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN); rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
usbdev = usbd_init(&stm32f107_usb_driver, dfu_init(&stm32f107_usb_driver);
&dev, &config, usb_strings, 4);
#elif defined(STM32F2)||defined(STM32F4) #elif defined(STM32F2)||defined(STM32F4)
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN);
@ -355,17 +191,10 @@ int main(void)
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO9 | GPIO10 | GPIO11 | GPIO12); GPIO9 | GPIO10 | GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO10| GPIO11 | GPIO12); gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO10| GPIO11 | GPIO12);
usbdev = usbd_init(&stm32f107_usb_driver, dfu_init(&stm32f107_usb_driver);
&dev, &config, usb_strings, 4);
#else #else
usbdev = usbd_init(&stm32f103_usb_driver, dfu_init(&stm32f103_usb_driver);
&dev, &config, usb_strings, 4);
#endif #endif
usbd_set_control_buffer_size(usbdev, sizeof(usbd_control_buffer));
usbd_register_control_callback(usbdev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
#if defined(BLACKMAGIC) #if defined(BLACKMAGIC)
gpio_set(GPIOA, GPIO8); gpio_set(GPIOA, GPIO8);
@ -373,45 +202,9 @@ int main(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
#endif #endif
while (1) dfu_main();
usbd_poll(usbdev);
} }
static char *get_dev_unique_id(char *s)
{
#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';
}
for(i = 0; i < 8; i++)
if(s[i] > '9')
s[i] += 'A' - '9' - 1;
s[8] = 0;
return s;
}
void sys_tick_handler() void sys_tick_handler()
{ {

View File

@ -0,0 +1,41 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2013 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/usb/usbd.h>
#ifdef STM32F4
# define APP_ADDRESS 0x08010000
#else
# define APP_ADDRESS 0x08002000
#endif
/* dfucore.c - DFU core, common to libopencm3 platforms. */
void dfu_init(const usbd_driver *driver);
void dfu_main(void);
/* Device specific functions */
void dfu_check_and_do_sector_erase(uint32_t sector);
void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len);
uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum);
void dfu_protect_enable(void);
void dfu_jump_app_if_valid(void);
/* Platform specific function */
void dfu_detach(void);

View File

@ -22,7 +22,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic.bin: blackmagic blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
blackmagic_dfu: usbdfu.o blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT) $(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu blackmagic_dfu.bin: blackmagic_dfu

View File

@ -40,7 +40,9 @@ extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1 #define CDCACM_GDB_ENDPOINT 1
#define CDCACM_UART_ENDPOINT 3 #define CDCACM_UART_ENDPOINT 3
#define BOARD_IDENT "Black Magic Probe (STM32_CAN), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")" #define BOARD_IDENT "Black Magic Probe (STM32_CAN), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for STM32_CAN, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (STM32_CAN)" #define DFU_IDENT "Black Magic Firmware Upgrade (STM32_CAN)"
#define DFU_IFACE_STRING "@Internal Flash /0x08000000/4*002Ka,124*002Kg"
/* Important pin mappings for STM32 implementation: /* Important pin mappings for STM32 implementation:
* *

View File

@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic.bin: blackmagic blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@ $(OBJCOPY) -O binary $^ $@
blackmagic_dfu: usbdfu.o blackmagic_dfu: usbdfu.o dfucore.o dfu_f4.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT) $(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu blackmagic_dfu.bin: blackmagic_dfu

View File

@ -36,7 +36,9 @@
#define CDCACM_PACKET_SIZE 64 #define CDCACM_PACKET_SIZE 64
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define BOARD_IDENT "Black Magic Probe (USPS_F407), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")" #define BOARD_IDENT "Black Magic Probe (USPS_F407), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for USPS_F407, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (USPS_F407)" #define DFU_IDENT "Black Magic Firmware Upgrade (USPS_F407)"
#define IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
extern usbd_device *usbdev; extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1 #define CDCACM_GDB_ENDPOINT 1