Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f030323119 | ||
|
|
89c9a7711f | ||
|
|
451513d4f6 | ||
|
|
ba204d0c24 |
@@ -26,7 +26,6 @@
|
||||
#include <pico/stdlib.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
#include "probe_config.h"
|
||||
@@ -191,7 +190,8 @@ void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
|
||||
*/
|
||||
uint32_t micros = (1000 * 1000 * 16 * 10) / MAX(line_coding->bit_rate, 1);
|
||||
/* Modifying state, so park the thread before changing it. */
|
||||
vTaskSuspend(uart_taskhandle);
|
||||
if (tud_cdc_connected())
|
||||
vTaskSuspend(uart_taskhandle);
|
||||
interval = MAX(1, micros / ((1000 * 1000) / configTICK_RATE_HZ));
|
||||
debounce_ticks = MAX(1, configTICK_RATE_HZ / (interval * DEBOUNCE_MS));
|
||||
probe_info("New baud rate %ld micros %ld interval %lu\n",
|
||||
@@ -245,7 +245,10 @@ void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
|
||||
}
|
||||
|
||||
uart_set_format(PROBE_UART_INTERFACE, data_bits, stop_bits, parity);
|
||||
vTaskResume(uart_taskhandle);
|
||||
/* Windows likes to arbitrarily set/get line coding after dtr/rts changes, so
|
||||
* don't resume if we shouldn't */
|
||||
if(tud_cdc_connected())
|
||||
vTaskResume(uart_taskhandle);
|
||||
}
|
||||
|
||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||
@@ -259,7 +262,7 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||
|
||||
/* CDC drivers use linestate as a bodge to activate/deactivate the interface.
|
||||
* Resume our UART polling on activate, stop on deactivate */
|
||||
if (!dtr && !rts) {
|
||||
if (!dtr) {
|
||||
vTaskSuspend(uart_taskhandle);
|
||||
#ifdef PROBE_UART_RX_LED
|
||||
gpio_put(PROBE_UART_RX_LED, 0);
|
||||
|
||||
78
src/main.c
78
src/main.c
@@ -45,6 +45,7 @@
|
||||
#include "led.h"
|
||||
#include "tusb_edpt_handler.h"
|
||||
#include "DAP.h"
|
||||
#include "hardware/structs/usb.h"
|
||||
|
||||
// UART0 for debugprobe debug
|
||||
// UART1 for debugprobe to target device
|
||||
@@ -58,7 +59,36 @@ static uint8_t RxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
|
||||
#define TUD_TASK_PRIO (tskIDLE_PRIORITY + 2)
|
||||
#define DAP_TASK_PRIO (tskIDLE_PRIORITY + 1)
|
||||
|
||||
TaskHandle_t dap_taskhandle, tud_taskhandle;
|
||||
TaskHandle_t dap_taskhandle, tud_taskhandle, mon_taskhandle;
|
||||
|
||||
void dev_mon(void *ptr)
|
||||
{
|
||||
uint32_t sof[3];
|
||||
int i = 0;
|
||||
TickType_t wake;
|
||||
wake = xTaskGetTickCount();
|
||||
do {
|
||||
/* ~5 SOF events per tick */
|
||||
xTaskDelayUntil(&wake, 100);
|
||||
if (tud_connected() && !tud_suspended()) {
|
||||
sof[i++] = usb_hw->sof_rd & USB_SOF_RD_BITS;
|
||||
i = i % 3;
|
||||
} else {
|
||||
for (i = 0; i < 3; i++)
|
||||
sof[i] = 0;
|
||||
}
|
||||
if ((sof[0] | sof[1] | sof[2]) != 0) {
|
||||
if ((sof[0] == sof[1]) && (sof[1] == sof[2])) {
|
||||
probe_info("Watchdog timeout! Resetting USBD\n");
|
||||
/* uh oh, signal disconnect (implicitly resets the controller) */
|
||||
tud_deinit(0);
|
||||
/* Make sure the port got the message */
|
||||
xTaskDelayUntil(&wake, 1);
|
||||
tud_init(0);
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
void usb_thread(void *ptr)
|
||||
{
|
||||
@@ -72,8 +102,11 @@ void usb_thread(void *ptr)
|
||||
else
|
||||
gpio_put(PROBE_USB_CONNECTED_LED, 0);
|
||||
#endif
|
||||
// If suspended or disconnected, delay for 1ms (20 ticks)
|
||||
if (tud_suspended() || !tud_connected())
|
||||
xTaskDelayUntil(&wake, 20);
|
||||
// Go to sleep for up to a tick if nothing to do
|
||||
if (!tud_task_event_ready())
|
||||
else if (!tud_task_event_ready())
|
||||
xTaskDelayUntil(&wake, 1);
|
||||
} while (1);
|
||||
}
|
||||
@@ -100,11 +133,10 @@ int main(void) {
|
||||
probe_info("Welcome to debugprobe!\n");
|
||||
|
||||
if (THREADED) {
|
||||
/* UART needs to preempt USB as if we don't, characters get lost */
|
||||
xTaskCreate(cdc_thread, "UART", configMINIMAL_STACK_SIZE, NULL, UART_TASK_PRIO, &uart_taskhandle);
|
||||
xTaskCreate(usb_thread, "TUD", configMINIMAL_STACK_SIZE, NULL, TUD_TASK_PRIO, &tud_taskhandle);
|
||||
/* Lowest priority thread is debug - need to shuffle buffers before we can toggle swd... */
|
||||
xTaskCreate(dap_thread, "DAP", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle);
|
||||
#if PICO_RP2040
|
||||
xTaskCreate(dev_mon, "WDOG", configMINIMAL_STACK_SIZE, NULL, TUD_TASK_PRIO, &mon_taskhandle);
|
||||
#endif
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
@@ -188,6 +220,40 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
|
||||
}
|
||||
#endif
|
||||
|
||||
void tud_suspend_cb(bool remote_wakeup_en)
|
||||
{
|
||||
probe_info("Suspended\n");
|
||||
/* Join DAP and UART threads? Or just suspend them, for transparency */
|
||||
vTaskSuspend(uart_taskhandle);
|
||||
vTaskSuspend(dap_taskhandle);
|
||||
/* slow down clk_sys for power saving ? */
|
||||
}
|
||||
|
||||
void tud_resume_cb(void)
|
||||
{
|
||||
probe_info("Resumed\n");
|
||||
vTaskResume(uart_taskhandle);
|
||||
vTaskResume(dap_taskhandle);
|
||||
}
|
||||
|
||||
void tud_unmount_cb(void)
|
||||
{
|
||||
probe_info("Disconnected\n");
|
||||
vTaskSuspend(uart_taskhandle);
|
||||
vTaskSuspend(dap_taskhandle);
|
||||
vTaskDelete(uart_taskhandle);
|
||||
vTaskDelete(dap_taskhandle);
|
||||
}
|
||||
|
||||
void tud_mount_cb(void)
|
||||
{
|
||||
probe_info("Connected, Configured\n");
|
||||
/* UART needs to preempt USB as if we don't, characters get lost */
|
||||
xTaskCreate(cdc_thread, "UART", configMINIMAL_STACK_SIZE, NULL, UART_TASK_PRIO, &uart_taskhandle);
|
||||
/* Lowest priority thread is debug - need to shuffle buffers before we can toggle swd... */
|
||||
xTaskCreate(dap_thread, "DAP", configMINIMAL_STACK_SIZE, NULL, DAP_TASK_PRIO, &dap_taskhandle);
|
||||
}
|
||||
|
||||
void vApplicationTickHook (void)
|
||||
{
|
||||
};
|
||||
|
||||
@@ -41,6 +41,15 @@ void dap_edpt_init(void) {
|
||||
|
||||
}
|
||||
|
||||
bool dap_edpt_deinit(void)
|
||||
{
|
||||
memset(DAPRequestBuffer, 0, sizeof(DAPRequestBuffer));
|
||||
memset(DAPResponseBuffer, 0, sizeof(DAPResponseBuffer));
|
||||
USBRequestBuffer.wptr = USBRequestBuffer.rptr = 0;
|
||||
USBResponseBuffer.wptr = USBResponseBuffer.rptr = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void dap_edpt_reset(uint8_t __unused rhport)
|
||||
{
|
||||
itf_num = 0;
|
||||
@@ -198,7 +207,7 @@ void dap_thread(void *ptr)
|
||||
*/
|
||||
n = USBRequestBuffer.rptr;
|
||||
while (USBRequestBuffer.data[n % DAP_PACKET_COUNT][0] == ID_DAP_QueueCommands) {
|
||||
probe_info("%u %u DAP queued cmd %s len %02x\n",
|
||||
probe_info("%lu %lu DAP queued cmd %s len %02x\n",
|
||||
USBRequestBuffer.wptr, USBRequestBuffer.rptr,
|
||||
dap_cmd_string[USBRequestBuffer.data[n % DAP_PACKET_COUNT][0]], USBRequestBuffer.data[n % DAP_PACKET_COUNT][1]);
|
||||
USBRequestBuffer.data[n % DAP_PACKET_COUNT][0] = ID_DAP_ExecuteCommands;
|
||||
@@ -211,7 +220,7 @@ void dap_thread(void *ptr)
|
||||
}
|
||||
// Read a single packet from the USB buffer into the DAP Request buffer
|
||||
memcpy(DAPRequestBuffer, RD_SLOT_PTR(USBRequestBuffer), DAP_PACKET_SIZE);
|
||||
probe_info("%u %u DAP cmd %s len %02x\n",
|
||||
probe_info("%lu %lu DAP cmd %s len %02x\n",
|
||||
USBRequestBuffer.wptr, USBRequestBuffer.rptr,
|
||||
dap_cmd_string[DAPRequestBuffer[0]], DAPRequestBuffer[1]);
|
||||
USBRequestBuffer.rptr++;
|
||||
@@ -227,7 +236,7 @@ void dap_thread(void *ptr)
|
||||
}
|
||||
|
||||
_resp_len = DAP_ExecuteCommand(DAPRequestBuffer, DAPResponseBuffer);
|
||||
probe_info("%u %u DAP resp %s\n",
|
||||
probe_info("%lu %lu DAP resp %s\n",
|
||||
USBResponseBuffer.wptr, USBResponseBuffer.rptr,
|
||||
dap_cmd_string[DAPResponseBuffer[0]]);
|
||||
|
||||
@@ -262,6 +271,7 @@ void dap_thread(void *ptr)
|
||||
usbd_class_driver_t const _dap_edpt_driver =
|
||||
{
|
||||
.init = dap_edpt_init,
|
||||
.deinit = dap_edpt_deinit,
|
||||
.reset = dap_edpt_reset,
|
||||
.open = dap_edpt_open,
|
||||
.control_xfer_cb = dap_edpt_control_xfer_cb,
|
||||
|
||||
Reference in New Issue
Block a user