Further split-up of DFU bootloader.
This commit is contained in:
parent
14e5e8b0b6
commit
55f161208d
|
@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
|
|||
blackmagic.bin: blackmagic
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
blackmagic_dfu: usbdfu.o
|
||||
blackmagic_dfu: usbdfu.o dfucore.o dfu_f4.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
|
||||
|
||||
blackmagic_dfu.bin: blackmagic_dfu
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#define CDCACM_PACKET_SIZE 64
|
||||
#define PLATFORM_HAS_TRACESWO
|
||||
#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 IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
|
||||
|
||||
extern usbd_device *usbdev;
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
|
|
|
@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
|
|||
blackmagic.bin: blackmagic
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
blackmagic_dfu: usbdfu.o
|
||||
blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
|
||||
|
||||
blackmagic_dfu.bin: blackmagic_dfu
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#define CDCACM_PACKET_SIZE 64
|
||||
#define PLATFORM_HAS_TRACESWO
|
||||
#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_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,120*001Kg"
|
||||
|
||||
extern usbd_device *usbdev;
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
|
|
|
@ -21,7 +21,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
|
|||
blackmagic.bin: blackmagic
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
blackmagic_dfu: usbdfu.o
|
||||
blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
|
||||
|
||||
blackmagic_dfu.bin: blackmagic_dfu
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
#define INLINE_GPIO
|
||||
#define CDCACM_PACKET_SIZE 64
|
||||
#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_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg"
|
||||
|
||||
extern usbd_device *usbdev;
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
|
|
|
@ -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))();
|
||||
}
|
||||
}
|
||||
|
|
@ -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))();
|
||||
}
|
||||
}
|
||||
|
|
@ -17,10 +17,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "platform.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/dfu.h>
|
||||
|
||||
#include "usbdfu.h"
|
||||
|
||||
/* Commands sent with wBlockNum == 0 as per ST implementation. */
|
||||
#define CMD_SETADDR 0x21
|
||||
#define CMD_ERASE 0x41
|
||||
|
@ -29,6 +40,8 @@ usbd_device *usbdev;
|
|||
/* We need a special large control buffer for this device: */
|
||||
u8 usbd_control_buffer[1024];
|
||||
|
||||
static u32 max_address;
|
||||
|
||||
static enum dfu_state usbdfu_state = STATE_DFU_IDLE;
|
||||
|
||||
static char *get_dev_unique_id(char *serial_no);
|
||||
|
@ -106,10 +119,10 @@ static char serial_no[9];
|
|||
|
||||
static const char *usb_strings[] = {
|
||||
"Black Sphere Technologies",
|
||||
PRODUCT_STRING,
|
||||
BOARD_IDENT_DFU,
|
||||
serial_no,
|
||||
/* This string is used by ST Microelectronics' DfuSe utility */
|
||||
IFACE_STRING,
|
||||
DFU_IFACE_STRING,
|
||||
};
|
||||
|
||||
static u8 usbdfu_getstatus(u32 *bwPollTimeout)
|
||||
|
@ -117,7 +130,7 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout)
|
|||
switch(usbdfu_state) {
|
||||
case STATE_DFU_DNLOAD_SYNC:
|
||||
usbdfu_state = STATE_DFU_DNBUSY;
|
||||
*bwPollTimeout = poll_timeout(prog.buf[0],
|
||||
*bwPollTimeout = dfu_poll_timeout(prog.buf[0],
|
||||
*(u32 *)(prog.buf + 1),
|
||||
prog.blocknum);
|
||||
return DFU_STATUS_OK;
|
||||
|
@ -151,7 +164,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
|
|||
}
|
||||
switch(prog.buf[0]) {
|
||||
case CMD_ERASE:
|
||||
check_and_do_sector_erase(addr);
|
||||
dfu_check_and_do_sector_erase(addr);
|
||||
case CMD_SETADDR:
|
||||
prog.addr = addr;
|
||||
}
|
||||
|
@ -159,7 +172,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
|
|||
u32 baseaddr = prog.addr +
|
||||
((prog.blocknum - 2) *
|
||||
dfu_function.wTransferSize);
|
||||
flash_program_buffer(baseaddr, prog.buf, prog.len);
|
||||
dfu_flash_program_buffer(baseaddr, prog.buf, prog.len);
|
||||
}
|
||||
flash_lock();
|
||||
|
||||
|
@ -170,7 +183,7 @@ usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
|
|||
return;
|
||||
|
||||
case STATE_DFU_MANIFEST:
|
||||
detach();
|
||||
dfu_detach();
|
||||
return; /* Will never return */
|
||||
default:
|
||||
return;
|
||||
|
@ -236,3 +249,56 @@ static int usbdfu_control_request(usbd_device *dev,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -21,27 +21,9 @@
|
|||
#include <libopencm3/cm3/systick.h>
|
||||
#include <libopencm3/stm32/rcc.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>
|
||||
|
||||
#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
|
||||
#include "usbdfu.h"
|
||||
|
||||
#if defined(DISCOVERY_STLINK)
|
||||
uint8_t rev;
|
||||
|
@ -86,119 +68,7 @@ int stlink_test_nrst(void) {
|
|||
}
|
||||
#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
|
||||
|
||||
#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)
|
||||
void dfu_detach(void)
|
||||
{
|
||||
#if defined (DISCOVERY_STLINK)
|
||||
/* Disconnect USB cable by resetting USB Device
|
||||
|
@ -216,8 +86,6 @@ static void detach(void)
|
|||
scb_reset_system();
|
||||
}
|
||||
|
||||
#include "dfucore.c"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Check the force bootloader pin*/
|
||||
|
@ -247,40 +115,10 @@ int main(void)
|
|||
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 & 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))();
|
||||
}
|
||||
dfu_jump_app_if_valid();
|
||||
}
|
||||
|
||||
#if defined (STM32F4)
|
||||
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
|
||||
dfu_protect_enable();
|
||||
|
||||
/* Set up clock*/
|
||||
#if defined (F4DISCOVERY) || defined(USPS_F407)
|
||||
|
@ -316,7 +154,6 @@ int main(void)
|
|||
#endif
|
||||
systick_interrupt_enable();
|
||||
systick_counter_enable();
|
||||
get_dev_unique_id(serial_no);
|
||||
|
||||
/* Handle LEDs */
|
||||
#if defined(F4DISCOVERY)
|
||||
|
@ -345,8 +182,7 @@ int main(void)
|
|||
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);
|
||||
usbdev = usbd_init(&stm32f107_usb_driver,
|
||||
&dev, &config, usb_strings, 4);
|
||||
dfu_init(&stm32f107_usb_driver);
|
||||
#elif defined(STM32F2)||defined(STM32F4)
|
||||
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN);
|
||||
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,
|
||||
GPIO9 | GPIO10 | GPIO11 | GPIO12);
|
||||
gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO10| GPIO11 | GPIO12);
|
||||
usbdev = usbd_init(&stm32f107_usb_driver,
|
||||
&dev, &config, usb_strings, 4);
|
||||
dfu_init(&stm32f107_usb_driver);
|
||||
#else
|
||||
usbdev = usbd_init(&stm32f103_usb_driver,
|
||||
&dev, &config, usb_strings, 4);
|
||||
dfu_init(&stm32f103_usb_driver);
|
||||
#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)
|
||||
gpio_set(GPIOA, GPIO8);
|
||||
|
@ -373,45 +202,9 @@ int main(void)
|
|||
GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
usbd_poll(usbdev);
|
||||
dfu_main();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -22,7 +22,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
|
|||
blackmagic.bin: blackmagic
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
blackmagic_dfu: usbdfu.o
|
||||
blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
|
||||
|
||||
blackmagic_dfu.bin: blackmagic_dfu
|
||||
|
|
|
@ -40,7 +40,9 @@ extern usbd_device *usbdev;
|
|||
#define CDCACM_GDB_ENDPOINT 1
|
||||
#define CDCACM_UART_ENDPOINT 3
|
||||
#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_IFACE_STRING "@Internal Flash /0x08000000/4*002Ka,124*002Kg"
|
||||
|
||||
/* Important pin mappings for STM32 implementation:
|
||||
*
|
||||
|
|
|
@ -23,7 +23,7 @@ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
|
|||
blackmagic.bin: blackmagic
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
blackmagic_dfu: usbdfu.o
|
||||
blackmagic_dfu: usbdfu.o dfucore.o dfu_f4.o
|
||||
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
|
||||
|
||||
blackmagic_dfu.bin: blackmagic_dfu
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#define CDCACM_PACKET_SIZE 64
|
||||
#define PLATFORM_HAS_TRACESWO
|
||||
#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 IFACE_STRING "@Internal Flash /0x08000000/1*016Ka,3*016Kg,1*064Kg,7*128Kg"
|
||||
|
||||
extern usbd_device *usbdev;
|
||||
#define CDCACM_GDB_ENDPOINT 1
|
||||
|
|
Loading…
Reference in New Issue