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 3c9cc56..4198af5 100644 --- a/src/stm32/cdcacm.c +++ b/src/stm32/cdcacm.c @@ -47,6 +47,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, @@ -347,9 +348,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: { @@ -404,6 +408,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 561498a..84528aa 100644 --- a/src/stm32/platform.c +++ b/src/stm32/platform.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "platform.h" #include "jtag_scan.h" diff --git a/src/stm32/platform.h b/src/stm32/platform.h index 2b0f0ea..d23d42b 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