#include "general.h"
#include "usb_serial.h"
#include "traceswo.h"
static uint8_t swo_buf[CDCACM_PACKET_SIZE];
static int swo_buf_len = 0;
static uint32_t swo_decode = 0;
static int swo_pkt_len = 0;
static bool swo_print = false;
uint16_t traceswo_decode(usbd_device *usbd_dev, uint8_t addr, const void *buf, uint16_t len)
{
if (usbd_dev == NULL)
return 0;
const uint8_t *const data = (const uint8_t *)buf;
for (uint16_t i = 0; i < len; i++) {
const uint8_t ch = data[i];
if (swo_pkt_len == 0) {
uint32_t channel = (uint32_t)ch >> 3U;
uint32_t size = ch & 0x7U;
if (size == 0x01U)
swo_pkt_len = 1;
else if (size == 0x02U)
swo_pkt_len = 2;
else if (size == 0x03U)
swo_pkt_len = 4;
swo_print = (swo_pkt_len != 0) && ((swo_decode & (1UL << channel)) != 0UL);
} else if (swo_pkt_len <= 4) {
if (swo_print) {
swo_buf[swo_buf_len++] = ch;
if (swo_buf_len == sizeof(swo_buf)) {
if (usb_get_config() && gdb_serial_get_dtr())
usbd_ep_write_packet(usbd_dev, addr, swo_buf, swo_buf_len);
swo_buf_len = 0;
}
}
--swo_pkt_len;
} else {
swo_buf_len = 0;
swo_pkt_len = 0;
}
}
return len;
}
void traceswo_setmask(uint32_t mask)
{
swo_decode = mask;
}