From ea6cdf17a13d7247dce9a76e72ee8e72238a9401 Mon Sep 17 00:00:00 2001 From: "Matheus T. dos Santos" Date: Tue, 7 May 2024 22:33:52 -0300 Subject: [PATCH] chore: format the files on src folder with clang-format --- .clang-format | 27 +++ src/cdc_uart.c | 383 ++++++++++++++++++++-------------------- src/get_serial.c | 21 ++- src/led.c | 23 +-- src/main.c | 209 +++++++++++----------- src/probe.c | 183 ++++++++++--------- src/probe_config.c | 29 ++- src/probe_config.h | 47 +++-- src/sw_dp_pio.c | 306 ++++++++++++++++---------------- src/tusb_config.h | 24 +-- src/tusb_edpt_handler.c | 214 +++++++++++----------- src/tusb_edpt_handler.h | 9 +- src/usb_descriptors.c | 267 ++++++++++++++-------------- 13 files changed, 905 insertions(+), 837 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..479f029a4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,27 @@ +BasedOnStyle: LLVM +AlignConsecutiveMacros: AcrossComments +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AttributeMacros: + - __aligned + - __deprecated + - __packed + - __printf_like + - __syscall + - __syscall_always_inline + - __subsystem +BitFieldColonSpacing: After +BreakBeforeBraces: Linux +ColumnLimit: 100 +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +IndentCaseLabels: false +IndentWidth: 8 +InsertBraces: true +SpaceBeforeParens: ControlStatementsExceptControlMacros +SortIncludes: Never +UseTab: ForContinuationAndIndentation diff --git a/src/cdc_uart.c b/src/cdc_uart.c index 6dc6534de..0bb7cd4d3 100644 --- a/src/cdc_uart.c +++ b/src/cdc_uart.c @@ -51,253 +51,260 @@ static volatile uint tx_led_debounce; static uint rx_led_debounce; #endif -void cdc_uart_init(void) { - gpio_set_function(PROBE_UART_TX, GPIO_FUNC_UART); - gpio_set_function(PROBE_UART_RX, GPIO_FUNC_UART); - gpio_set_pulls(PROBE_UART_TX, 1, 0); - gpio_set_pulls(PROBE_UART_RX, 1, 0); - uart_init(PROBE_UART_INTERFACE, PROBE_UART_BAUDRATE); +void cdc_uart_init(void) +{ + gpio_set_function(PROBE_UART_TX, GPIO_FUNC_UART); + gpio_set_function(PROBE_UART_RX, GPIO_FUNC_UART); + gpio_set_pulls(PROBE_UART_TX, 1, 0); + gpio_set_pulls(PROBE_UART_RX, 1, 0); + uart_init(PROBE_UART_INTERFACE, PROBE_UART_BAUDRATE); #ifdef PROBE_UART_HWFC - /* HWFC implies that hardware flow control is implemented and the - * UART operates in "full-duplex" mode (See USB CDC PSTN120 6.3.12). - * Default to pulling in the active direction, so an unconnected CTS - * behaves the same as if CTS were not enabled. */ - gpio_set_pulls(PROBE_UART_CTS, 0, 1); - gpio_set_function(PROBE_UART_RTS, GPIO_FUNC_UART); - gpio_set_function(PROBE_UART_CTS, GPIO_FUNC_UART); - uart_set_hw_flow(PROBE_UART_INTERFACE, true, true); + /* HWFC implies that hardware flow control is implemented and the + * UART operates in "full-duplex" mode (See USB CDC PSTN120 6.3.12). + * Default to pulling in the active direction, so an unconnected CTS + * behaves the same as if CTS were not enabled. */ + gpio_set_pulls(PROBE_UART_CTS, 0, 1); + gpio_set_function(PROBE_UART_RTS, GPIO_FUNC_UART); + gpio_set_function(PROBE_UART_CTS, GPIO_FUNC_UART); + uart_set_hw_flow(PROBE_UART_INTERFACE, true, true); #else #ifdef PROBE_UART_RTS - gpio_init(PROBE_UART_RTS); - gpio_set_dir(PROBE_UART_RTS, GPIO_OUT); - gpio_put(PROBE_UART_RTS, 1); + gpio_init(PROBE_UART_RTS); + gpio_set_dir(PROBE_UART_RTS, GPIO_OUT); + gpio_put(PROBE_UART_RTS, 1); #endif #endif #ifdef PROBE_UART_DTR - gpio_init(PROBE_UART_DTR); - gpio_set_dir(PROBE_UART_DTR, GPIO_OUT); - gpio_put(PROBE_UART_DTR, 1); + gpio_init(PROBE_UART_DTR); + gpio_set_dir(PROBE_UART_DTR, GPIO_OUT); + gpio_put(PROBE_UART_DTR, 1); #endif } bool cdc_task(void) { - static int was_connected = 0; - static uint cdc_tx_oe = 0; - uint rx_len = 0; - bool keep_alive = false; + static int was_connected = 0; + static uint cdc_tx_oe = 0; + uint rx_len = 0; + bool keep_alive = false; - // Consume uart fifo regardless even if not connected - while(uart_is_readable(PROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) { - rx_buf[rx_len++] = uart_getc(PROBE_UART_INTERFACE); - } + // Consume uart fifo regardless even if not connected + while (uart_is_readable(PROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) { + rx_buf[rx_len++] = uart_getc(PROBE_UART_INTERFACE); + } - if (tud_cdc_connected()) { - was_connected = 1; - int written = 0; - /* Implicit overflow if we don't write all the bytes to the host. - * Also throw away bytes if we can't write... */ - if (rx_len) { + if (tud_cdc_connected()) { + was_connected = 1; + int written = 0; + /* Implicit overflow if we don't write all the bytes to the host. + * Also throw away bytes if we can't write... */ + if (rx_len) { #ifdef PROBE_UART_RX_LED - gpio_put(PROBE_UART_RX_LED, 1); - rx_led_debounce = debounce_ticks; + gpio_put(PROBE_UART_RX_LED, 1); + rx_led_debounce = debounce_ticks; #endif - written = MIN(tud_cdc_write_available(), rx_len); - if (rx_len > written) - cdc_tx_oe++; + written = MIN(tud_cdc_write_available(), rx_len); + if (rx_len > written) { + cdc_tx_oe++; + } - if (written > 0) { - tud_cdc_write(rx_buf, written); - tud_cdc_write_flush(); - } - } else { + if (written > 0) { + tud_cdc_write(rx_buf, written); + tud_cdc_write_flush(); + } + } else { #ifdef PROBE_UART_RX_LED - if (rx_led_debounce) - rx_led_debounce--; - else - gpio_put(PROBE_UART_RX_LED, 0); + if (rx_led_debounce) { + rx_led_debounce--; + } else { + gpio_put(PROBE_UART_RX_LED, 0); + } #endif - } + } - /* Reading from a firehose and writing to a FIFO. */ - size_t watermark = MIN(tud_cdc_available(), sizeof(tx_buf)); - if (watermark > 0) { - size_t tx_len; + /* Reading from a firehose and writing to a FIFO. */ + size_t watermark = MIN(tud_cdc_available(), sizeof(tx_buf)); + if (watermark > 0) { + size_t tx_len; #ifdef PROBE_UART_TX_LED - gpio_put(PROBE_UART_TX_LED, 1); - tx_led_debounce = debounce_ticks; + gpio_put(PROBE_UART_TX_LED, 1); + tx_led_debounce = debounce_ticks; #endif - /* Batch up to half a FIFO of data - don't clog up on RX */ - watermark = MIN(watermark, 16); - tx_len = tud_cdc_read(tx_buf, watermark); - uart_write_blocking(PROBE_UART_INTERFACE, tx_buf, tx_len); - } else { + /* Batch up to half a FIFO of data - don't clog up on RX */ + watermark = MIN(watermark, 16); + tx_len = tud_cdc_read(tx_buf, watermark); + uart_write_blocking(PROBE_UART_INTERFACE, tx_buf, tx_len); + } else { #ifdef PROBE_UART_TX_LED - if (tx_led_debounce) - tx_led_debounce--; - else - gpio_put(PROBE_UART_TX_LED, 0); + if (tx_led_debounce) { + tx_led_debounce--; + } else { + gpio_put(PROBE_UART_TX_LED, 0); + } #endif - } - /* Pending break handling */ - if (timed_break) { - if (((int)break_expiry - (int)xTaskGetTickCount()) < 0) { - timed_break = false; - uart_set_break(PROBE_UART_INTERFACE, false); + } + /* Pending break handling */ + if (timed_break) { + if (((int)break_expiry - (int)xTaskGetTickCount()) < 0) { + timed_break = false; + uart_set_break(PROBE_UART_INTERFACE, false); #ifdef PROBE_UART_TX_LED - tx_led_debounce = 0; + tx_led_debounce = 0; #endif - } else { - keep_alive = true; - } - } - } else if (was_connected) { - tud_cdc_write_clear(); - uart_set_break(PROBE_UART_INTERFACE, false); - timed_break = false; - was_connected = 0; + } else { + keep_alive = true; + } + } + } else if (was_connected) { + tud_cdc_write_clear(); + uart_set_break(PROBE_UART_INTERFACE, false); + timed_break = false; + was_connected = 0; #ifdef PROBE_UART_TX_LED - tx_led_debounce = 0; + tx_led_debounce = 0; #endif - cdc_tx_oe = 0; - } - return keep_alive; + cdc_tx_oe = 0; + } + return keep_alive; } void cdc_thread(void *ptr) { - BaseType_t delayed; - last_wake = xTaskGetTickCount(); - bool keep_alive; - /* Threaded with a polling interval that scales according to linerate */ - while (1) { - keep_alive = cdc_task(); - if (!keep_alive) { - delayed = xTaskDelayUntil(&last_wake, interval); - if (delayed == pdFALSE) - last_wake = xTaskGetTickCount(); - } - } + BaseType_t delayed; + last_wake = xTaskGetTickCount(); + bool keep_alive; + /* Threaded with a polling interval that scales according to linerate */ + while (1) { + keep_alive = cdc_task(); + if (!keep_alive) { + delayed = xTaskDelayUntil(&last_wake, interval); + if (delayed == pdFALSE) { + last_wake = xTaskGetTickCount(); + } + } + } } -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 - * fill up half a FIFO. Millis is too coarse for integer divide. - */ - 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); - 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", - line_coding->bit_rate, micros, interval); - uart_deinit(PROBE_UART_INTERFACE); - tud_cdc_write_clear(); - tud_cdc_read_flush(); - uart_init(PROBE_UART_INTERFACE, line_coding->bit_rate); + uart_parity_t parity; + uint data_bits, stop_bits; + /* 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. + */ + 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); + 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", line_coding->bit_rate, micros, + interval); + uart_deinit(PROBE_UART_INTERFACE); + tud_cdc_write_clear(); + tud_cdc_read_flush(); + uart_init(PROBE_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: - probe_info("invalid parity setting %u\n", line_coding->parity); - /* fallthrough */ - case CDC_LINE_CODING_PARITY_NONE: - parity = UART_PARITY_NONE; - break; - } + 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: + probe_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: - probe_info("invalid data bits setting: %u\n", line_coding->data_bits); - data_bits = 8; - break; - } + switch (line_coding->data_bits) { + case 5: + case 6: + case 7: + case 8: + data_bits = line_coding->data_bits; + break; + default: + probe_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: - probe_info("invalid stop bits setting: %u\n", line_coding->stop_bits); - /* fallthrough */ - case CDC_LINE_CONDING_STOP_BITS_1: - stop_bits = 1; - 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: + probe_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(PROBE_UART_INTERFACE, data_bits, stop_bits, parity); - vTaskResume(uart_taskhandle); + uart_set_format(PROBE_UART_INTERFACE, data_bits, stop_bits, parity); + vTaskResume(uart_taskhandle); } void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { #ifdef PROBE_UART_RTS - gpio_put(PROBE_UART_RTS, !rts); + gpio_put(PROBE_UART_RTS, !rts); #endif #ifdef PROBE_UART_DTR - gpio_put(PROBE_UART_DTR, !dtr); + gpio_put(PROBE_UART_DTR, !dtr); #endif - /* CDC drivers use linestate as a bodge to activate/deactivate the interface. - * Resume our UART polling on activate, stop on deactivate */ - if (!dtr && !rts) { - vTaskSuspend(uart_taskhandle); + /* CDC drivers use linestate as a bodge to activate/deactivate the interface. + * Resume our UART polling on activate, stop on deactivate */ + if (!dtr && !rts) { + vTaskSuspend(uart_taskhandle); #ifdef PROBE_UART_RX_LED - gpio_put(PROBE_UART_RX_LED, 0); - rx_led_debounce = 0; + gpio_put(PROBE_UART_RX_LED, 0); + rx_led_debounce = 0; #endif #ifdef PROBE_UART_TX_LED - gpio_put(PROBE_UART_TX_LED, 0); - tx_led_debounce = 0; + gpio_put(PROBE_UART_TX_LED, 0); + tx_led_debounce = 0; #endif - } else - vTaskResume(uart_taskhandle); + } else { + vTaskResume(uart_taskhandle); + } } -void tud_cdc_send_break_cb(uint8_t itf, uint16_t wValue) { - switch(wValue) { - case 0: - uart_set_break(PROBE_UART_INTERFACE, false); - timed_break = false; +void tud_cdc_send_break_cb(uint8_t itf, uint16_t wValue) +{ + switch (wValue) { + case 0: + uart_set_break(PROBE_UART_INTERFACE, false); + timed_break = false; #ifdef PROBE_UART_TX_LED - tx_led_debounce = 0; + tx_led_debounce = 0; #endif - break; - case 0xffff: - uart_set_break(PROBE_UART_INTERFACE, true); - timed_break = false; + break; + case 0xffff: + uart_set_break(PROBE_UART_INTERFACE, true); + timed_break = false; #ifdef PROBE_UART_TX_LED - gpio_put(PROBE_UART_TX_LED, 1); - tx_led_debounce = 1 << 30; + gpio_put(PROBE_UART_TX_LED, 1); + tx_led_debounce = 1 << 30; #endif - break; - default: - uart_set_break(PROBE_UART_INTERFACE, true); - timed_break = true; + break; + default: + uart_set_break(PROBE_UART_INTERFACE, true); + timed_break = true; #ifdef PROBE_UART_TX_LED - gpio_put(PROBE_UART_TX_LED, 1); - tx_led_debounce = 1 << 30; + gpio_put(PROBE_UART_TX_LED, 1); + tx_led_debounce = 1 << 30; #endif - break_expiry = xTaskGetTickCount() + (wValue * (configTICK_RATE_HZ / 1000)); - break; - } + break_expiry = xTaskGetTickCount() + (wValue * (configTICK_RATE_HZ / 1000)); + break; + } } diff --git a/src/get_serial.c b/src/get_serial.c index 04bf77a33..a20071606 100644 --- a/src/get_serial.c +++ b/src/get_serial.c @@ -36,16 +36,15 @@ static pico_unique_board_id_t uID; void usb_serial_init(void) { - pico_get_unique_board_id(&uID); + pico_get_unique_board_id(&uID); - for (int i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2; i++) - { - /* Byte index inside the uid array */ - int bi = i / 2; - /* Use high nibble first to keep memory order (just cosmetics) */ - uint8_t nibble = (uID.id[bi] >> 4) & 0x0F; - uID.id[bi] <<= 4; - /* Binary to hex digit */ - usb_serial[i] = nibble < 10 ? nibble + '0' : nibble + 'A' - 10; - } + for (int i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2; i++) { + /* Byte index inside the uid array */ + int bi = i / 2; + /* Use high nibble first to keep memory order (just cosmetics) */ + uint8_t nibble = (uID.id[bi] >> 4) & 0x0F; + uID.id[bi] <<= 4; + /* Binary to hex digit */ + usb_serial[i] = nibble < 10 ? nibble + '0' : nibble + 'A' - 10; + } } diff --git a/src/led.c b/src/led.c index c004c9b3b..930c6c5be 100644 --- a/src/led.c +++ b/src/led.c @@ -28,25 +28,26 @@ #include "probe_config.h" -void led_init(void) { +void led_init(void) +{ #ifdef PROBE_USB_CONNECTED_LED - gpio_init(PROBE_USB_CONNECTED_LED); - gpio_set_dir(PROBE_USB_CONNECTED_LED, GPIO_OUT); + gpio_init(PROBE_USB_CONNECTED_LED); + gpio_set_dir(PROBE_USB_CONNECTED_LED, GPIO_OUT); #endif #ifdef PROBE_DAP_CONNECTED_LED - gpio_init(PROBE_DAP_CONNECTED_LED); - gpio_set_dir(PROBE_DAP_CONNECTED_LED, GPIO_OUT); + gpio_init(PROBE_DAP_CONNECTED_LED); + gpio_set_dir(PROBE_DAP_CONNECTED_LED, GPIO_OUT); #endif #ifdef PROBE_DAP_RUNNING_LED - gpio_init(PROBE_DAP_RUNNING_LED); - gpio_set_dir(PROBE_DAP_RUNNING_LED, GPIO_OUT); + gpio_init(PROBE_DAP_RUNNING_LED); + gpio_set_dir(PROBE_DAP_RUNNING_LED, GPIO_OUT); #endif #ifdef PROBE_UART_RX_LED - gpio_init(PROBE_UART_RX_LED); - gpio_set_dir(PROBE_UART_RX_LED, GPIO_OUT); + gpio_init(PROBE_UART_RX_LED); + gpio_set_dir(PROBE_UART_RX_LED, GPIO_OUT); #endif #ifdef PROBE_UART_TX_LED - gpio_init(PROBE_UART_TX_LED); - gpio_set_dir(PROBE_UART_TX_LED, GPIO_OUT); + gpio_init(PROBE_UART_TX_LED); + gpio_set_dir(PROBE_UART_TX_LED, GPIO_OUT); #endif } diff --git a/src/main.c b/src/main.c index f14aebefd..817489f46 100644 --- a/src/main.c +++ b/src/main.c @@ -58,20 +58,22 @@ TaskHandle_t dap_taskhandle, tud_taskhandle; void usb_thread(void *ptr) { - TickType_t wake; - wake = xTaskGetTickCount(); - do { - tud_task(); + TickType_t wake; + wake = xTaskGetTickCount(); + do { + tud_task(); #ifdef PROBE_USB_CONNECTED_LED - if (!gpio_get(PROBE_USB_CONNECTED_LED) && tud_ready()) - gpio_put(PROBE_USB_CONNECTED_LED, 1); - else - gpio_put(PROBE_USB_CONNECTED_LED, 0); + if (!gpio_get(PROBE_USB_CONNECTED_LED) && tud_ready()) { + gpio_put(PROBE_USB_CONNECTED_LED, 1); + } else { + gpio_put(PROBE_USB_CONNECTED_LED, 0); + } #endif - // Go to sleep for up to a tick if nothing to do - if (!tud_task_event_ready()) - xTaskDelayUntil(&wake, 1); - } while (1); + // Go to sleep for up to a tick if nothing to do + if (!tud_task_event_ready()) { + xTaskDelayUntil(&wake, 1); + } + } while (1); } // Workaround API change in 0.13 @@ -79,121 +81,128 @@ void usb_thread(void *ptr) #define tud_vendor_flush(x) ((void)0) #endif -int main(void) { - // Declare pins in binary information - bi_decl_config(); - - board_init(); - usb_serial_init(); - cdc_uart_init(); - tusb_init(); - stdio_uart_init(); - - DAP_Setup(); - - led_init(); - - 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); - vTaskStartScheduler(); - } - - while (!THREADED) { - tud_task(); - cdc_task(); +int main(void) +{ + // Declare pins in binary information + bi_decl_config(); + + board_init(); + usb_serial_init(); + cdc_uart_init(); + tusb_init(); + stdio_uart_init(); + + DAP_Setup(); + + led_init(); + + 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); + vTaskStartScheduler(); + } + + while (!THREADED) { + tud_task(); + cdc_task(); #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V2) - if (tud_vendor_available()) { - uint32_t resp_len; - tud_vendor_read(RxDataBuffer, sizeof(RxDataBuffer)); - resp_len = DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); - tud_vendor_write(TxDataBuffer, resp_len); - } + if (tud_vendor_available()) { + uint32_t resp_len; + tud_vendor_read(RxDataBuffer, sizeof(RxDataBuffer)); + resp_len = DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); + tud_vendor_write(TxDataBuffer, resp_len); + } #endif - } + } - return 0; + return 0; } -uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, + uint8_t *buffer, uint16_t reqlen) { - // TODO not Implemented - (void) itf; - (void) report_id; - (void) report_type; - (void) buffer; - (void) reqlen; - - return 0; + // TODO not Implemented + (void)itf; + (void)report_id; + (void)report_type; + (void)buffer; + (void)reqlen; + + return 0; } -void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize) +void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, + uint8_t const *RxDataBuffer, uint16_t bufsize) { - uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize); + uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize); - // This doesn't use multiple report and report ID - (void) itf; - (void) report_id; - (void) report_type; + // This doesn't use multiple report and report ID + (void)itf; + (void)report_id; + (void)report_type; - DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); + DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); - tud_hid_report(0, TxDataBuffer, response_size); + tud_hid_report(0, TxDataBuffer, response_size); } #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V2) extern uint8_t const desc_ms_os_20[]; -bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, + tusb_control_request_t const *request) { - // nothing to with DATA & ACK stage - if (stage != CONTROL_STAGE_SETUP) return true; - - switch (request->bmRequestType_bit.type) - { - case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) - { - case 1: - if ( request->wIndex == 7 ) - { - // Get Microsoft OS 2.0 compatible descriptor - uint16_t total_len; - memcpy(&total_len, desc_ms_os_20+8, 2); - - return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len); - }else - { - return false; - } - - default: break; - } - break; - default: break; - } - - // stall unknown request - return false; + // nothing to with DATA & ACK stage + if (stage != CONTROL_STAGE_SETUP) { + return true; + } + + switch (request->bmRequestType_bit.type) { + case TUSB_REQ_TYPE_VENDOR: + switch (request->bRequest) { + case 1: + if (request->wIndex == 7) { + // Get Microsoft OS 2.0 compatible descriptor + uint16_t total_len; + memcpy(&total_len, desc_ms_os_20 + 8, 2); + + return tud_control_xfer(rhport, request, (void *)desc_ms_os_20, + total_len); + } else { + return false; + } + + default: + break; + } + break; + default: + break; + } + + // stall unknown request + return false; } #endif -void vApplicationTickHook (void) -{ -}; +void vApplicationTickHook(void){}; void vApplicationStackOverflowHook(TaskHandle_t Task, char *pcTaskName) { - panic("stack overflow (not the helpful kind) for %s\n", *pcTaskName); + panic("stack overflow (not the helpful kind) for %s\n", *pcTaskName); } void vApplicationMallocFailedHook(void) { - panic("Malloc Failed\n"); + panic("Malloc Failed\n"); }; diff --git a/src/probe.c b/src/probe.c index a6ef404f4..97f0b2c9f 100644 --- a/src/probe.c +++ b/src/probe.c @@ -35,144 +35,153 @@ #include "probe.pio.h" #include "tusb.h" -#define DIV_ROUND_UP(m, n) (((m) + (n) - 1) / (n)) +#define DIV_ROUND_UP(m, n) (((m) + (n)-1) / (n)) // Only want to set / clear one gpio per event so go up in powers of 2 enum _dbg_pins { - DBG_PIN_WRITE = 1, - DBG_PIN_WRITE_WAIT = 2, - DBG_PIN_READ = 4, - DBG_PIN_PKT = 8, + DBG_PIN_WRITE = 1, + DBG_PIN_WRITE_WAIT = 2, + DBG_PIN_READ = 4, + DBG_PIN_PKT = 8, }; CU_REGISTER_DEBUG_PINS(probe_timing) // Uncomment to enable debug -//CU_SELECT_DEBUG_PINS(probe_timing) +// CU_SELECT_DEBUG_PINS(probe_timing) #define PROBE_BUF_SIZE 8192 struct _probe { - // PIO offset - uint offset; - uint initted; + // PIO offset + uint offset; + uint initted; }; static struct _probe probe; -void probe_set_swclk_freq(uint freq_khz) { - uint clk_sys_freq_khz = clock_get_hz(clk_sys) / 1000; - probe_info("Set swclk freq %dKHz sysclk %dkHz\n", freq_khz, clk_sys_freq_khz); - uint32_t divider = clk_sys_freq_khz / freq_khz / 4; - if (divider == 0) - divider = 1; - pio_sm_set_clkdiv_int_frac(pio0, PROBE_SM, divider, 0); +void probe_set_swclk_freq(uint freq_khz) +{ + uint clk_sys_freq_khz = clock_get_hz(clk_sys) / 1000; + probe_info("Set swclk freq %dKHz sysclk %dkHz\n", freq_khz, clk_sys_freq_khz); + uint32_t divider = clk_sys_freq_khz / freq_khz / 4; + if (divider == 0) { + divider = 1; + } + pio_sm_set_clkdiv_int_frac(pio0, PROBE_SM, divider, 0); } void probe_assert_reset(bool state) { #if defined(PROBE_PIN_RESET) - /* Change the direction to out to drive pin to 0 or to in to emulate open drain */ - gpio_set_dir(PROBE_PIN_RESET, state == 0 ? GPIO_OUT : GPIO_IN); + /* Change the direction to out to drive pin to 0 or to in to emulate open drain */ + gpio_set_dir(PROBE_PIN_RESET, state == 0 ? GPIO_OUT : GPIO_IN); #endif } int probe_reset_level(void) { #if defined(PROBE_PIN_RESET) - return gpio_get(PROBE_PIN_RESET); + return gpio_get(PROBE_PIN_RESET); #else - return 0; + return 0; #endif } typedef enum probe_pio_command { - CMD_WRITE = 0, - CMD_SKIP, - CMD_TURNAROUND, - CMD_READ + CMD_WRITE = 0, + CMD_SKIP, + CMD_TURNAROUND, + CMD_READ } probe_pio_command_t; -static inline uint32_t fmt_probe_command(uint bit_count, bool out_en, probe_pio_command_t cmd) { - uint cmd_addr = - cmd == CMD_WRITE ? probe.offset + probe_offset_write_cmd : - cmd == CMD_SKIP ? probe.offset + probe_offset_get_next_cmd : - cmd == CMD_TURNAROUND ? probe.offset + probe_offset_turnaround_cmd : - probe.offset + probe_offset_read_cmd; - return ((bit_count - 1) & 0xff) | ((uint)out_en << 8) | (cmd_addr << 9); +static inline uint32_t fmt_probe_command(uint bit_count, bool out_en, probe_pio_command_t cmd) +{ + uint cmd_addr = cmd == CMD_WRITE ? probe.offset + probe_offset_write_cmd + : cmd == CMD_SKIP ? probe.offset + probe_offset_get_next_cmd + : cmd == CMD_TURNAROUND ? probe.offset + probe_offset_turnaround_cmd + : probe.offset + probe_offset_read_cmd; + return ((bit_count - 1) & 0xff) | ((uint)out_en << 8) | (cmd_addr << 9); } -void probe_write_bits(uint bit_count, uint32_t data_byte) { - DEBUG_PINS_SET(probe_timing, DBG_PIN_WRITE); - pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, true, CMD_WRITE)); - pio_sm_put_blocking(pio0, PROBE_SM, data_byte); - probe_dump("Write %d bits 0x%x\n", bit_count, data_byte); - // Return immediately so we can cue up the next command whilst this one runs - DEBUG_PINS_CLR(probe_timing, DBG_PIN_WRITE); +void probe_write_bits(uint bit_count, uint32_t data_byte) +{ + DEBUG_PINS_SET(probe_timing, DBG_PIN_WRITE); + pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, true, CMD_WRITE)); + pio_sm_put_blocking(pio0, PROBE_SM, data_byte); + probe_dump("Write %d bits 0x%x\n", bit_count, data_byte); + // Return immediately so we can cue up the next command whilst this one runs + DEBUG_PINS_CLR(probe_timing, DBG_PIN_WRITE); } -void probe_hiz_clocks(uint bit_count) { - pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_TURNAROUND)); - pio_sm_put_blocking(pio0, PROBE_SM, 0); +void probe_hiz_clocks(uint bit_count) +{ + pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_TURNAROUND)); + pio_sm_put_blocking(pio0, PROBE_SM, 0); } -uint32_t probe_read_bits(uint bit_count) { - DEBUG_PINS_SET(probe_timing, DBG_PIN_READ); - pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_READ)); - uint32_t data = pio_sm_get_blocking(pio0, PROBE_SM); - uint32_t data_shifted = data; - if (bit_count < 32) { - data_shifted = data >> (32 - bit_count); - } - - probe_dump("Read %d bits 0x%x (shifted 0x%x)\n", bit_count, data, data_shifted); - DEBUG_PINS_CLR(probe_timing, DBG_PIN_READ); - return data_shifted; +uint32_t probe_read_bits(uint bit_count) +{ + DEBUG_PINS_SET(probe_timing, DBG_PIN_READ); + pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(bit_count, false, CMD_READ)); + uint32_t data = pio_sm_get_blocking(pio0, PROBE_SM); + uint32_t data_shifted = data; + if (bit_count < 32) { + data_shifted = data >> (32 - bit_count); + } + + probe_dump("Read %d bits 0x%x (shifted 0x%x)\n", bit_count, data, data_shifted); + DEBUG_PINS_CLR(probe_timing, DBG_PIN_READ); + return data_shifted; } -static void probe_wait_idle() { - pio0->fdebug = 1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM); - while (!(pio0->fdebug & (1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM)))) - ; +static void probe_wait_idle() +{ + pio0->fdebug = 1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM); + while (!(pio0->fdebug & (1u << (PIO_FDEBUG_TXSTALL_LSB + PROBE_SM)))) + ; } -void probe_read_mode(void) { - pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, false, CMD_SKIP)); - probe_wait_idle(); +void probe_read_mode(void) +{ + pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, false, CMD_SKIP)); + probe_wait_idle(); } -void probe_write_mode(void) { - pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, true, CMD_SKIP)); - probe_wait_idle(); +void probe_write_mode(void) +{ + pio_sm_put_blocking(pio0, PROBE_SM, fmt_probe_command(0, true, CMD_SKIP)); + probe_wait_idle(); } -void probe_init() { - if (!probe.initted) { - uint offset = pio_add_program(pio0, &probe_program); - probe.offset = offset; - - pio_sm_config sm_config = probe_program_get_default_config(offset); - probe_sm_init(&sm_config); - pio_sm_init(pio0, PROBE_SM, offset, &sm_config); - - // Set up divisor - probe_set_swclk_freq(1000); - - // Jump SM to command dispatch routine, and enable it - pio_sm_exec(pio0, PROBE_SM, offset + probe_offset_get_next_cmd); - pio_sm_set_enabled(pio0, PROBE_SM, 1); - probe.initted = 1; - } +void probe_init() +{ + if (!probe.initted) { + uint offset = pio_add_program(pio0, &probe_program); + probe.offset = offset; + + pio_sm_config sm_config = probe_program_get_default_config(offset); + probe_sm_init(&sm_config); + pio_sm_init(pio0, PROBE_SM, offset, &sm_config); + + // Set up divisor + probe_set_swclk_freq(1000); + + // Jump SM to command dispatch routine, and enable it + pio_sm_exec(pio0, PROBE_SM, offset + probe_offset_get_next_cmd); + pio_sm_set_enabled(pio0, PROBE_SM, 1); + probe.initted = 1; + } } void probe_deinit(void) { - if (probe.initted) { - probe_read_mode(); - pio_sm_set_enabled(pio0, PROBE_SM, 0); - pio_remove_program(pio0, &probe_program, probe.offset); + if (probe.initted) { + probe_read_mode(); + pio_sm_set_enabled(pio0, PROBE_SM, 0); + pio_remove_program(pio0, &probe_program, probe.offset); - probe_assert_reset(1); // de-assert nRESET + probe_assert_reset(1); // de-assert nRESET - probe.initted = 0; - } + probe.initted = 0; + } } diff --git a/src/probe_config.c b/src/probe_config.c index eeef0a43a..8fd1e6584 100644 --- a/src/probe_config.c +++ b/src/probe_config.c @@ -1,48 +1,45 @@ #include "probe_config.h" #include "pico/binary_info.h" - #define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - +#define STR(x) STR_HELPER(x) void bi_decl_config() { #ifdef PROBE_PIN_RESET - bi_decl(bi_1pin_with_name(PROBE_PIN_RESET, "PROBE RESET")); + bi_decl(bi_1pin_with_name(PROBE_PIN_RESET, "PROBE RESET")); #endif #ifdef PROBE_PIN_SWCLK - bi_decl(bi_1pin_with_name(PROBE_PIN_SWCLK, "PROBE SWCLK")); + bi_decl(bi_1pin_with_name(PROBE_PIN_SWCLK, "PROBE SWCLK")); #endif #ifdef PROBE_PIN_SWDIO - bi_decl(bi_1pin_with_name(PROBE_PIN_SWDIO, "PROBE SWDIO")); + bi_decl(bi_1pin_with_name(PROBE_PIN_SWDIO, "PROBE SWDIO")); #endif #ifdef PROBE_PIN_SWDI - bi_decl(bi_1pin_with_name(PROBE_PIN_SWDI, "PROBE SWDI")); + bi_decl(bi_1pin_with_name(PROBE_PIN_SWDI, "PROBE SWDI")); #endif #ifdef PROBE_PIN_SWDIOEN - bi_decl(bi_1pin_with_name(PROBE_PIN_SWDIOEN, "PROBE SWDIOEN")); + bi_decl(bi_1pin_with_name(PROBE_PIN_SWDIOEN, "PROBE SWDIOEN")); #endif #ifdef PROBE_CDC_UART - bi_decl(bi_program_feature("PROBE UART INTERFACE " STR(PROBE_UART_INTERFACE))); - bi_decl(bi_program_feature("PROBE UART BAUDRATE " STR(PROBE_UART_BAUDRATE))); - bi_decl(bi_1pin_with_name(PROBE_UART_TX, "PROBE UART TX")); - bi_decl(bi_1pin_with_name(PROBE_UART_RX, "PROBE UART RX")); + bi_decl(bi_program_feature("PROBE UART INTERFACE " STR(PROBE_UART_INTERFACE))); + bi_decl(bi_program_feature("PROBE UART BAUDRATE " STR(PROBE_UART_BAUDRATE))); + bi_decl(bi_1pin_with_name(PROBE_UART_TX, "PROBE UART TX")); + bi_decl(bi_1pin_with_name(PROBE_UART_RX, "PROBE UART RX")); #endif #ifdef PROBE_UART_CTS - bi_decl(bi_1pin_with_name(PROBE_UART_CTS, "PROBE UART CTS")); + bi_decl(bi_1pin_with_name(PROBE_UART_CTS, "PROBE UART CTS")); #endif #ifdef PROBE_UART_RTS - bi_decl(bi_1pin_with_name(PROBE_UART_RTS, "PROBE UART RTS")); + bi_decl(bi_1pin_with_name(PROBE_UART_RTS, "PROBE UART RTS")); #endif #ifdef PROBE_UART_DTR - bi_decl(bi_1pin_with_name(PROBE_UART_DTR, "PROBE UART DTR")); + bi_decl(bi_1pin_with_name(PROBE_UART_DTR, "PROBE UART DTR")); #endif - } diff --git a/src/probe_config.h b/src/probe_config.h index 5c5e14909..308b5032d 100644 --- a/src/probe_config.h +++ b/src/probe_config.h @@ -30,47 +30,46 @@ #include "task.h" #if false -#define probe_info(format,args...) \ -do { \ - vTaskSuspendAll(); \ - printf(format, ## args); \ - xTaskResumeAll(); \ -} while (0) +#define probe_info(format, args...) \ + do { \ + vTaskSuspendAll(); \ + printf(format, ##args); \ + xTaskResumeAll(); \ + } while (0) #else -#define probe_info(format,...) ((void)0) +#define probe_info(format, ...) ((void)0) #endif - #if false -#define probe_debug(format,args...) \ -do { \ - vTaskSuspendAll(); \ - printf(format, ## args); \ - xTaskResumeAll(); \ -} while (0) +#define probe_debug(format, args...) \ + do { \ + vTaskSuspendAll(); \ + printf(format, ##args); \ + xTaskResumeAll(); \ + } while (0) #else -#define probe_debug(format,...) ((void)0) +#define probe_debug(format, ...) ((void)0) #endif #if false -#define probe_dump(format,args...)\ -do { \ - vTaskSuspendAll(); \ - printf(format, ## args); \ - xTaskResumeAll(); \ -} while (0) +#define probe_dump(format, args...) \ + do { \ + vTaskSuspendAll(); \ + printf(format, ##args); \ + xTaskResumeAll(); \ + } while (0) #else -#define probe_dump(format,...) ((void)0) +#define probe_dump(format, ...) ((void)0) #endif // TODO tie this up with PICO_BOARD defines in the main SDK -#ifdef DEBUG_ON_PICO +#ifdef DEBUG_ON_PICO #include "board_pico_config.h" #else #include "board_debug_probe_config.h" #endif -//#include "board_example_config.h" +// #include "board_example_config.h" // Add the configuration to binary information void bi_decl_config(); diff --git a/src/sw_dp_pio.c b/src/sw_dp_pio.c index 2dbe7a4fe..848c3853a 100755 --- a/src/sw_dp_pio.c +++ b/src/sw_dp_pio.c @@ -39,24 +39,26 @@ volatile uint32_t cached_delay = 0; // data: pointer to sequence bit data // return: none #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) -void SWJ_Sequence (uint32_t count, const uint8_t *data) { - uint32_t bits; - uint32_t n; - - if (DAP_Data.clock_delay != cached_delay) { - probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); - cached_delay = DAP_Data.clock_delay; - } - probe_debug("SWJ sequence count = %d FDB=0x%2x\n", count, data[0]); - n = count; - while (n > 0) { - if (n > 8) - bits = 8; - else - bits = n; - probe_write_bits(bits, *data++); - n -= bits; - } +void SWJ_Sequence(uint32_t count, const uint8_t *data) +{ + uint32_t bits; + uint32_t n; + + if (DAP_Data.clock_delay != cached_delay) { + probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); + cached_delay = DAP_Data.clock_delay; + } + probe_debug("SWJ sequence count = %d FDB=0x%2x\n", count, data[0]); + n = count; + while (n > 0) { + if (n > 8) { + bits = 8; + } else { + bits = n; + } + probe_write_bits(bits, *data++); + n -= bits; + } } #endif @@ -66,39 +68,42 @@ void SWJ_Sequence (uint32_t count, const uint8_t *data) { // swdi: pointer to SWDIO captured data // return: none #if (DAP_SWD != 0) -void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { - uint32_t bits; - uint32_t n; - - if (DAP_Data.clock_delay != cached_delay) { - probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); - cached_delay = DAP_Data.clock_delay; - } - probe_debug("SWD sequence\n"); - n = info & SWD_SEQUENCE_CLK; - if (n == 0U) { - n = 64U; - } - bits = n; - if (info & SWD_SEQUENCE_DIN) { - while (n > 0) { - if (n > 8) - bits = 8; - else - bits = n; - *swdi++ = probe_read_bits(bits); - n -= bits; - } - } else { - while (n > 0) { - if (n > 8) - bits = 8; - else - bits = n; - probe_write_bits(bits, *swdo++); - n -= bits; - } - } +void SWD_Sequence(uint32_t info, const uint8_t *swdo, uint8_t *swdi) +{ + uint32_t bits; + uint32_t n; + + if (DAP_Data.clock_delay != cached_delay) { + probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); + cached_delay = DAP_Data.clock_delay; + } + probe_debug("SWD sequence\n"); + n = info & SWD_SEQUENCE_CLK; + if (n == 0U) { + n = 64U; + } + bits = n; + if (info & SWD_SEQUENCE_DIN) { + while (n > 0) { + if (n > 8) { + bits = 8; + } else { + bits = n; + } + *swdi++ = probe_read_bits(bits); + n -= bits; + } + } else { + while (n > 0) { + if (n > 8) { + bits = 8; + } else { + bits = n; + } + probe_write_bits(bits, *swdo++); + n -= bits; + } + } } #endif @@ -107,104 +112,105 @@ void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { // request: A[3:2] RnW APnDP // data: DATA[31:0] // return: ACK[2:0] -uint8_t SWD_Transfer (uint32_t request, uint32_t *data) { - uint8_t prq = 0; - uint8_t ack; - uint8_t bit; - uint32_t val = 0; - uint32_t parity = 0; - uint32_t n; - - if (DAP_Data.clock_delay != cached_delay) { - probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); - cached_delay = DAP_Data.clock_delay; - } - probe_debug("SWD_transfer\n"); - /* Generate the request packet */ - prq |= (1 << 0); /* Start Bit */ - for (n = 1; n < 5; n++) { - bit = (request >> (n - 1)) & 0x1; - prq |= bit << n; - parity += bit; - } - prq |= (parity & 0x1) << 5; /* Parity Bit */ - prq |= (0 << 6); /* Stop Bit */ - prq |= (1 << 7); /* Park bit */ - probe_write_bits(8, prq); - - /* Turnaround (ignore read bits) */ - ack = probe_read_bits(DAP_Data.swd_conf.turnaround + 3); - ack >>= DAP_Data.swd_conf.turnaround; - - if (ack == DAP_TRANSFER_OK) { - /* Data transfer phase */ - if (request & DAP_TRANSFER_RnW) { - /* Read RDATA[0:31] - note probe_read shifts to LSBs */ - val = probe_read_bits(32); - bit = probe_read_bits(1); - parity = __builtin_popcount(val); - if ((parity ^ bit) & 1U) { - /* Parity error */ - ack = DAP_TRANSFER_ERROR; - } - if (data) - *data = val; - probe_debug("Read %02x ack %02x 0x%08x parity %01x\n", - prq, ack, val, bit); - /* Turnaround for line idle */ - probe_hiz_clocks(DAP_Data.swd_conf.turnaround); - } else { - /* Turnaround for write */ - probe_hiz_clocks(DAP_Data.swd_conf.turnaround); - - /* Write WDATA[0:31] */ - val = *data; - probe_write_bits(32, val); - parity = __builtin_popcount(val); - /* Write Parity Bit */ - probe_write_bits(1, parity & 0x1); - probe_debug("write %02x ack %02x 0x%08x parity %01x\n", - prq, ack, val, parity); - } - /* Capture Timestamp */ - if (request & DAP_TRANSFER_TIMESTAMP) { - DAP_Data.timestamp = time_us_32(); - } - - /* Idle cycles - drive 0 for N clocks */ - if (DAP_Data.transfer.idle_cycles) { - for (n = DAP_Data.transfer.idle_cycles; n; ) { - if (n > 256) { - probe_write_bits(256, 0); - n -= 256; - } else { - probe_write_bits(n, 0); - n -= n; - } - } - } - return ((uint8_t)ack); - } - - if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { - if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { - /* Dummy Read RDATA[0:31] + Parity */ - probe_read_bits(33); - } - probe_hiz_clocks(DAP_Data.swd_conf.turnaround); - if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { - /* Dummy Write WDATA[0:31] + Parity */ - probe_write_bits(32, 0); - probe_write_bits(1, 0); - } - return ((uint8_t)ack); - } - - /* Protocol error */ - n = DAP_Data.swd_conf.turnaround + 32U + 1U; - /* Back off data phase */ - probe_read_bits(n); - return ((uint8_t)ack); +uint8_t SWD_Transfer(uint32_t request, uint32_t *data) +{ + uint8_t prq = 0; + uint8_t ack; + uint8_t bit; + uint32_t val = 0; + uint32_t parity = 0; + uint32_t n; + + if (DAP_Data.clock_delay != cached_delay) { + probe_set_swclk_freq(MAKE_KHZ(DAP_Data.clock_delay)); + cached_delay = DAP_Data.clock_delay; + } + probe_debug("SWD_transfer\n"); + /* Generate the request packet */ + prq |= (1 << 0); /* Start Bit */ + for (n = 1; n < 5; n++) { + bit = (request >> (n - 1)) & 0x1; + prq |= bit << n; + parity += bit; + } + prq |= (parity & 0x1) << 5; /* Parity Bit */ + prq |= (0 << 6); /* Stop Bit */ + prq |= (1 << 7); /* Park bit */ + probe_write_bits(8, prq); + + /* Turnaround (ignore read bits) */ + ack = probe_read_bits(DAP_Data.swd_conf.turnaround + 3); + ack >>= DAP_Data.swd_conf.turnaround; + + if (ack == DAP_TRANSFER_OK) { + /* Data transfer phase */ + if (request & DAP_TRANSFER_RnW) { + /* Read RDATA[0:31] - note probe_read shifts to LSBs */ + val = probe_read_bits(32); + bit = probe_read_bits(1); + parity = __builtin_popcount(val); + if ((parity ^ bit) & 1U) { + /* Parity error */ + ack = DAP_TRANSFER_ERROR; + } + if (data) { + *data = val; + } + probe_debug("Read %02x ack %02x 0x%08x parity %01x\n", prq, ack, val, bit); + /* Turnaround for line idle */ + probe_hiz_clocks(DAP_Data.swd_conf.turnaround); + } else { + /* Turnaround for write */ + probe_hiz_clocks(DAP_Data.swd_conf.turnaround); + + /* Write WDATA[0:31] */ + val = *data; + probe_write_bits(32, val); + parity = __builtin_popcount(val); + /* Write Parity Bit */ + probe_write_bits(1, parity & 0x1); + probe_debug("write %02x ack %02x 0x%08x parity %01x\n", prq, ack, val, + parity); + } + /* Capture Timestamp */ + if (request & DAP_TRANSFER_TIMESTAMP) { + DAP_Data.timestamp = time_us_32(); + } + + /* Idle cycles - drive 0 for N clocks */ + if (DAP_Data.transfer.idle_cycles) { + for (n = DAP_Data.transfer.idle_cycles; n;) { + if (n > 256) { + probe_write_bits(256, 0); + n -= 256; + } else { + probe_write_bits(n, 0); + n -= n; + } + } + } + return ((uint8_t)ack); + } + + if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { + if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { + /* Dummy Read RDATA[0:31] + Parity */ + probe_read_bits(33); + } + probe_hiz_clocks(DAP_Data.swd_conf.turnaround); + if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { + /* Dummy Write WDATA[0:31] + Parity */ + probe_write_bits(32, 0); + probe_write_bits(1, 0); + } + return ((uint8_t)ack); + } + + /* Protocol error */ + n = DAP_Data.swd_conf.turnaround + 32U + 1U; + /* Back off data phase */ + probe_read_bits(n); + return ((uint8_t)ack); } -#endif /* (DAP_SWD != 0) */ +#endif /* (DAP_SWD != 0) */ diff --git a/src/tusb_config.h b/src/tusb_config.h index a1b92b064..35a4c75d6 100644 --- a/src/tusb_config.h +++ b/src/tusb_config.h @@ -27,7 +27,7 @@ #define _TUSB_CONFIG_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif //-------------------------------------------------------------------- @@ -36,13 +36,13 @@ // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU - #error CFG_TUSB_MCU must be defined +#error CFG_TUSB_MCU must be defined #endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_PICO +#define CFG_TUSB_OS OPT_OS_PICO #endif #ifndef CFG_TUSB_MEM_SECTION @@ -50,7 +50,7 @@ #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4))) #endif //-------------------------------------------------------------------- @@ -58,15 +58,15 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE -#define CFG_TUD_ENDPOINT0_SIZE 64 +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// -#define CFG_TUD_HID 1 -#define CFG_TUD_CDC 1 -#define CFG_TUD_MSC 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 1 +#define CFG_TUD_HID 1 +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 1 /* * TX bufsize (actually UART RX) is oversized because the Windows CDC-ACM @@ -86,7 +86,7 @@ #endif #ifdef __cplusplus - } +} #endif #endif /* _TUSB_CONFIG_H_ */ diff --git a/src/tusb_edpt_handler.c b/src/tusb_edpt_handler.c index a77d6df8a..9d427cc1c 100644 --- a/src/tusb_edpt_handler.c +++ b/src/tusb_edpt_handler.c @@ -37,8 +37,8 @@ bool buffer_empty(buffer_t *buffer) return (buffer->wptr == buffer->rptr); } -void dap_edpt_init(void) { - +void dap_edpt_init(void) +{ } void dap_edpt_reset(uint8_t __unused rhport) @@ -46,44 +46,45 @@ void dap_edpt_reset(uint8_t __unused rhport) itf_num = 0; } -char * dap_cmd_string[] = { - [ID_DAP_Info ] = "DAP_Info", - [ID_DAP_HostStatus ] = "DAP_HostStatus", - [ID_DAP_Connect ] = "DAP_Connect", - [ID_DAP_Disconnect ] = "DAP_Disconnect", - [ID_DAP_TransferConfigure ] = "DAP_TransferConfigure", - [ID_DAP_Transfer ] = "DAP_Transfer", - [ID_DAP_TransferBlock ] = "DAP_TransferBlock", - [ID_DAP_TransferAbort ] = "DAP_TransferAbort", - [ID_DAP_WriteABORT ] = "DAP_WriteABORT", - [ID_DAP_Delay ] = "DAP_Delay", - [ID_DAP_ResetTarget ] = "DAP_ResetTarget", - [ID_DAP_SWJ_Pins ] = "DAP_SWJ_Pins", - [ID_DAP_SWJ_Clock ] = "DAP_SWJ_Clock", - [ID_DAP_SWJ_Sequence ] = "DAP_SWJ_Sequence", - [ID_DAP_SWD_Configure ] = "DAP_SWD_Configure", - [ID_DAP_SWD_Sequence ] = "DAP_SWD_Sequence", - [ID_DAP_JTAG_Sequence ] = "DAP_JTAG_Sequence", - [ID_DAP_JTAG_Configure ] = "DAP_JTAG_Configure", - [ID_DAP_JTAG_IDCODE ] = "DAP_JTAG_IDCODE", - [ID_DAP_SWO_Transport ] = "DAP_SWO_Transport", - [ID_DAP_SWO_Mode ] = "DAP_SWO_Mode", - [ID_DAP_SWO_Baudrate ] = "DAP_SWO_Baudrate", - [ID_DAP_SWO_Control ] = "DAP_SWO_Control", - [ID_DAP_SWO_Status ] = "DAP_SWO_Status", - [ID_DAP_SWO_ExtendedStatus ] = "DAP_SWO_ExtendedStatus", - [ID_DAP_SWO_Data ] = "DAP_SWO_Data", - [ID_DAP_QueueCommands ] = "DAP_QueueCommands", - [ID_DAP_ExecuteCommands ] = "DAP_ExecuteCommands", +char *dap_cmd_string[] = { + [ID_DAP_Info] = "DAP_Info", + [ID_DAP_HostStatus] = "DAP_HostStatus", + [ID_DAP_Connect] = "DAP_Connect", + [ID_DAP_Disconnect] = "DAP_Disconnect", + [ID_DAP_TransferConfigure] = "DAP_TransferConfigure", + [ID_DAP_Transfer] = "DAP_Transfer", + [ID_DAP_TransferBlock] = "DAP_TransferBlock", + [ID_DAP_TransferAbort] = "DAP_TransferAbort", + [ID_DAP_WriteABORT] = "DAP_WriteABORT", + [ID_DAP_Delay] = "DAP_Delay", + [ID_DAP_ResetTarget] = "DAP_ResetTarget", + [ID_DAP_SWJ_Pins] = "DAP_SWJ_Pins", + [ID_DAP_SWJ_Clock] = "DAP_SWJ_Clock", + [ID_DAP_SWJ_Sequence] = "DAP_SWJ_Sequence", + [ID_DAP_SWD_Configure] = "DAP_SWD_Configure", + [ID_DAP_SWD_Sequence] = "DAP_SWD_Sequence", + [ID_DAP_JTAG_Sequence] = "DAP_JTAG_Sequence", + [ID_DAP_JTAG_Configure] = "DAP_JTAG_Configure", + [ID_DAP_JTAG_IDCODE] = "DAP_JTAG_IDCODE", + [ID_DAP_SWO_Transport] = "DAP_SWO_Transport", + [ID_DAP_SWO_Mode] = "DAP_SWO_Mode", + [ID_DAP_SWO_Baudrate] = "DAP_SWO_Baudrate", + [ID_DAP_SWO_Control] = "DAP_SWO_Control", + [ID_DAP_SWO_Status] = "DAP_SWO_Status", + [ID_DAP_SWO_ExtendedStatus] = "DAP_SWO_ExtendedStatus", + [ID_DAP_SWO_Data] = "DAP_SWO_Data", + [ID_DAP_QueueCommands] = "DAP_QueueCommands", + [ID_DAP_ExecuteCommands] = "DAP_ExecuteCommands", }; - -uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) +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 && - DAP_INTERFACE_SUBCLASS == itf_desc->bInterfaceSubClass && - DAP_INTERFACE_PROTOCOL == itf_desc->bInterfaceProtocol, 0); + DAP_INTERFACE_SUBCLASS == itf_desc->bInterfaceSubClass && + DAP_INTERFACE_PROTOCOL == itf_desc->bInterfaceProtocol, + 0); // Initialise circular buffer indices USBResponseBuffer.wptr = 0; @@ -97,18 +98,20 @@ uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf USBRequestBuffer.wasFull = false; USBRequestBuffer.wasEmpty = true; - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + (itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + 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); + 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 + // 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, WR_SLOT_PTR(USBRequestBuffer), DAP_PACKET_SIZE); @@ -119,37 +122,41 @@ uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf _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 + // 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) +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) +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) - { + if (ep_dir == TUSB_DIR_IN) { + if (xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE) { USBResponseBuffer.rptr++; - // 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, RD_SLOT_PTR(USBResponseBuffer), (uint16_t) _resp_len); - USBResponseBuffer.wasEmpty = (USBResponseBuffer.rptr + 1) == USBResponseBuffer.wptr; + // 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, RD_SLOT_PTR(USBResponseBuffer), + (uint16_t)_resp_len); + USBResponseBuffer.wasEmpty = + (USBResponseBuffer.rptr + 1) == USBResponseBuffer.wptr; } // Wake up DAP thread after processing the callback @@ -159,19 +166,17 @@ bool dap_edpt_xfer_cb(uint8_t __unused rhport, uint8_t ep_addr, xfer_result_t re return false; - } else if(ep_dir == TUSB_DIR_OUT) { + } else if (ep_dir == TUSB_DIR_OUT) { - if(xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE) - { + 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)) - { + if (!buffer_full(&USBRequestBuffer)) { USBRequestBuffer.wptr++; - usbd_edpt_xfer(rhport, ep_addr, WR_SLOT_PTR(USBRequestBuffer), DAP_PACKET_SIZE); + usbd_edpt_xfer(rhport, ep_addr, WR_SLOT_PTR(USBRequestBuffer), + DAP_PACKET_SIZE); USBRequestBuffer.wasFull = false; - } - else { + } else { USBRequestBuffer.wasFull = true; } @@ -180,73 +185,82 @@ bool dap_edpt_xfer_cb(uint8_t __unused rhport, uint8_t ep_addr, xfer_result_t re return true; } + return false; + } else { return false; } - else return false; } void dap_thread(void *ptr) { uint32_t n; - do - { - while(USBRequestBuffer.rptr != USBRequestBuffer.wptr) - { + do { + while (USBRequestBuffer.rptr != USBRequestBuffer.wptr) { /* * Atomic command support - buffer QueueCommands, but don't process them * until a non-QueueCommands packet is seen. */ n = USBRequestBuffer.rptr; - while (USBRequestBuffer.data[n % DAP_PACKET_COUNT][0] == ID_DAP_QueueCommands) { + while (USBRequestBuffer.data[n % DAP_PACKET_COUNT][0] == + ID_DAP_QueueCommands) { probe_info("%u %u 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; + 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; n++; while (n == USBRequestBuffer.wptr) { - /* Need yield in a loop here, as IN callbacks will also wake the thread */ + /* Need yield in a loop here, as IN callbacks will also wake + * the thread */ probe_info("DAP wait\n"); vTaskSuspend(dap_taskhandle); } } // 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", - USBRequestBuffer.wptr, USBRequestBuffer.rptr, - dap_cmd_string[DAPRequestBuffer[0]], DAPRequestBuffer[1]); + probe_info("%u %u DAP cmd %s len %02x\n", USBRequestBuffer.wptr, + USBRequestBuffer.rptr, dap_cmd_string[DAPRequestBuffer[0]], + DAPRequestBuffer[1]); USBRequestBuffer.rptr++; - // 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 + // 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.wptr++; - usbd_edpt_xfer(_rhport, _out_ep_addr, WR_SLOT_PTR(USBRequestBuffer), DAP_PACKET_SIZE); + usbd_edpt_xfer(_rhport, _out_ep_addr, WR_SLOT_PTR(USBRequestBuffer), + DAP_PACKET_SIZE); USBRequestBuffer.wasFull = false; xTaskResumeAll(); } _resp_len = DAP_ExecuteCommand(DAPRequestBuffer, DAPResponseBuffer); - probe_info("%u %u DAP resp %s\n", - USBResponseBuffer.wptr, USBResponseBuffer.rptr, - dap_cmd_string[DAPResponseBuffer[0]]); - + probe_info("%u %u DAP resp %s\n", USBResponseBuffer.wptr, + USBResponseBuffer.rptr, dap_cmd_string[DAPResponseBuffer[0]]); - // Suspend the scheduler to avoid stale values/race conditions between threads + // Suspend the scheduler to avoid stale values/race conditions between + // threads vTaskSuspendAll(); - if(buffer_empty(&USBResponseBuffer)) - { - memcpy(WR_SLOT_PTR(USBResponseBuffer), DAPResponseBuffer, (uint16_t) _resp_len); + if (buffer_empty(&USBResponseBuffer)) { + memcpy(WR_SLOT_PTR(USBResponseBuffer), DAPResponseBuffer, + (uint16_t)_resp_len); USBResponseBuffer.wptr++; - usbd_edpt_xfer(_rhport, _in_ep_addr, RD_SLOT_PTR(USBResponseBuffer), (uint16_t) _resp_len); + usbd_edpt_xfer(_rhport, _in_ep_addr, RD_SLOT_PTR(USBResponseBuffer), + (uint16_t)_resp_len); } else { - memcpy(WR_SLOT_PTR(USBResponseBuffer), DAPResponseBuffer, (uint16_t) _resp_len); + memcpy(WR_SLOT_PTR(USBResponseBuffer), DAPResponseBuffer, + (uint16_t)_resp_len); USBResponseBuffer.wptr++; - // The In callback needs to check this flag to know when to queue up the next buffer. + // The In callback needs to check this flag to know when to queue up + // the next buffer. USBResponseBuffer.wasEmpty = false; } xTaskResumeAll(); @@ -256,19 +270,16 @@ void dap_thread(void *ptr) 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, +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 = "DAP ENDPOINT" + .name = "DAP ENDPOINT" #endif }; @@ -278,4 +289,3 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) *driver_count = 1; return &_dap_edpt_driver; } - diff --git a/src/tusb_edpt_handler.h b/src/tusb_edpt_handler.h index be1fdd0fa..d5990a64a 100644 --- a/src/tusb_edpt_handler.h +++ b/src/tusb_edpt_handler.h @@ -30,9 +30,12 @@ void dap_thread(void *ptr); /* Endpoint Handling */ void dap_edpt_init(void); -uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len); -bool dap_edpt_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const *request); -bool dap_edpt_xfer_cb(uint8_t __unused rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +uint16_t dap_edpt_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, + uint16_t max_len); +bool dap_edpt_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, + tusb_control_request_t const *request); +bool dap_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); diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 8f5aba5e4..556f8d1f2 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -32,98 +32,93 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = -{ - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, +tusb_desc_device_t const desc_device = {.bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V2) - .bcdUSB = 0x0210, // USB Specification version 2.1 for BOS + .bcdUSB = 0x0210, // USB Specification version 2.1 for BOS #else - .bcdUSB = 0x0110, + .bcdUSB = 0x0110, #endif - .bDeviceClass = 0x00, // Each interface specifies its own - .bDeviceSubClass = 0x00, // Each interface specifies its own - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = 0x2E8A, // Pi - .idProduct = 0x000c, // CMSIS-DAP Debug Probe - .bcdDevice = 0x0201, // Version 02.01 - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - .bNumConfigurations = 0x01 -}; + .bDeviceClass = 0x00, // Each interface specifies its own + .bDeviceSubClass = 0x00, // Each interface specifies its own + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0x2E8A, // Pi + .idProduct = 0x000c, // CMSIS-DAP Debug Probe + .bcdDevice = 0x0201, // Version 02.01 + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + .bNumConfigurations = 0x01}; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor -uint8_t const * tud_descriptor_device_cb(void) +uint8_t const *tud_descriptor_device_cb(void) { - return (uint8_t const *) &desc_device; + return (uint8_t const *)&desc_device; } //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -enum -{ - ITF_NUM_PROBE, // Old versions of Keil MDK only look at interface 0 - ITF_NUM_CDC_COM, - ITF_NUM_CDC_DATA, - ITF_NUM_TOTAL +enum { + ITF_NUM_PROBE, // Old versions of Keil MDK only look at interface 0 + ITF_NUM_CDC_COM, + ITF_NUM_CDC_DATA, + ITF_NUM_TOTAL }; #define CDC_NOTIFICATION_EP_NUM 0x81 -#define CDC_DATA_OUT_EP_NUM 0x02 -#define CDC_DATA_IN_EP_NUM 0x83 -#define DAP_OUT_EP_NUM 0x04 -#define DAP_IN_EP_NUM 0x85 +#define CDC_DATA_OUT_EP_NUM 0x02 +#define CDC_DATA_IN_EP_NUM 0x83 +#define DAP_OUT_EP_NUM 0x04 +#define DAP_IN_EP_NUM 0x85 #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V1) -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_INOUT_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_INOUT_DESC_LEN) #else -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN) #endif -static uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE) -}; +static uint8_t const desc_hid_report[] = { + TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)}; -uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) +uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) { - (void) itf; - return desc_hid_report; + (void)itf; + return desc_hid_report; } -uint8_t desc_configuration[] = -{ - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), - // Interface 0 +uint8_t desc_configuration[] = { + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100), +// Interface 0 #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V1) - // HID (named interface) - TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_PROBE, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), DAP_OUT_EP_NUM, DAP_IN_EP_NUM, CFG_TUD_HID_EP_BUFSIZE, 1), + // HID (named interface) + TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_PROBE, 4, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), + DAP_OUT_EP_NUM, DAP_IN_EP_NUM, CFG_TUD_HID_EP_BUFSIZE, 1), #elif (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V2) - // Bulk (named interface) - TUD_VENDOR_DESCRIPTOR(ITF_NUM_PROBE, 5, DAP_OUT_EP_NUM, DAP_IN_EP_NUM, 64), + // Bulk (named interface) + TUD_VENDOR_DESCRIPTOR(ITF_NUM_PROBE, 5, DAP_OUT_EP_NUM, DAP_IN_EP_NUM, 64), #elif (PROBE_DEBUG_PROTOCOL == PROTO_OPENOCD_CUSTOM) - // Bulk - TUD_VENDOR_DESCRIPTOR(ITF_NUM_PROBE, 0, DAP_OUT_EP_NUM, DAP_IN_EP_NUM, 64), + // Bulk + TUD_VENDOR_DESCRIPTOR(ITF_NUM_PROBE, 0, DAP_OUT_EP_NUM, DAP_IN_EP_NUM, 64), #endif - // Interface 1 + 2 - TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_COM, 6, CDC_NOTIFICATION_EP_NUM, 64, CDC_DATA_OUT_EP_NUM, CDC_DATA_IN_EP_NUM, 64), + // Interface 1 + 2 + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_COM, 6, CDC_NOTIFICATION_EP_NUM, 64, CDC_DATA_OUT_EP_NUM, + CDC_DATA_IN_EP_NUM, 64), }; // Invoked when received GET CONFIGURATION DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { - (void) index; // for multiple configurations - /* Hack in CAP_BREAK support */ - desc_configuration[CONFIG_TOTAL_LEN - TUD_CDC_DESC_LEN + 8 + 9 + 5 + 5 + 4 - 1] = 0x6; - return desc_configuration; + (void)index; // for multiple configurations + /* Hack in CAP_BREAK support */ + desc_configuration[CONFIG_TOTAL_LEN - TUD_CDC_DESC_LEN + 8 + 9 + 5 + 5 + 4 - 1] = 0x6; + return desc_configuration; } //--------------------------------------------------------------------+ @@ -131,53 +126,54 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) //--------------------------------------------------------------------+ // array of pointer to string descriptors -char const* string_desc_arr [] = -{ - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "Raspberry Pi", // 1: Manufacturer - PROBE_PRODUCT_STRING, // 2: Product - usb_serial, // 3: Serial, uses flash unique ID - "CMSIS-DAP v1 Interface", // 4: Interface descriptor for HID transport - "CMSIS-DAP v2 Interface", // 5: Interface descriptor for Bulk transport - "CDC-ACM UART Interface", // 6: Interface descriptor for CDC +char const *string_desc_arr[] = { + (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + "Raspberry Pi", // 1: Manufacturer + PROBE_PRODUCT_STRING, // 2: Product + usb_serial, // 3: Serial, uses flash unique ID + "CMSIS-DAP v1 Interface", // 4: Interface descriptor for HID transport + "CMSIS-DAP v2 Interface", // 5: Interface descriptor for Bulk transport + "CDC-ACM UART Interface", // 6: Interface descriptor for CDC }; static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) +// Application return pointer to descriptor, whose contents must exist long enough for transfer to +// complete +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; + (void)langid; - uint8_t chr_count; + uint8_t chr_count; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Convert ASCII string into UTF-16 + if (index == 0) { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + } else { + // Convert ASCII string into UTF-16 - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) { + return NULL; + } - const char* str = string_desc_arr[index]; + const char *str = string_desc_arr[index]; - // Cap at max char - chr_count = strlen(str); - if ( chr_count > 31 ) chr_count = 31; + // Cap at max char + chr_count = strlen(str); + if (chr_count > 31) { + chr_count = 31; + } - for(uint8_t i=0; i