#include "general.h"
#include "platform.h"
#include "usb.h"
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/lm4f/rcc.h>
#include <libopencm3/lm4f/nvic.h>
#include <libopencm3/lm4f/uart.h>
#include <libopencm3/usb/usbd.h>
void traceswo_init(void)
{
periph_clock_enable(RCC_GPIOD);
periph_clock_enable(TRACEUART_CLK);
__asm__("nop");
__asm__("nop");
__asm__("nop");
gpio_mode_setup(SWO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SWO_PIN);
gpio_set_af(SWO_PORT, 1, SWO_PIN);
uart_disable(TRACEUART);
uart_clock_from_sysclk(TRACEUART);
uart_set_baudrate(TRACEUART, 800000);
uart_set_databits(TRACEUART, 8);
uart_set_stopbits(TRACEUART, 1);
uart_set_parity(TRACEUART, UART_PARITY_NONE);
uart_enable_fifo(TRACEUART);
uart_set_fifo_trigger_levels(TRACEUART, UART_FIFO_RX_TRIG_1_2, UART_FIFO_TX_TRIG_7_8);
uart_clear_interrupt_flag(TRACEUART, UART_INT_RX | UART_INT_RT);
uart_enable_interrupts(TRACEUART, UART_INT_RX | UART_INT_RT);
uart_enable(TRACEUART);
nvic_set_priority(TRACEUART_IRQ, 0);
nvic_enable_irq(TRACEUART_IRQ);
usbd_ep_stall_set(usbdev, 0x85, 0);
gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
}
void traceswo_baud(unsigned int baud)
{
uart_set_baudrate(TRACEUART, baud);
uart_set_databits(TRACEUART, 8);
}
#define FIFO_SIZE 256U
static volatile uint8_t buf_rx[FIFO_SIZE];
static volatile uint32_t buf_rx_in = 0;
static volatile uint32_t buf_rx_out = 0;
void trace_buf_push(void)
{
size_t len;
if (buf_rx_in == buf_rx_out)
return;
if (buf_rx_in > buf_rx_out)
len = buf_rx_in - buf_rx_out;
else
len = FIFO_SIZE - buf_rx_out;
if (len > 64U)
len = 64;
if (usbd_ep_write_packet(usbdev, 0x85, (uint8_t *)&buf_rx[buf_rx_out], len) == len) {
buf_rx_out += len;
buf_rx_out %= FIFO_SIZE;
}
}
void trace_buf_drain(usbd_device *dev, uint8_t ep)
{
(void)dev;
(void)ep;
trace_buf_push();
}
void trace_tick(void)
{
trace_buf_push();
}
void TRACEUART_ISR(void)
{
uint32_t flush = uart_is_interrupt_source(TRACEUART, UART_INT_RT);
while (!uart_is_rx_fifo_empty(TRACEUART)) {
const uint32_t c = uart_recv(TRACEUART);
if ((buf_rx_in + 1U) % FIFO_SIZE != buf_rx_out) {
buf_rx[buf_rx_in++] = c;
if (buf_rx_in >= FIFO_SIZE)
buf_rx_in = 0;
} else {
flush = 1;
break;
}
}
if (flush)
trace_buf_push();
}