commit
b10971b19b
|
@ -0,0 +1,39 @@
|
||||||
|
Announced versus available Flash size on F103
|
||||||
|
============================================
|
||||||
|
Up to Stlink V2, the CPU soldered on the board was a F103C8 with 64 kiByte
|
||||||
|
flash. Up to about version 280 of BMP, this limit was not hit when linked
|
||||||
|
against nanolib.
|
||||||
|
|
||||||
|
StlinkV2-1 has a STM32F103CB, like a genuine BMP.
|
||||||
|
|
||||||
|
However with more and more devices supported, BMP at about version 282 hit
|
||||||
|
this limit. There are two ways to work around:
|
||||||
|
- Branch STlink V2-1 as separate platform and and care for the original STlink
|
||||||
|
platform by restricting/ommitting features.
|
||||||
|
- Rely on uncertain upper flash on F103C8
|
||||||
|
|
||||||
|
The first option needs more care as an additional platform is introduced and
|
||||||
|
will restrict usage of older STlinks as BMPs.
|
||||||
|
|
||||||
|
However F103C8 and F103CB have the same chip and upper flash exists on F103C8.
|
||||||
|
This flash may have been tested bad, or not have been tested at all,
|
||||||
|
or, in the best case, was tested good but market requirements made STM sell
|
||||||
|
it as F103C8.
|
||||||
|
|
||||||
|
Ignoring the chip marking and using an F103C8 blindly as a F103Cb is done
|
||||||
|
already with few problems on many china boards (e.g. blue pill). Probably
|
||||||
|
this second approach will work for many of the older STLinks.
|
||||||
|
|
||||||
|
Use at your own risk!
|
||||||
|
|
||||||
|
With DFU upload available in the bootloader, you can verify by uploading the
|
||||||
|
binary from flash and comparing it against the binary downloaded.
|
||||||
|
- Download new BMP binary (if not already done)
|
||||||
|
dfu-util -s 0x08002000:leave:force -D blackmagic.bin
|
||||||
|
- Get length of binary
|
||||||
|
> ls -l blackmagic.bin
|
||||||
|
-rwxr-xr-x 1 bon users 57372 15. Apr 14:17 blackmagic.bin
|
||||||
|
- Upload binary from flash
|
||||||
|
> dfu-util -s 0x08002000:leave:force:57372 -U blackmagic.bin.1
|
||||||
|
- Compare
|
||||||
|
> diff blackmagic.bin*
|
|
@ -48,6 +48,7 @@ static struct {
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
uint16_t blocknum;
|
uint16_t blocknum;
|
||||||
} prog;
|
} prog;
|
||||||
|
static uint8_t current_error;
|
||||||
|
|
||||||
const struct usb_device_descriptor dev = {
|
const struct usb_device_descriptor dev = {
|
||||||
.bLength = USB_DT_DEVICE_SIZE,
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
|
@ -69,7 +70,7 @@ const struct usb_device_descriptor dev = {
|
||||||
const struct usb_dfu_descriptor dfu_function = {
|
const struct usb_dfu_descriptor dfu_function = {
|
||||||
.bLength = sizeof(struct usb_dfu_descriptor),
|
.bLength = sizeof(struct usb_dfu_descriptor),
|
||||||
.bDescriptorType = DFU_FUNCTIONAL,
|
.bDescriptorType = DFU_FUNCTIONAL,
|
||||||
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
|
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_WILL_DETACH,
|
||||||
.wDetachTimeout = 255,
|
.wDetachTimeout = 255,
|
||||||
.wTransferSize = 1024,
|
.wTransferSize = 1024,
|
||||||
.bcdDFUVersion = 0x011A,
|
.bcdDFUVersion = 0x011A,
|
||||||
|
@ -149,7 +150,8 @@ static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout)
|
||||||
/* Device will reset when read is complete */
|
/* Device will reset when read is complete */
|
||||||
usbdfu_state = STATE_DFU_MANIFEST;
|
usbdfu_state = STATE_DFU_MANIFEST;
|
||||||
return DFU_STATUS_OK;
|
return DFU_STATUS_OK;
|
||||||
|
case STATE_DFU_ERROR:
|
||||||
|
return current_error;
|
||||||
default:
|
default:
|
||||||
return DFU_STATUS_OK;
|
return DFU_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
@ -159,23 +161,17 @@ static void
|
||||||
usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
|
usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
|
||||||
{
|
{
|
||||||
(void)req;
|
(void)req;
|
||||||
|
(void)dev;
|
||||||
|
|
||||||
switch(usbdfu_state) {
|
switch(usbdfu_state) {
|
||||||
case STATE_DFU_DNBUSY:
|
case STATE_DFU_DNBUSY:
|
||||||
|
|
||||||
flash_unlock();
|
flash_unlock();
|
||||||
if(prog.blocknum == 0) {
|
if(prog.blocknum == 0) {
|
||||||
uint32_t addr = get_le32(prog.buf + 1);
|
int32_t addr = get_le32(prog.buf + 1);
|
||||||
if ((addr < app_address) || (addr >= max_address)) {
|
|
||||||
flash_lock();
|
|
||||||
usbd_ep_stall_set(dev, 0, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch(prog.buf[0]) {
|
switch(prog.buf[0]) {
|
||||||
case CMD_ERASE:
|
case CMD_ERASE:
|
||||||
dfu_check_and_do_sector_erase(addr);
|
dfu_check_and_do_sector_erase(addr);
|
||||||
case CMD_SETADDR:
|
|
||||||
prog.addr = addr;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint32_t baseaddr = prog.addr +
|
uint32_t baseaddr = prog.addr +
|
||||||
|
@ -218,6 +214,15 @@ static int usbdfu_control_request(usbd_device *dev,
|
||||||
prog.blocknum = req->wValue;
|
prog.blocknum = req->wValue;
|
||||||
prog.len = *len;
|
prog.len = *len;
|
||||||
memcpy(prog.buf, *buf, *len);
|
memcpy(prog.buf, *buf, *len);
|
||||||
|
if ((req->wValue == 0) && (prog.buf[0] == CMD_SETADDR)) {
|
||||||
|
uint32_t addr = get_le32(prog.buf + 1);
|
||||||
|
if ((addr < app_address) || (addr >= max_address)) {
|
||||||
|
current_error = DFU_STATUS_ERR_TARGET;
|
||||||
|
usbdfu_state = STATE_DFU_ERROR;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
prog.addr = addr;
|
||||||
|
}
|
||||||
usbdfu_state = STATE_DFU_DNLOAD_SYNC;
|
usbdfu_state = STATE_DFU_DNLOAD_SYNC;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -231,8 +236,22 @@ static int usbdfu_control_request(usbd_device *dev,
|
||||||
usbdfu_state = STATE_DFU_IDLE;
|
usbdfu_state = STATE_DFU_IDLE;
|
||||||
return 1;
|
return 1;
|
||||||
case DFU_UPLOAD:
|
case DFU_UPLOAD:
|
||||||
/* Upload not supported for now */
|
if ((usbdfu_state == STATE_DFU_IDLE) ||
|
||||||
|
(usbdfu_state == STATE_DFU_DNLOAD_IDLE) ||
|
||||||
|
(usbdfu_state == STATE_DFU_UPLOAD_IDLE)) {
|
||||||
|
prog.blocknum = req->wValue;
|
||||||
|
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
|
||||||
|
if(prog.blocknum > 1) {
|
||||||
|
uint32_t baseaddr = prog.addr +
|
||||||
|
((prog.blocknum - 2) *
|
||||||
|
dfu_function.wTransferSize);
|
||||||
|
memcpy(*buf, (void*)baseaddr, *len);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
usbd_ep_stall_set(dev, 0, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
case DFU_GETSTATUS: {
|
case DFU_GETSTATUS: {
|
||||||
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
|
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue