definitely not functuonal but hey its something
This commit is contained in:
parent
f73f890276
commit
144b351d74
|
@ -7,6 +7,9 @@ set(TOP "./tinyusb")
|
||||||
get_filename_component(TOP "${TOP}" REALPATH)
|
get_filename_component(TOP "${TOP}" REALPATH)
|
||||||
|
|
||||||
option(USE_SYSTEMWIDE_PICOSDK "Use the systemwide Pico SDK instead of relying on the one from a deeply nested Git submodule (OFF by default)" OFF)
|
option(USE_SYSTEMWIDE_PICOSDK "Use the systemwide Pico SDK instead of relying on the one from a deeply nested Git submodule (OFF by default)" OFF)
|
||||||
|
# OPTION: PICO_NO_FLASH: load only into RAM (useful for testing)
|
||||||
|
# OPTION: PICO_COPY_TO_RAM: place the code/rodata into RAM at startup (while still stored in flash)
|
||||||
|
# TODO: add option for FAMILY and BOARD
|
||||||
|
|
||||||
# Check for -DFAMILY=
|
# Check for -DFAMILY=
|
||||||
if(FAMILY STREQUAL "rp2040")
|
if(FAMILY STREQUAL "rp2040")
|
||||||
|
@ -25,6 +28,10 @@ if(FAMILY STREQUAL "rp2040")
|
||||||
|
|
||||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||||
|
|
||||||
|
# need uart stdio, usb is busy doing other stuff
|
||||||
|
pico_enable_stdio_uart(${PROJECT} 1)
|
||||||
|
pico_enable_stdio_usb(${PROJECT} 0)
|
||||||
|
|
||||||
# Example source
|
# Example source
|
||||||
target_sources(${PROJECT} PUBLIC
|
target_sources(${PROJECT} PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/main.c
|
${CMAKE_CURRENT_SOURCE_DIR}/main.c
|
||||||
|
@ -35,6 +42,8 @@ if(FAMILY STREQUAL "rp2040")
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c
|
${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c
|
${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_uart.c
|
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_uart.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/spi_serprog.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/cdc_serprog.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Example include
|
# Example include
|
||||||
|
@ -50,7 +59,8 @@ if(FAMILY STREQUAL "rp2040")
|
||||||
target_compile_definitions(${PROJECT} PUBLIC
|
target_compile_definitions(${PROJECT} PUBLIC
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration pico_unique_id)
|
target_link_libraries(${PROJECT} pico_stdlib pico_unique_id hardware_spi
|
||||||
|
pico_fix_rp2040_usb_device_enumeration)
|
||||||
|
|
||||||
pico_add_extra_outputs(${PROJECT})
|
pico_add_extra_outputs(${PROJECT})
|
||||||
|
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -8,7 +8,7 @@ INC += \
|
||||||
./bsp/default \
|
./bsp/default \
|
||||||
$(TOP)/hw
|
$(TOP)/hw
|
||||||
|
|
||||||
APP_SOURCE += $(wildcard ./*.c)
|
APP_SOURCE += $(wildcard ./*.c) $(wildcard ./bsp/$(BOARD)/*.c)
|
||||||
|
|
||||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(APP_SOURCE))
|
SRC_C += $(addprefix $(CURRENT_PATH)/, $(APP_SOURCE))
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ SRC_C += \
|
||||||
./CMSIS_5/CMSIS/DAP/Firmware/Source/JTAG_DP.c \
|
./CMSIS_5/CMSIS/DAP/Firmware/Source/JTAG_DP.c \
|
||||||
./CMSIS_5/CMSIS/DAP/Firmware/Source/DAP_vendor.c \
|
./CMSIS_5/CMSIS/DAP/Firmware/Source/DAP_vendor.c \
|
||||||
./CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c \
|
./CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c \
|
||||||
./CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c \
|
./CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c
|
||||||
./bsp/$(BOARD)/cdc_uart.c
|
|
||||||
|
|
||||||
include ./tinyusb/examples/rules.mk
|
include ./tinyusb/examples/rules.mk
|
||||||
|
|
19
README.md
19
README.md
|
@ -74,7 +74,8 @@ The pin mapping for the RP2040 is as follows:
|
||||||
|
|
||||||
The UART pins are for connecting to the device to be debugged, the data is
|
The UART pins are for connecting to the device to be debugged, the data is
|
||||||
echoed back over the USB CDC interface (typically a `/dev/ttyACMx` device on
|
echoed back over the USB CDC interface (typically a `/dev/ttyACMx` device on
|
||||||
Linux).
|
Linux). If you want to get stdio readout on your computer, connect GP0 to GP5,
|
||||||
|
and GP1 to GP4.
|
||||||
|
|
||||||
In SWD mode, the pin mapping is entirely as with the standard Picoprobe setup,
|
In SWD mode, the pin mapping is entirely as with the standard Picoprobe setup,
|
||||||
as described in Chapter 5 and Appendix A of [Getting Started with Raspberry Pi
|
as described in Chapter 5 and Appendix A of [Getting Started with Raspberry Pi
|
||||||
|
@ -94,7 +95,23 @@ ARM's CMSIS_5 code is licensed under the [Apache 2.0 license](https://opensource
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
- [x] CMSIS-DAP JTAG implementation
|
||||||
- [ ] Flashrom/SPI support using Serprog
|
- [ ] Flashrom/SPI support using Serprog
|
||||||
|
- [ ] UART with CTS/RTS flow control
|
||||||
- [ ] I2C support by emulating the I2C Tiny USB
|
- [ ] I2C support by emulating the I2C Tiny USB
|
||||||
|
- [ ] Expose RP2040-internal temperature ADC on I2C-over-USB bus?
|
||||||
|
- Does SMBus stuff need special treatment here?
|
||||||
|
- [ ] Maybe add some way of reconfiguring features while the device is running.
|
||||||
|
Eg. CTS/RTS enable/disable, temperature ADC I2C address, ...
|
||||||
|
- Maybe use the Serprog USB serial interface for this, with some extension
|
||||||
|
commands not typically used for Serprog.
|
||||||
- [ ] AVR programming (USBavr emulation?)
|
- [ ] AVR programming (USBavr emulation?)
|
||||||
|
- Renesas E7-{0,1,2} programming thing????
|
||||||
|
- Renesas tell us how this works pls
|
||||||
|
- Maybe steal other features from the Bus Pirate or Glasgow or so
|
||||||
|
- 1-wire? Never seen this one in the wild
|
||||||
|
- MIDI? Feels mostly gimmicky...
|
||||||
|
- PS/2? Hmmmm idk
|
||||||
|
- HD44780 LCD? See MIDI
|
||||||
|
- CAN? If I'd first be able to find a CAN device to test it with, sure
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#ifndef PROTOCFG_H_
|
||||||
|
#define PROTOCFG_H_
|
||||||
|
|
||||||
|
/*#define DBOARD_HAS_UART*/
|
||||||
|
#define DBOARD_HAS_CMSISDAP
|
||||||
|
/*#define DBOARD_HAS_SERPROG*/
|
||||||
|
/*#define DBOARD_HAS_TINYI2C*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -57,6 +57,7 @@ This information includes:
|
||||||
#include <hardware/regs/io_bank0.h>
|
#include <hardware/regs/io_bank0.h>
|
||||||
#include <hardware/structs/iobank0.h>
|
#include <hardware/structs/iobank0.h>
|
||||||
#include <hardware/gpio.h>
|
#include <hardware/gpio.h>
|
||||||
|
#include <pico/binary_info.h>
|
||||||
|
|
||||||
#include "picoprobe_config.h"
|
#include "picoprobe_config.h"
|
||||||
|
|
||||||
|
@ -559,6 +560,17 @@ __STATIC_INLINE void DAP_SETUP (void) {
|
||||||
|
|
||||||
hw_write_masked(&padsbank0_hw->io[PICOPROBE_LED], 0, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
hw_write_masked(&padsbank0_hw->io[PICOPROBE_LED], 0, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||||
iobank0_hw->io[PICOPROBE_LED].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
iobank0_hw->io[PICOPROBE_LED].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||||
|
|
||||||
|
bi_decl(bi_2pins_with_names(
|
||||||
|
PROBE_PIN_JTAG_TCK, "TCK / SWCLK",
|
||||||
|
PROBE_PIN_JTAG_TMS, "TMS / SWDIO"
|
||||||
|
));
|
||||||
|
bi_decl(bi_4pins_with_names(
|
||||||
|
PROBE_PIN_JTAG_TDI , "TDI",
|
||||||
|
PROBE_PIN_JTAG_TDO , "TDO",
|
||||||
|
PROBE_PIN_JTAG_nTRST , "nTRST",
|
||||||
|
PROBE_PIN_JTAG_nRESET, "nRESET"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reset Target Device with custom specific I/O pin or command sequence.
|
/** Reset Target Device with custom specific I/O pin or command sequence.
|
||||||
|
|
|
@ -24,39 +24,49 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
|
#include <pico/binary_info.h>
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
#include "picoprobe_config.h"
|
#include "picoprobe_config.h"
|
||||||
|
#include "protocfg.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
// declare these so other CDC interfaces can use the same buffers, decreasing
|
||||||
|
// overall memory usage. however, this means the contents of these buffers
|
||||||
|
// can't be relied upon to persist between two cdc_*_task() calls
|
||||||
|
extern uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
|
extern uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
|
__attribute__((__weak__)) uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
|
__attribute__((__weak__)) uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
|
|
||||||
void cdc_uart_init(void) {
|
void cdc_uart_init(void) {
|
||||||
gpio_set_function(PICOPROBE_UART_TX, GPIO_FUNC_UART);
|
gpio_set_function(PICOPROBE_UART_TX, GPIO_FUNC_UART);
|
||||||
gpio_set_function(PICOPROBE_UART_RX, GPIO_FUNC_UART);
|
gpio_set_function(PICOPROBE_UART_RX, GPIO_FUNC_UART);
|
||||||
uart_init(PICOPROBE_UART_INTERFACE, PICOPROBE_UART_BAUDRATE);
|
uart_init(PICOPROBE_UART_INTERFACE, PICOPROBE_UART_BAUDRATE);
|
||||||
|
|
||||||
|
bi_decl(bi_2pins_with_func(PICOPROBE_UART_TX, PICOPROBE_UART_RX, GPIO_FUNC_UART));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdc_task(void) {
|
void cdc_uart_task(void) {
|
||||||
uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
|
||||||
uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
|
||||||
|
|
||||||
// Consume uart fifo regardless even if not connected
|
// Consume uart fifo regardless even if not connected
|
||||||
uint rx_len = 0;
|
uint rx_len = 0;
|
||||||
while(uart_is_readable(PICOPROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) {
|
while (uart_is_readable(PICOPROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) {
|
||||||
rx_buf[rx_len++] = uart_getc(PICOPROBE_UART_INTERFACE);
|
rx_buf[rx_len++] = uart_getc(PICOPROBE_UART_INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tud_cdc_connected()) {
|
if (tud_cdc_n_connected(CDC_N_UART)) {
|
||||||
// Do we have anything to display on the host's terminal?
|
// Do we have anything to display on the host's terminal?
|
||||||
if (rx_len) {
|
if (rx_len) {
|
||||||
for (uint i = 0; i < rx_len; i++) {
|
for (uint i = 0; i < rx_len; i++) {
|
||||||
tud_cdc_write_char(rx_buf[i]);
|
tud_cdc_n_write_char(CDC_N_UART, rx_buf[i]);
|
||||||
}
|
}
|
||||||
tud_cdc_write_flush();
|
tud_cdc_n_write_flush(CDC_N_UART);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tud_cdc_available()) {
|
if (tud_cdc_n_available(CDC_N_UART)) {
|
||||||
// Is there any data from the host for us to tx
|
// Is there any data from the host for us to tx
|
||||||
uint tx_len = tud_cdc_read(tx_buf, sizeof(tx_buf));
|
uint tx_len = tud_cdc_n_read(CDC_N_UART, tx_buf, sizeof(tx_buf));
|
||||||
uart_write_blocking(PICOPROBE_UART_INTERFACE, tx_buf, tx_len);
|
uart_write_blocking(PICOPROBE_UART_INTERFACE, tx_buf, tx_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,3 +76,4 @@ void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) {
|
||||||
picoprobe_info("New baud rate %d\n", line_coding->bit_rate);
|
picoprobe_info("New baud rate %d\n", line_coding->bit_rate);
|
||||||
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,13 @@
|
||||||
#define PROBE_PIN_JTAG_nTRST 8
|
#define PROBE_PIN_JTAG_nTRST 8
|
||||||
#define PROBE_PIN_JTAG_nRESET 9
|
#define PROBE_PIN_JTAG_nRESET 9
|
||||||
|
|
||||||
|
// SPI config
|
||||||
|
#define PROBE_SPI_DEV spi1
|
||||||
|
#define PROBE_SPI_SCLK 10
|
||||||
|
#define PROBE_SPI_MOSI 11
|
||||||
|
#define PROBE_SPI_MISO 12
|
||||||
|
#define PROBE_SPI_nCS 13
|
||||||
|
|
||||||
// LED config
|
// LED config
|
||||||
|
|
||||||
// you can change these two as you like
|
// you can change these two as you like
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
#ifndef PROTOCFG_H_
|
||||||
|
#define PROTOCFG_H_
|
||||||
|
|
||||||
|
#define DBOARD_HAS_UART
|
||||||
|
#define DBOARD_HAS_CMSISDAP
|
||||||
|
#define DBOARD_HAS_SERPROG
|
||||||
|
/*#define DBOARD_HAS_TINYI2C*/
|
||||||
|
|
||||||
|
#define HID_N_CMSISDAP 0
|
||||||
|
#define CDC_N_UART 0
|
||||||
|
#define CDC_N_SERPROG 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <pico/stdlib.h>
|
||||||
|
#include <pico/binary_info.h>
|
||||||
|
#include <hardware/spi.h>
|
||||||
|
|
||||||
|
#include "protocfg.h"
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
#include "serprog.h"
|
||||||
|
|
||||||
|
#include "picoprobe_config.h"
|
||||||
|
|
||||||
|
static bool cs_asserted;
|
||||||
|
|
||||||
|
void sp_spi_init(void) {
|
||||||
|
printf("spi init!\n");
|
||||||
|
|
||||||
|
cs_asserted = false;
|
||||||
|
|
||||||
|
spi_init(PROBE_SPI_DEV, 512*1000); // default to 512 kHz
|
||||||
|
|
||||||
|
gpio_init(PROBE_SPI_nCS);
|
||||||
|
gpio_put(PROBE_SPI_nCS, 1);
|
||||||
|
gpio_set_dir(PROBE_SPI_nCS, GPIO_OUT);
|
||||||
|
|
||||||
|
gpio_set_function(PROBE_SPI_MISO, GPIO_FUNC_SPI);
|
||||||
|
gpio_set_function(PROBE_SPI_MOSI, GPIO_FUNC_SPI);
|
||||||
|
gpio_set_function(PROBE_SPI_SCLK, GPIO_FUNC_SPI);
|
||||||
|
|
||||||
|
bi_decl(bi_3pins_with_func(PROBE_SPI_MISO, PROBE_SPI_MOSI, PROBE_SPI_SCLK, GPIO_FUNC_SPI));
|
||||||
|
bi_decl(bi_1pin_with_name(PROBE_SPI_nCS, "SPI #CS"));
|
||||||
|
}
|
||||||
|
uint32_t __not_in_flash_func(sp_spi_set_freq)(uint32_t freq_wanted) {
|
||||||
|
return spi_set_baudrate(PROBE_SPI_DEV, freq_wanted);
|
||||||
|
}
|
||||||
|
void __not_in_flash_func(sp_spi_cs_deselect)(void) {
|
||||||
|
asm volatile("nop\nnop\nnop"); // idk if this is needed
|
||||||
|
gpio_put(PROBE_SPI_nCS, 1);
|
||||||
|
asm volatile("nop\nnop\nnop"); // idk if this is needed
|
||||||
|
cs_asserted = false;
|
||||||
|
}
|
||||||
|
void __not_in_flash_func(sp_spi_cs_select)(void) {
|
||||||
|
asm volatile("nop\nnop\nnop"); // idk if this is needed
|
||||||
|
gpio_put(PROBE_SPI_nCS, 0);
|
||||||
|
asm volatile("nop\nnop\nnop"); // idk if this is needed
|
||||||
|
cs_asserted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __not_in_flash_func(sp_spi_op_begin)(void) {
|
||||||
|
if (!cs_asserted) sp_spi_cs_select();
|
||||||
|
}
|
||||||
|
void __not_in_flash_func(sp_spi_op_end)(void) {
|
||||||
|
if (cs_asserted) sp_spi_cs_deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use dma?
|
||||||
|
void __not_in_flash_func(sp_spi_op_write)(uint32_t write_len, const uint8_t* write_data) {
|
||||||
|
spi_write_blocking(PROBE_SPI_DEV, write_data, write_len);
|
||||||
|
}
|
||||||
|
void __not_in_flash_func(sp_spi_op_read)(uint32_t read_len, uint8_t* read_data) {
|
||||||
|
spi_read_blocking(PROBE_SPI_DEV, 0, read_data, read_len);
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@ void cdc_uart_init(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdc_task(void)
|
void cdc_uart_task(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#ifndef PROTOCFG_H_
|
||||||
|
#define PROTOCFG_H_
|
||||||
|
|
||||||
|
/*#define DBOARD_HAS_UART*/
|
||||||
|
#define DBOARD_HAS_CMSISDAP
|
||||||
|
/*#define DBOARD_HAS_SERPROG*/
|
||||||
|
/*#define DBOARD_HAS_TINYI2C*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
#include "serprog.h"
|
||||||
|
|
||||||
|
void sp_spi_init(void) {
|
||||||
|
}
|
||||||
|
uint32_t sp_spi_set_freq(uint32_t freq_wanted) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void sp_spi_cs_deselect(void) {
|
||||||
|
}
|
||||||
|
void sp_spi_cs_select(void) {
|
||||||
|
}
|
||||||
|
void sp_spi_op_begin(void){}
|
||||||
|
void sp_spi_op_write(uint32_t write_len, uint8_t* write_data){}
|
||||||
|
void sp_spi_op_read(uint32_t read_len, const uint8_t* read_data){}
|
||||||
|
void sp_spi_op_end(void){}
|
||||||
|
|
|
@ -0,0 +1,241 @@
|
||||||
|
// vim: set et:
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include "protocfg.h"
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
|
||||||
|
#include "protos.h"
|
||||||
|
|
||||||
|
#include "serprog.h"
|
||||||
|
|
||||||
|
// TODO: refactor some of this stuff into another header & split off serprog
|
||||||
|
// protocol handling from the SPI stuff. one thing we should think about
|
||||||
|
// when performing this refactor is, would other boards support
|
||||||
|
// parallell, LPC, or FWH, or only SPI? if only SPI, the entire proto
|
||||||
|
// handler can just be made reusable verbatim.
|
||||||
|
|
||||||
|
// kinda refactored this already but it still has a good note for non-SPI stuff,
|
||||||
|
// so leaving it here for now
|
||||||
|
|
||||||
|
static const uint8_t serprog_cmdmap[32] = {
|
||||||
|
0x3f, // cmd 00..05 not 0x06 (Q_CHIPSIZE) and 0x07 (Q_OPBUF), as this is a SPI-only device
|
||||||
|
0x01, // only cmd 08
|
||||||
|
0x1f, // cmd 10..15 supported
|
||||||
|
0, // rest is 0
|
||||||
|
};
|
||||||
|
static const char serprog_pgmname[16] = {
|
||||||
|
'D','a','p','p','e','r','M','i','m','e','-','J','T','A','G',0 // TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
// declare these so other CDC interfaces can use the same buffers, decreasing
|
||||||
|
// overall memory usage. however, this means the contents of these buffers
|
||||||
|
// can't be relied upon to persist between two cdc_*_task() calls
|
||||||
|
extern uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
|
extern uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
|
__attribute__((__weak__)) uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||||
|
__attribute__((__weak__)) uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||||
|
|
||||||
|
static uint32_t bufpos;
|
||||||
|
|
||||||
|
void cdc_serprog_init(void) {
|
||||||
|
bufpos = 0;
|
||||||
|
|
||||||
|
sp_spi_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t serprog_handle_cmd(const uint8_t* buf, uint32_t nread) {
|
||||||
|
if (nread == 0) return 0;
|
||||||
|
|
||||||
|
uint32_t nresp = 0, rv = 1;
|
||||||
|
|
||||||
|
switch (buf[0]) {
|
||||||
|
case S_CMD_NOP:
|
||||||
|
printf("nop\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
nresp = 1;
|
||||||
|
break;
|
||||||
|
case S_CMD_SYNCNOP:
|
||||||
|
printf("syncnop\n");
|
||||||
|
tx_buf[0] = S_NAK;
|
||||||
|
tx_buf[1] = S_ACK;
|
||||||
|
nresp = 2;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_IFACE:
|
||||||
|
printf("q_iface\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = SERPROG_IFACE_VERSION & 0xff;
|
||||||
|
tx_buf[2] = (SERPROG_IFACE_VERSION >> 8) & 0xff;
|
||||||
|
nresp = 3;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_CMDMAP:
|
||||||
|
printf("q_cmdmap\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
memcpy(&tx_buf[1], serprog_cmdmap, sizeof serprog_cmdmap);
|
||||||
|
nresp = sizeof(serprog_cmdmap) + 1;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_PGMNAME:
|
||||||
|
printf("q_pgmname\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
memcpy(&tx_buf[1], serprog_pgmname, sizeof serprog_pgmname);
|
||||||
|
nresp = sizeof(serprog_pgmname) + 1;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_SERBUF:
|
||||||
|
printf("q_serbuf\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = sizeof(rx_buf) & 0xff;
|
||||||
|
tx_buf[2] = (sizeof(rx_buf) >> 8) & 0xff;
|
||||||
|
nresp = 3;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_BUSTYPE:
|
||||||
|
printf("q_bustype\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = 1<<3; // SPI only
|
||||||
|
nresp = 2;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_WRNMAXLEN:
|
||||||
|
printf("q_wrnmaxlen\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = (sizeof(tx_buf)-1) & 0xff;
|
||||||
|
tx_buf[2] = ((sizeof(tx_buf)-1) >> 8) & 0xff;
|
||||||
|
nresp = 3;
|
||||||
|
break;
|
||||||
|
case S_CMD_Q_RDNMAXLEN:
|
||||||
|
printf("q_rdnmaxlen\n");
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = (sizeof(rx_buf)-1) & 0xff;
|
||||||
|
tx_buf[2] = ((sizeof(rx_buf)-1) >> 8) & 0xff;
|
||||||
|
nresp = 3;
|
||||||
|
break;
|
||||||
|
case S_CMD_S_BUSTYPE:
|
||||||
|
printf("s_bustype\n");
|
||||||
|
if (nread < 2) return 0; // need more data
|
||||||
|
|
||||||
|
if (buf[1] == (1<<3)) {
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
} else {
|
||||||
|
tx_buf[0] = S_NAK;
|
||||||
|
}
|
||||||
|
nresp = 1;
|
||||||
|
rv = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_CMD_SPIOP: {
|
||||||
|
printf("spiop\n");
|
||||||
|
if (nread < 7) return 0; // need more data
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
slen = (uint32_t)buf[1] | ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]),
|
||||||
|
rlen = (uint32_t)buf[4] | ((uint32_t)buf[5] << 8) | ((uint32_t)buf[6]);
|
||||||
|
|
||||||
|
if (7 + slen > sizeof(rx_buf) || 1 + rlen > sizeof(tx_buf)) {
|
||||||
|
// TODO: stream buffers in and out here for larger xfers
|
||||||
|
tx_buf[0] = S_NAK;
|
||||||
|
nresp = 1;
|
||||||
|
} else {
|
||||||
|
if (nread < 7 + slen) return 0;
|
||||||
|
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
sp_spi_op_do(slen, &buf[7], rlen, &tx_buf[1]);
|
||||||
|
nresp = 7 + rlen;
|
||||||
|
rv = 7 + slen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_CMD_S_SPI_FREQ: {
|
||||||
|
printf("s_spi_freq\n");
|
||||||
|
if (nread < 5) return 0; // need more data
|
||||||
|
uint32_t freq = (uint32_t)buf[1] | ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3] << 16) | ((uint32_t)buf[4] << 24);
|
||||||
|
|
||||||
|
uint32_t nfreq = sp_spi_set_freq(freq);
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
tx_buf[1] = nfreq & 0xff;
|
||||||
|
tx_buf[2] = (nfreq >> 8) & 0xff;
|
||||||
|
tx_buf[3] = (nfreq >> 16) & 0xff;
|
||||||
|
tx_buf[4] = (nfreq >> 24) & 0xff;
|
||||||
|
nresp = 5;
|
||||||
|
rv = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_CMD_S_PINSTATE: {
|
||||||
|
printf("s_pinstate\n");
|
||||||
|
if (nread < 2) return 0; // need more data
|
||||||
|
|
||||||
|
if (buf[1] == 0) sp_spi_cs_deselect();
|
||||||
|
else sp_spi_cs_select();
|
||||||
|
|
||||||
|
tx_buf[0] = S_ACK;
|
||||||
|
nresp = 1;
|
||||||
|
rv = 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("illcmd %d\n", buf[0]);
|
||||||
|
tx_buf[0] = S_NAK;
|
||||||
|
nresp = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nresp > 0) {
|
||||||
|
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, nresp);
|
||||||
|
tud_cdc_n_write_flush(CDC_N_SERPROG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void cdc_uart_task();
|
||||||
|
void cdc_serprog_task(void) {
|
||||||
|
bool conn = tud_cdc_n_connected(CDC_N_SERPROG),
|
||||||
|
avail = tud_cdc_n_available(CDC_N_SERPROG);
|
||||||
|
//printf("hi conn=%c avail=%c\n", conn?'y':'n', avail?'y':'n');
|
||||||
|
// TODO: this is, apparently, not at all how this works: in practice,
|
||||||
|
// bytes seem to be sent one by one, so its probably better to rework
|
||||||
|
// this, a lot
|
||||||
|
if (conn && avail) {
|
||||||
|
printf("rbp=%d\n", bufpos);
|
||||||
|
uint32_t nread = tud_cdc_n_read(CDC_N_SERPROG, &rx_buf[bufpos], sizeof(rx_buf) - bufpos);
|
||||||
|
printf("got %d\n", nread);
|
||||||
|
cdc_uart_task();
|
||||||
|
|
||||||
|
bufpos = 0;
|
||||||
|
do {
|
||||||
|
printf("hbp=%d\n", /*rx_buf[bufpos],*/ bufpos);
|
||||||
|
cdc_uart_task();
|
||||||
|
uint32_t dec = serprog_handle_cmd(&rx_buf[bufpos], nread);
|
||||||
|
cdc_uart_task();
|
||||||
|
printf("dec=%d\n", dec);
|
||||||
|
|
||||||
|
cdc_uart_task();
|
||||||
|
|
||||||
|
// didn't do a decrement => not enough data, wait for the next
|
||||||
|
// task() call to read it in
|
||||||
|
if (dec == 0) {
|
||||||
|
// so we move the leftover data to the start of the buffer,
|
||||||
|
// and make sure the next call will put the new data right
|
||||||
|
// after it
|
||||||
|
printf("mv %d %d %d ", nread, bufpos, rx_buf[bufpos]);
|
||||||
|
memmove(rx_buf, &rx_buf[bufpos], nread);
|
||||||
|
printf("%d\n", rx_buf[0]);
|
||||||
|
bufpos = nread;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nread -= dec;
|
||||||
|
bufpos += dec;
|
||||||
|
// read everything left in the buffer => we're done here
|
||||||
|
if (nread == 0) {
|
||||||
|
// and we can start using the full rx buffer again
|
||||||
|
bufpos = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (tud_cdc_n_connected(CDC_N_SERPROG) && tud_cdc_n_available(CDC_N_SERPROG));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DBOARD_HAS_SERPROG */
|
||||||
|
|
33
main.c
33
main.c
|
@ -27,27 +27,50 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "bsp/board.h"
|
#include "bsp/board.h" /* a tinyusb header */
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
#include "DAP_config.h" /* ARM code *assumes* this is included prior to DAP.h */
|
#include "DAP_config.h" /* ARM code *assumes* this is included prior to DAP.h */
|
||||||
#include "DAP.h"
|
#include "DAP.h"
|
||||||
|
|
||||||
void cdc_uart_init(void);
|
#include "protocfg.h"
|
||||||
void cdc_task(void);
|
#include "protos.h"
|
||||||
|
|
||||||
|
#ifdef PICO_BOARD
|
||||||
|
#include <pico/binary_info.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
// TODO: split this out in a bsp-specific file
|
||||||
|
#ifdef PICO_BOARD
|
||||||
|
// use hardcoded values from TinyUSB board.h
|
||||||
|
bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART));
|
||||||
|
#endif
|
||||||
board_init();
|
board_init();
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_UART
|
||||||
cdc_uart_init();
|
cdc_uart_init();
|
||||||
|
#endif
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
cdc_serprog_init();
|
||||||
|
#endif
|
||||||
|
#ifdef DBOARD_HAS_CMSISDAP
|
||||||
DAP_Setup();
|
DAP_Setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
tusb_init();
|
tusb_init();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
tud_task(); // tinyusb device task
|
tud_task(); // tinyusb device task
|
||||||
cdc_task();
|
#ifdef DBOARD_HAS_UART
|
||||||
|
cdc_uart_task();
|
||||||
|
#endif
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
cdc_serprog_task();
|
||||||
|
#endif
|
||||||
|
sleep_ms(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -80,7 +103,9 @@ void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uin
|
||||||
(void) report_id;
|
(void) report_id;
|
||||||
(void) report_type;
|
(void) report_type;
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_CMSISDAP
|
||||||
DAP_ProcessCommand(RxDataBuffer, TxDataBuffer);
|
DAP_ProcessCommand(RxDataBuffer, TxDataBuffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
tud_hid_report(0, TxDataBuffer, response_size);
|
tud_hid_report(0, TxDataBuffer, response_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
#ifndef PROTOS_H_
|
||||||
|
#define PROTOS_H_
|
||||||
|
|
||||||
|
#include "protocfg.h"
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_UART
|
||||||
|
void cdc_uart_init(void);
|
||||||
|
void cdc_uart_task(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
void cdc_serprog_init(void);
|
||||||
|
void cdc_serprog_task(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
#ifndef SERPROG_H_
|
||||||
|
#define SERPROG_H_
|
||||||
|
|
||||||
|
enum serprog_cmd {
|
||||||
|
S_CMD_NOP = 0x00,
|
||||||
|
S_CMD_Q_IFACE = 0x01,
|
||||||
|
S_CMD_Q_CMDMAP = 0x02,
|
||||||
|
S_CMD_Q_PGMNAME = 0x03,
|
||||||
|
S_CMD_Q_SERBUF = 0x04,
|
||||||
|
S_CMD_Q_BUSTYPE = 0x05,
|
||||||
|
S_CMD_Q_CHIPSIZE = 0x06,
|
||||||
|
S_CMD_Q_OPBUF = 0x07,
|
||||||
|
S_CMD_Q_WRNMAXLEN = 0x08,
|
||||||
|
S_CMD_R_BYTE = 0x09,
|
||||||
|
S_CMD_R_NBYTES = 0x0a,
|
||||||
|
S_CMD_O_INIT = 0x0b,
|
||||||
|
S_CMD_O_WRITEB = 0x0c,
|
||||||
|
S_CMD_O_WRITEN = 0x0d,
|
||||||
|
S_CMD_O_DELAY = 0x0e,
|
||||||
|
S_CMD_O_EXEC = 0x0f,
|
||||||
|
S_CMD_SYNCNOP = 0x10,
|
||||||
|
S_CMD_Q_RDNMAXLEN = 0x11,
|
||||||
|
S_CMD_S_BUSTYPE = 0x12,
|
||||||
|
S_CMD_SPIOP = 0x13,
|
||||||
|
S_CMD_S_SPI_FREQ = 0x14,
|
||||||
|
S_CMD_S_PINSTATE = 0x15,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum serprog_response {
|
||||||
|
S_ACK = 0x06,
|
||||||
|
S_NAK = 0x15
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SERPROG_IFACE_VERSION 0x0001
|
||||||
|
|
||||||
|
void sp_spi_init(void);
|
||||||
|
uint32_t/*freq_applied*/ sp_spi_set_freq(uint32_t freq_wanted);
|
||||||
|
void sp_spi_cs_deselect(void);
|
||||||
|
void sp_spi_cs_select(void);
|
||||||
|
void sp_spi_op_begin(void);
|
||||||
|
void sp_spi_op_write(uint32_t write_len, const uint8_t* write_data);
|
||||||
|
void sp_spi_op_read(uint32_t read_len, uint8_t* read_data);
|
||||||
|
void sp_spi_op_end(void);
|
||||||
|
|
||||||
|
static inline void sp_spi_op_do(uint32_t write_len, const uint8_t* write_data,
|
||||||
|
uint32_t read_len, uint8_t* read_data) {
|
||||||
|
sp_spi_op_begin();
|
||||||
|
sp_spi_op_write(write_len, write_data);
|
||||||
|
sp_spi_op_write(read_len, read_data);
|
||||||
|
sp_spi_op_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -65,7 +65,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This example doesn't use an RTOS
|
// This example doesn't use an RTOS
|
||||||
|
#ifdef PICO_BOARD
|
||||||
|
#define CFG_TUSB_OS OPT_OS_PICO
|
||||||
|
#else
|
||||||
#define CFG_TUSB_OS OPT_OS_NONE
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||||
// #define CFG_TUSB_DEBUG 0
|
// #define CFG_TUSB_DEBUG 0
|
||||||
|
@ -94,7 +98,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------- CLASS -------------//
|
//------------- CLASS -------------//
|
||||||
#define CFG_TUD_CDC 1
|
#define CFG_TUD_CDC 2
|
||||||
#define CFG_TUD_MSC 0
|
#define CFG_TUD_MSC 0
|
||||||
#define CFG_TUD_HID 1
|
#define CFG_TUD_HID 1
|
||||||
#define CFG_TUD_MIDI 0
|
#define CFG_TUD_MIDI 0
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
#include "unique.h"
|
#include "unique.h"
|
||||||
|
|
||||||
|
#include "protocfg.h"
|
||||||
|
|
||||||
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||||
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||||
*
|
*
|
||||||
|
@ -52,13 +54,13 @@ tusb_desc_device_t const desc_device =
|
||||||
{
|
{
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0110, // FIXME: 0x0200 ?
|
||||||
.bDeviceClass = 0x00,
|
.bDeviceClass = 0x00,
|
||||||
.bDeviceSubClass = 0x00,
|
.bDeviceSubClass = 0x00,
|
||||||
.bDeviceProtocol = 0x00,
|
.bDeviceProtocol = 0x00,
|
||||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
.idVendor = 0xCafe,
|
.idVendor = 0xCafe, // TODO
|
||||||
.idProduct = USB_PID,
|
.idProduct = USB_PID,
|
||||||
.bcdDevice = 0x0101,
|
.bcdDevice = 0x0101,
|
||||||
|
|
||||||
|
@ -99,29 +101,65 @@ uint8_t const * tud_hid_descriptor_report_cb(void)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ITF_NUM_HID,
|
#ifdef DBOARD_HAS_CMSISDAP
|
||||||
ITF_NUM_CDC_COM,
|
ITF_NUM_HID_CMSISDAP,
|
||||||
ITF_NUM_CDC_DATA,
|
#endif
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_UART
|
||||||
|
ITF_NUM_CDC_UART_COM,
|
||||||
|
ITF_NUM_CDC_UART_DATA,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
ITF_NUM_CDC_SERPROG_COM,
|
||||||
|
ITF_NUM_CDC_SERPROG_DATA,
|
||||||
|
#endif
|
||||||
|
|
||||||
ITF_NUM_TOTAL
|
ITF_NUM_TOTAL
|
||||||
};
|
};
|
||||||
|
|
||||||
#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)*/
|
||||||
|
|
||||||
#define EPNUM_HID 0x01
|
static const int CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN
|
||||||
#define EPNUM_CDC_NOTIF 0x83
|
#ifdef DBOARD_HAS_UART
|
||||||
#define EPNUM_CDC_OUT 0x02
|
+ TUD_CDC_DESC_LEN
|
||||||
#define EPNUM_CDC_IN 0x82
|
#endif
|
||||||
|
#ifdef DBOARD_HAS_CMSISDAP
|
||||||
|
+ TUD_HID_INOUT_DESC_LEN
|
||||||
|
#endif
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
+ TUD_CDC_DESC_LEN
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
#define EPNUM_CDC_UART_OUT 0x02 // 2
|
||||||
|
#define EPNUM_CDC_UART_IN 0x82 // 83
|
||||||
|
#define EPNUM_CDC_UART_NOTIF 0x83 // 1
|
||||||
|
#define EPNUM_HID_CMSISDAP 0x04 // 4,5?
|
||||||
|
#define EPNUM_CDC_SERPROG_OUT 0x05 // 7
|
||||||
|
#define EPNUM_CDC_SERPROG_IN 0x85 // 8
|
||||||
|
#define EPNUM_CDC_SERPROG_NOTIF 0x86 // 6
|
||||||
|
|
||||||
|
// NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well!
|
||||||
uint8_t const desc_configuration[] =
|
uint8_t const desc_configuration[] =
|
||||||
{
|
{
|
||||||
// Config number, interface count, string index, total length, attribute, power in mA
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
|
|
||||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
#ifdef DBOARD_HAS_UART
|
||||||
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 1),
|
|
||||||
|
|
||||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_COM, 0, EPNUM_CDC_NOTIF, 64, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_UART_COM, 0, EPNUM_CDC_UART_NOTIF, 64, EPNUM_CDC_UART_OUT, EPNUM_CDC_UART_IN, 64),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_CMSISDAP
|
||||||
|
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||||
|
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID_CMSISDAP, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID_CMSISDAP, 0x80 | (EPNUM_HID_CMSISDAP+0), CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DBOARD_HAS_SERPROG
|
||||||
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_SERPROG_COM, 0, EPNUM_CDC_SERPROG_NOTIF, 64, EPNUM_CDC_SERPROG_OUT, EPNUM_CDC_SERPROG_IN, 64),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
@ -141,8 +179,8 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||||
char const* string_desc_arr [] =
|
char const* string_desc_arr [] =
|
||||||
{
|
{
|
||||||
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
||||||
[STRID_MANUFACTURER] = "TinyUSB", // Manufacturer
|
[STRID_MANUFACTURER] = "TinyUSB", // Manufacturer // TODO
|
||||||
[STRID_PRODUCT] = PRODUCT_PREFIX "CMSIS-DAP", // Product
|
[STRID_PRODUCT] = PRODUCT_PREFIX "CMSIS-DAP", // Product // TODO
|
||||||
};
|
};
|
||||||
static uint16_t _desc_str[32];
|
static uint16_t _desc_str[32];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue