From 89bcdcc60ab5e3c35e99c4f2cc7d052e831cc563 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 10 Jun 2012 17:34:26 +1200 Subject: Moved stm32 generic platform files out of native platform dir. --- src/platforms/native/Makefile.inc | 2 + src/platforms/native/gdb_if.c | 86 --------------------- src/platforms/native/jtagtap.c | 81 -------------------- src/platforms/native/platform.h | 3 + src/platforms/native/swdptap.c | 155 -------------------------------------- src/platforms/native/usbuart.c | 4 +- src/platforms/stm32/gdb_if.c | 86 +++++++++++++++++++++ src/platforms/stm32/jtagtap.c | 81 ++++++++++++++++++++ src/platforms/stm32/swdptap.c | 155 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 329 insertions(+), 324 deletions(-) delete mode 100644 src/platforms/native/gdb_if.c delete mode 100644 src/platforms/native/jtagtap.c delete mode 100644 src/platforms/native/swdptap.c create mode 100644 src/platforms/stm32/gdb_if.c create mode 100644 src/platforms/stm32/jtagtap.c create mode 100644 src/platforms/stm32/swdptap.c diff --git a/src/platforms/native/Makefile.inc b/src/platforms/native/Makefile.inc index 3bddde9..b60b562 100644 --- a/src/platforms/native/Makefile.inc +++ b/src/platforms/native/Makefile.inc @@ -8,6 +8,8 @@ LDFLAGS_BOOT = -lopencm3_stm32f1 -Wl,--defsym,_stack=0x20005000 \ -mthumb -mcpu=cortex-m3 -Wl,-gc-sections LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8002000 +VPATH += platforms/stm32 + SRC += cdcacm.c \ platform.c \ traceswo.c \ diff --git a/src/platforms/native/gdb_if.c b/src/platforms/native/gdb_if.c deleted file mode 100644 index aa43293..0000000 --- a/src/platforms/native/gdb_if.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2011 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* This file implements a transparent channel over which the GDB Remote - * Serial Debugging protocol is implemented. This implementation for STM32 - * uses the USB CDC-ACM device bulk endpoints to implement the channel. - */ -#include "platform.h" -#include - -#include "gdb_if.h" - -static uint32_t count_out; -static uint32_t count_in; -static uint32_t out_ptr; -static uint8_t buffer_out[CDCACM_PACKET_SIZE]; -static uint8_t buffer_in[CDCACM_PACKET_SIZE]; - -void gdb_if_putchar(unsigned char c, int flush) -{ - buffer_in[count_in++] = c; - if(flush || (count_in == CDCACM_PACKET_SIZE)) { - /* Refuse to send if USB isn't configured, and - * don't bother if nobody's listening */ - if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { - count_in = 0; - return; - } - while(usbd_ep_write_packet(1, buffer_in, count_in) <= 0); - count_in = 0; - } -} - -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, - CDCACM_PACKET_SIZE); - out_ptr = 0; - } - - return buffer_out[out_ptr++]; -} - -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, - CDCACM_PACKET_SIZE); - out_ptr = 0; - } while(timeout_counter && !(out_ptr < count_out)); - - if(out_ptr < count_out) - return gdb_if_getchar(); - - return -1; -} - diff --git a/src/platforms/native/jtagtap.c b/src/platforms/native/jtagtap.c deleted file mode 100644 index 8160be8..0000000 --- a/src/platforms/native/jtagtap.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2011 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* This file implements the low-level JTAG TAP interface. */ - -#include - -#include "general.h" - -#include "jtagtap.h" - -int jtagtap_init(void) -{ - gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); - - /* Go to JTAG mode for SWJ-DP */ - for(int i = 0; i <= 50; i++) jtagtap_next(1, 0); /* Reset SW-DP */ - jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */ - jtagtap_soft_reset(); - - return 0; -} - -void jtagtap_reset(void) -{ - volatile int i; - gpio_clear(TRST_PORT, TRST_PIN); - for(i = 0; i < 10000; i++) asm("nop"); - gpio_set(TRST_PORT, TRST_PIN); - jtagtap_soft_reset(); -} - -void jtagtap_srst(void) -{ - volatile int i; - gpio_set(SRST_PORT, SRST_PIN); - for(i = 0; i < 10000; i++) asm("nop"); - gpio_clear(SRST_PORT, SRST_PIN); -} - -inline uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDO) -{ - uint16_t ret; - - gpio_set_val(TMS_PORT, TMS_PIN, dTMS); - gpio_set_val(TDI_PORT, TDI_PIN, dTDO); - gpio_set(TCK_PORT, TCK_PIN); - ret = gpio_get(TDO_PORT, TDO_PIN); - gpio_clear(TCK_PORT, TCK_PIN); - - DEBUG("jtagtap_next(TMS = %d, TDO = %d) = %d\n", dTMS, dTDO, ret); - - return ret != 0; -} - - - -#define PROVIDE_GENERIC_JTAGTAP_TMS_SEQ -#define PROVIDE_GENERIC_JTAGTAP_TDI_TDO_SEQ -#define PROVIDE_GENERIC_JTAGTAP_TDI_SEQ - -#include "jtagtap_generic.c" - diff --git a/src/platforms/native/platform.h b/src/platforms/native/platform.h index c8f5f2b..1f4416d 100644 --- a/src/platforms/native/platform.h +++ b/src/platforms/native/platform.h @@ -35,6 +35,9 @@ #define CDCACM_PACKET_SIZE 64 #define PLATFORM_HAS_TRACESWO +#define CDCACM_GDB_ENDPOINT 1 +#define CDCACM_UART_ENDPOINT 3 + /* Important pin mappings for STM32 implementation: * * LED0 = PB2 (Yellow LED : Running) diff --git a/src/platforms/native/swdptap.c b/src/platforms/native/swdptap.c deleted file mode 100644 index dceb23e..0000000 --- a/src/platforms/native/swdptap.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2011 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* This file implements the low-level SW-DP interface. */ - -#include - -#include "general.h" - -#include "swdptap.h" - -#include "gdb_packet.h" - -static void swdptap_turnaround(uint8_t dir) -{ - static uint8_t olddir = 0; - - DEBUG("%s", dir ? "\n-> ":"\n<- "); - - /* Don't turnaround if direction not changing */ - if(dir == olddir) return; - olddir = dir; - - if(dir) - gpio_set_mode(SWDIO_PORT, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_FLOAT, SWDIO_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_clear(SWCLK_PORT, SWCLK_PIN); - if(!dir) - gpio_set_mode(SWDIO_PORT, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, SWDIO_PIN); -} - -static uint8_t swdptap_bit_in(void) -{ - uint16_t ret; - - ret = gpio_get(SWDIO_PORT, SWDIO_PIN); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_clear(SWCLK_PORT, SWCLK_PIN); - - DEBUG("%d", ret?1:0); - - return ret != 0; -} - -static void swdptap_bit_out(uint8_t val) -{ - DEBUG("%d", val); - - gpio_set_val(SWDIO_PORT, SWDIO_PIN, val); - gpio_set(SWCLK_PORT, SWCLK_PIN); - gpio_clear(SWCLK_PORT, SWCLK_PIN); -} - -int swdptap_init(void) -{ - /* This must be investigated in more detail. - * As described in STM32 Reference Manual... */ - swdptap_reset(); - swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ - swdptap_reset(); - swdptap_seq_out(0, 16); - - return 0; -} - - -void swdptap_reset(void) -{ - swdptap_turnaround(0); - /* 50 clocks with TMS high */ - for(int i = 0; i < 50; i++) swdptap_bit_out(1); -} - - -uint32_t swdptap_seq_in(int ticks) -{ - uint32_t index = 1; - uint32_t ret = 0; - - swdptap_turnaround(1); - - while(ticks--) { - if(swdptap_bit_in()) ret |= index; - index <<= 1; - } - - return ret; -} - - -uint8_t swdptap_seq_in_parity(uint32_t *ret, int ticks) -{ - uint32_t index = 1; - uint8_t parity = 0; - *ret = 0; - - swdptap_turnaround(1); - - while(ticks--) { - if(swdptap_bit_in()) { - *ret |= index; - parity ^= 1; - } - index <<= 1; - } - if(swdptap_bit_in()) parity ^= 1; - - return parity; -} - - -void swdptap_seq_out(uint32_t MS, int ticks) -{ - swdptap_turnaround(0); - - while(ticks--) { - swdptap_bit_out(MS & 1); - MS >>= 1; - } -} - - -void swdptap_seq_out_parity(uint32_t MS, int ticks) -{ - uint8_t parity = 0; - - swdptap_turnaround(0); - - while(ticks--) { - swdptap_bit_out(MS & 1); - parity ^= MS; - MS >>= 1; - } - swdptap_bit_out(parity & 1); -} - diff --git a/src/platforms/native/usbuart.c b/src/platforms/native/usbuart.c index 2fac6ee..0d46253 100644 --- a/src/platforms/native/usbuart.c +++ b/src/platforms/native/usbuart.c @@ -91,7 +91,7 @@ void usbuart_usb_out_cb(uint8_t ep) (void)ep; char buf[CDCACM_PACKET_SIZE]; - int len = usbd_ep_read_packet(0x03, buf, CDCACM_PACKET_SIZE); + int len = usbd_ep_read_packet(CDCACM_UART_ENDPOINT, buf, CDCACM_PACKET_SIZE); /* Don't bother if uart is disabled. * This will be the case on mini while we're being debugged. @@ -126,7 +126,7 @@ void usart1_isr(void) gpio_set(LED_PORT, LED_UART); /* Try to send now */ - if (usbd_ep_write_packet(0x83, &c, 1) == 1) + if (usbd_ep_write_packet(CDCACM_UART_ENDPOINT, &c, 1) == 1) return; /* We failed, so queue for later */ diff --git a/src/platforms/stm32/gdb_if.c b/src/platforms/stm32/gdb_if.c new file mode 100644 index 0000000..30ad247 --- /dev/null +++ b/src/platforms/stm32/gdb_if.c @@ -0,0 +1,86 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file implements a transparent channel over which the GDB Remote + * Serial Debugging protocol is implemented. This implementation for STM32 + * uses the USB CDC-ACM device bulk endpoints to implement the channel. + */ +#include "platform.h" +#include + +#include "gdb_if.h" + +static uint32_t count_out; +static uint32_t count_in; +static uint32_t out_ptr; +static uint8_t buffer_out[CDCACM_PACKET_SIZE]; +static uint8_t buffer_in[CDCACM_PACKET_SIZE]; + +void gdb_if_putchar(unsigned char c, int flush) +{ + buffer_in[count_in++] = c; + if(flush || (count_in == CDCACM_PACKET_SIZE)) { + /* Refuse to send if USB isn't configured, and + * don't bother if nobody's listening */ + if((cdcacm_get_config() != 1) || !cdcacm_get_dtr()) { + count_in = 0; + return; + } + while(usbd_ep_write_packet(CDCACM_GDB_ENDPOINT, buffer_in, count_in) <= 0); + count_in = 0; + } +} + +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(CDCACM_GDB_ENDPOINT, buffer_out, + CDCACM_PACKET_SIZE); + out_ptr = 0; + } + + return buffer_out[out_ptr++]; +} + +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(CDCACM_GDB_ENDPOINT, buffer_out, + CDCACM_PACKET_SIZE); + out_ptr = 0; + } while(timeout_counter && !(out_ptr < count_out)); + + if(out_ptr < count_out) + return gdb_if_getchar(); + + return -1; +} + diff --git a/src/platforms/stm32/jtagtap.c b/src/platforms/stm32/jtagtap.c new file mode 100644 index 0000000..8160be8 --- /dev/null +++ b/src/platforms/stm32/jtagtap.c @@ -0,0 +1,81 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file implements the low-level JTAG TAP interface. */ + +#include + +#include "general.h" + +#include "jtagtap.h" + +int jtagtap_init(void) +{ + gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); + + /* Go to JTAG mode for SWJ-DP */ + for(int i = 0; i <= 50; i++) jtagtap_next(1, 0); /* Reset SW-DP */ + jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */ + jtagtap_soft_reset(); + + return 0; +} + +void jtagtap_reset(void) +{ + volatile int i; + gpio_clear(TRST_PORT, TRST_PIN); + for(i = 0; i < 10000; i++) asm("nop"); + gpio_set(TRST_PORT, TRST_PIN); + jtagtap_soft_reset(); +} + +void jtagtap_srst(void) +{ + volatile int i; + gpio_set(SRST_PORT, SRST_PIN); + for(i = 0; i < 10000; i++) asm("nop"); + gpio_clear(SRST_PORT, SRST_PIN); +} + +inline uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDO) +{ + uint16_t ret; + + gpio_set_val(TMS_PORT, TMS_PIN, dTMS); + gpio_set_val(TDI_PORT, TDI_PIN, dTDO); + gpio_set(TCK_PORT, TCK_PIN); + ret = gpio_get(TDO_PORT, TDO_PIN); + gpio_clear(TCK_PORT, TCK_PIN); + + DEBUG("jtagtap_next(TMS = %d, TDO = %d) = %d\n", dTMS, dTDO, ret); + + return ret != 0; +} + + + +#define PROVIDE_GENERIC_JTAGTAP_TMS_SEQ +#define PROVIDE_GENERIC_JTAGTAP_TDI_TDO_SEQ +#define PROVIDE_GENERIC_JTAGTAP_TDI_SEQ + +#include "jtagtap_generic.c" + diff --git a/src/platforms/stm32/swdptap.c b/src/platforms/stm32/swdptap.c new file mode 100644 index 0000000..dceb23e --- /dev/null +++ b/src/platforms/stm32/swdptap.c @@ -0,0 +1,155 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file implements the low-level SW-DP interface. */ + +#include + +#include "general.h" + +#include "swdptap.h" + +#include "gdb_packet.h" + +static void swdptap_turnaround(uint8_t dir) +{ + static uint8_t olddir = 0; + + DEBUG("%s", dir ? "\n-> ":"\n<- "); + + /* Don't turnaround if direction not changing */ + if(dir == olddir) return; + olddir = dir; + + if(dir) + gpio_set_mode(SWDIO_PORT, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_FLOAT, SWDIO_PIN); + gpio_set(SWCLK_PORT, SWCLK_PIN); + gpio_clear(SWCLK_PORT, SWCLK_PIN); + if(!dir) + gpio_set_mode(SWDIO_PORT, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, SWDIO_PIN); +} + +static uint8_t swdptap_bit_in(void) +{ + uint16_t ret; + + ret = gpio_get(SWDIO_PORT, SWDIO_PIN); + gpio_set(SWCLK_PORT, SWCLK_PIN); + gpio_clear(SWCLK_PORT, SWCLK_PIN); + + DEBUG("%d", ret?1:0); + + return ret != 0; +} + +static void swdptap_bit_out(uint8_t val) +{ + DEBUG("%d", val); + + gpio_set_val(SWDIO_PORT, SWDIO_PIN, val); + gpio_set(SWCLK_PORT, SWCLK_PIN); + gpio_clear(SWCLK_PORT, SWCLK_PIN); +} + +int swdptap_init(void) +{ + /* This must be investigated in more detail. + * As described in STM32 Reference Manual... */ + swdptap_reset(); + swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ + swdptap_reset(); + swdptap_seq_out(0, 16); + + return 0; +} + + +void swdptap_reset(void) +{ + swdptap_turnaround(0); + /* 50 clocks with TMS high */ + for(int i = 0; i < 50; i++) swdptap_bit_out(1); +} + + +uint32_t swdptap_seq_in(int ticks) +{ + uint32_t index = 1; + uint32_t ret = 0; + + swdptap_turnaround(1); + + while(ticks--) { + if(swdptap_bit_in()) ret |= index; + index <<= 1; + } + + return ret; +} + + +uint8_t swdptap_seq_in_parity(uint32_t *ret, int ticks) +{ + uint32_t index = 1; + uint8_t parity = 0; + *ret = 0; + + swdptap_turnaround(1); + + while(ticks--) { + if(swdptap_bit_in()) { + *ret |= index; + parity ^= 1; + } + index <<= 1; + } + if(swdptap_bit_in()) parity ^= 1; + + return parity; +} + + +void swdptap_seq_out(uint32_t MS, int ticks) +{ + swdptap_turnaround(0); + + while(ticks--) { + swdptap_bit_out(MS & 1); + MS >>= 1; + } +} + + +void swdptap_seq_out_parity(uint32_t MS, int ticks) +{ + uint8_t parity = 0; + + swdptap_turnaround(0); + + while(ticks--) { + swdptap_bit_out(MS & 1); + parity ^= MS; + MS >>= 1; + } + swdptap_bit_out(parity & 1); +} + -- cgit v1.2.3