aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@ka-ata-killa.ourano.james.local>2021-03-03 15:24:13 +0000
committerroot <root@ka-ata-killa.ourano.james.local>2021-03-03 16:03:28 +0000
commit49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3 (patch)
treef65cb7440711ea1708c25fe78819e9986b2d8566
parent129a103238d69bd90b4fe9a44bbed943b9488fc2 (diff)
downloadserial_over_dp-49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3.tar.gz
serial_over_dp-49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3.tar.bz2
serial_over_dp-49148e76706e5e24c2ba7f6ccc1d7ec4736ab2f3.zip
support cheap chinese blue pill boards, make usb dfu compatible with dfuse
-rw-r--r--.gitignore2
-rw-r--r--Makefile.include4
-rw-r--r--Makefile.rules6
-rw-r--r--app/Makefile29
-rw-r--r--app/cdcacm.c188
-rw-r--r--app/dfu.c28
-rw-r--r--app/dummy_kb.c26
-rw-r--r--app/gdb.script2
-rw-r--r--app/i2c_bb.c70
-rw-r--r--app/i2c_hw.c12
-rw-r--r--app/main.c34
-rw-r--r--app/project.h11
-rw-r--r--app/prototypes.h20
-rw-r--r--app/ring.c12
-rw-r--r--app/ticker.c24
-rw-r--r--app/usart.c18
-rw-r--r--app/usb.c139
-rw-r--r--app/vuart.c45
-rw-r--r--boot/Makefile16
-rw-r--r--boot/gdb.script2
-rw-r--r--boot/usbdfu.c448
-rw-r--r--id.h5
-rwxr-xr-xtools/dfuse-pack.py256
23 files changed, 919 insertions, 478 deletions
diff --git a/.gitignore b/.gitignore
index e46adcb..ac9bbcd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@
*.hex
*~
*.dfu
+*.bin
+*.orig
diff --git a/Makefile.include b/Makefile.include
index 5d6f84f..389aa68 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -28,8 +28,8 @@ ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
# OpenOCD specific variables
OOCD ?= openocd
-#OOCD_INTERFACE ?= ../oocd/interface/stlink-v2.cfg
-OOCD_INTERFACE ?= ../oocd/interface/j-link.cfg
+OOCD_INTERFACE ?= ../oocd/interface/stlink-v2.cfg
+#OOCD_INTERFACE ?= ../oocd/interface/j-link.cfg
OOCD_BOARD ?= ../oocd/board/STM32F103R_BOARD.cfg
################################################################################
diff --git a/Makefile.rules b/Makefile.rules
index 28422d9..6e9fe6c 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -149,9 +149,9 @@ flash: $(BINARY).flash
@#printf " OBJCOPY $(*).hex\n"
$(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex
-%.dfu: %.elf
- @#printf " OBJCOPY $(*).dfu\n"
- $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).dfu
+#%.dfu: %.elf
+# @#printf " OBJCOPY $(*).dfu\n"
+# $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).dfu
%.srec: %.elf
@#printf " OBJCOPY $(*).srec\n"
diff --git a/app/Makefile b/app/Makefile
index dc5503b..e264ad4 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -24,7 +24,7 @@ PROG=serial_over_dp
V=1
default: ${PROG}.elf
-CSRCS= main.c cdcacm.c dfu.c i2c_bb.c vuart.c ring.c usart.c i2c_hw.c ticker.c ddc.c
+CSRCS= main.c cdcacm.c dfu.c i2c_bb.c vuart.c ring.c usart.c i2c_hw.c ticker.c ddc.c dummy_kb.c usb.c
HSRCS = project.h
@@ -38,14 +38,37 @@ VID=$(shell printf '\#include "id.h"\nID_VENDOR' | ${CC} -I.. -E - | grep -v ^\#
INCLUDES += -I..
-dfu:${PROG}.dfu
- dfu-util -R -a 0 -d ${VID}:${DID} -s 0x08002000:leave -D $<
+
+%.bin: %.elf
+ $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
+
+%.dfu:%.bin
+ ../tools/dfuse-pack.py -D 0x483:0xff03 -b 0x08002000:$< $@
+
+dfu:${PROG}.bin
+ dfu-util -R -a 0 -d 0483:ff03,0483:df11 -s 0x08002000:leave -D $<
program: ${PROG}.elf
echo halt | nc -t localhost 4444
echo flash write_image erase ${PWD}/$< 0x2000 | nc -t localhost 4444
echo reset run | nc -t localhost 4444
+ds:
+ $(Q)$(OOCD) -f $(OOCD_INTERFACE) \
+ -f $(OOCD_BOARD) \
+
+debug: ${PROG}.elf
+ ${PREFIX}-gdb -x gdb.script ${PROG}.elf
+
+reset:
+ $(Q)$(OOCD) -f $(OOCD_INTERFACE) \
+ -f $(OOCD_BOARD) \
+ -c "init" -c "reset run" \
+ -c shutdown
+
+
+
+
protos:
echo -n > prototypes.h
${CPROTO} $(INCLUDES) $(DEFINES) -e -v ${CSRCS} > prototypes.h.tmp
diff --git a/app/cdcacm.c b/app/cdcacm.c
index b300241..f6a1b0f 100644
--- a/app/cdcacm.c
+++ b/app/cdcacm.c
@@ -9,30 +9,17 @@ static uint8_t cdcacm_rx_ring_buf[BUFFER_SIZE];
ring_t cdcacm_tx_ring;
static uint8_t cdcacm_tx_ring_buf[BUFFER_SIZE];
+static int cdcacm_ready = 0;
-static const struct usb_device_descriptor dev = {
- .bLength = USB_DT_DEVICE_SIZE,
- .bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = 0x0200,
- .bDeviceClass = USB_CLASS_CDC,
- .bDeviceSubClass = 0,
- .bDeviceProtocol = 0,
- .bMaxPacketSize0 = 64,
- .idVendor = ID_VENDOR,
- .idProduct = ID_PRODUCT,
- .bcdDevice = 0x0200,
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 3,
- .bNumConfigurations = 1,
-};
-
+#define COMM_EP 0x83
+#define DATA_IN 0x01
+#define DATA_OUT 0x82
static const struct usb_endpoint_descriptor comm_endp[] = {
{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x83,
+ .bEndpointAddress = COMM_EP,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = 255,
@@ -43,7 +30,7 @@ static const struct usb_endpoint_descriptor data_endp[] = {
{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x01,
+ .bEndpointAddress = DATA_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 1,
@@ -51,7 +38,7 @@ static const struct usb_endpoint_descriptor data_endp[] = {
{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x82,
+ .bEndpointAddress = DATA_OUT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 1,
@@ -63,7 +50,7 @@ static const struct {
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
-} __attribute__ ( (packed)) cdcacm_functional_descriptors = {
+} __attribute__ ((packed)) cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof (struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
@@ -76,7 +63,7 @@ static const struct {
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
- .bDataInterface = 1,
+ .bDataInterface = 3,
},
.acm = {
.bFunctionLength = sizeof (struct usb_cdc_acm_descriptor),
@@ -88,15 +75,15 @@ static const struct {
.bFunctionLength = sizeof (struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
- .bControlInterface = 0,
- .bSubordinateInterface0 = 1,
+ .bControlInterface = 2,
+ .bSubordinateInterface0 = 3,
}
};
-static const struct usb_interface_descriptor comm_iface = {
+const struct usb_interface_descriptor comm_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
+ .bInterfaceNumber = 2,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
@@ -108,10 +95,10 @@ static const struct usb_interface_descriptor comm_iface = {
.extralen = sizeof (cdcacm_functional_descriptors)
};
-static const struct usb_interface_descriptor data_iface = {
+const struct usb_interface_descriptor data_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 1,
+ .bInterfaceNumber = 3,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
@@ -121,71 +108,30 @@ static const struct usb_interface_descriptor data_iface = {
.endpoint = data_endp,
};
-static const struct usb_interface ifaces[] = {
- {
- .num_altsetting = 1,
- .altsetting = &comm_iface,
- },
- {
- .num_altsetting = 1,
- .altsetting = &data_iface,
- },
-#ifdef INCLUDE_DFU_INTERFACE
- {
- .num_altsetting = 1,
- .altsetting = &dfu_iface,
- },
-#endif
-};
-
-static const struct usb_config_descriptor config = {
- .bLength = USB_DT_CONFIGURATION_SIZE,
- .bDescriptorType = USB_DT_CONFIGURATION,
- .wTotalLength = 0,
-#ifdef INCLUDE_DFU_INTERFACE
- .bNumInterfaces = 3,
-#else
- .bNumInterfaces = 2,
-#endif
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = 0x80,
- .bMaxPower = 0x32,
- .interface = ifaces,
-};
-static const char *usb_strings[] = {
- "Meh",
- "Fish",
- "Soup",
-#ifdef INCLUDE_DFU_INTERFACE
- "DFU",
-#endif
+const struct usb_iface_assoc_descriptor cdc_iface_assoc = {
+ .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
+ .bFirstInterface = 2,
+ .bInterfaceCount = 2,
+ .bFunctionClass = USB_CLASS_CDC,
+ .bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
+ .bFunctionProtocol = USB_CDC_PROTOCOL_AT,
+ .iFunction = 6,
};
-/* Buffer to be used for control requests. */
-uint8_t usbd_control_buffer[128];
-
-usbd_device *usbd_dev;
-
-static int cdcacm_control_request (usbd_device *usbd_dev,
- struct usb_setup_data *req,
- uint8_t **buf,
- uint16_t *len,
- usbd_control_complete_callback *complete)
+int cdcacm_control_request (usbd_device *usbd_dev,
+ struct usb_setup_data *req,
+ uint8_t **buf,
+ uint16_t *len,
+ usbd_control_complete_callback *complete)
{
(void) complete;
(void) buf;
(void) usbd_dev;
-#ifdef INCLUDE_DFU_INTERFACE
-
- if (dfu_control_request (usbd_dev, req, buf, len, complete)) {
- return 1;
- }
-#endif
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
@@ -194,24 +140,12 @@ static int cdcacm_control_request (usbd_device *usbd_dev,
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor.
*/
- char local_buf[10];
- struct usb_cdc_notification *notif = (void *) local_buf;
- /* We echo signals back to host as notification. */
- notif->bmRequestType = 0xA1;
- notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
- notif->wValue = 0;
- notif->wIndex = 0;
- notif->wLength = 2;
- local_buf[8] = req->wValue & 3;
- local_buf[9] = 0;
- // usbd_ep_write_packet(0x83, buf, 10);
return 1;
}
- case USB_CDC_REQ_SET_LINE_CODING:
- if (*len < sizeof (struct usb_cdc_line_coding)) {
+ case USB_CDC_REQ_SET_LINE_CODING:
+ if (*len < sizeof (struct usb_cdc_line_coding))
return 0;
- }
return 1;
}
@@ -220,69 +154,67 @@ static int cdcacm_control_request (usbd_device *usbd_dev,
}
+
void cdcacm_tick (void)
{
- unsigned ep = 0x82;
+ unsigned ep = DATA_OUT;
uint8_t buf[16];
uint8_t *ptr = buf;
size_t n = 0;
- if (ring_empty (&cdcacm_tx_ring)) {
+ if (!cdcacm_ready)
return;
- }
- if ( (*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) {
+ if (ring_empty (&cdcacm_tx_ring))
+ return;
+
+ /* Return if endpoint is already enabled. */
+ if ((*USB_EP_REG (ep & 0x7f) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID)
return;
- }
while (!ring_read_byte (&cdcacm_tx_ring, ptr++)) {
n++;
+
+ if (n == sizeof (buf)) break;
}
- usbd_ep_write_packet (usbd_dev, ep, buf, n);
+ usbd_ep_write_packet (usb_device, ep, buf, n);
+}
+
+int cdcacm_write (char *ptr, int len)
+{
+ int ret;
+
+ ret = ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len);
+ return ret;
}
+
static void cdcacm_data_rx_cb (usbd_device *usbd_dev, uint8_t ep)
{
(void) ep;
uint8_t buf[64];
- int len = usbd_ep_read_packet (usbd_dev, 0x01, buf, 64);
+ int len = usbd_ep_read_packet (usbd_dev, DATA_IN, buf, 64);
- if (len) {
+ if (len)
ring_write (&cdcacm_rx_ring, buf, len);
- }
}
-static void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue)
+void cdcacm_set_config (usbd_device *usbd_dev, uint16_t wValue)
{
(void) wValue;
- usbd_ep_setup (usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup (usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup (usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
- usbd_register_control_callback (usbd_dev,
- USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
- USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
- cdcacm_control_request);
+
+ usbd_ep_setup (usbd_dev, DATA_IN, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
+ usbd_ep_setup (usbd_dev, DATA_OUT, USB_ENDPOINT_ATTR_BULK, 64, NULL);
+ usbd_ep_setup (usbd_dev, COMM_EP, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
+ cdcacm_ready = 1;
}
-void usb_init (void)
+void cdcacm_rings_init (void)
{
ring_init (&cdcacm_rx_ring, cdcacm_rx_ring_buf, sizeof (cdcacm_rx_ring_buf));
ring_init (&cdcacm_tx_ring, cdcacm_tx_ring_buf, sizeof (cdcacm_tx_ring_buf));
- usbd_dev = usbd_init (&stm32f103_usb_driver,
- &dev,
- &config,
- usb_strings,
-#ifdef INCLUDE_DFU_INTERFACE
- 4,
-#else
- 3,
-#endif
- usbd_control_buffer,
- sizeof (usbd_control_buffer));
- usbd_register_set_config_callback (usbd_dev, cdcacm_set_config);
}
-
diff --git a/app/dfu.c b/app/dfu.c
index dcde674..b0715be 100644
--- a/app/dfu.c
+++ b/app/dfu.c
@@ -1,13 +1,9 @@
#include "project.h"
-#ifdef INCLUDE_DFU_INTERFACE
-
-extern uint32_t dfu_flag;
-
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof (struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
- .bmAttributes = USB_DFU_CAN_DOWNLOAD,
+ .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
@@ -16,25 +12,37 @@ const struct usb_dfu_descriptor dfu_function = {
const struct usb_interface_descriptor dfu_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 2,
+ .bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = 0xFE,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 1,
.iInterface = 4,
-
.extra = &dfu_function,
.extralen = sizeof (dfu_function),
};
+const struct usb_iface_assoc_descriptor dfu_iface_assoc = {
+ .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
+ .bFirstInterface = 1,
+ .bInterfaceCount = 1,
+ .bFunctionClass = 0xfe,
+ .bFunctionSubClass = 1,
+ .bFunctionProtocol = 1,
+ .iFunction = 5,
+};
+
+
static int
dfu_detach_complete (usbd_device *usbd_dev, struct usb_setup_data *req)
{
(void) req;
(void) usbd_dev;
dfu_flag = 0xfee1dead;
+
scb_reset_core();
return 1;
}
@@ -48,7 +56,7 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req,
(void) len;
(void) usbd_dev;
- if ( (req->bmRequestType & 0x7F) != 0x21) {
+ if ((req->bmRequestType & 0x7F) != 0x21) {
return 0; /* Only accept class request. */
}
@@ -63,11 +71,13 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req,
*len = 6;
return 1;
}
+
case DFU_GETSTATE:
/* Return state with no state transision. */
*buf[0] = STATE_APP_IDLE;
*len = 1;
return 1;
+
case DFU_DETACH:
*complete = dfu_detach_complete;
return 1;
@@ -75,4 +85,4 @@ dfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req,
return 0;
}
-#endif
+
diff --git a/app/dummy_kb.c b/app/dummy_kb.c
new file mode 100644
index 0000000..a1d61c7
--- /dev/null
+++ b/app/dummy_kb.c
@@ -0,0 +1,26 @@
+#include "project.h"
+
+const struct usb_interface_descriptor dummy_kb_iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = 0xff,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0,
+};
+
+
+const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc = {
+ .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
+ .bFirstInterface = 0,
+ .bInterfaceCount = 1,
+ .bFunctionClass = 0xff,
+ .bFunctionSubClass = 0,
+ .bFunctionProtocol = 0,
+ .iFunction = 4,
+};
+
diff --git a/app/gdb.script b/app/gdb.script
new file mode 100644
index 0000000..7cf9d09
--- /dev/null
+++ b/app/gdb.script
@@ -0,0 +1,2 @@
+target remote localhost:3333
+cont
diff --git a/app/i2c_bb.c b/app/i2c_bb.c
index f392b5e..cfa6742 100644
--- a/app/i2c_bb.c
+++ b/app/i2c_bb.c
@@ -106,57 +106,54 @@ static void i2c_bb_sm (int od, int d, int oc, int c)
}
// Check for STOP
- if (oc && c && !od && d) {
+ if (oc && c && !od && d)
state = ST_LOST;
- }
switch (state) {
case ST_LOST:
i2c_bb_sda (1);
i2c_bb_scl (1);
break;
+
case ST_ADDRESS_7...ST_ADDRESS_0:
- if (! (!oc && c)) {
+ if (! (!oc && c))
break;
- }
//rising scl of a7...a0
sr = (sr << 1) | !!d;
if (state == ST_ADDRESS_0) {
- if ( (sr & ~I2C_READ) == OUR_ADDRESS) {
+ if ((sr & ~I2C_READ) == OUR_ADDRESS) {
state++;
rnw = d;
- } else {
+ } else
state = ST_LOST;
- }
- } else {
+ } else
state++;
- }
break;
+
case ST_ADDRESS_ACK:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of a0
i2c_bb_sda (0);
- if (rnw) {
+ if (rnw)
state++;
- } else {
+
+ else
state = ST_PREP_REG_7;
- }
break;
+
case ST_OUT_7:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of ack
i2c_bb_sda (1);
@@ -168,32 +165,32 @@ static void i2c_bb_sm (int od, int d, int oc, int c)
i2c_bb_scl (1);
state++;
break;
+
case ST_OUT_6...ST_OUT_0:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of d6...d0
i2c_bb_sda (sr & 0x80);
sr <<= 1;
state++;
break;
+
case ST_PREP_OUT_ACK:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of d0
i2c_bb_sda (1);
state++;
break;
+
case ST_OUT_ACK:
- if (! (!oc && c)) {
+ if (! (!oc && c))
break;
- }
//rising scl of ack
@@ -207,74 +204,74 @@ static void i2c_bb_sm (int od, int d, int oc, int c)
}
break;
+
case ST_PREP_REG_7:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of ack
i2c_bb_sda (1);
sr = 0;
state++;
break;
+
case ST_REG_7...ST_REG_0:
- if (! (!oc && c)) {
+ if (! (!oc && c))
break;
- }
//rising scl of r7..r0
sr = (sr << 1) | !!d;
state++;
break;
+
case ST_REG_ACK:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of r0
reg = sr;
i2c_bb_sda (0);
state = ST_PREP_IN_7;
break;
+
case ST_PREP_IN_7:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of ack
i2c_bb_sda (1);
sr = 0;
state++;
break;
+
case ST_IN_7...ST_IN_0:
- if (! (!oc && c)) {
+ if (! (!oc && c))
break;
- }
//rising scl of i7..i0
sr = (sr << 1) | !!d;
state++;
break;
+
case ST_IN_ACK:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of i0
i2c_bb_sda (0);
state++;
break;
+
case ST_REG_WRITE:
- if (! (oc && !c)) {
+ if (! (oc && !c))
break;
- }
//falling scl of ack
i2c_bb_sda (1);
@@ -286,6 +283,7 @@ static void i2c_bb_sm (int od, int d, int oc, int c)
sr = 0;
state = ST_IN_7;
break;
+
default:
state = ST_LOST;
}
diff --git a/app/i2c_hw.c b/app/i2c_hw.c
index 11e796e..9b77009 100644
--- a/app/i2c_hw.c
+++ b/app/i2c_hw.c
@@ -34,11 +34,11 @@ void i2c1_ev_isr (void)
}
if (sr1 & I2C_SR1_TxE) {
- if (device) {
+ if (device)
v = ddc_read (reg++);
- } else {
+
+ else
v = vuart_read (reg++);
- }
I2C_DR (I2C) = v;
}
@@ -50,11 +50,11 @@ void i2c1_ev_isr (void)
reg = v;
next_is_reg = 0;
} else {
- if (reg == 0x10) {
+ if (reg == 0x10)
vuart_write (0, v);
- } else {
+
+ else
vuart_write (reg++, v);
- }
}
}
diff --git a/app/main.c b/app/main.c
index b98bd82..2ac458f 100644
--- a/app/main.c
+++ b/app/main.c
@@ -15,39 +15,27 @@ int main (void)
rcc_periph_clock_enable (RCC_USART1);
rcc_periph_clock_enable (RCC_AFIO);
rcc_periph_clock_enable (RCC_I2C1);
-#if 0
- nvic_set_priority (NVIC_I2C1_EV_IRQ, 0x38);
- nvic_set_priority (NVIC_I2C1_ER_IRQ, 0x39);
- nvic_set_priority (NVIC_USART1_IRQ, 0x44);
- nvic_set_priority (NVIC_SYSTICK_IRQ, 0xff);
-#else
nvic_set_priority (NVIC_I2C1_EV_IRQ, 0xff);
nvic_set_priority (NVIC_I2C1_ER_IRQ, 0xff);
nvic_set_priority (NVIC_SYSTICK_IRQ, 0x80);
nvic_set_priority (NVIC_USART1_IRQ, 0x40);
-#endif
+ nvic_set_priority (NVIC_USB_HP_CAN_TX_IRQ, 0x40);
+ nvic_set_priority (NVIC_USB_LP_CAN_RX0_IRQ, 0x40);
+
gpio_set_mode (LED1_BANK, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LED1_GPIO);
gpio_set_mode (LED2_BANK, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LED2_GPIO);
usart_init();
ticker_init();
- printf ("Morning chaps!\r\n");
-#ifdef USB
+ cdcacm_rings_init();
usb_init();
-#endif
-#ifdef I2C_BIT_BANG
- i2c_bb_init();
-#else
+
+ printf ("Morning chaps!\r\n");
+
i2c_hw_init();
-#endif
-
- for (;;) {
-#ifdef USB
- usbd_poll (usbd_dev);
-#endif
-#ifdef I2C_BIT_BANG
- i2c_bb_poll();
-#endif
- }
+
+ printf ("Ready\n");
+
+ for (;;);
return 0;
}
diff --git a/app/project.h b/app/project.h
index 3df1a38..f4b113b 100644
--- a/app/project.h
+++ b/app/project.h
@@ -10,16 +10,11 @@
#include <libopencm3/usb/hid.h>
#include <libopencm3/cm3/cortex.h>
#include <libopencm3/usb/cdc.h>
+#include <libopencm3/cm3/scb.h>
+#include <libopencm3/usb/dfu.h>
#include <id.h>
-#define INCLUDE_DFU_INTERFACE
#undef I2C_BIT_BANG
-#define USB
-
-#ifdef INCLUDE_DFU_INTERFACE
-#include <libopencm3/cm3/scb.h>
-#include <libopencm3/usb/dfu.h>
-#endif
#include <stdio.h>
#include <errno.h>
@@ -33,3 +28,5 @@
#include "ring.h"
#include "prototypes.h"
+
+extern uint32_t dfu_flag;
diff --git a/app/prototypes.h b/app/prototypes.h
index a877992..a432df4 100644
--- a/app/prototypes.h
+++ b/app/prototypes.h
@@ -3,13 +3,18 @@ extern int main(void);
/* cdcacm.c */
extern ring_t cdcacm_rx_ring;
extern ring_t cdcacm_tx_ring;
-extern uint8_t usbd_control_buffer[128];
-extern usbd_device *usbd_dev;
+extern const struct usb_interface_descriptor comm_iface;
+extern const struct usb_interface_descriptor data_iface;
+extern const struct usb_iface_assoc_descriptor cdc_iface_assoc;
+extern int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete);
extern void cdcacm_tick(void);
-extern void usb_init(void);
+extern int cdcacm_write(char *ptr, int len);
+extern void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue);
+extern void cdcacm_rings_init(void);
/* dfu.c */
extern const struct usb_dfu_descriptor dfu_function;
extern const struct usb_interface_descriptor dfu_iface;
+extern const struct usb_iface_assoc_descriptor dfu_iface_assoc;
extern int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete);
/* i2c_bb.c */
extern void i2c_bb_init(void);
@@ -42,3 +47,12 @@ extern void sys_tick_handler(void);
extern void ticker_init(void);
/* ddc.c */
extern uint8_t ddc_read(uint8_t v);
+/* dummy_kb.c */
+extern const struct usb_interface_descriptor dummy_kb_iface;
+extern const struct usb_iface_assoc_descriptor dummy_kb_iface_assoc;
+/* usb.c */
+extern uint8_t usbd_control_buffer[128];
+extern usbd_device *usb_device;
+extern void usb_hp_can_tx_isr(void);
+extern void usb_lp_can_rx0_isr(void);
+extern void usb_init(void);
diff --git a/app/ring.c b/app/ring.c
index e3a6209..26bba3a 100644
--- a/app/ring.c
+++ b/app/ring.c
@@ -6,9 +6,8 @@ ring_next (ring_t *r, size_t p)
{
p++;
- if (p >= r->size) {
+ if (p >= r->size)
p -= r->size;
- }
return p;
}
@@ -27,9 +26,8 @@ ring_write_byte (ring_t *r, uint8_t c)
{
size_t n = ring_next (r, r->write);
- if (n == r->read) {
+ if (n == r->read)
return -1;
- }
r->data[r->write] = c;
r->write = n;
@@ -46,9 +44,8 @@ ring_read_byte (ring_t *r, uint8_t *c)
{
size_t n = ring_next (r, r->read);
- if (r->read == r->write) {
+ if (r->read == r->write)
return -1;
- }
*c = r->data[r->read];
r->read = n;
@@ -59,9 +56,8 @@ int
ring_write (ring_t *r, uint8_t *buf, size_t len)
{
while (len--) {
- if (ring_write_byte (r, * (buf++))) {
+ if (ring_write_byte (r, * (buf++)))
return -1;
- }
}
return 0;
diff --git a/app/ticker.c b/app/ticker.c
index 05990d2..a28824c 100644
--- a/app/ticker.c
+++ b/app/ticker.c
@@ -13,9 +13,8 @@ delay_us (uint32_t d)
{
d *= scale;
- while (d--) {
+ while (d--)
__asm__ ("nop");
- }
}
void
@@ -24,25 +23,23 @@ sys_tick_handler (void)
ticks++;
cdcacm_tick();
- if (led1) {
+ if (led1)
led1--;
- }
- if (led2) {
+ if (led2)
led2--;
- }
- if (led1) {
+ if (led1)
gpio_clear (LED1_BANK, LED1_GPIO);
- } else {
+
+ else
gpio_set (LED1_BANK, LED1_GPIO);
- }
- if (led2) {
+ if (led2)
gpio_clear (LED2_BANK, LED2_GPIO);
- } else {
+
+ else
gpio_set (LED2_BANK, LED2_GPIO);
- }
}
@@ -63,9 +60,8 @@ ticker_init (void)
scale--;
v = ticks;
- while (v == ticks) {
+ while (v == ticks)
;
- }
delay_us (1000);
w = ticks;
diff --git a/app/usart.c b/app/usart.c
index ecd8e56..8659ab0 100644
--- a/app/usart.c
+++ b/app/usart.c
@@ -14,30 +14,28 @@ usart1_isr (void)
uint8_t data;
/* Check if we were called because of RXNE. */
- if ( ( (USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) &&
- ( (USART_SR (USART1) & USART_SR_RXNE) != 0)) {
+ if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) &&
+ ((USART_SR (USART1) & USART_SR_RXNE) != 0)) {
/* Retrieve the data from the peripheral. */
data = usart_recv (USART1);
ring_write_byte (&usart_rx_ring, data);
}
/* Check if we were called because of TXE. */
- if ( ( (USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) &&
- ( (USART_SR (USART1) & USART_SR_TXE) != 0)) {
+ if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) &&
+ ((USART_SR (USART1) & USART_SR_TXE) != 0)) {
if (ring_read_byte (&usart_tx_ring, &data)) {
/*No more data, Disable the TXE interrupt, it's no longer needed. */
USART_CR1 (USART1) &= ~USART_CR1_TXEIE;
- } else {
+ } else
usart_send (USART1, data);
- }
}
}
void usart_kick (void)
{
- if (!ring_empty (&usart_tx_ring)) {
+ if (!ring_empty (&usart_tx_ring))
USART_CR1 (USART1) |= USART_CR1_TXEIE;
- }
}
@@ -49,10 +47,10 @@ _write (int file, char *ptr, int len)
if (file == 1) {
ret = ring_write (&usart_tx_ring, (uint8_t *) ptr, len);
usart_kick();
+ ring_write (&cdcacm_tx_ring, (uint8_t *) ptr, len);
- if (ret < 0) {
+ if (ret < 0)
ret = -ret;
- }
return ret;
}
diff --git a/app/usb.c b/app/usb.c
new file mode 100644
index 0000000..8023ea3
--- /dev/null
+++ b/app/usb.c
@@ -0,0 +1,139 @@
+#include "project.h"
+
+#define USB_DM GPIO11
+#define USB_DM_PORT GPIOA
+#define USB_DP GPIO12
+#define USB_DP_PORT GPIOA
+
+/* Buffer to be used for control requests. */
+uint8_t usbd_control_buffer[128];
+usbd_device *usb_device;
+
+static const struct usb_device_descriptor dev = {
+ .bLength = USB_DT_DEVICE_SIZE,
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = 0x0200,
+ .bDeviceClass = 0xef,
+ .bDeviceSubClass = 0x02,
+ .bDeviceProtocol = 0x01,
+ .bMaxPacketSize0 = 64,
+ .idVendor = 0x0483,
+ .idProduct = 0xff03,
+ .bcdDevice = 0x0200,
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 3,
+ .bNumConfigurations = 1,
+};
+
+
+static const struct usb_interface ifaces[] = {
+ {
+ .num_altsetting = 1,
+ .altsetting = &dummy_kb_iface,
+ .iface_assoc = &dummy_kb_iface_assoc,
+ },
+ {
+ .num_altsetting = 1,
+ .altsetting = &dfu_iface,
+ .iface_assoc = &dfu_iface_assoc,
+ },
+ {
+ .num_altsetting = 1,
+ .altsetting = &comm_iface,
+ .iface_assoc = &cdc_iface_assoc,
+ },
+ {
+ .num_altsetting = 1,
+ .altsetting = &data_iface,
+ },
+};
+
+static const struct usb_config_descriptor config = {
+ .bLength = USB_DT_CONFIGURATION_SIZE,
+ .bDescriptorType = USB_DT_CONFIGURATION,
+ .wTotalLength = 0,
+ .bNumInterfaces = 4,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = 0x80,
+ .bMaxPower = 0x32,
+ .interface = ifaces,
+};
+
+static const char *usb_strings[] = {
+ VENDOR_NAME, /*1*/
+ PRODUCT_NAME, /*2*/
+ SERIAL_NUMBER, /*3*/
+ "dummy device", /*4*/
+ "DFU interface", /*5*/
+ "Debug interface", /*6*/
+};
+#define N_USB_STRINGS (sizeof(usb_strings)/sizeof(usb_strings[0]))
+
+void usb_hp_can_tx_isr (void)
+{
+ usbd_poll (usb_device);
+}
+
+void usb_lp_can_rx0_isr (void)
+{
+ usbd_poll (usb_device);
+}
+
+static int control_request (usbd_device *usbd_dev,
+ struct usb_setup_data *req,
+ uint8_t **buf,
+ uint16_t *len,
+ usbd_control_complete_callback *complete)
+{
+ if (dfu_control_request (usbd_dev, req, buf, len, complete))
+ return 1;
+
+ return cdcacm_control_request (usbd_dev, req, buf, len, complete);
+}
+
+static void set_config (usbd_device *usbd_dev, uint16_t wValue)
+{
+
+ cdcacm_set_config (usbd_dev, wValue);
+
+ usbd_register_control_callback (usbd_dev,
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ control_request);
+
+}
+
+
+
+void usb_init (void)
+{
+ /*Force USB reset */
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
+ gpio_clear (GPIOA, GPIO12);
+ gpio_clear (GPIOA, GPIO13);
+ delay_us (50000);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO13);
+
+
+ usb_device = usbd_init (&stm32f103_usb_driver,
+ &dev,
+ &config,
+ usb_strings,
+ N_USB_STRINGS,
+ usbd_control_buffer,
+ sizeof (usbd_control_buffer));
+
+ usbd_register_set_config_callback (usb_device, set_config);
+
+ nvic_enable_irq (NVIC_USB_HP_CAN_TX_IRQ);
+ nvic_enable_irq (NVIC_USB_LP_CAN_RX0_IRQ);
+
+
+
+}
+
+
diff --git a/app/vuart.c b/app/vuart.c
index 5aaf2d3..3c4ab79 100644
--- a/app/vuart.c
+++ b/app/vuart.c
@@ -82,25 +82,18 @@ static void vuart_xmit (uint8_t c)
led1 = 100;
ring_write_byte (&usart_tx_ring, c);
usart_kick();
-#ifdef USB
ring_write_byte (&cdcacm_tx_ring, c);
-#endif
}
static int vuart_recv_empty (void)
{
- if (!ring_empty (&usart_rx_ring)) {
+ if (!ring_empty (&usart_rx_ring))
return 0;
- }
-
-#ifdef USB
- if (!ring_empty (&cdcacm_rx_ring)) {
+ if (!ring_empty (&cdcacm_rx_ring))
return 0;
- }
-#endif
return 1;
}
@@ -114,25 +107,22 @@ static int vuart_recv (uint8_t *c)
return 0;
}
-#ifdef USB
-
if (!ring_read_byte (&cdcacm_rx_ring, c)) {
led2 = 100;
return 0;
}
-#endif
return -1;
}
static void update_lsr (void)
{
- if (vuart_recv_empty()) {
+ if (vuart_recv_empty())
lsr &= ~LSR_DA;
- } else {
+
+ else
lsr |= LSR_DA;
- }
}
uint8_t vuart_read (unsigned reg)
@@ -147,28 +137,33 @@ uint8_t vuart_read (unsigned reg)
vuart_recv (&val);
update_lsr();
return val;
- } else {
+ } else
return dllr;
- }
case IER:
//case DLLH:
return (lcr & LCR_DLAB) ? dlhr : ier;
+
case IIR:
return iir;
+
case LCR:
return lcr;
+
case MCR:
return mcr;
+
case LSR:
update_lsr();
val = lsr;
lsr &= 0xe1;
return val;
+
case MSR:
val = msr;
msr &= 0xf0;
return val;
+
case SR:
return sr;
}
@@ -183,29 +178,33 @@ void vuart_write (unsigned reg, uint8_t val)
case RXR:
//case DLLR:
- if (! (lcr & LCR_DLAB)) {
+ if (! (lcr & LCR_DLAB))
vuart_xmit (val);
- } else {
+
+ else
dllr = val;
- }
break;
+
case IER:
//case DLHR:
- if (! (lcr & LCR_DLAB)) {
+ if (! (lcr & LCR_DLAB))
ier = val & 0xf;
- } else {
+
+ else
dlhr = val;
- }
break;
+
case LCR:
lcr = val;
break;
+
case MCR:
mcr = val & 0x1f;
break;
+
case SR:
sr = val;
break;
diff --git a/boot/Makefile b/boot/Makefile
index 86d4d2c..4891184 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -30,3 +30,19 @@ include ../Makefile.include
CFLAGS += -I..
+ds:
+ $(Q)$(OOCD) -f $(OOCD_INTERFACE) \
+ -f $(OOCD_BOARD) \
+
+debug: ${PROG}.elf
+ ${PREFIX}-gdb -x gdb.script ${PROG}.elf
+
+reset:
+ $(Q)$(OOCD) -f $(OOCD_INTERFACE) \
+ -f $(OOCD_BOARD) \
+ -c "init" -c "reset run" \
+ -c shutdown
+
+tidy:
+ astyle -A3 -s2 --attach-extern-c -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS} || astyle -A3 -s2 -L -c -w -Y -m0 -f -p -H -U -k3 -xj -xd ${CSRCS} ${HSRCS}
+
diff --git a/boot/gdb.script b/boot/gdb.script
new file mode 100644
index 0000000..7cf9d09
--- /dev/null
+++ b/boot/gdb.script
@@ -0,0 +1,2 @@
+target remote localhost:3333
+cont
diff --git a/boot/usbdfu.c b/boot/usbdfu.c
index d538234..9287f57 100644
--- a/boot/usbdfu.c
+++ b/boot/usbdfu.c
@@ -27,13 +27,13 @@
#include <id.h>
-#define APP_ADDRESS 0x08002000
+#define APP_ADDRESS 0x08002000
/* Commands sent with wBlockNum == 0 as per ST implementation. */
-#define CMD_SETADDR 0x21
-#define CMD_ERASE 0x41
+#define CMD_SETADDR 0x21
+#define CMD_ERASE 0x41
-void usb_set_config (usbd_device * usbd_dev, uint16_t wValue);
+void usb_set_config (usbd_device *usbd_dev, uint16_t wValue);
/* We need a special large control buffer for this device: */
uint8_t usbd_control_buffer[1024];
@@ -43,248 +43,294 @@ static enum dfu_state usbdfu_state = STATE_DFU_IDLE;
extern uint32_t dfu_flag;
static struct {
- uint8_t buf[sizeof(usbd_control_buffer)];
- uint16_t len;
- uint32_t addr;
- uint16_t blocknum;
+ uint8_t buf[sizeof (usbd_control_buffer)];
+ uint16_t len;
+ uint32_t addr;
+ uint16_t blocknum;
} prog;
const struct usb_device_descriptor dev = {
- .bLength = USB_DT_DEVICE_SIZE,
- .bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = 0x0200,
- .bDeviceClass = 0,
- .bDeviceSubClass = 0,
- .bDeviceProtocol = 0,
- .bMaxPacketSize0 = 64,
- .idVendor = ID_VENDOR,
- .idProduct = ID_PRODUCT,
- .bcdDevice = 0x0200,
- .iManufacturer = 1,
- .iProduct = 2,
- .iSerialNumber = 3,
- .bNumConfigurations = 1,
+ .bLength = USB_DT_DEVICE_SIZE,
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = 0x0200,
+ .bDeviceClass = 0,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .bMaxPacketSize0 = 64,
+ .idVendor = 0x0483,
+ .idProduct = 0xdf11,
+ .bcdDevice = 0x0200,
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 3,
+ .bNumConfigurations = 1,
};
const struct usb_dfu_descriptor dfu_function = {
- .bLength = sizeof(struct usb_dfu_descriptor),
- .bDescriptorType = DFU_FUNCTIONAL,
- .bmAttributes = USB_DFU_CAN_DOWNLOAD,
- .wDetachTimeout = 255,
- .wTransferSize = 1024,
- .bcdDFUVersion = 0x011A,
+ .bLength = sizeof (struct usb_dfu_descriptor),
+ .bDescriptorType = DFU_FUNCTIONAL,
+ .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
+ .wDetachTimeout = 255,
+ .wTransferSize = 1024,
+ .bcdDFUVersion = 0x011A,
};
const struct usb_interface_descriptor iface = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bAlternateSetting = 0,
- .bNumEndpoints = 0,
- .bInterfaceClass = 0xFE, /* Device Firmware Upgrade */
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 2,
-
- /* The ST Microelectronics DfuSe application needs this string.
- * The format isn't documented... */
- .iInterface = 4,
-
- .extra = &dfu_function,
- .extralen = sizeof(dfu_function),
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = 0xFE, /* Device Firmware Upgrade */
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 2,
+
+ /* The ST Microelectronics DfuSe application needs this string.
+ * The format isn't documented... */
+ .iInterface = 4,
+
+ .extra = &dfu_function,
+ .extralen = sizeof (dfu_function),
};
const struct usb_interface ifaces[] = {{
- .num_altsetting = 1,
- .altsetting = &iface,
-}};
+ .num_altsetting = 1,
+ .altsetting = &iface,
+ }
+};
const struct usb_config_descriptor config = {
- .bLength = USB_DT_CONFIGURATION_SIZE,
- .bDescriptorType = USB_DT_CONFIGURATION,
- .wTotalLength = 0,
- .bNumInterfaces = 1,
- .bConfigurationValue = 1,
- .iConfiguration = 0,
- .bmAttributes = 0xC0,
- .bMaxPower = 0x32,
-
- .interface = ifaces,
+ .bLength = USB_DT_CONFIGURATION_SIZE,
+ .bDescriptorType = USB_DT_CONFIGURATION,
+ .wTotalLength = 0,
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = 0xC0,
+ .bMaxPower = 0x32,
+
+ .interface = ifaces,
};
static const char *usb_strings[] = {
- "Cabbages are good for you",
- "fish",
- "soup",
- /* This string is used by ST Microelectronics' DfuSe utility. */
- "@Internal Flash /0x08000000/8*001Ka,56*001Kg",
+ VENDOR_NAME,
+ PRODUCT_NAME " (dfu mode)",
+ SERIAL_NUMBER,
+ /* This string is used by ST Microelectronics' DfuSe utility. */
+ "@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
+#define N_USB_STRINGS (sizeof(usb_strings)/sizeof(usb_strings[0]))
-static uint8_t usbdfu_getstatus(usbd_device *usbd_dev, uint32_t *bwPollTimeout)
+static void
+delay_us (uint32_t d)
{
- (void)usbd_dev;
-
- switch (usbdfu_state) {
- case STATE_DFU_DNLOAD_SYNC:
- usbdfu_state = STATE_DFU_DNBUSY;
- *bwPollTimeout = 100;
- return DFU_STATUS_OK;
- case STATE_DFU_MANIFEST_SYNC:
- /* Device will reset when read is complete. */
- usbdfu_state = STATE_DFU_MANIFEST;
- return DFU_STATUS_OK;
- default:
- return DFU_STATUS_OK;
- }
+ d *= 7;
+
+ while (d--)
+ __asm__ ("nop");
}
-static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
+
+static uint8_t usbdfu_getstatus (usbd_device *usbd_dev, uint32_t *bwPollTimeout)
{
- int i;
- (void)req;
- (void)usbd_dev;
-
- switch (usbdfu_state) {
- case STATE_DFU_DNBUSY:
- flash_unlock();
- if (prog.blocknum == 0) {
- switch (prog.buf[0]) {
- case CMD_ERASE:
- {
- uint32_t *dat = (uint32_t *)(prog.buf + 1);
- flash_erase_page(*dat);
- }
- case CMD_SETADDR:
- {
- uint32_t *dat = (uint32_t *)(prog.buf + 1);
- prog.addr = *dat;
- }
- }
- } else {
- uint32_t baseaddr = prog.addr + ((prog.blocknum - 2) *
- dfu_function.wTransferSize);
- for (i = 0; i < prog.len; i += 2) {
- uint16_t *dat = (uint16_t *)(prog.buf + i);
- flash_program_half_word(baseaddr + i,
- *dat);
- }
- }
- flash_lock();
-
- /* Jump straight to dfuDNLOAD-IDLE, skipping dfuDNLOAD-SYNC. */
- usbdfu_state = STATE_DFU_DNLOAD_IDLE;
- return;
- case STATE_DFU_MANIFEST:
- /* USB device must detach, we just reset... */
- scb_reset_system();
- return; /* Will never return. */
- default:
- return;
- }
+ (void)usbd_dev;
+
+ switch (usbdfu_state) {
+ case STATE_DFU_DNLOAD_SYNC:
+ usbdfu_state = STATE_DFU_DNBUSY;
+ *bwPollTimeout = 100;
+ return DFU_STATUS_OK;
+
+ case STATE_DFU_MANIFEST_SYNC:
+ /* Device will reset when read is complete. */
+ usbdfu_state = STATE_DFU_MANIFEST;
+ return DFU_STATUS_OK;
+
+ default:
+ return DFU_STATUS_OK;
+ }
}
-static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
- uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
+static int usbdfu_getstatus_complete (usbd_device *usbd_dev, struct usb_setup_data *req)
{
+ int i;
+ (void)req;
+ (void)usbd_dev;
+
+ switch (usbdfu_state) {
+ case STATE_DFU_DNBUSY:
+ flash_unlock();
+
+ if (prog.blocknum == 0) {
+ switch (prog.buf[0]) {
+ case CMD_ERASE: {
+ uint32_t *dat = (uint32_t *) (prog.buf + 1);
+ flash_erase_page (*dat);
+ }
+ break;
+
+ case CMD_SETADDR: {
+ uint32_t *dat = (uint32_t *) (prog.buf + 1);
+ prog.addr = *dat;
+ }
+ }
+ } else {
+ uint32_t baseaddr = prog.addr + ((prog.blocknum - 2) *
+ dfu_function.wTransferSize);
+
+ for (i = 0; i < prog.len; i += 2) {
+ uint16_t *dat = (uint16_t *) (prog.buf + i);
+ flash_program_half_word (baseaddr + i,
+ *dat);
+ }
+ }
+
+ flash_lock();
+
+ /* Jump straight to dfuDNLOAD-IDLE, skipping dfuDNLOAD-SYNC. */
+ usbdfu_state = STATE_DFU_DNLOAD_IDLE;
+ return 0;
+
+ case STATE_DFU_MANIFEST:
+ /* USB device must detach, we just reset... */
+ scb_reset_system();
+ return 0; /* Will never return. */
+
+ default:
+ ;
+ }
+
+ return 0;
+}
- if ((req->bmRequestType & 0x7F) != 0x21)
- return 0; /* Only accept class request. */
-
- switch (req->bRequest) {
- case DFU_DNLOAD:
- if ((len == NULL) || (*len == 0)) {
- usbdfu_state = STATE_DFU_MANIFEST_SYNC;
- return 1;
- } else {
- /* Copy download data for use on GET_STATUS. */
- prog.blocknum = req->wValue;
- prog.len = *len;
- memcpy(prog.buf, *buf, *len);
- usbdfu_state = STATE_DFU_DNLOAD_SYNC;
- return 1;
- }
- case DFU_CLRSTATUS:
- /* Clear error and return to dfuIDLE. */
- if (usbdfu_state == STATE_DFU_ERROR)
- usbdfu_state = STATE_DFU_IDLE;
- return 1;
- case DFU_ABORT:
- /* Abort returns to dfuIDLE state. */
- usbdfu_state = STATE_DFU_IDLE;
- return 1;
- case DFU_UPLOAD:
- /* Upload not supported for now. */
- return 0;
- case DFU_GETSTATUS: {
- uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
- (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout);
- (*buf)[1] = bwPollTimeout & 0xFF;
- (*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
- (*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
- (*buf)[4] = usbdfu_state;
- (*buf)[5] = 0; /* iString not used here */
- *len = 6;
- *complete = usbdfu_getstatus_complete;
- return 1;
- }
- case DFU_GETSTATE:
- /* Return state with no state transision. */
- *buf[0] = usbdfu_state;
- *len = 1;
- return 1;
- }
-
- return 0;
+static int usbdfu_control_request (usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
+ uint16_t *len, usbd_control_complete_callback *complete)
+{
+
+ if ((req->bmRequestType & 0x7F) != 0x21)
+ return 0; /* Only accept class request. */
+
+ switch (req->bRequest) {
+ case DFU_DNLOAD:
+ if ((len == NULL) || (*len == 0)) {
+ usbdfu_state = STATE_DFU_MANIFEST_SYNC;
+ return 1;
+ } else {
+ /* Copy download data for use on GET_STATUS. */
+ prog.blocknum = req->wValue;
+ prog.len = *len;
+ memcpy (prog.buf, *buf, *len);
+ usbdfu_state = STATE_DFU_DNLOAD_SYNC;
+ return 1;
+ }
+
+ case DFU_CLRSTATUS:
+
+ /* Clear error and return to dfuIDLE. */
+ if (usbdfu_state == STATE_DFU_ERROR)
+ usbdfu_state = STATE_DFU_IDLE;
+
+ return 1;
+
+ case DFU_ABORT:
+ /* Abort returns to dfuIDLE state. */
+ usbdfu_state = STATE_DFU_IDLE;
+ return 1;
+
+ case DFU_UPLOAD:
+ /* Upload not supported for now. */
+ return 0;
+
+ case DFU_GETSTATUS: {
+ uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
+ (*buf)[0] = usbdfu_getstatus (usbd_dev, &bwPollTimeout);
+ (*buf)[1] = bwPollTimeout & 0xFF;
+ (*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
+ (*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
+ (*buf)[4] = usbdfu_state;
+ (*buf)[5] = 0; /* iString not used here */
+ *len = 6;
+ *complete = usbdfu_getstatus_complete;
+ return 1;
+ }
+
+ case DFU_GETSTATE:
+ /* Return state with no state transision. */
+ *buf[0] = usbdfu_state;
+ *len = 1;
+ return 1;
+ }
+
+ return 0;
}
+static void usb_reset (void)
+{
+ /*Force USB reset */
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
+ gpio_clear (GPIOA, GPIO12);
+ gpio_clear (GPIOA, GPIO13);
+
+ delay_us (5000);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO13);
+}
+
+
void
-usb_set_config (usbd_device * usbd_dev, uint16_t wValue)
+usb_set_config (usbd_device *usbd_dev, uint16_t wValue)
{
(void) wValue;
(void) usbd_dev;
-
- usbd_register_control_callback(
- usbd_dev,
- USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
- USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
- usbdfu_control_request);
+
+ usbd_register_control_callback (
+ usbd_dev,
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ usbdfu_control_request);
}
-int main(void)
+int main (void)
{
- usbd_device *usbd_dev;
+ usbd_device *usbd_dev;
+
+ rcc_periph_clock_enable (RCC_GPIOA);
+ rcc_periph_reset_pulse (RST_USB);
+
+ if (dfu_flag != 0xfee1dead) {
+ /* Boot the application if it's valid. */
+ if ((* (volatile uint32_t *)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
+ /* Set vector table base address. */
+ SCB_VTOR = APP_ADDRESS & 0xFFFF;
+ /* Initialise master stack pointer. */
+ asm volatile ("msr msp, %0"::"g"
+ (* (volatile uint32_t *)APP_ADDRESS));
+ /* Jump to application. */
+ (* (void (* *)()) (APP_ADDRESS + 4))();
+ }
+ }
- rcc_periph_clock_enable(RCC_GPIOA);
+ usb_reset();
- if (dfu_flag!=0xfee1dead) {
- /* Boot the application if it's valid. */
- if ((*(volatile uint32_t *)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
- /* Set vector table base address. */
- SCB_VTOR = APP_ADDRESS & 0xFFFF;
- /* Initialise master stack pointer. */
- asm volatile("msr msp, %0"::"g"
- (*(volatile uint32_t *)APP_ADDRESS));
- /* Jump to application. */
- (*(void (**)())(APP_ADDRESS + 4))();
- }
- }
+ dfu_flag = 0;
- dfu_flag=0;
+ rcc_clock_setup_in_hsi_out_48mhz();
- rcc_clock_setup_in_hsi_out_48mhz();
+ rcc_periph_clock_enable (RCC_GPIOC);
- rcc_periph_clock_enable(RCC_GPIOC);
+ gpio_set_mode (GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
+ gpio_set (GPIOC, GPIO11);
- gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
- GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
- gpio_set(GPIOC, GPIO11);
- usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 4, usbd_control_buffer, sizeof(usbd_control_buffer));
+ usbd_dev = usbd_init (&stm32f103_usb_driver, &dev, &config, usb_strings, N_USB_STRINGS, usbd_control_buffer, sizeof (usbd_control_buffer));
- usbd_register_set_config_callback (usbd_dev, usb_set_config);
+ usbd_register_set_config_callback (usbd_dev, usb_set_config);
- gpio_clear(GPIOC, GPIO11);
+ gpio_clear (GPIOC, GPIO11);
- while (1)
- usbd_poll(usbd_dev);
+ while (1)
+ usbd_poll (usbd_dev);
}
diff --git a/id.h b/id.h
index c65f067..d27ecf7 100644
--- a/id.h
+++ b/id.h
@@ -1,3 +1,4 @@
-#define ID_VENDOR 0x1234
-#define ID_PRODUCT 0x5678
+#define VENDOR_NAME "HP"
+#define PRODUCT_NAME "DDC Debug Dongle"
+#define SERIAL_NUMBER "Serialy McSerialFace"
diff --git a/tools/dfuse-pack.py b/tools/dfuse-pack.py
new file mode 100755
index 0000000..c0a5f0a
--- /dev/null
+++ b/tools/dfuse-pack.py
@@ -0,0 +1,256 @@
+#!/usr/bin/python
+
+# Written by Antonio Galea - 2010/11/18
+# Distributed under Gnu LGPL 3.0
+# see http://www.gnu.org/licenses/lgpl-3.0.txt
+
+import sys,struct,zlib,os
+import binascii
+from optparse import OptionParser
+
+try:
+ from intelhex import IntelHex
+except ImportError:
+ IntelHex = None
+
+DEFAULT_DEVICE="0x0483:0xdf11"
+DEFAULT_NAME=b'ST...'
+
+# Prefix and Suffix sizes are derived from ST's DfuSe File Format Specification (UM0391), DFU revision 1.1a
+PREFIX_SIZE=11
+SUFFIX_SIZE=16
+
+def named(tuple,names):
+ return dict(list(zip(names.split(),tuple)))
+def consume(fmt,data,names):
+ n = struct.calcsize(fmt)
+ return named(struct.unpack(fmt,data[:n]),names),data[n:]
+def cstring(bytestring):
+ return bytestring.partition(b'\0')[0]
+def compute_crc(data):
+ return 0xFFFFFFFF & -zlib.crc32(data) -1
+
+def parse(file,dump_images=False):
+ print('File: "%s"' % file)
+ data = open(file,'rb').read()
+ crc = compute_crc(data[:-4])
+ prefix, data = consume('<5sBIB',data,'signature version size targets')
+ print('%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix)
+ for t in range(prefix['targets']):
+ tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements')
+ tprefix['num'] = t
+ if tprefix['named']:
+ tprefix['name'] = cstring(tprefix['name'])
+ else:
+ tprefix['name'] = ''
+ print('%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix)
+ tsize = tprefix['size']
+ target, data = data[:tsize], data[tsize:]
+ for e in range(tprefix['elements']):
+ eprefix, target = consume('<2I',target,'address size')
+ eprefix['num'] = e
+ print(' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix)
+ esize = eprefix['size']
+ image, target = target[:esize], target[esize:]
+ if dump_images:
+ out = '%s.target%d.image%d.bin' % (file,t,e)
+ open(out,'wb').write(image)
+ print(' DUMPED IMAGE TO "%s"' % out)
+ if len(target):
+ print("target %d: PARSE ERROR" % t)
+ suffix = named(struct.unpack('<4H3sBI',data[:SUFFIX_SIZE]),'device product vendor dfu ufd len crc')
+ print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix)
+ if crc != suffix['crc']:
+ print("CRC ERROR: computed crc32 is 0x%08x" % crc)
+ data = data[SUFFIX_SIZE:]
+ if data:
+ print("PARSE ERROR")
+
+def checkbin(binfile):
+ data = open(binfile,'rb').read()
+ if (len(data) < SUFFIX_SIZE):
+ return
+ crc = compute_crc(data[:-4])
+ suffix = named(struct.unpack('<4H3sBI',data[-SUFFIX_SIZE:]),'device product vendor dfu ufd len crc')
+ if crc == suffix['crc'] and suffix['ufd'] == b'UFD':
+ print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix)
+ print("It looks like the file %s has a DFU suffix!" % binfile)
+ print("Please remove any DFU suffix and retry.")
+ sys.exit(1)
+
+def build(file,targets,name=DEFAULT_NAME,device=DEFAULT_DEVICE):
+ data = b''
+ for t,target in enumerate(targets):
+ tdata = b''
+ for image in target:
+ tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data']
+ ealt = image['alt']
+ tdata = struct.pack('<6sBI255s2I',b'Target',ealt,1,name,len(tdata),len(target)) + tdata
+ data += tdata
+ data = struct.pack('<5sBIB',b'DfuSe',1,PREFIX_SIZE + len(data) + SUFFIX_SIZE,len(targets)) + data
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
+ data += struct.pack('<4H3sB',0,d,v,0x011a,b'UFD',SUFFIX_SIZE)
+ crc = compute_crc(data)
+ data += struct.pack('<I',crc)
+ open(file,'wb').write(data)
+
+if __name__=="__main__":
+ usage = """
+%prog [-d|--dump] infile.dfu
+%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu
+%prog {-s|--build-s19} file.s19 [{-D|--device}=vendor:device] outfile.dfu
+%prog {-i|--build-ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu"""
+ parser = OptionParser(usage=usage)
+ parser.add_option("-b", "--build", action="append", dest="binfiles",
+ help="Include a raw binary file, to be loaded at the specified address. The BINFILES argument is of the form address:path-to-file. The address can have @X appended where X is the alternate interface number for this binary file. Note that the binary files must not have any DFU suffix!", metavar="BINFILES")
+ parser.add_option("-i", "--build-ihex", action="append", dest="hexfiles",
+ help="build a DFU file from given Intel HEX HEXFILES", metavar="HEXFILES")
+ parser.add_option("-s", "--build-s19", type="string", dest="s19files",
+ help="build a DFU file from given S19 S-record S19FILE", metavar="S19FILE")
+ parser.add_option("-D", "--device", action="store", dest="device",
+ help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
+ parser.add_option("-a", "--alt-intf", action="store", dest="alt",
+ help="build for alternate interface number ALTINTF, defaults to 0", metavar="ALTINTF")
+ parser.add_option("-d", "--dump", action="store_true", dest="dump_images",
+ default=False, help="dump contained images to current directory")
+ (options, args) = parser.parse_args()
+
+ targets = []
+
+ if options.alt:
+ try:
+ default_alt = int(options.alt)
+ except ValueError:
+ print("Alternate interface option argument %s invalid." % options.alt)
+ sys.exit(1)
+ else:
+ default_alt = 0
+
+ if (options.binfiles or options.hexfiles) and len(args)==1:
+ target = []
+ old_ealt = None
+
+ if options.binfiles:
+ for arg in options.binfiles:
+ try:
+ address,binfile = arg.split(':',1)
+ except ValueError:
+ print("Address:file couple '%s' invalid." % arg)
+ sys.exit(1)
+ try:
+ address,alts = address.split('@',1)
+ if alts:
+ try:
+ ealt = int(alts)
+ except ValueError:
+ print("Alternate interface number %s invalid." % alts)
+ sys.exit(1)
+ else:
+ ealt = default_alt
+ except ValueError:
+ ealt = default_alt
+ try:
+ address = int(address,0) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ if not os.path.isfile(binfile):
+ print("Unreadable file '%s'." % binfile)
+ sys.exit(1)
+ checkbin(binfile)
+ if old_ealt is not None and ealt != old_ealt:
+ targets.append(target)
+ target = []
+ target.append({ 'address': address, 'alt': ealt, 'data': open(binfile,'rb').read() })
+ old_ealt = ealt
+ targets.append(target)
+
+ if options.hexfiles:
+ if not IntelHex:
+ print("Error: IntelHex python module could not be found")
+ sys.exit(1)
+ for hexf in options.hexfiles:
+ ih = IntelHex(hexf)
+ for (address,end) in ih.segments():
+ try:
+ address = address & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ target.append({ 'address': address, 'alt': default_alt, 'data': ih.tobinstr(start=address, end=end-1)})
+ targets.append(target)
+
+ outfile = args[0]
+ device = DEFAULT_DEVICE
+ if options.device:
+ device=options.device
+ try:
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
+ except:
+ print("Invalid device '%s'." % device)
+ sys.exit(1)
+ build(outfile,targets,DEFAULT_NAME,device)
+ elif options.s19files and len(args)==1:
+ address = 0
+ data = ""
+ target = []
+ name = DEFAULT_NAME
+ with open(options.s19files) as f:
+ lines = f.readlines()
+ for line in lines:
+ curaddress = 0
+ curdata = ""
+ line = line.rstrip()
+ if line.startswith ( "S0" ):
+ name = binascii.a2b_hex(line[8:len(line) - 2])
+ elif line.startswith ( "S3" ):
+ try:
+ curaddress = int(line[4:12], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[12:-2])
+ elif line.startswith ( "S2" ):
+ try:
+ curaddress = int(line[4:10], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[10:-2])
+ elif line.startswith ( "S1" ):
+ try:
+ curaddress = int(line[4:8], 16) & 0xFFFFFFFF
+ except ValueError:
+ print("Address %s invalid." % address)
+ sys.exit(1)
+ curdata = binascii.unhexlify(line[8:-2])
+ if address == 0:
+ address = curaddress
+ data = curdata
+ elif address + len(data) != curaddress:
+ target.append({ 'address': address, 'alt': default_alt, 'data': data })
+ address = curaddress
+ data = curdata
+ else:
+ data += curdata
+ outfile = args[0]
+ device = DEFAULT_DEVICE
+ if options.device:
+ device=options.device
+ try:
+ v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
+ except:
+ print("Invalid device '%s'." % device)
+ sys.exit(1)
+ build(outfile,[target],name,device)
+ elif len(args)==1:
+ infile = args[0]
+ if not os.path.isfile(infile):
+ print("Unreadable file '%s'." % infile)
+ sys.exit(1)
+ parse(infile, dump_images=options.dump_images)
+ else:
+ parser.print_help()
+ if not IntelHex:
+ print("Note: Intel hex files support requires the IntelHex python module")
+ sys.exit(1)