summaryrefslogtreecommitdiff
path: root/src/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/quirks.c')
-rwxr-xr-xsrc/quirks.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/src/quirks.c b/src/quirks.c
index de394a6..eec9ef9 100755
--- a/src/quirks.c
+++ b/src/quirks.c
@@ -1,7 +1,7 @@
/*
* Simple quirk system for dfu-util
*
- * Copyright 2010-2014 Tormod Volden
+ * Copyright 2010-2017 Tormod Volden
*
* 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
@@ -18,8 +18,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "portable.h"
#include "quirks.h"
+#include "dfuse_mem.h"
uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
{
@@ -32,7 +41,8 @@ uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
quirks |= QUIRK_POLLTIMEOUT;
if (vendor == VENDOR_VOTI &&
- product == PRODUCT_OPENPCD)
+ (product == PRODUCT_OPENPCD || product == PRODUCT_SIMTRACE ||
+ product == PRODUCT_OPENPICC))
quirks |= QUIRK_POLLTIMEOUT;
/* Reports wrong DFU version in DFU descriptor */
@@ -52,5 +62,66 @@ uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice)
product == PRODUCT_TRANSIT)
quirks |= QUIRK_POLLTIMEOUT;
+ /* Some GigaDevice GD32 devices have improperly-encoded serial numbers
+ * and bad DfuSe descriptors which we use serial number to correct.
+ * They also "leave" without a DFU_GETSTATUS request */
+ if (vendor == VENDOR_GIGADEVICE &&
+ product == PRODUCT_GD32) {
+ quirks |= QUIRK_UTF8_SERIAL;
+ quirks |= QUIRK_DFUSE_LAYOUT;
+ quirks |= QUIRK_DFUSE_LEAVE;
+ }
+
return (quirks);
}
+
+#define GD32VF103_FLASH_BASE 0x08000000
+
+void fixup_dfuse_layout(struct dfu_if *dif, struct memsegment **segment_list)
+{
+ if (dif->vendor == VENDOR_GIGADEVICE &&
+ dif->product == PRODUCT_GD32 &&
+ dif->altsetting == 0 &&
+ dif->serial_name &&
+ strlen(dif->serial_name) == 4 &&
+ dif->serial_name[0] == '3' &&
+ dif->serial_name[3] == 'J') {
+ struct memsegment *seg;
+ int count;
+
+ printf("Found GD32VF103, which reports a bad page size and "
+ "count for its internal memory.\n");
+
+ seg = find_segment(*segment_list, GD32VF103_FLASH_BASE);
+ if (!seg) {
+ warnx("Could not fix GD32VF103 layout because there "
+ "is no segment at 0x%08x", GD32VF103_FLASH_BASE);
+ return;
+ }
+
+ /* All GD32VF103 have this page size, according to Nucleisys's
+ * dfu-util (https://github.com/riscv-mcu/gd32-dfu-utils/). */
+ seg->pagesize = 1024;
+
+ /* From Tables 2-1 and 2-2 ("devices features and peripheral
+ * list") in the GD32VF103 Datasheet */
+ if (dif->serial_name[2] == 'B') {
+ count = 128;
+ } else if (dif->serial_name[2] == '8') {
+ count = 64;
+ } else if (dif->serial_name[2] == '6') {
+ count = 32;
+ } else if (dif->serial_name[2] == '4') {
+ count = 16;
+ } else {
+ warnx("Unknown flash size '%c' in part number; "
+ "defaulting to 128KB.", dif->serial_name[2]);
+ count = 128;
+ }
+
+ seg->end = seg->start + (count * seg->pagesize) - 1;
+
+ printf("Fixed layout based on part number: page size %d, "
+ "count %d.\n", seg->pagesize, count);
+ }
+}