From 1d8ebcd75f9191cdbb0f6ebde2cb80ff03f1d815 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 3 Mar 2017 13:12:14 +0100 Subject: [PATCH 1/2] Handle SET_ADDRESS according to DFUSE specs. --- src/platforms/stm32/dfucore.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/platforms/stm32/dfucore.c b/src/platforms/stm32/dfucore.c index 7b733d7..38cb421 100644 --- a/src/platforms/stm32/dfucore.c +++ b/src/platforms/stm32/dfucore.c @@ -48,6 +48,7 @@ static struct { uint32_t addr; uint16_t blocknum; } prog; +static uint8_t current_error; const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, @@ -149,7 +150,8 @@ static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout) /* Device will reset when read is complete */ usbdfu_state = STATE_DFU_MANIFEST; return DFU_STATUS_OK; - + case STATE_DFU_ERROR: + return current_error; default: return DFU_STATUS_OK; } @@ -159,23 +161,17 @@ static void usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req) { (void)req; + (void)dev; switch(usbdfu_state) { case STATE_DFU_DNBUSY: flash_unlock(); if(prog.blocknum == 0) { - uint32_t addr = get_le32(prog.buf + 1); - if ((addr < app_address) || (addr >= max_address)) { - flash_lock(); - usbd_ep_stall_set(dev, 0, 1); - return; - } + int32_t addr = get_le32(prog.buf + 1); switch(prog.buf[0]) { case CMD_ERASE: dfu_check_and_do_sector_erase(addr); - case CMD_SETADDR: - prog.addr = addr; } } else { uint32_t baseaddr = prog.addr + @@ -218,6 +214,15 @@ static int usbdfu_control_request(usbd_device *dev, prog.blocknum = req->wValue; prog.len = *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; return 1; } From d7965714382b6492c53341039e44fa893691db4a Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 3 Mar 2017 15:34:22 +0100 Subject: [PATCH 2/2] Implement DFU_UPLOAD. --- src/platforms/stlink/Flashsize_F103 | 39 +++++++++++++++++++++++++++++ src/platforms/stm32/dfucore.c | 20 ++++++++++++--- 2 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 src/platforms/stlink/Flashsize_F103 diff --git a/src/platforms/stlink/Flashsize_F103 b/src/platforms/stlink/Flashsize_F103 new file mode 100644 index 0000000..d4ece0f --- /dev/null +++ b/src/platforms/stlink/Flashsize_F103 @@ -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* diff --git a/src/platforms/stm32/dfucore.c b/src/platforms/stm32/dfucore.c index 38cb421..bfe4f3a 100644 --- a/src/platforms/stm32/dfucore.c +++ b/src/platforms/stm32/dfucore.c @@ -70,7 +70,7 @@ const struct usb_device_descriptor dev = { const struct usb_dfu_descriptor dfu_function = { .bLength = sizeof(struct usb_dfu_descriptor), .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, .wTransferSize = 1024, .bcdDFUVersion = 0x011A, @@ -236,8 +236,22 @@ static int usbdfu_control_request(usbd_device *dev, usbdfu_state = STATE_DFU_IDLE; return 1; case DFU_UPLOAD: - /* Upload not supported for now */ - return 0; + 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; + } case DFU_GETSTATUS: { uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */