Added capture of SWO, passed to host over a vendor specific USB interface.
This commit is contained in:
parent
9cff48dc6b
commit
21ecbd23ea
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
#include "adiv5.h"
|
#include "adiv5.h"
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
static void cmd_version(void);
|
static void cmd_version(void);
|
||||||
static void cmd_help(void);
|
static void cmd_help(void);
|
||||||
|
|
||||||
|
@ -45,6 +47,8 @@ static void cmd_swdp_scan(void);
|
||||||
static void cmd_targets(void);
|
static void cmd_targets(void);
|
||||||
static void cmd_morse(void);
|
static void cmd_morse(void);
|
||||||
|
|
||||||
|
static void cmd_traceswo(void);
|
||||||
|
|
||||||
const struct command_s cmd_list[] = {
|
const struct command_s cmd_list[] = {
|
||||||
{"version", (cmd_handler)cmd_version, "Display firmware version info"},
|
{"version", (cmd_handler)cmd_version, "Display firmware version info"},
|
||||||
{"help", (cmd_handler)cmd_help, "Display help for monitor commands"},
|
{"help", (cmd_handler)cmd_help, "Display help for monitor commands"},
|
||||||
|
@ -52,6 +56,7 @@ const struct command_s cmd_list[] = {
|
||||||
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
|
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
|
||||||
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
|
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
|
||||||
{"morse", (cmd_handler)cmd_morse, "Display morse error message" },
|
{"morse", (cmd_handler)cmd_morse, "Display morse error message" },
|
||||||
|
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture" },
|
||||||
|
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -159,4 +164,8 @@ void cmd_morse(void)
|
||||||
gdb_outf("%s\n", morse_msg);
|
gdb_outf("%s\n", morse_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmd_traceswo(void)
|
||||||
|
{
|
||||||
|
traceswo_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8002000
|
||||||
|
|
||||||
SRC += cdcacm.c \
|
SRC += cdcacm.c \
|
||||||
platform.c \
|
platform.c \
|
||||||
|
traceswo.c \
|
||||||
|
|
||||||
all: blackmagic.bin blackmagic_dfu.bin
|
all: blackmagic.bin blackmagic_dfu.bin
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "traceswo.h"
|
||||||
|
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
#define DFU_IF_NO 4
|
||||||
# define DFU_IF_NO 4
|
|
||||||
#else
|
|
||||||
# define DFU_IF_NO 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static char *get_dev_unique_id(char *serial_no);
|
static char *get_dev_unique_id(char *serial_no);
|
||||||
|
|
||||||
|
@ -172,7 +169,6 @@ static const struct usb_iface_assoc_descriptor gdb_assoc = {
|
||||||
.iFunction = 0,
|
.iFunction = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
/* Serial ACM interface */
|
/* Serial ACM interface */
|
||||||
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
@ -275,7 +271,6 @@ static const struct usb_iface_assoc_descriptor uart_assoc = {
|
||||||
.bFunctionProtocol = USB_CDC_PROTOCOL_AT,
|
.bFunctionProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
.iFunction = 0,
|
.iFunction = 0,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
const struct usb_dfu_descriptor dfu_function = {
|
const struct usb_dfu_descriptor dfu_function = {
|
||||||
.bLength = sizeof(struct usb_dfu_descriptor),
|
.bLength = sizeof(struct usb_dfu_descriptor),
|
||||||
|
@ -312,6 +307,40 @@ static const struct usb_iface_assoc_descriptor dfu_assoc = {
|
||||||
.iFunction = 6,
|
.iFunction = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct usb_endpoint_descriptor trace_endp[] = {{
|
||||||
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
|
.bEndpointAddress = 0x85,
|
||||||
|
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
|
||||||
|
.wMaxPacketSize = 16,
|
||||||
|
.bInterval = 0,
|
||||||
|
}};
|
||||||
|
|
||||||
|
const struct usb_interface_descriptor trace_iface = {
|
||||||
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
|
.bInterfaceNumber = 5,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = 0xFF,
|
||||||
|
.bInterfaceSubClass = 0xFF,
|
||||||
|
.bInterfaceProtocol = 0xFF,
|
||||||
|
.iInterface = 7,
|
||||||
|
|
||||||
|
.endpoint = trace_endp,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct usb_iface_assoc_descriptor trace_assoc = {
|
||||||
|
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
|
||||||
|
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
|
||||||
|
.bFirstInterface = 5,
|
||||||
|
.bInterfaceCount = 1,
|
||||||
|
.bFunctionClass = 0xFF,
|
||||||
|
.bFunctionSubClass = 0xFF,
|
||||||
|
.bFunctionProtocol = 0xFF,
|
||||||
|
.iFunction = 7,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct usb_interface ifaces[] = {{
|
static const struct usb_interface ifaces[] = {{
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
.iface_assoc = &gdb_assoc,
|
.iface_assoc = &gdb_assoc,
|
||||||
|
@ -320,7 +349,6 @@ static const struct usb_interface ifaces[] = {{
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
.altsetting = gdb_data_iface,
|
.altsetting = gdb_data_iface,
|
||||||
}, {
|
}, {
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
.iface_assoc = &uart_assoc,
|
.iface_assoc = &uart_assoc,
|
||||||
.altsetting = uart_comm_iface,
|
.altsetting = uart_comm_iface,
|
||||||
|
@ -328,21 +356,20 @@ static const struct usb_interface ifaces[] = {{
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
.altsetting = uart_data_iface,
|
.altsetting = uart_data_iface,
|
||||||
}, {
|
}, {
|
||||||
#endif
|
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
.iface_assoc = &dfu_assoc,
|
.iface_assoc = &dfu_assoc,
|
||||||
.altsetting = &dfu_iface,
|
.altsetting = &dfu_iface,
|
||||||
|
}, {
|
||||||
|
.num_altsetting = 1,
|
||||||
|
.iface_assoc = &trace_assoc,
|
||||||
|
.altsetting = &trace_iface,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static const struct usb_config_descriptor config = {
|
static const struct usb_config_descriptor config = {
|
||||||
.bLength = USB_DT_CONFIGURATION_SIZE,
|
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||||
.bDescriptorType = USB_DT_CONFIGURATION,
|
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||||
.wTotalLength = 0,
|
.wTotalLength = 0,
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
.bNumInterfaces = 6,
|
||||||
.bNumInterfaces = 5,
|
|
||||||
#else
|
|
||||||
.bNumInterfaces = 3,
|
|
||||||
#endif
|
|
||||||
.bConfigurationValue = 1,
|
.bConfigurationValue = 1,
|
||||||
.iConfiguration = 0,
|
.iConfiguration = 0,
|
||||||
.bmAttributes = 0x80,
|
.bmAttributes = 0x80,
|
||||||
|
@ -361,6 +388,7 @@ static const char *usb_strings[] = {
|
||||||
"Black Magic GDB Server",
|
"Black Magic GDB Server",
|
||||||
"Black Magic UART Port",
|
"Black Magic UART Port",
|
||||||
"Black Magic Firmware Upgrade",
|
"Black Magic Firmware Upgrade",
|
||||||
|
"Black Magic Trace Capture",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dfu_detach_complete(struct usb_setup_data *req)
|
static void dfu_detach_complete(struct usb_setup_data *req)
|
||||||
|
@ -395,7 +423,6 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf,
|
||||||
cdcacm_gdb_dtr = req->wValue & 1;
|
cdcacm_gdb_dtr = req->wValue & 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
case USB_CDC_REQ_SET_LINE_CODING: {
|
case USB_CDC_REQ_SET_LINE_CODING: {
|
||||||
if(*len < sizeof(struct usb_cdc_line_coding))
|
if(*len < sizeof(struct usb_cdc_line_coding))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -434,7 +461,6 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf,
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case DFU_GETSTATUS:
|
case DFU_GETSTATUS:
|
||||||
if(req->wIndex == DFU_IF_NO) {
|
if(req->wIndex == DFU_IF_NO) {
|
||||||
(*buf)[0] = DFU_STATUS_OK;
|
(*buf)[0] = DFU_STATUS_OK;
|
||||||
|
@ -467,7 +493,6 @@ int cdcacm_get_dtr(void)
|
||||||
return cdcacm_gdb_dtr;
|
return cdcacm_gdb_dtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
static void cdcacm_data_rx_cb(u8 ep)
|
static void cdcacm_data_rx_cb(u8 ep)
|
||||||
{
|
{
|
||||||
(void)ep;
|
(void)ep;
|
||||||
|
@ -477,7 +502,6 @@ static void cdcacm_data_rx_cb(u8 ep)
|
||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
usart_send_blocking(USART1, buf[i]);
|
usart_send_blocking(USART1, buf[i]);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void cdcacm_set_config(u16 wValue)
|
static void cdcacm_set_config(u16 wValue)
|
||||||
{
|
{
|
||||||
|
@ -488,12 +512,13 @@ static void cdcacm_set_config(u16 wValue)
|
||||||
usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
|
usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
|
||||||
usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
|
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
/* Serial interface */
|
/* Serial interface */
|
||||||
usbd_ep_setup(0x03, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, cdcacm_data_rx_cb);
|
usbd_ep_setup(0x03, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, cdcacm_data_rx_cb);
|
||||||
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
|
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
|
||||||
usbd_ep_setup(0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
usbd_ep_setup(0x84, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
|
||||||
#endif
|
|
||||||
|
/* Trace interface */
|
||||||
|
usbd_ep_setup(0x85, USB_ENDPOINT_ATTR_BULK, 16, trace_buf_drain);
|
||||||
|
|
||||||
usbd_register_control_callback(
|
usbd_register_control_callback(
|
||||||
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||||
|
@ -514,10 +539,8 @@ static void cdcacm_set_config(u16 wValue)
|
||||||
buf[8] = 3; /* DCD | DSR */
|
buf[8] = 3; /* DCD | DSR */
|
||||||
buf[9] = 0;
|
buf[9] = 0;
|
||||||
usbd_ep_write_packet(0x82, buf, 10);
|
usbd_ep_write_packet(0x82, buf, 10);
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
|
||||||
notif->wIndex = 2;
|
notif->wIndex = 2;
|
||||||
usbd_ep_write_packet(0x84, buf, 10);
|
usbd_ep_write_packet(0x84, buf, 10);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need a special large control buffer for this device: */
|
/* We need a special large control buffer for this device: */
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Black Magic Debug project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Black Sphere Technologies Ltd.
|
||||||
|
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file implements capture of the TRACESWO output.
|
||||||
|
*
|
||||||
|
* ARM DDI 0403D - ARMv7M Architecture Reference Manual
|
||||||
|
* ARM DDI 0337I - Cortex-M3 Technical Reference Manual
|
||||||
|
* ARM DDI 0314H - CoreSight Components Technical Reference Manual
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TDO/TRACESWO signal comes into pin PA6/TIM3_CH1
|
||||||
|
* Manchester coding is assumed on TRACESWO, so bit timing can be detected.
|
||||||
|
* The idea is to use TIM3 input capture modes to capture pulse timings.
|
||||||
|
* These can be capture directly to RAM by DMA.
|
||||||
|
* The core can then process the buffer to extract the frame.
|
||||||
|
*/
|
||||||
|
#include <libopencm3/stm32/nvic.h>
|
||||||
|
#include <libopencm3/stm32/timer.h>
|
||||||
|
#include <libopencm3/stm32/f1/rcc.h>
|
||||||
|
|
||||||
|
#include <libopencm3/usb/usbd.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void traceswo_init(void)
|
||||||
|
{
|
||||||
|
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM3EN);
|
||||||
|
|
||||||
|
timer_reset(TIM3);
|
||||||
|
|
||||||
|
/* Refer to ST doc RM0008 - STM32F10xx Reference Manual.
|
||||||
|
* Section 14.3.4 - 14.3.6 (General Purpose Timer - Input Capture)
|
||||||
|
*
|
||||||
|
* CCR1 captures cycle time, CCR2 captures high time
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Use TI1 as capture input for CH1 and CH2 */
|
||||||
|
timer_ic_set_input(TIM3, TIM_IC1, TIM_IC_IN_TI1);
|
||||||
|
timer_ic_set_input(TIM3, TIM_IC2, TIM_IC_IN_TI1);
|
||||||
|
|
||||||
|
/* Capture CH1 on rising edge, CH2 on falling edge */
|
||||||
|
timer_ic_set_polarity(TIM3, TIM_IC1, TIM_IC_RISING);
|
||||||
|
timer_ic_set_polarity(TIM3, TIM_IC2, TIM_IC_FALLING);
|
||||||
|
|
||||||
|
/* Trigger on Filtered Timer Input 1 (TI1FP1) */
|
||||||
|
timer_slave_set_trigger(TIM3, TIM_SMCR_TS_IT1FP1);
|
||||||
|
|
||||||
|
/* Slave reset mode: reset counter on trigger */
|
||||||
|
timer_slave_set_mode(TIM3, TIM_SMCR_SMS_RM);
|
||||||
|
|
||||||
|
/* Enable capture interrupt */
|
||||||
|
nvic_enable_irq(NVIC_TIM3_IRQ);
|
||||||
|
timer_enable_irq(TIM3, TIM_DIER_CC1IE);
|
||||||
|
|
||||||
|
/* Enable the capture channels */
|
||||||
|
timer_ic_enable(TIM3, TIM_IC1);
|
||||||
|
timer_ic_enable(TIM3, TIM_IC2);
|
||||||
|
|
||||||
|
timer_enable_counter(TIM3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t trace_usb_buf[16];
|
||||||
|
static uint8_t trace_usb_buf_size;
|
||||||
|
|
||||||
|
void trace_buf_push(uint8_t *buf, int len)
|
||||||
|
{
|
||||||
|
if (usbd_ep_write_packet(0x85, buf, len) != len) {
|
||||||
|
memcpy(trace_usb_buf, buf, len);
|
||||||
|
trace_usb_buf_size = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trace_buf_drain(uint8_t ep)
|
||||||
|
{
|
||||||
|
if (!trace_usb_buf_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
usbd_ep_write_packet(ep, trace_usb_buf, trace_usb_buf_size);
|
||||||
|
trace_usb_buf_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tim3_isr(void)
|
||||||
|
{
|
||||||
|
uint16_t sr = TIM_SR(TIM3) & TIM_DIER(TIM3);
|
||||||
|
uint16_t duty, cycle;
|
||||||
|
static uint16_t bt;
|
||||||
|
static uint8_t lastbit;
|
||||||
|
static uint8_t decbuf[17];
|
||||||
|
static uint8_t decbuf_pos;
|
||||||
|
|
||||||
|
/* Reset decoder state if capture overflowed */
|
||||||
|
if (sr & (TIM_SR_CC1OF | TIM_SR_UIF)) {
|
||||||
|
timer_clear_flag(TIM3, TIM_SR_CC1OF | TIM_SR_UIF);
|
||||||
|
if (!(sr & TIM_SR_CC1IF)) {
|
||||||
|
trace_buf_push(decbuf, decbuf_pos >> 3);
|
||||||
|
memset(decbuf, 0, sizeof(decbuf));
|
||||||
|
decbuf_pos = 0;
|
||||||
|
bt = 0;
|
||||||
|
timer_set_period(TIM3, -1);
|
||||||
|
timer_disable_irq(TIM3, TIM_DIER_UIE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(sr & TIM_SR_CC1IF))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cycle = TIM_CCR1(TIM3);
|
||||||
|
duty = TIM_CCR2(TIM3);
|
||||||
|
|
||||||
|
/* Reset decoder state if crazy shit happened */
|
||||||
|
if ((bt && (((duty / bt) > 2) || ((cycle / bt) > 4))) ||
|
||||||
|
(duty == 0)) {
|
||||||
|
bt = 0;
|
||||||
|
trace_buf_push(decbuf, decbuf_pos >> 3);
|
||||||
|
decbuf_pos = 0;
|
||||||
|
memset(decbuf, 0, sizeof(decbuf));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bt) {
|
||||||
|
/* First bit, sync decoder */
|
||||||
|
if ((cycle / (duty - 5)) != 2)
|
||||||
|
return;
|
||||||
|
bt = duty - 5;
|
||||||
|
lastbit = 1;
|
||||||
|
timer_set_period(TIM3, duty * 5);
|
||||||
|
timer_clear_flag(TIM3, TIM_SR_UIF);
|
||||||
|
timer_enable_irq(TIM3, TIM_DIER_UIE);
|
||||||
|
} else {
|
||||||
|
/* If high time is extended we need to flip the bit */
|
||||||
|
if ((duty / bt) > 1)
|
||||||
|
lastbit ^= 1;
|
||||||
|
decbuf[decbuf_pos >> 3] |= lastbit << (decbuf_pos & 7);
|
||||||
|
decbuf_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((cycle - duty) / bt) > 1) {
|
||||||
|
/* If low time extended we need to pack another bit. */
|
||||||
|
lastbit ^= 1;
|
||||||
|
decbuf[decbuf_pos >> 3] |= lastbit << (decbuf_pos & 7);
|
||||||
|
decbuf_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decbuf_pos >= 128) {
|
||||||
|
trace_buf_push(decbuf, 16);
|
||||||
|
/* bt = 0; */
|
||||||
|
decbuf_pos = 0;
|
||||||
|
memset(decbuf, 0, sizeof(decbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Black Magic Debug project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Black Sphere Technologies Ltd.
|
||||||
|
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __TRACESWO_H
|
||||||
|
#define __TRACESWO_H
|
||||||
|
|
||||||
|
void traceswo_init(void);
|
||||||
|
void trace_buf_drain(uint8_t ep);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue