Compare commits
3 Commits
line_codin
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ab8c86465 | ||
|
|
2a6f9911db | ||
|
|
5b6eb3e427 |
@@ -17,7 +17,6 @@ add_executable(picoprobe
|
|||||||
src/cdc_uart.c
|
src/cdc_uart.c
|
||||||
src/get_serial.c
|
src/get_serial.c
|
||||||
src/sw_dp_pio.c
|
src/sw_dp_pio.c
|
||||||
src/tusb_edpt_handler.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(picoprobe PRIVATE
|
target_sources(picoprobe PRIVATE
|
||||||
|
|||||||
@@ -34,9 +34,8 @@
|
|||||||
TaskHandle_t uart_taskhandle;
|
TaskHandle_t uart_taskhandle;
|
||||||
TickType_t last_wake, interval = 100;
|
TickType_t last_wake, interval = 100;
|
||||||
|
|
||||||
/* Max 1 FIFO worth of data */
|
static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
static uint8_t tx_buf[32];
|
static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
static uint8_t rx_buf[32];
|
|
||||||
// Actually s^-1 so 25ms
|
// Actually s^-1 so 25ms
|
||||||
#define DEBOUNCE_MS 40
|
#define DEBOUNCE_MS 40
|
||||||
static uint debounce_ticks = 5;
|
static uint debounce_ticks = 5;
|
||||||
@@ -60,7 +59,6 @@ void cdc_uart_init(void) {
|
|||||||
void cdc_task(void)
|
void cdc_task(void)
|
||||||
{
|
{
|
||||||
static int was_connected = 0;
|
static int was_connected = 0;
|
||||||
static uint cdc_tx_oe = 0;
|
|
||||||
uint rx_len = 0;
|
uint rx_len = 0;
|
||||||
|
|
||||||
// Consume uart fifo regardless even if not connected
|
// Consume uart fifo regardless even if not connected
|
||||||
@@ -79,9 +77,6 @@ void cdc_task(void)
|
|||||||
rx_led_debounce = debounce_ticks;
|
rx_led_debounce = debounce_ticks;
|
||||||
#endif
|
#endif
|
||||||
written = MIN(tud_cdc_write_available(), rx_len);
|
written = MIN(tud_cdc_write_available(), rx_len);
|
||||||
if (rx_len > written)
|
|
||||||
cdc_tx_oe++;
|
|
||||||
|
|
||||||
if (written > 0) {
|
if (written > 0) {
|
||||||
tud_cdc_write(rx_buf, written);
|
tud_cdc_write(rx_buf, written);
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
@@ -118,7 +113,6 @@ void cdc_task(void)
|
|||||||
} else if (was_connected) {
|
} else if (was_connected) {
|
||||||
tud_cdc_write_clear();
|
tud_cdc_write_clear();
|
||||||
was_connected = 0;
|
was_connected = 0;
|
||||||
cdc_tx_oe = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +131,6 @@ void cdc_thread(void *ptr)
|
|||||||
|
|
||||||
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
|
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
|
||||||
{
|
{
|
||||||
uart_parity_t parity;
|
|
||||||
uint data_bits, stop_bits;
|
|
||||||
/* Set the tick thread interval to the amount of time it takes to
|
/* Set the tick thread interval to the amount of time it takes to
|
||||||
* fill up half a FIFO. Millis is too coarse for integer divide.
|
* fill up half a FIFO. Millis is too coarse for integer divide.
|
||||||
*/
|
*/
|
||||||
@@ -153,51 +145,6 @@ void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
|
|||||||
tud_cdc_write_clear();
|
tud_cdc_write_clear();
|
||||||
tud_cdc_read_flush();
|
tud_cdc_read_flush();
|
||||||
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
||||||
|
|
||||||
switch (line_coding->parity) {
|
|
||||||
case CDC_LINE_CODING_PARITY_ODD:
|
|
||||||
parity = UART_PARITY_ODD;
|
|
||||||
break;
|
|
||||||
case CDC_LINE_CODING_PARITY_EVEN:
|
|
||||||
parity = UART_PARITY_EVEN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
picoprobe_info("invalid parity setting %u\n", line_coding->parity);
|
|
||||||
/* fallthrough */
|
|
||||||
case CDC_LINE_CODING_PARITY_NONE:
|
|
||||||
parity = UART_PARITY_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (line_coding->data_bits) {
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
data_bits = line_coding->data_bits;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
picoprobe_info("invalid data bits setting: %u\n", line_coding->data_bits);
|
|
||||||
data_bits = 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The PL011 only supports 1 or 2 stop bits. 1.5 stop bits is translated to 2,
|
|
||||||
* which is safer than the alternative. */
|
|
||||||
switch (line_coding->stop_bits) {
|
|
||||||
case CDC_LINE_CONDING_STOP_BITS_1_5:
|
|
||||||
case CDC_LINE_CONDING_STOP_BITS_2:
|
|
||||||
stop_bits = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
picoprobe_info("invalid stop bits setting: %u\n", line_coding->stop_bits);
|
|
||||||
/* fallthrough */
|
|
||||||
case CDC_LINE_CONDING_STOP_BITS_1:
|
|
||||||
stop_bits = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uart_set_format(PICOPROBE_UART_INTERFACE, data_bits, stop_bits, parity);
|
|
||||||
vTaskResume(uart_taskhandle);
|
vTaskResume(uart_taskhandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
src/main.c
26
src/main.c
@@ -39,7 +39,6 @@
|
|||||||
#include "cdc_uart.h"
|
#include "cdc_uart.h"
|
||||||
#include "get_serial.h"
|
#include "get_serial.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "tusb_edpt_handler.h"
|
|
||||||
#include "DAP.h"
|
#include "DAP.h"
|
||||||
|
|
||||||
// UART0 for Picoprobe debug
|
// UART0 for Picoprobe debug
|
||||||
@@ -54,12 +53,10 @@ static uint8_t RxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
|
|||||||
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 2)
|
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 2)
|
||||||
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 1)
|
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 1)
|
||||||
|
|
||||||
TaskHandle_t dap_taskhandle, tud_taskhandle;
|
static TaskHandle_t dap_taskhandle, tud_taskhandle;
|
||||||
|
|
||||||
void usb_thread(void *ptr)
|
void usb_thread(void *ptr)
|
||||||
{
|
{
|
||||||
TickType_t wake;
|
|
||||||
wake = xTaskGetTickCount();
|
|
||||||
do {
|
do {
|
||||||
tud_task();
|
tud_task();
|
||||||
#ifdef PICOPROBE_USB_CONNECTED_LED
|
#ifdef PICOPROBE_USB_CONNECTED_LED
|
||||||
@@ -68,9 +65,8 @@ void usb_thread(void *ptr)
|
|||||||
else
|
else
|
||||||
gpio_put(PICOPROBE_USB_CONNECTED_LED, 0);
|
gpio_put(PICOPROBE_USB_CONNECTED_LED, 0);
|
||||||
#endif
|
#endif
|
||||||
// Go to sleep for up to a tick if nothing to do
|
// Trivial delay to save power
|
||||||
if (!tud_task_event_ready())
|
vTaskDelay(1);
|
||||||
xTaskDelayUntil(&wake, 1);
|
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +75,22 @@ void usb_thread(void *ptr)
|
|||||||
#define tud_vendor_flush(x) ((void)0)
|
#define tud_vendor_flush(x) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void dap_thread(void *ptr)
|
||||||
|
{
|
||||||
|
uint32_t resp_len;
|
||||||
|
do {
|
||||||
|
if (tud_vendor_available()) {
|
||||||
|
tud_vendor_read(RxDataBuffer, sizeof(RxDataBuffer));
|
||||||
|
resp_len = DAP_ProcessCommand(RxDataBuffer, TxDataBuffer);
|
||||||
|
tud_vendor_write(TxDataBuffer, resp_len);
|
||||||
|
tud_vendor_flush();
|
||||||
|
} else {
|
||||||
|
// Trivial delay to save power
|
||||||
|
vTaskDelay(1);
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
board_init();
|
board_init();
|
||||||
|
|||||||
@@ -68,15 +68,8 @@
|
|||||||
#define CFG_TUD_MIDI 0
|
#define CFG_TUD_MIDI 0
|
||||||
#define CFG_TUD_VENDOR 1
|
#define CFG_TUD_VENDOR 1
|
||||||
|
|
||||||
/*
|
#define CFG_TUD_CDC_RX_BUFSIZE 64
|
||||||
* TX bufsize (actually UART RX) is oversized because the Windows CDC-ACM
|
#define CFG_TUD_CDC_TX_BUFSIZE 64
|
||||||
* driver submits a grand total of _one_ URB at any one time.
|
|
||||||
* This means the application must consume the data before the next IN token
|
|
||||||
* is issued. At high datarates this leads to huge variation in instantaneous
|
|
||||||
* throughput on USB, so a large runway is needed.
|
|
||||||
*/
|
|
||||||
#define CFG_TUD_CDC_RX_BUFSIZE 128
|
|
||||||
#define CFG_TUD_CDC_TX_BUFSIZE 4096
|
|
||||||
|
|
||||||
#define CFG_TUD_VENDOR_RX_BUFSIZE 8192
|
#define CFG_TUD_VENDOR_RX_BUFSIZE 8192
|
||||||
#define CFG_TUD_VENDOR_TX_BUFSIZE 8192
|
#define CFG_TUD_VENDOR_TX_BUFSIZE 8192
|
||||||
|
|||||||
@@ -1,218 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tusb_edpt_handler.h"
|
|
||||||
#include "DAP.h"
|
|
||||||
|
|
||||||
static uint8_t itf_num;
|
|
||||||
static uint8_t _rhport;
|
|
||||||
|
|
||||||
volatile uint32_t _resp_len;
|
|
||||||
|
|
||||||
uint8_t _out_ep_addr;
|
|
||||||
uint8_t _in_ep_addr;
|
|
||||||
|
|
||||||
buffer_t USBRequestBuffer;
|
|
||||||
buffer_t USBResponseBuffer;
|
|
||||||
|
|
||||||
void dap_edpt_init(void) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void dap_edpt_reset(uint8_t __unused rhport)
|
|
||||||
{
|
|
||||||
itf_num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
|
|
||||||
{
|
|
||||||
|
|
||||||
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass &&
|
|
||||||
PICOPROBE_INTERFACE_SUBCLASS == itf_desc->bInterfaceSubClass &&
|
|
||||||
PICOPROBE_INTERFACE_PROTOCOL == itf_desc->bInterfaceProtocol, 0);
|
|
||||||
|
|
||||||
// Initialise circular buffer indices
|
|
||||||
USBResponseBuffer.packet_wr_idx = 0;
|
|
||||||
USBResponseBuffer.packet_rd_idx = 0;
|
|
||||||
USBRequestBuffer.packet_wr_idx = 0;
|
|
||||||
USBRequestBuffer.packet_rd_idx = 0;
|
|
||||||
|
|
||||||
// Initialse full/empty flags
|
|
||||||
USBResponseBuffer.wasFull = false;
|
|
||||||
USBResponseBuffer.wasEmpty = true;
|
|
||||||
USBRequestBuffer.wasFull = false;
|
|
||||||
USBRequestBuffer.wasEmpty = true;
|
|
||||||
|
|
||||||
uint16_t const drv_len = sizeof(tusb_desc_interface_t) + (itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
|
|
||||||
TU_VERIFY(max_len >= drv_len, 0);
|
|
||||||
itf_num = itf_desc->bInterfaceNumber;
|
|
||||||
|
|
||||||
// Initialising the OUT endpoint
|
|
||||||
|
|
||||||
tusb_desc_endpoint_t *edpt_desc = (tusb_desc_endpoint_t *) (itf_desc + 1);
|
|
||||||
uint8_t ep_addr = edpt_desc->bEndpointAddress;
|
|
||||||
|
|
||||||
_out_ep_addr = ep_addr;
|
|
||||||
|
|
||||||
// The OUT endpoint requires a call to usbd_edpt_xfer to initialise the endpoint, giving tinyUSB a buffer to consume when a transfer occurs at the endpoint
|
|
||||||
usbd_edpt_open(rhport, edpt_desc);
|
|
||||||
usbd_edpt_xfer(rhport, ep_addr, &(USBRequestBuffer.data[USBRequestBuffer.packet_wr_idx][0]), DAP_PACKET_SIZE);
|
|
||||||
|
|
||||||
// Initiliasing the IN endpoint
|
|
||||||
|
|
||||||
edpt_desc++;
|
|
||||||
ep_addr = edpt_desc->bEndpointAddress;
|
|
||||||
|
|
||||||
_in_ep_addr = ep_addr;
|
|
||||||
|
|
||||||
// The IN endpoint doesn't need a transfer to initialise it, as this will be done by the main loop of dap_thread
|
|
||||||
usbd_edpt_open(rhport, edpt_desc);
|
|
||||||
|
|
||||||
return drv_len;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dap_edpt_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const *request)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage USBResponseBuffer (request) write and USBRequestBuffer (response) read indices
|
|
||||||
bool dap_edpt_xfer_cb(uint8_t __unused rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
|
||||||
{
|
|
||||||
const uint8_t ep_dir = tu_edpt_dir(ep_addr);
|
|
||||||
|
|
||||||
if(ep_dir == TUSB_DIR_IN)
|
|
||||||
{
|
|
||||||
if(xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE)
|
|
||||||
{
|
|
||||||
USBResponseBuffer.packet_rd_idx = (USBResponseBuffer.packet_rd_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
|
|
||||||
// This checks that the buffer was not empty in DAP thread, which means the next buffer was not queued up for the in endpoint callback
|
|
||||||
// So, queue up the buffer at the new read index, since we expect read to catch up to write at this point.
|
|
||||||
// It is possible for the read index to be multiple spaces behind the write index (if the USB callbacks are lagging behind dap thread),
|
|
||||||
// so we account for this by only setting wasEmpty to true if the next callback will empty the buffer
|
|
||||||
if(!USBResponseBuffer.wasEmpty)
|
|
||||||
{
|
|
||||||
usbd_edpt_xfer(rhport, ep_addr, &(USBResponseBuffer.data[USBResponseBuffer.packet_rd_idx][0]), (uint16_t) _resp_len);
|
|
||||||
USBResponseBuffer.wasEmpty = ((USBResponseBuffer.packet_rd_idx + 1) % DAP_PACKET_COUNT == USBResponseBuffer.packet_wr_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wake up DAP thread after processing the callback
|
|
||||||
vTaskResume(dap_taskhandle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else if(ep_dir == TUSB_DIR_OUT) {
|
|
||||||
|
|
||||||
if(xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE)
|
|
||||||
{
|
|
||||||
// Only queue the next buffer in the out callback if the buffer is not full
|
|
||||||
// If full, we set the wasFull flag, which will be checked by dap thread
|
|
||||||
if(!buffer_full(&USBRequestBuffer))
|
|
||||||
{
|
|
||||||
USBRequestBuffer.packet_wr_idx = (USBRequestBuffer.packet_wr_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
usbd_edpt_xfer(rhport, ep_addr, &(USBRequestBuffer.data[USBRequestBuffer.packet_wr_idx][0]), DAP_PACKET_SIZE);
|
|
||||||
USBRequestBuffer.wasFull = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
USBRequestBuffer.wasFull = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wake up DAP thread after processing the callback
|
|
||||||
vTaskResume(dap_taskhandle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dap_thread(void *ptr)
|
|
||||||
{
|
|
||||||
uint8_t DAPRequestBuffer[DAP_PACKET_SIZE];
|
|
||||||
uint8_t DAPResponseBuffer[DAP_PACKET_SIZE];
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
while(USBRequestBuffer.packet_rd_idx != USBRequestBuffer.packet_wr_idx)
|
|
||||||
{
|
|
||||||
// Read a single packet from the USB buffer into the DAP Request buffer
|
|
||||||
memcpy(DAPRequestBuffer, &(USBRequestBuffer.data[USBRequestBuffer.packet_rd_idx]), DAP_PACKET_SIZE);
|
|
||||||
USBRequestBuffer.packet_rd_idx = (USBRequestBuffer.packet_rd_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
|
|
||||||
// If the buffer was full in the out callback, we need to queue up another buffer for the endpoint to consume, now that we know there is space in the buffer.
|
|
||||||
if(USBRequestBuffer.wasFull)
|
|
||||||
{
|
|
||||||
vTaskSuspendAll(); // Suspend the scheduler to safely update the write index
|
|
||||||
USBRequestBuffer.packet_wr_idx = (USBRequestBuffer.packet_wr_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
usbd_edpt_xfer(_rhport, _out_ep_addr, &(USBRequestBuffer.data[USBRequestBuffer.packet_wr_idx][0]), DAP_PACKET_SIZE);
|
|
||||||
USBRequestBuffer.wasFull = false;
|
|
||||||
xTaskResumeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
_resp_len = DAP_ProcessCommand(DAPRequestBuffer, DAPResponseBuffer);
|
|
||||||
|
|
||||||
|
|
||||||
// Suspend the scheduler to avoid stale values/race conditions between threads
|
|
||||||
vTaskSuspendAll();
|
|
||||||
|
|
||||||
if(buffer_empty(&USBResponseBuffer))
|
|
||||||
{
|
|
||||||
memcpy(&(USBResponseBuffer.data[USBResponseBuffer.packet_wr_idx]), DAPResponseBuffer, (uint16_t) _resp_len);
|
|
||||||
USBResponseBuffer.packet_wr_idx = (USBResponseBuffer.packet_wr_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
|
|
||||||
usbd_edpt_xfer(_rhport, _in_ep_addr, &(USBResponseBuffer.data[USBResponseBuffer.packet_rd_idx][0]), (uint16_t) _resp_len);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
memcpy(&(USBResponseBuffer.data[USBResponseBuffer.packet_wr_idx]), DAPResponseBuffer, (uint16_t) _resp_len);
|
|
||||||
USBResponseBuffer.packet_wr_idx = (USBResponseBuffer.packet_wr_idx + 1) % DAP_PACKET_COUNT;
|
|
||||||
|
|
||||||
// The In callback needs to check this flag to know when to queue up the next buffer.
|
|
||||||
USBResponseBuffer.wasEmpty = false;
|
|
||||||
}
|
|
||||||
xTaskResumeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Suspend DAP thread until it is awoken by a USB thread callback
|
|
||||||
vTaskSuspend(dap_taskhandle);
|
|
||||||
|
|
||||||
} while (1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
usbd_class_driver_t const _dap_edpt_driver =
|
|
||||||
{
|
|
||||||
.init = dap_edpt_init,
|
|
||||||
.reset = dap_edpt_reset,
|
|
||||||
.open = dap_edpt_open,
|
|
||||||
.control_xfer_cb = dap_edpt_control_xfer_cb,
|
|
||||||
.xfer_cb = dap_edpt_xfer_cb,
|
|
||||||
.sof = NULL,
|
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
|
||||||
.name = "PICOPROBE ENDPOINT"
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add the custom driver to the tinyUSB stack
|
|
||||||
usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count)
|
|
||||||
{
|
|
||||||
*driver_count = 1;
|
|
||||||
return &_dap_edpt_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool buffer_full(buffer_t *buffer)
|
|
||||||
{
|
|
||||||
return ((buffer->packet_wr_idx + 1) % DAP_PACKET_COUNT == buffer->packet_rd_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool buffer_empty(buffer_t *buffer)
|
|
||||||
{
|
|
||||||
return (buffer->packet_wr_idx == buffer->packet_rd_idx);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TUSB_EDPT_HANDLER_H
|
|
||||||
#define TUSB_EDPT_HANDLER_H
|
|
||||||
|
|
||||||
#include "tusb.h"
|
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
|
||||||
#include "DAP_config.h"
|
|
||||||
|
|
||||||
#define PICOPROBE_INTERFACE_SUBCLASS 0x00
|
|
||||||
#define PICOPROBE_INTERFACE_PROTOCOL 0x00
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t data[DAP_PACKET_COUNT][DAP_PACKET_SIZE];
|
|
||||||
volatile uint32_t packet_wr_idx;
|
|
||||||
volatile uint32_t packet_rd_idx;
|
|
||||||
volatile bool wasEmpty;
|
|
||||||
volatile bool wasFull;
|
|
||||||
} buffer_t;
|
|
||||||
|
|
||||||
extern TaskHandle_t dap_taskhandle, tud_taskhandle;
|
|
||||||
|
|
||||||
/* Main DAP loop */
|
|
||||||
void dap_thread(void *ptr);
|
|
||||||
|
|
||||||
/* Endpoint Handling */
|
|
||||||
void picoprobe_edpt_init(void);
|
|
||||||
uint16_t picoprobe_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
|
|
||||||
bool picoprobe_edpt_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const *request);
|
|
||||||
bool picoprobe_edpt_xfer_cb(uint8_t __unused rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
|
||||||
|
|
||||||
/* Helper Functions */
|
|
||||||
bool buffer_full(buffer_t *buffer);
|
|
||||||
bool buffer_empty(buffer_t *buffer);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -242,4 +242,4 @@ TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
|
|||||||
uint8_t const * tud_descriptor_bos_cb(void)
|
uint8_t const * tud_descriptor_bos_cb(void)
|
||||||
{
|
{
|
||||||
return desc_bos;
|
return desc_bos;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user