aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth McMullin2011-07-02 20:47:39 +1200
committerGareth McMullin2011-07-02 20:47:39 +1200
commitadabaa759296b8f2470d7c562963d4e34dc35b19 (patch)
tree77d4ac2f07cce527a3d65bd7a35d2cc46b2485cb
parentbd779aa618fab9ceb47d432d8f31719618fd75a4 (diff)
Halt and detach target if host releases DTR.
Port reads 0x04 (EOF) when DTR is released. GDB loop detaches from target if EOF is read. Fixes bug 3307433.
-rw-r--r--src/gdb_main.c6
-rw-r--r--src/stm32/cdcacm.c15
-rw-r--r--src/stm32/gdb_if.c8
-rw-r--r--src/stm32/platform.c1
-rw-r--r--src/stm32/platform.h1
5 files changed, 26 insertions, 5 deletions
diff --git a/src/gdb_main.c b/src/gdb_main.c
index 0ffa4ec..1851b2c 100644
--- a/src/gdb_main.c
+++ b/src/gdb_main.c
@@ -151,11 +151,13 @@ gdb_main(void)
}
/* Wait for target halt */
- while(!target_halt_wait(cur_target))
- if(gdb_if_getchar_to(0) == '\x03') {
+ while(!target_halt_wait(cur_target)) {
+ unsigned char c = gdb_if_getchar_to(0);
+ if((c == '\x03') || (c == '\x04')) {
target_halt_request(cur_target);
sent_int = 1;
}
+ }
SET_RUN_STATE(0);
/* Report reason for halt */
diff --git a/src/stm32/cdcacm.c b/src/stm32/cdcacm.c
index 9cbd44b..a4f0527 100644
--- a/src/stm32/cdcacm.c
+++ b/src/stm32/cdcacm.c
@@ -46,6 +46,7 @@
static char *get_dev_unique_id(char *serial_no);
static int configured;
+static int cdcacm_gdb_dtr;
static const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
@@ -346,9 +347,12 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf,
switch(req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
- /* This Linux cdc_acm driver requires this to be implemented
- * even though it's optional in the CDC spec, and we don't
- * advertise it in the ACM functional descriptor. */
+ /* Ignore if not for GDB interface */
+ if(req->wIndex != 0)
+ return 1;
+
+ cdcacm_gdb_dtr = req->wValue & 1;
+
return 1;
#ifdef INCLUDE_UART_INTERFACE
case USB_CDC_REQ_SET_LINE_CODING: {
@@ -402,6 +406,11 @@ int cdcacm_get_config(void)
return configured;
}
+int cdcacm_get_dtr(void)
+{
+ return cdcacm_gdb_dtr;
+}
+
#ifdef INCLUDE_UART_INTERFACE
static void cdcacm_data_rx_cb(u8 ep)
{
diff --git a/src/stm32/gdb_if.c b/src/stm32/gdb_if.c
index 08dfa03..2ed8c41 100644
--- a/src/stm32/gdb_if.c
+++ b/src/stm32/gdb_if.c
@@ -47,6 +47,10 @@ void gdb_if_putchar(unsigned char c, int flush)
unsigned char gdb_if_getchar(void)
{
while(!(out_ptr < count_out)) {
+ /* Detach if port closed */
+ if(!cdcacm_get_dtr())
+ return 0x04;
+
while(cdcacm_get_config() != 1);
count_out = usbd_ep_read_packet(1, buffer_out,
VIRTUAL_COM_PORT_DATA_SIZE);
@@ -61,6 +65,10 @@ unsigned char gdb_if_getchar_to(int timeout)
timeout_counter = timeout/100;
if(!(out_ptr < count_out)) do {
+ /* Detach if port closed */
+ if(!cdcacm_get_dtr())
+ return 0x04;
+
count_out = usbd_ep_read_packet(1, buffer_out,
VIRTUAL_COM_PORT_DATA_SIZE);
out_ptr = 0;
diff --git a/src/stm32/platform.c b/src/stm32/platform.c
index 71458b1..d4a4471 100644
--- a/src/stm32/platform.c
+++ b/src/stm32/platform.c
@@ -28,6 +28,7 @@
#include <libopencm3/stm32/scb.h>
#include <libopencm3/stm32/nvic.h>
#include <libopencm3/stm32/usart.h>
+#include <libopencm3/usb/usbd.h>
#include "platform.h"
#include "jtag_scan.h"
diff --git a/src/stm32/platform.h b/src/stm32/platform.h
index 2925ae8..93f1694 100644
--- a/src/stm32/platform.h
+++ b/src/stm32/platform.h
@@ -124,6 +124,7 @@ void morse(const char *msg, char repeat);
void cdcacm_init(void);
/* Returns current usb configuration, or 0 if not configured. */
int cdcacm_get_config(void);
+int cdcacm_get_dtr(void);
/* Use newlib provided integer only stdio functions */
#define sscanf siscanf