make whitespace & indentation etc. consistent, make usb descriptors a bit nicer
This commit is contained in:
parent
c6fdc53fdd
commit
4c93827bed
|
@ -51,6 +51,9 @@ This information includes:
|
|||
#include "cmsis_compiler.h"
|
||||
#include "bsp/board.h"
|
||||
|
||||
#include "protos.h"
|
||||
#include "unique.h"
|
||||
|
||||
/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
|
||||
/// This value is used to calculate the SWD/JTAG clock speed.
|
||||
#define CPU_CLOCK 100000000U ///< Specifies the CPU Clock in Hz.
|
||||
|
@ -132,8 +135,9 @@ This information includes:
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
const static char vnd[] = INFO_MANUFACTURER;
|
||||
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
|
||||
return sizeof(vnd)-1;
|
||||
}
|
||||
|
||||
/** Get Product ID string.
|
||||
|
@ -141,8 +145,9 @@ __STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
const static char prd[] = INFO_PRODUCT(INFO_BOARDNAME);
|
||||
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
|
||||
return sizeof(prd)-1;
|
||||
}
|
||||
|
||||
/** Get Serial Number string.
|
||||
|
@ -150,8 +155,7 @@ __STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
return get_unique_id_u8(str);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -199,18 +203,18 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided:
|
|||
Configures the DAP Hardware I/O pins for JTAG mode:
|
||||
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
|
||||
- TDO to input mode.
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_JTAG_SETUP (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
|
||||
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
|
||||
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
|
||||
- TDI, nTRST to HighZ mode (pins are unused in SWD mode).
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_SWD_SETUP (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** Disable JTAG/SWD I/O Pins.
|
||||
|
@ -218,7 +222,7 @@ Disables the DAP Hardware I/O pins which configures:
|
|||
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
|
||||
*/
|
||||
__STATIC_INLINE void PORT_OFF (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,21 +232,21 @@ __STATIC_INLINE void PORT_OFF (void) {
|
|||
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to High.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to Low.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
@ -252,35 +256,35 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
|||
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to High.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to Low.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Get Input (used in SWD mode only).
|
||||
\return Current status of the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) {
|
||||
return (board_millis() & 1); /* pacify GCC warning */
|
||||
return (board_millis() & 1); /* pacify GCC warning */
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Set Output (used in SWD mode only).
|
||||
\param bit Output value for the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
|
||||
|
@ -288,7 +292,7 @@ Configure the SWDIO DAP hardware I/O pin to output mode. This function is
|
|||
called prior \ref PIN_SWDIO_OUT function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
|
||||
|
@ -296,7 +300,7 @@ Configure the SWDIO DAP hardware I/O pin to input mode. This function is
|
|||
called prior \ref PIN_SWDIO_IN function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,14 +310,14 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
|||
\return Current status of the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** TDI I/O pin: Set Output.
|
||||
\param bit Output value for the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
|
||||
|
@ -323,7 +327,7 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
|||
\return Current status of the TDO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
||||
return (board_millis() & 1); /* pacify GCC warning */
|
||||
return (board_millis() & 1); /* pacify GCC warning */
|
||||
}
|
||||
|
||||
|
||||
|
@ -333,7 +337,7 @@ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
|||
\return Current status of the nTRST DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** nTRST I/O pin: Set Output.
|
||||
|
@ -342,7 +346,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
|||
- 1: release JTAG TRST Test Reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
// nRESET Pin I/O------------------------------------------
|
||||
|
@ -351,7 +355,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
|||
\return Current status of the nRESET DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** nRESET I/O pin: Set Output.
|
||||
|
@ -360,7 +364,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
|||
- 1: release device hardware reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -385,7 +389,7 @@ It is recommended to provide the following LEDs for status indication:
|
|||
- 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
|
||||
*/
|
||||
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
/** Debug Unit: Set status Target Running LED.
|
||||
|
@ -394,7 +398,7 @@ __STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
|||
- 0: Target Running LED OFF: program execution in target stopped.
|
||||
*/
|
||||
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -417,9 +421,9 @@ default, the DWT timer is used. The frequency of this timer is configured with
|
|||
*/
|
||||
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
||||
#if TIMESTAMP_CLOCK > 0
|
||||
return (DWT->CYCCNT);
|
||||
return (DWT->CYCCNT);
|
||||
#else
|
||||
return 0;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -444,7 +448,7 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
|
|||
- LED output pins are enabled and LEDs are turned off.
|
||||
*/
|
||||
__STATIC_INLINE void DAP_SETUP (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** Reset Target Device with custom specific I/O pin or command sequence.
|
||||
|
@ -455,7 +459,7 @@ when a device needs a time-critical unlock sequence that enables the debug port.
|
|||
1 = a device specific reset sequence is implemented.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t RESET_TARGET (void) {
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
@ -7,5 +7,7 @@
|
|||
/*#define DBOARD_HAS_SERPROG*/
|
||||
/*#define DBOARD_HAS_TINYI2C*/
|
||||
|
||||
#define INFO_BOARDNAME "unknown"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3,17 +3,23 @@
|
|||
|
||||
/* in the absence of the board-specific directory providing a unique ID, we provide a canned one */
|
||||
|
||||
static uint8_t get_unique_id(uint16_t *desc_str)
|
||||
{
|
||||
const char canned[] = "123456";
|
||||
uint8_t i;
|
||||
static uint8_t get_unique_id_u8(uint8_t *desc_str) {
|
||||
static const char canned[] = "123456";
|
||||
|
||||
for(i=0; i<TU_ARRAY_SIZE(canned); i++)
|
||||
{
|
||||
desc_str[i] = canned[i];
|
||||
}
|
||||
for (int i=0; i<TU_ARRAY_SIZE(canned); i++) {
|
||||
desc_str[i] = canned[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
|
||||
static uint8_t get_unique_id_u16(uint16_t *desc_str) {
|
||||
static const char canned[] = "123456";
|
||||
|
||||
for (int i=0; i<TU_ARRAY_SIZE(canned); i++) {
|
||||
desc_str[i] = canned[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define PRODUCT_PREFIX ""
|
||||
|
|
|
@ -60,6 +60,8 @@ This information includes:
|
|||
#include <pico/binary_info.h>
|
||||
|
||||
#include "picoprobe_config.h"
|
||||
#include "protos.h"
|
||||
#include "unique.h"
|
||||
|
||||
#define PROBE_PIN_SWCLK_MASK (1UL << (PROBE_PIN_SWCLK))
|
||||
#define PROBE_PIN_SWDIO_MASK (1UL << (PROBE_PIN_SWDIO))
|
||||
|
@ -156,11 +158,9 @@ This information includes:
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
||||
const static char vnd[] = "Raspberry Pi";
|
||||
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
|
||||
return sizeof(vnd)-1;
|
||||
//(void)str;
|
||||
//return (0U);
|
||||
const static char vnd[] = INFO_MANUFACTURER;
|
||||
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
|
||||
return sizeof(vnd)-1;
|
||||
}
|
||||
|
||||
/** Get Product ID string.
|
||||
|
@ -168,11 +168,9 @@ __STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
||||
const static char prd[] = "RP2040 DapperMime-JTAG";
|
||||
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
|
||||
return sizeof(prd)-1;
|
||||
//(void)str;
|
||||
//return (0U);
|
||||
const static char prd[] = INFO_PRODUCT(INFO_BOARDNAME);
|
||||
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
|
||||
return sizeof(prd)-1;
|
||||
}
|
||||
|
||||
/** Get Serial Number string.
|
||||
|
@ -180,11 +178,7 @@ __STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) {
|
||||
const static char ser[] = "1337";
|
||||
for (size_t i = 0; i < sizeof(ser); ++i) str[i] = ser[i];
|
||||
return sizeof(ser)-1;
|
||||
//(void)str;
|
||||
//return (0U);
|
||||
return get_unique_id_u8(str);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -232,66 +226,64 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided:
|
|||
Configures the DAP Hardware I/O pins for JTAG mode:
|
||||
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
|
||||
- TDO to input mode.
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_JTAG_SETUP (void) {
|
||||
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
|
||||
|
||||
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
|
||||
/* set to default high level */
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_TCK_MASK | PROBE_PIN_TMS_MASK | PROBE_PIN_TDI_MASK | PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_TCK_MASK | PROBE_PIN_TMS_MASK | PROBE_PIN_TDI_MASK | PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
/* TDO needs to be an input */
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_TDO_MASK;
|
||||
|
||||
/* set to default high level */
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_TCK_MASK | PROBE_PIN_TMS_MASK | PROBE_PIN_TDI_MASK | PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_TCK_MASK | PROBE_PIN_TMS_MASK | PROBE_PIN_TDI_MASK | PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
/* TDO needs to be an input */
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_TDO_MASK;
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TCK],
|
||||
PADS_BANK0_GPIO0_IE_BITS, // bits to set: input enable
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); // bits to mask out: input enable, output disable
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TMS],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TDI],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TDO],
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS, // TDO needs to have its output disabled
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_nTRST],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_nRESET],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TCK],
|
||||
PADS_BANK0_GPIO0_IE_BITS, // bits to set: input enable
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); // bits to mask out: input enable, output disable
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TMS],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TDI],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_TDO],
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS, // TDO needs to have its output disabled
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_nTRST],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_JTAG_nRESET],
|
||||
PADS_BANK0_GPIO0_IE_BITS,
|
||||
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
// NOTE: hiZ: ctrl = (ctrl & ~(CTRL_OEOVER_BITS)) | (GPIO_OVERRIDE_LOW << CTRL_OEOVER_LSB);
|
||||
// normal == 0, low == 2
|
||||
|
||||
// NOTE: hiZ: ctrl = (ctrl & ~(CTRL_OEOVER_BITS)) | (GPIO_OVERRIDE_LOW << CTRL_OEOVER_LSB);
|
||||
// normal == 0, low == 2
|
||||
|
||||
// set pin modes to general IO (SIO)
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TCK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TMS].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TDI].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TDO].ctrl = (GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
|
||||
/*| (GPIO_OVERRIDE_LOW << IO_BANK0_GPIO0_CTRL_OEOVER_LSB)*/;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_nTRST].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_nRESET].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
// set pin modes to general IO (SIO)
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TCK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TMS].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TDI].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_TDO].ctrl = (GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
|
||||
/*| (GPIO_OVERRIDE_LOW << IO_BANK0_GPIO0_CTRL_OEOVER_LSB)*/;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_nTRST].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_JTAG_nRESET].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
}
|
||||
|
||||
|
||||
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
|
||||
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
|
||||
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
|
||||
- TDI, nTRST to HighZ mode (pins are unused in SWD mode).
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_SWD_SETUP (void) {
|
||||
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
|
||||
|
||||
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
|
||||
/* set to default high level */
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK;
|
||||
|
||||
/* set to default high level */
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK;
|
||||
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_SWCLK], PADS_BANK0_GPIO0_IE_BITS, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_SWDIO], PADS_BANK0_GPIO0_IE_BITS, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
iobank0_hw->io[PROBE_PIN_SWCLK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_SWDIO].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_SWCLK], PADS_BANK0_GPIO0_IE_BITS, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
hw_write_masked(&padsbank0_hw->io[PROBE_PIN_SWDIO], PADS_BANK0_GPIO0_IE_BITS, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
|
||||
iobank0_hw->io[PROBE_PIN_SWCLK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
iobank0_hw->io[PROBE_PIN_SWDIO].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
|
||||
}
|
||||
|
||||
/** Disable JTAG/SWD I/O Pins.
|
||||
|
@ -299,9 +291,9 @@ Disables the DAP Hardware I/O pins which configures:
|
|||
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
|
||||
*/
|
||||
__STATIC_INLINE void PORT_OFF (void) {
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK
|
||||
| PROBE_PIN_TDI_MASK //| PROBE_PIN_TDO_MASK
|
||||
| PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_SWCLK_MASK | PROBE_PIN_SWDIO_MASK
|
||||
| PROBE_PIN_TDI_MASK //| PROBE_PIN_TDO_MASK
|
||||
| PROBE_PIN_nTRST_MASK | PROBE_PIN_nRESET_MASK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -311,21 +303,21 @@ __STATIC_INLINE void PORT_OFF (void) {
|
|||
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWCLK_MASK) >> PROBE_PIN_SWCLK;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWCLK_MASK) >> PROBE_PIN_SWCLK;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to High.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) {
|
||||
sio_hw->gpio_set = PROBE_PIN_SWCLK_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_SWCLK_MASK;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to Low.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWCLK_MASK;
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWCLK_MASK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -335,7 +327,7 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
|||
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWDIO_MASK) >> PROBE_PIN_SWDIO;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWDIO_MASK) >> PROBE_PIN_SWDIO;
|
||||
}
|
||||
|
||||
/* PIN_SWDIO_TMS_SET and PIN_SWDIO_TMS_CLR are used by SWJ_Sequence */
|
||||
|
@ -344,31 +336,31 @@ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
|
|||
Set the SWDIO/TMS DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) {
|
||||
sio_hw->gpio_set = PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_set = PROBE_PIN_SWDIO_MASK;
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to Low.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) {
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWDIO_MASK;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Get Input (used in SWD mode only).
|
||||
\return Current status of the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWDIO_MASK) ? 1U : 0U;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_SWDIO_MASK) ? 1U : 0U;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Set Output (used in SWD mode only).
|
||||
\param bit Output value for the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) {
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_SWDIO_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWDIO_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_SWDIO_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_SWDIO_MASK;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
|
||||
|
@ -376,7 +368,7 @@ Configure the SWDIO DAP hardware I/O pin to output mode. This function is
|
|||
called prior \ref PIN_SWDIO_OUT function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) {
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_oe_set = PROBE_PIN_SWDIO_MASK;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
|
||||
|
@ -384,7 +376,7 @@ Configure the SWDIO DAP hardware I/O pin to input mode. This function is
|
|||
called prior \ref PIN_SWDIO_IN function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_SWDIO_MASK;
|
||||
sio_hw->gpio_oe_clr = PROBE_PIN_SWDIO_MASK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -394,17 +386,17 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
|||
\return Current status of the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_TDI_MASK) >> PROBE_PIN_JTAG_TDI;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_TDI_MASK) >> PROBE_PIN_JTAG_TDI;
|
||||
}
|
||||
|
||||
/** TDI I/O pin: Set Output.
|
||||
\param bit Output value for the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_TDI_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_TDI_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_TDI_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_TDI_MASK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,7 +406,7 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
|||
\return Current status of the TDO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_TDO_MASK) >> PROBE_PIN_JTAG_TDO;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_TDO_MASK) >> PROBE_PIN_JTAG_TDO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -424,7 +416,7 @@ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
|||
\return Current status of the nTRST DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_nTRST_MASK) >> PROBE_PIN_JTAG_nTRST;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_nTRST_MASK) >> PROBE_PIN_JTAG_nTRST;
|
||||
}
|
||||
|
||||
/** nTRST I/O pin: Set Output.
|
||||
|
@ -433,10 +425,10 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
|||
- 1: release JTAG TRST Test Reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_nTRST_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_nTRST_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_nTRST_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_nTRST_MASK;
|
||||
}
|
||||
|
||||
// nRESET Pin I/O------------------------------------------
|
||||
|
@ -445,7 +437,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
|||
\return Current status of the nRESET DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
return (sio_hw->gpio_in & PROBE_PIN_nRESET_MASK) >> PROBE_PIN_JTAG_nRESET;
|
||||
return (sio_hw->gpio_in & PROBE_PIN_nRESET_MASK) >> PROBE_PIN_JTAG_nRESET;
|
||||
}
|
||||
|
||||
/** nRESET I/O pin: Set Output.
|
||||
|
@ -454,10 +446,10 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
|||
- 1: release device hardware reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_nRESET_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_nRESET_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PROBE_PIN_nRESET_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PROBE_PIN_nRESET_MASK;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -483,12 +475,12 @@ It is recommended to provide the following LEDs for status indication:
|
|||
*/
|
||||
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
||||
#if PICOPROBE_LED_CONNECTED
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PICOPROBE_LED_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PICOPROBE_LED_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
#else
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -499,12 +491,12 @@ __STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
|||
*/
|
||||
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
|
||||
#if PICOPROBE_LED_RUNNING
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PICOPROBE_LED_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
if (bit & 1)
|
||||
sio_hw->gpio_set = PICOPROBE_LED_MASK;
|
||||
else
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
#else
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -512,7 +504,7 @@ __STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
|
|||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
/**
|
||||
\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
@ -528,9 +520,9 @@ default, the DWT timer is used. The frequency of this timer is configured with
|
|||
*/
|
||||
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
||||
#if TIMESTAMP_CLOCK > 0
|
||||
return (DWT->CYCCNT);
|
||||
return (DWT->CYCCNT);
|
||||
#else
|
||||
return 0;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -538,7 +530,7 @@ __STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
|||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
/**
|
||||
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
@ -555,22 +547,22 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
|
|||
- LED output pins are enabled and LEDs are turned off.
|
||||
*/
|
||||
__STATIC_INLINE void DAP_SETUP (void) {
|
||||
sio_hw->gpio_oe_set = PICOPROBE_LED_MASK;
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
sio_hw->gpio_oe_set = PICOPROBE_LED_MASK;
|
||||
sio_hw->gpio_clr = PICOPROBE_LED_MASK;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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"
|
||||
));
|
||||
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.
|
||||
|
@ -581,10 +573,9 @@ when a device needs a time-critical unlock sequence that enables the debug port.
|
|||
1 = a device specific reset sequence is implemented.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t RESET_TARGET (void) {
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
#endif /* __DAP_CONFIG_H__ */
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define BOARD_H_MOD
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef PICO_DEFAULT_LED_PIN
|
||||
|
@ -47,7 +47,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARD_H_ */
|
||||
|
|
|
@ -36,43 +36,43 @@ static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
|||
static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
||||
|
||||
void cdc_uart_init(void) {
|
||||
gpio_set_function(PICOPROBE_UART_TX, GPIO_FUNC_UART);
|
||||
gpio_set_function(PICOPROBE_UART_RX, GPIO_FUNC_UART);
|
||||
uart_init(PICOPROBE_UART_INTERFACE, PICOPROBE_UART_BAUDRATE);
|
||||
gpio_set_function(PICOPROBE_UART_TX, GPIO_FUNC_UART);
|
||||
gpio_set_function(PICOPROBE_UART_RX, GPIO_FUNC_UART);
|
||||
uart_init(PICOPROBE_UART_INTERFACE, PICOPROBE_UART_BAUDRATE);
|
||||
|
||||
bi_decl(bi_2pins_with_func(PICOPROBE_UART_TX, PICOPROBE_UART_RX, GPIO_FUNC_UART));
|
||||
bi_decl(bi_2pins_with_func(PICOPROBE_UART_TX, PICOPROBE_UART_RX, GPIO_FUNC_UART));
|
||||
}
|
||||
|
||||
void cdc_uart_task(void) {
|
||||
// Consume uart fifo regardless even if not connected
|
||||
uint rx_len = 0;
|
||||
while (uart_is_readable(PICOPROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) {
|
||||
rx_buf[rx_len++] = uart_getc(PICOPROBE_UART_INTERFACE);
|
||||
}
|
||||
// Consume uart fifo regardless even if not connected
|
||||
uint rx_len = 0;
|
||||
while (uart_is_readable(PICOPROBE_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) {
|
||||
rx_buf[rx_len++] = uart_getc(PICOPROBE_UART_INTERFACE);
|
||||
}
|
||||
|
||||
if (tud_cdc_n_connected(CDC_N_UART)) {
|
||||
// Do we have anything to display on the host's terminal?
|
||||
if (rx_len) {
|
||||
for (uint i = 0; i < rx_len; i++) {
|
||||
tud_cdc_n_write_char(CDC_N_UART, rx_buf[i]);
|
||||
}
|
||||
tud_cdc_n_write_flush(CDC_N_UART);
|
||||
}
|
||||
if (tud_cdc_n_connected(CDC_N_UART)) {
|
||||
// Do we have anything to display on the host's terminal?
|
||||
if (rx_len) {
|
||||
for (uint i = 0; i < rx_len; i++) {
|
||||
tud_cdc_n_write_char(CDC_N_UART, rx_buf[i]);
|
||||
}
|
||||
tud_cdc_n_write_flush(CDC_N_UART);
|
||||
}
|
||||
|
||||
if (tud_cdc_n_available(CDC_N_UART)) {
|
||||
// Is there any data from the host for us to tx
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (tud_cdc_n_available(CDC_N_UART)) {
|
||||
// Is there any data from the host for us to tx
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_uart_set_hwflow(bool enable) {
|
||||
uart_set_hw_flow(PICOPROBE_UART_INTERFACE, enable, enable);
|
||||
uart_set_hw_flow(PICOPROBE_UART_INTERFACE, enable, enable);
|
||||
}
|
||||
|
||||
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);
|
||||
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
||||
picoprobe_info("New baud rate %d\n", line_coding->bit_rate);
|
||||
uart_init(PICOPROBE_UART_INTERFACE, line_coding->bit_rate);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,5 +16,13 @@
|
|||
#define CDC_N_STDIO 2
|
||||
#endif
|
||||
|
||||
/*#define USB_VID 0x2e8a*/ /* Raspberry Pi */
|
||||
#define USB_VID 0xcafe /* TinyUSB */
|
||||
/*#define USB_VID 0x1209*/ /* Generic */
|
||||
/*#define USB_VID 0x1d50*/ /* OpenMoko */
|
||||
|
||||
// TODO: other RP2040 boards
|
||||
#define INFO_BOARDNAME "RP2040 Pico"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,26 +1,44 @@
|
|||
#include <stdint.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/unique_id.h"
|
||||
#include <pico/stdlib.h>
|
||||
#include <pico/unique_id.h>
|
||||
#include "tusb.h"
|
||||
|
||||
static uint8_t get_unique_id(uint16_t *desc_str)
|
||||
{
|
||||
pico_unique_board_id_t uid;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
pico_get_unique_board_id(&uid);
|
||||
|
||||
for (int byte = 0; byte < TU_ARRAY_SIZE(uid.id); byte++)
|
||||
{
|
||||
uint8_t tmp = uid.id[byte];
|
||||
for (int digit = 0; digit < 2; digit++)
|
||||
{
|
||||
desc_str[chr_count++] = "0123456789ABCDEF"[tmp & 0xf];
|
||||
tmp >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
static inline char nyb2hex(int x) {
|
||||
if (x < 0xa) return '0'+x;
|
||||
else return 'A'+x;
|
||||
}
|
||||
|
||||
static uint8_t get_unique_id_u8(uint8_t *desc_str) {
|
||||
pico_unique_board_id_t uid;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
pico_get_unique_board_id(&uid);
|
||||
|
||||
for (int byte = 0; byte < TU_ARRAY_SIZE(uid.id); byte++) {
|
||||
uint8_t tmp = uid.id[byte];
|
||||
for (int digit = 0; digit < 2; digit++) {
|
||||
desc_str[chr_count++] = nyb2hex(tmp & 0xf);
|
||||
tmp >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
}
|
||||
|
||||
static uint8_t get_unique_id_u16(uint16_t *desc_str) {
|
||||
pico_unique_board_id_t uid;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
pico_get_unique_board_id(&uid);
|
||||
|
||||
for (int byte = 0; byte < TU_ARRAY_SIZE(uid.id); byte++) {
|
||||
uint8_t tmp = uid.id[byte];
|
||||
for (int digit = 0; digit < 2; digit++) {
|
||||
desc_str[chr_count++] = nyb2hex(tmp & 0xf);
|
||||
tmp >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
}
|
||||
|
||||
#define PRODUCT_PREFIX "RP2040 "
|
||||
|
|
|
@ -51,6 +51,9 @@ This information includes:
|
|||
|
||||
#include <stm32f0xx_hal.h>
|
||||
|
||||
#include "protos.h"
|
||||
#include "unique.h"
|
||||
|
||||
/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
|
||||
/// This value is used to calculate the SWD/JTAG clock speed.
|
||||
#define CPU_CLOCK 48000000U ///< Specifies the CPU Clock in Hz.
|
||||
|
@ -134,8 +137,9 @@ This information includes:
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
const static char vnd[] = INFO_MANUFACTURER;
|
||||
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
|
||||
return sizeof(vnd)-1;
|
||||
}
|
||||
|
||||
/** Get Product ID string.
|
||||
|
@ -143,8 +147,9 @@ __STATIC_INLINE uint8_t DAP_GetVendorString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
const static char prd[] = INFO_PRODUCT(INFO_BOARDNAME);
|
||||
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
|
||||
return sizeof(prd)-1;
|
||||
}
|
||||
|
||||
/** Get Serial Number string.
|
||||
|
@ -152,8 +157,7 @@ __STATIC_INLINE uint8_t DAP_GetProductString (char *str) {
|
|||
\return String length.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
return get_unique_id_u8(str);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -226,21 +230,21 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided:
|
|||
Configures the DAP Hardware I/O pins for JTAG mode:
|
||||
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
|
||||
- TDO to input mode.
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_JTAG_SETUP (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
|
||||
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
|
||||
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
|
||||
- TDI, nTRST to HighZ mode (pins are unused in SWD mode).
|
||||
*/
|
||||
*/
|
||||
__STATIC_INLINE void PORT_SWD_SETUP (void) {
|
||||
CLK_ENABLE;
|
||||
DATA_ENABLE;
|
||||
SWDIO_INIT;
|
||||
CLK_HIGH; DATA_HIGH;
|
||||
CLK_ENABLE;
|
||||
DATA_ENABLE;
|
||||
SWDIO_INIT;
|
||||
CLK_HIGH; DATA_HIGH;
|
||||
}
|
||||
|
||||
/** Disable JTAG/SWD I/O Pins.
|
||||
|
@ -248,9 +252,9 @@ Disables the DAP Hardware I/O pins which configures:
|
|||
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
|
||||
*/
|
||||
__STATIC_INLINE void PORT_OFF (void) {
|
||||
CLK_HIZ;
|
||||
DATA_HIZ;
|
||||
RESET_HIZ;
|
||||
CLK_HIZ;
|
||||
DATA_HIZ;
|
||||
RESET_HIZ;
|
||||
}
|
||||
|
||||
// SWCLK/TCK I/O pin -------------------------------------
|
||||
|
@ -259,21 +263,21 @@ __STATIC_INLINE void PORT_OFF (void) {
|
|||
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) {
|
||||
return (CLK_READ) ? 1 : 0;
|
||||
return (CLK_READ) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to High.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) {
|
||||
CLK_HIGH;
|
||||
CLK_HIGH;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to Low.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
||||
CLK_LOW;
|
||||
CLK_LOW;
|
||||
}
|
||||
|
||||
|
||||
|
@ -283,35 +287,35 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
|||
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
|
||||
return (DATA_READ) ? 1 : 0;
|
||||
return (DATA_READ) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to High.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) {
|
||||
DATA_HIGH;
|
||||
DATA_HIGH;
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to Low.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) {
|
||||
DATA_LOW;
|
||||
DATA_LOW;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Get Input (used in SWD mode only).
|
||||
\return Current status of the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) {
|
||||
return (DATA_READ) ? 1 : 0;
|
||||
return (DATA_READ) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Set Output (used in SWD mode only).
|
||||
\param bit Output value for the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) {
|
||||
if (bit & 1) { DATA_HIGH; } else { DATA_LOW; }
|
||||
if (bit & 1) { DATA_HIGH; } else { DATA_LOW; }
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
|
||||
|
@ -319,7 +323,7 @@ Configure the SWDIO DAP hardware I/O pin to output mode. This function is
|
|||
called prior \ref PIN_SWDIO_OUT function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) {
|
||||
DATA_ENABLE;
|
||||
DATA_ENABLE;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
|
||||
|
@ -327,7 +331,7 @@ Configure the SWDIO DAP hardware I/O pin to input mode. This function is
|
|||
called prior \ref PIN_SWDIO_IN function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
||||
DATA_HIZ;
|
||||
DATA_HIZ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -337,14 +341,14 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
|||
\return Current status of the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** TDI I/O pin: Set Output.
|
||||
\param bit Output value for the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,7 +358,7 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
|||
\return Current status of the TDO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,7 +368,7 @@ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
|||
\return Current status of the nTRST DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
||||
return (0U);
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** nTRST I/O pin: Set Output.
|
||||
|
@ -373,7 +377,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
|||
- 1: release JTAG TRST Test Reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
// nRESET Pin I/O------------------------------------------
|
||||
|
@ -382,7 +386,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
|||
\return Current status of the nRESET DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
return (RESET_READ) ? 1 : 0;
|
||||
return (RESET_READ) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** nRESET I/O pin: Set Output.
|
||||
|
@ -391,7 +395,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
|||
- 1: release device hardware reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
|
||||
if (bit & 1) { RESET_HIGH; } else { RESET_LOW; }
|
||||
if (bit & 1) { RESET_HIGH; } else { RESET_LOW; }
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -416,7 +420,7 @@ It is recommended to provide the following LEDs for status indication:
|
|||
- 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
|
||||
*/
|
||||
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
/** Debug Unit: Set status Target Running LED.
|
||||
|
@ -425,7 +429,7 @@ __STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
|
|||
- 0: Target Running LED OFF: program execution in target stopped.
|
||||
*/
|
||||
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
|
||||
(void)bit;
|
||||
(void)bit;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
@ -448,9 +452,9 @@ default, the DWT timer is used. The frequency of this timer is configured with
|
|||
*/
|
||||
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
||||
#if TIMESTAMP_CLOCK > 0
|
||||
return (DWT->CYCCNT);
|
||||
return (DWT->CYCCNT);
|
||||
#else
|
||||
return 0;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -458,7 +462,7 @@ __STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
|||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
/**
|
||||
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
@ -475,7 +479,7 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
|
|||
- LED output pins are enabled and LEDs are turned off.
|
||||
*/
|
||||
__STATIC_INLINE void DAP_SETUP (void) {
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
/** Reset Target Device with custom specific I/O pin or command sequence.
|
||||
|
@ -486,7 +490,7 @@ when a device needs a time-critical unlock sequence that enables the debug port.
|
|||
1 = a device specific reset sequence is implemented.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t RESET_TARGET (void) {
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
void cdc_uart_init(void)
|
||||
{
|
||||
|
||||
void cdc_uart_init(void) {
|
||||
}
|
||||
|
||||
void cdc_uart_task(void)
|
||||
{
|
||||
void cdc_uart_task(void) {
|
||||
}
|
||||
|
|
|
@ -7,5 +7,11 @@
|
|||
/*#define DBOARD_HAS_SERPROG*/
|
||||
/*#define DBOARD_HAS_TINYI2C*/
|
||||
|
||||
#define USB_VID 0xcafe /* TinyUSB */
|
||||
/*#define USB_VID 0x1209*/ /* Generic */
|
||||
/*#define USB_VID 0x1d50*/ /* OpenMoko */
|
||||
|
||||
#define INFO_BOARDNAME "STM32F072 Disco"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,20 +1,36 @@
|
|||
#include <stdint.h>
|
||||
#include "tusb.h"
|
||||
|
||||
static uint8_t get_unique_id(uint16_t *desc_str)
|
||||
{
|
||||
const uint32_t *idpnt = (uint32_t*)(0x1FFFF7AC); /*DEVICE_ID1*/
|
||||
uint32_t tmp = 0;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
for (int digit = 0; digit < 24; digit++)
|
||||
{
|
||||
if (0 == (digit & 7)) tmp = *idpnt++;
|
||||
desc_str[chr_count++] = "0123456789ABCDEF"[tmp & 0xf];
|
||||
tmp >>= 4;
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
static inline char nyb2hex(int x) {
|
||||
if (x < 0xa) return '0'+x;
|
||||
else return 'A'+x;
|
||||
}
|
||||
|
||||
static uint8_t get_unique_id_u8(uint8_t *desc_str) {
|
||||
const uint32_t *idpnt = (uint32_t*)(0x1FFFF7AC); /*DEVICE_ID1*/
|
||||
uint32_t tmp = 0;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
for (int digit = 0; digit < 24; digit++) {
|
||||
if (0 == (digit & 7)) tmp = *idpnt++;
|
||||
desc_str[chr_count++] = nyb2hex(tmp & 0xf);
|
||||
tmp >>= 4;
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
}
|
||||
|
||||
static uint8_t get_unique_id_u16(uint16_t *desc_str) {
|
||||
const uint32_t *idpnt = (uint32_t*)(0x1FFFF7AC); /*DEVICE_ID1*/
|
||||
uint32_t tmp = 0;
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
for (int digit = 0; digit < 24; digit++) {
|
||||
if (0 == (digit & 7)) tmp = *idpnt++;
|
||||
desc_str[chr_count++] = nyb2hex(tmp & 0xf);
|
||||
tmp >>= 4;
|
||||
}
|
||||
|
||||
return chr_count;
|
||||
}
|
||||
|
||||
#define PRODUCT_PREFIX "STM32F072 "
|
||||
|
|
|
@ -130,7 +130,7 @@ static u32 usb_func(struct i2c_adapter *adapter)
|
|||
/* get functionality from adapter */
|
||||
if (!pfunc || (i=usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc,
|
||||
sizeof(*pfunc))) != sizeof(*pfunc)) {
|
||||
dev_err(&adapter->dev, "failure reading functionality: %i\n");
|
||||
dev_err(&adapter->dev, "failure reading functionality: %i\n", i);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ static const struct i2c_algorithm usb_algorithm = {
|
|||
static const struct usb_device_id i2c_tiny_usb_table[] = {
|
||||
{ USB_DEVICE(0x0403, 0xc631) }, /* FTDI */
|
||||
{ USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0xcafe, 0x4017, 0/*255*/) }, /* TinyUSB DapperMime: we want the Vendor interface */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2e8a, 0x6043, 0/*255*/) }, /* TinyUSB DapperMime: we want the Vendor interface */
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,6 @@ struct i2c_tiny_usb {
|
|||
struct usb_device *usb_dev; /* the usb device for this device */
|
||||
struct usb_interface *interface; /* the interface for this device */
|
||||
struct i2c_adapter adapter; /* i2c related things */
|
||||
bool is_tusb_dmime;
|
||||
};
|
||||
|
||||
static int usb_read(struct i2c_adapter *adapter, int cmd,
|
||||
|
@ -179,63 +178,19 @@ static int usb_read(struct i2c_adapter *adapter, int cmd,
|
|||
{
|
||||
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
|
||||
uint8_t *dmadata;
|
||||
int ret, actual_len = 0;
|
||||
int ret;
|
||||
|
||||
if (dev->is_tusb_dmime) {
|
||||
// actual_len = len;
|
||||
// if (actual_len < 7) actual_len = 7; /* cmd(1), value(2), index(2), len(2) */
|
||||
//
|
||||
// dmadata = (uint8_t*)kzalloc(actual_len, GFP_KERNEL);
|
||||
// if (!dmadata)
|
||||
// return -ENOMEM;
|
||||
//
|
||||
// dmadata[0] = cmd;
|
||||
// dmadata[1] = value & 0xff;
|
||||
// dmadata[2] = (value >> 8) & 0xff;
|
||||
// dmadata[3] = index & 0xff;
|
||||
// dmadata[4] = (index >> 8) & 0xff;
|
||||
// dmadata[5] = len & 0xff;
|
||||
// dmadata[6] = (len >> 8) & 0xff;
|
||||
//
|
||||
// /* send command */
|
||||
// ret = usb_bulk_msg(dev->usb_dev, usb_sndbulkpipe(dev->usb_dev, 9),
|
||||
// dmadata, 7, &actual_len, 2000);
|
||||
//
|
||||
// dev_warn(&dev->usb_dev->dev, "read bulk msg retval=%i\n", ret);
|
||||
//
|
||||
// /* command received correctly */
|
||||
// if (ret == 7) {
|
||||
// actual_len = 0;
|
||||
// /* receive reply */
|
||||
// ret = usb_bulk_msg(dev->usb_dev, usb_rcvbulkpipe(dev->usb_dev, 9),
|
||||
// dmadata, len, &actual_len, 2000);
|
||||
//
|
||||
// memcpy(data, dmadata, len);
|
||||
// }
|
||||
dmadata = kmalloc(len, GFP_KERNEL);
|
||||
dmadata = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
value, index, dmadata, len, 2000);
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
value, index, dmadata, len, 2000);
|
||||
|
||||
memcpy(data, dmadata, len);
|
||||
} else {
|
||||
dmadata = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
value, index, dmadata, len, 2000);
|
||||
|
||||
memcpy(data, dmadata, len);
|
||||
}
|
||||
memcpy(data, dmadata, len);
|
||||
|
||||
kfree(dmadata);
|
||||
return ret;
|
||||
|
@ -246,45 +201,16 @@ static int usb_write(struct i2c_adapter *adapter, int cmd,
|
|||
{
|
||||
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
|
||||
uint8_t *dmadata;
|
||||
int ret, actual_len = 0;
|
||||
int ret;
|
||||
|
||||
if (dev->is_tusb_dmime) {
|
||||
// dmadata = (uint8_t*)kzalloc(len + 7, GFP_KERNEL); /* cmd(1), value(2), index(2), len(2) */
|
||||
// if (!dmadata)
|
||||
// return -ENOMEM;
|
||||
//
|
||||
// dmadata[0] = cmd;
|
||||
// dmadata[1] = value & 0xff;
|
||||
// dmadata[2] = (value >> 8) & 0xff;
|
||||
// dmadata[3] = index & 0xff;
|
||||
// dmadata[4] = (index >> 8) & 0xff;
|
||||
// dmadata[5] = len & 0xff;
|
||||
// dmadata[6] = (len >> 8) & 0xff;
|
||||
//
|
||||
// if (data && len)
|
||||
// memcpy(&dmadata[7], data, len);
|
||||
//
|
||||
// /* send command data */
|
||||
// ret = usb_bulk_msg(dev->usb_dev, usb_sndbulkpipe(dev->usb_dev, 9),
|
||||
// dmadata, len+7, &actual_len, 2000);
|
||||
dmadata = (uint8_t*)kmemdup(data, len, GFP_KERNEL);
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
dmadata = (uint8_t*)kmemdup(data, len, GFP_KERNEL);
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
||||
value, index, dmadata, len, 2000);
|
||||
} else {
|
||||
dmadata = (uint8_t*)kmemdup(data, len, GFP_KERNEL);
|
||||
if (!dmadata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
||||
value, index, dmadata, len, 2000);
|
||||
}
|
||||
/* do control transfer */
|
||||
ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
|
||||
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
||||
value, index, dmadata, len, 2000);
|
||||
|
||||
kfree(dmadata);
|
||||
return ret;
|
||||
|
@ -315,10 +241,6 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface,
|
|||
dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
|
||||
dev->interface = interface;
|
||||
|
||||
/* TinyUSB DapperMime needs different treatment because it has MANY endpoints */
|
||||
dev->is_tusb_dmime = le16_to_cpu(dev->usb_dev->descriptor.idVendor ) == 0xcafe
|
||||
&& le16_to_cpu(dev->usb_dev->descriptor.idProduct) == 0x4017;
|
||||
|
||||
/* save our data pointer in this interface device */
|
||||
usb_set_intfdata(interface, dev);
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// vim: set et:
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -24,22 +23,22 @@
|
|||
// 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, // 18..1f
|
||||
0, // 20..27
|
||||
0, // 28..2f
|
||||
0, // 30..37
|
||||
0, // 38..3f
|
||||
0, // 40..47
|
||||
0, // 48..4f
|
||||
(1<<3), // 50..57: enable 0x53
|
||||
0, // 58..5f
|
||||
0, // rest is 0
|
||||
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, // 18..1f
|
||||
0, // 20..27
|
||||
0, // 28..2f
|
||||
0, // 30..37
|
||||
0, // 38..3f
|
||||
0, // 40..47
|
||||
0, // 48..4f
|
||||
(1<<3), // 50..57: enable 0x53
|
||||
0, // 58..5f
|
||||
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
|
||||
'D','a','p','p','e','r','M','i','m','e','-','J','T','A','G',0 // TODO
|
||||
};
|
||||
|
||||
static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
|
||||
|
@ -48,213 +47,194 @@ static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
|
|||
static uint32_t rxavail, rxpos;
|
||||
|
||||
void cdc_serprog_init(void) {
|
||||
rxavail = 0;
|
||||
rxpos = 0;
|
||||
rxavail = 0;
|
||||
rxpos = 0;
|
||||
|
||||
sp_spi_init();
|
||||
sp_spi_init();
|
||||
}
|
||||
|
||||
static uint8_t read_byte(void) {
|
||||
while (rxavail <= 0) {
|
||||
if (!tud_cdc_n_connected(CDC_N_SERPROG) || !tud_cdc_n_available(CDC_N_SERPROG)) {
|
||||
thread_yield();
|
||||
continue;
|
||||
}
|
||||
while (rxavail <= 0) {
|
||||
if (!tud_cdc_n_connected(CDC_N_SERPROG) || !tud_cdc_n_available(CDC_N_SERPROG)) {
|
||||
thread_yield();
|
||||
continue;
|
||||
}
|
||||
|
||||
rxpos = 0;
|
||||
rxavail = tud_cdc_n_read(CDC_N_SERPROG, rx_buf, sizeof rx_buf);
|
||||
rxpos = 0;
|
||||
rxavail = tud_cdc_n_read(CDC_N_SERPROG, rx_buf, sizeof rx_buf);
|
||||
|
||||
if (rxavail == 0) thread_yield();
|
||||
}
|
||||
if (rxavail == 0) thread_yield();
|
||||
}
|
||||
|
||||
uint8_t rv = rx_buf[rxpos];
|
||||
++rxpos;
|
||||
--rxavail;
|
||||
//printf("r %02x\n",rv);
|
||||
return rv;
|
||||
uint8_t rv = rx_buf[rxpos];
|
||||
++rxpos;
|
||||
--rxavail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void handle_cmd(void) {
|
||||
uint32_t nresp = 0;
|
||||
uint32_t nresp = 0;
|
||||
|
||||
uint8_t cmd = read_byte();
|
||||
switch (cmd) {
|
||||
case S_CMD_NOP:
|
||||
//printf("nop\n");
|
||||
tx_buf[0] = S_ACK;
|
||||
nresp = 1;
|
||||
break;
|
||||
case S_CMD_SYNCNOP:
|
||||
//printf("snop\n");
|
||||
tx_buf[0] = S_NAK;
|
||||
tx_buf[1] = S_ACK;
|
||||
nresp = 2;
|
||||
break;
|
||||
case S_CMD_Q_IFACE:
|
||||
//printf("q_if\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_cmap\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_pgm\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_sbuf\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_btyp\n");
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = 1<<3; // SPI only
|
||||
nresp = 2;
|
||||
break;
|
||||
case S_CMD_Q_WRNMAXLEN:
|
||||
//printf("q_wlen\n");
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = (sizeof(tx_buf)-1) & 0xff;
|
||||
tx_buf[2] = ((sizeof(tx_buf)-1) >> 8) & 0xff;
|
||||
tx_buf[3] = ((sizeof(tx_buf)-1) >>16) & 0xff;
|
||||
nresp = 4;
|
||||
break;
|
||||
case S_CMD_Q_RDNMAXLEN:
|
||||
//printf("q_rlen\n");
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = (sizeof(rx_buf)-1) & 0xff;
|
||||
tx_buf[2] = ((sizeof(rx_buf)-1) >> 8) & 0xff;
|
||||
tx_buf[3] = ((sizeof(rx_buf)-1) >>16) & 0xff;
|
||||
nresp = 4;
|
||||
break;
|
||||
case S_CMD_S_BUSTYPE:
|
||||
//printf("s_btyp\n");
|
||||
uint8_t cmd = read_byte();
|
||||
switch (cmd) {
|
||||
case S_CMD_NOP:
|
||||
tx_buf[0] = S_ACK;
|
||||
nresp = 1;
|
||||
break;
|
||||
case S_CMD_SYNCNOP:
|
||||
tx_buf[0] = S_NAK;
|
||||
tx_buf[1] = S_ACK;
|
||||
nresp = 2;
|
||||
break;
|
||||
case S_CMD_Q_IFACE:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = 1<<3; // SPI only
|
||||
nresp = 2;
|
||||
break;
|
||||
case S_CMD_Q_WRNMAXLEN:
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = (sizeof(tx_buf)-1) & 0xff;
|
||||
tx_buf[2] = ((sizeof(tx_buf)-1) >> 8) & 0xff;
|
||||
tx_buf[3] = ((sizeof(tx_buf)-1) >>16) & 0xff;
|
||||
nresp = 4;
|
||||
break;
|
||||
case S_CMD_Q_RDNMAXLEN:
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = (sizeof(rx_buf)-1) & 0xff;
|
||||
tx_buf[2] = ((sizeof(rx_buf)-1) >> 8) & 0xff;
|
||||
tx_buf[3] = ((sizeof(rx_buf)-1) >>16) & 0xff;
|
||||
nresp = 4;
|
||||
break;
|
||||
case S_CMD_S_BUSTYPE:
|
||||
if (read_byte()/* bus type to set */ == (1<<3)) {
|
||||
tx_buf[0] = S_ACK;
|
||||
} else {
|
||||
tx_buf[0] = S_NAK;
|
||||
}
|
||||
nresp = 1;
|
||||
break;
|
||||
|
||||
if (read_byte()/* bus type to set */ == (1<<3)) {
|
||||
tx_buf[0] = S_ACK;
|
||||
} else {
|
||||
tx_buf[0] = S_NAK;
|
||||
}
|
||||
nresp = 1;
|
||||
break;
|
||||
case S_CMD_SPIOP: {
|
||||
uint32_t slen, rlen;
|
||||
slen = (uint32_t)read_byte();
|
||||
slen |= (uint32_t)read_byte() << 8;
|
||||
slen |= (uint32_t)read_byte() << 16;
|
||||
rlen = (uint32_t)read_byte();
|
||||
rlen |= (uint32_t)read_byte() << 8;
|
||||
rlen |= (uint32_t)read_byte() << 16;
|
||||
|
||||
case S_CMD_SPIOP: {
|
||||
//printf("spiop\n");
|
||||
sp_spi_op_begin();
|
||||
size_t this_batch;
|
||||
|
||||
uint32_t slen, rlen;
|
||||
slen = (uint32_t)read_byte();
|
||||
slen |= (uint32_t)read_byte() << 8;
|
||||
slen |= (uint32_t)read_byte() << 16;
|
||||
rlen = (uint32_t)read_byte();
|
||||
rlen |= (uint32_t)read_byte() << 8;
|
||||
rlen |= (uint32_t)read_byte() << 16;
|
||||
// 1. write slen data bytes
|
||||
// we're going to use the tx buf for all operations here
|
||||
while (slen > 0) {
|
||||
this_batch = sizeof(tx_buf);
|
||||
if (this_batch > slen) this_batch = slen;
|
||||
|
||||
sp_spi_op_begin();
|
||||
size_t this_batch;
|
||||
for (size_t i = 0; i < this_batch; ++i) tx_buf[i] = read_byte();
|
||||
sp_spi_op_write(this_batch, tx_buf);
|
||||
|
||||
// 1. write slen data bytes
|
||||
// we're going to use the tx buf for all operations here
|
||||
while (slen > 0) {
|
||||
this_batch = sizeof(tx_buf);
|
||||
if (this_batch > slen) this_batch = slen;
|
||||
slen -= this_batch;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this_batch; ++i) tx_buf[i] = read_byte();
|
||||
sp_spi_op_write(this_batch, tx_buf);
|
||||
// 2. write data
|
||||
// first, do a batch of 63, because we also need to send an ACK byte
|
||||
this_batch = sizeof(tx_buf)-1;
|
||||
if (this_batch > rlen) this_batch = rlen;
|
||||
sp_spi_op_read(this_batch, &tx_buf[1]);
|
||||
tx_buf[0] = S_ACK;
|
||||
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch+1);
|
||||
rlen -= this_batch;
|
||||
|
||||
slen -= this_batch;
|
||||
}
|
||||
// now do in batches of 64
|
||||
while (rlen > 0) {
|
||||
this_batch = sizeof(tx_buf);
|
||||
if (this_batch > rlen) this_batch = rlen;
|
||||
|
||||
// 2. write data
|
||||
// first, do a batch of 63, because we also need to send an ACK byte
|
||||
this_batch = sizeof(tx_buf)-1;
|
||||
if (this_batch > rlen) this_batch = rlen;
|
||||
sp_spi_op_read(this_batch, &tx_buf[1]);
|
||||
tx_buf[0] = S_ACK;
|
||||
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch+1);
|
||||
rlen -= this_batch;
|
||||
sp_spi_op_read(this_batch, tx_buf);
|
||||
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch);
|
||||
|
||||
// now do in batches of 64
|
||||
while (rlen > 0) {
|
||||
this_batch = sizeof(tx_buf);
|
||||
if (this_batch > rlen) this_batch = rlen;
|
||||
rlen -= this_batch;
|
||||
}
|
||||
tud_cdc_n_write_flush(CDC_N_SERPROG);
|
||||
|
||||
sp_spi_op_read(this_batch, tx_buf);
|
||||
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch);
|
||||
// that's it!
|
||||
sp_spi_op_end();
|
||||
nresp = 0; // we sent our own response manually
|
||||
}
|
||||
break;
|
||||
case S_CMD_S_SPI_FREQ: {
|
||||
uint32_t freq;
|
||||
freq = (uint32_t)read_byte();
|
||||
freq |= (uint32_t)read_byte() << 8;
|
||||
freq |= (uint32_t)read_byte() << 16;
|
||||
freq |= (uint32_t)read_byte() << 24;
|
||||
|
||||
rlen -= this_batch;
|
||||
}
|
||||
tud_cdc_n_write_flush(CDC_N_SERPROG);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case S_CMD_S_PINSTATE: {
|
||||
if (read_byte() == 0) sp_spi_cs_deselect();
|
||||
else sp_spi_cs_select();
|
||||
|
||||
// that's it!
|
||||
sp_spi_op_end();
|
||||
nresp = 0; // we sent our own response manually
|
||||
}
|
||||
break;
|
||||
case S_CMD_S_SPI_FREQ: {
|
||||
//printf("s_spi_freq\n");
|
||||
uint32_t freq;
|
||||
freq = (uint32_t)read_byte();
|
||||
freq |= (uint32_t)read_byte() << 8;
|
||||
freq |= (uint32_t)read_byte() << 16;
|
||||
freq |= (uint32_t)read_byte() << 24;
|
||||
tx_buf[0] = S_ACK;
|
||||
nresp = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case S_CMD_S_PINSTATE: {
|
||||
//printf("s_pins\n");
|
||||
case S_CMD_MAGIC_SETTINGS: {
|
||||
uint8_t a = read_byte();
|
||||
uint8_t b = read_byte();
|
||||
|
||||
if (read_byte() == 0) sp_spi_cs_deselect();
|
||||
else sp_spi_cs_select();
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = rtconf_do(a, b);
|
||||
nresp = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
tx_buf[0] = S_ACK;
|
||||
nresp = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tx_buf[0] = S_NAK;
|
||||
nresp = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case S_CMD_MAGIC_SETTINGS: {
|
||||
uint8_t a = read_byte();
|
||||
uint8_t b = read_byte();
|
||||
|
||||
tx_buf[0] = S_ACK;
|
||||
tx_buf[1] = rtconf_do(a, b);
|
||||
nresp = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//printf("ill %d\n", cmd);
|
||||
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);
|
||||
}
|
||||
if (nresp > 0) {
|
||||
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, nresp);
|
||||
tud_cdc_n_write_flush(CDC_N_SERPROG);
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_serprog_task(void) {
|
||||
handle_cmd();
|
||||
//printf("d\n");
|
||||
handle_cmd();
|
||||
}
|
||||
|
||||
#endif /* DBOARD_HAS_SERPROG */
|
||||
|
|
|
@ -81,14 +81,18 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
|
|||
case 4: case 5: case 6: case 7: // I2C_IO
|
||||
{
|
||||
if (req->wValue & 1) { // read: we need to return shit
|
||||
printf("read!%c%c%c%c%c\n", ' ', ' ', ' ', ' ', ' ');
|
||||
//printf("read!%c%c%c%c%c\n", ' ', ' ', ' ', ' ', ' ');
|
||||
// so, we'll return some garbage
|
||||
uint8_t buf[req->wLength];
|
||||
return tud_control_xfer(rhport, req, buf, req->wLength);
|
||||
} else {
|
||||
//printf("write!%c%c%c%c%c\n", ' ', ' ', ' ', ' ', ' ');
|
||||
// ????
|
||||
return tud_control_status(rhport, req);
|
||||
uint8_t buf[req->wLength];
|
||||
bool rv = tud_control_xfer(rhport, req, buf, req->wLength);
|
||||
printf("rv %c len %04x buf %02x %02x %02x ...\n",
|
||||
(rv?'t':'f'), req->wLength, buf[0], buf[1], buf[2]);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
166
src/main.c
166
src/main.c
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
@ -45,34 +45,32 @@
|
|||
#include <pico/binary_info.h>
|
||||
#endif
|
||||
|
||||
static cothread_t mainthread
|
||||
#ifdef DBOARD_HAS_UART
|
||||
, uartthread
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
, serprogthread
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
//, ituthread
|
||||
#endif
|
||||
;
|
||||
static cothread_t mainthread;
|
||||
|
||||
void thread_yield(void) {
|
||||
co_switch(mainthread);
|
||||
co_switch(mainthread);
|
||||
}
|
||||
|
||||
#define DEFAULT_STACK_SIZE 1024
|
||||
|
||||
#ifdef DBOARD_HAS_UART
|
||||
static cothread_t uartthread;
|
||||
static uint8_t uartstack[DEFAULT_STACK_SIZE];
|
||||
|
||||
static void uart_thread_fn(void) {
|
||||
cdc_uart_init();
|
||||
thread_yield();
|
||||
while (1) {
|
||||
cdc_uart_task();
|
||||
thread_yield();
|
||||
}
|
||||
cdc_uart_init();
|
||||
thread_yield();
|
||||
while (1) {
|
||||
cdc_uart_task();
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
static cothread_t serprogthread;
|
||||
static uint8_t serprogstack[DEFAULT_STACK_SIZE];
|
||||
|
||||
static void serprog_thread_fn(void) {
|
||||
cdc_serprog_init();
|
||||
thread_yield();
|
||||
|
@ -83,102 +81,53 @@ static void serprog_thread_fn(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
/*static void itu_thread_fn(void) {
|
||||
itu_init();
|
||||
thread_yield();
|
||||
while (1) {
|
||||
itu_task();
|
||||
thread_yield();
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
#ifdef DBOARD_HAS_UART
|
||||
static uint8_t uartstack[4096];
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
static uint8_t serprogstack[4096];
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
static uint8_t itustack[4096];
|
||||
#endif
|
||||
|
||||
// FIXME
|
||||
extern uint32_t co_active_buffer[64];
|
||||
uint32_t co_active_buffer[64];
|
||||
extern cothread_t co_active_handle;
|
||||
cothread_t co_active_handle;
|
||||
|
||||
extern char msgbuf[256];
|
||||
extern volatile bool msgflag;
|
||||
static void domsg(void) {
|
||||
if (msgflag) {
|
||||
printf("%s", msgbuf);
|
||||
//msgflag = false;
|
||||
}
|
||||
}
|
||||
int main(void) {
|
||||
mainthread = co_active();
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mainthread = co_active();
|
||||
|
||||
// TODO: split this out in a bsp-specific file
|
||||
// TODO: split this out in a bsp-specific file
|
||||
#if defined(PICO_BOARD) && !defined(USE_USBCDC_FOR_STDIO)
|
||||
// use hardcoded values from TinyUSB board.h
|
||||
bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART));
|
||||
// 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
|
||||
uartthread = co_derive(uartstack, sizeof uartstack, uart_thread_fn);
|
||||
co_switch(uartthread); // will call cdc_uart_init() on correct thread
|
||||
uartthread = co_derive(uartstack, sizeof uartstack, uart_thread_fn);
|
||||
co_switch(uartthread); // will call cdc_uart_init() on correct thread
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn);
|
||||
co_switch(serprogthread); // will call cdc_serprog_init() on correct thread
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
//ituthread = co_derive(itustack, sizeof itustack, itu_thread_fn);
|
||||
//co_switch(ituthread);
|
||||
serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn);
|
||||
co_switch(serprogthread); // will call cdc_serprog_init() on correct thread
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_CMSISDAP
|
||||
DAP_Setup();
|
||||
DAP_Setup();
|
||||
#endif
|
||||
|
||||
tusb_init();
|
||||
tusb_init();
|
||||
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
stdio_usb_init();
|
||||
stdio_usb_init();
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
//printf("hi\n");
|
||||
|
||||
domsg();
|
||||
tud_task(); // tinyusb device task
|
||||
while (1) {
|
||||
tud_task(); // tinyusb device task
|
||||
#ifdef DBOARD_HAS_UART
|
||||
//cdc_uart_task();
|
||||
co_switch(uartthread);
|
||||
co_switch(uartthread);
|
||||
#endif
|
||||
|
||||
domsg();
|
||||
tud_task(); // tinyusb device task
|
||||
tud_task(); // tinyusb device task
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
//cdc_serprog_task();
|
||||
co_switch(serprogthread);
|
||||
co_switch(serprogthread);
|
||||
#endif
|
||||
}
|
||||
|
||||
//domsg();
|
||||
//tud_task();
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
//co_switch(ituthread);
|
||||
#endif
|
||||
|
||||
//printf("hi2\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -188,31 +137,32 @@ int main(void)
|
|||
// Invoked when received GET_REPORT control request
|
||||
// Application must fill buffer report's content and return its length.
|
||||
// Return zero will cause the stack to STALL request
|
||||
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
|
||||
{
|
||||
// TODO not Implemented
|
||||
(void) instance;
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
(void) buffer;
|
||||
(void) reqlen;
|
||||
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id,
|
||||
hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
|
||||
// TODO not Implemented
|
||||
(void) instance;
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
(void) buffer;
|
||||
(void) reqlen;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize)
|
||||
{
|
||||
static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
|
||||
uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize);
|
||||
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id,
|
||||
hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize) {
|
||||
static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
|
||||
uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize);
|
||||
|
||||
// This doesn't use multiple report and report ID
|
||||
(void) instance;
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
// This doesn't use multiple report and report ID
|
||||
(void) instance;
|
||||
(void) report_id;
|
||||
(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include "protocfg.h"
|
||||
|
||||
#define INFO_MANUFACTURER "BLAHAJ CTF"
|
||||
#define INFO_PRODUCT(board) "Dragnbus (" board ")"
|
||||
|
||||
#ifdef DBOARD_HAS_UART
|
||||
void cdc_uart_init(void);
|
||||
void cdc_uart_task(void);
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include "rtconf.h"
|
||||
|
||||
uint8_t rtconf_do(uint8_t a, uint8_t b) {
|
||||
//printf("rtconf %02x,%02x\n", a, b);
|
||||
|
||||
switch ((enum rtconf_opt)a) {
|
||||
#ifdef DBOARD_HAS_UART
|
||||
case opt_uart_hwfc_endis:
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define _TUSB_CONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -115,8 +115,6 @@
|
|||
// CDC FIFO size of TX and RX
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
@ -25,175 +25,170 @@
|
|||
|
||||
#include "tusb.h"
|
||||
#include "unique.h"
|
||||
#include "protos.h"
|
||||
|
||||
#include "protocfg.h"
|
||||
|
||||
// TODO: actually do this properly
|
||||
/* 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.
|
||||
*
|
||||
* Auto ProductID layout's Bitmap:
|
||||
* [MSB] HID | MSC | CDC [LSB]
|
||||
*/
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
#define USB_PID_BASE 0x6000
|
||||
#else
|
||||
#define USB_PID_BASE 0x4000
|
||||
#endif
|
||||
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
|
||||
#define USB_PID (USB_PID_BASE | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 3) | _PID_MAP(HID, 6) | \
|
||||
_PID_MAP(MIDI, 9) | _PID_MAP(VENDOR, 12) ) \
|
||||
|
||||
|
||||
// String Descriptor Index
|
||||
enum
|
||||
{
|
||||
STRID_LANGID = 0,
|
||||
STRID_MANUFACTURER,
|
||||
STRID_PRODUCT,
|
||||
STRID_SERIAL,
|
||||
enum {
|
||||
STRID_LANGID = 0,
|
||||
STRID_MANUFACTURER,
|
||||
STRID_PRODUCT,
|
||||
STRID_SERIAL,
|
||||
|
||||
STRID_CONFIG,
|
||||
|
||||
STRID_IF_HID_CMSISDAP,
|
||||
STRID_IF_VND_I2CTINYUSB,
|
||||
STRID_IF_CDC_UART,
|
||||
STRID_IF_CDC_SERPROG,
|
||||
STRID_IF_CDC_STDIO,
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_device_t const desc_device =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0110, // FIXME: 0x0200 ?
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
tusb_desc_device_t const desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0110, // TODO: 0x0200 ?
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = 0xCafe, // TODO
|
||||
.idProduct = USB_PID,
|
||||
.bcdDevice = 0x0101,
|
||||
.idVendor = USB_VID,
|
||||
.idProduct = USB_PID,
|
||||
.bcdDevice = 0x0101, // TODO
|
||||
|
||||
.iManufacturer = STRID_MANUFACTURER,
|
||||
.iProduct = STRID_PRODUCT,
|
||||
.iSerialNumber = STRID_SERIAL,
|
||||
.iManufacturer = STRID_MANUFACTURER,
|
||||
.iProduct = STRID_PRODUCT,
|
||||
.iSerialNumber = STRID_SERIAL,
|
||||
|
||||
.bNumConfigurations = 0x01
|
||||
.bNumConfigurations = 0x01
|
||||
};
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const * tud_descriptor_device_cb(void)
|
||||
{
|
||||
return (uint8_t const *) &desc_device;
|
||||
uint8_t const * tud_descriptor_device_cb(void) {
|
||||
return (uint8_t const *) &desc_device;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// HID Report Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance)
|
||||
{
|
||||
(void) instance;
|
||||
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) {
|
||||
(void) instance;
|
||||
|
||||
return desc_hid_report;
|
||||
return desc_hid_report;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
enum
|
||||
{
|
||||
ITF_NUM_HID_CMSISDAP,
|
||||
ITF_NUM_CDC_UART_COM,
|
||||
ITF_NUM_CDC_UART_DATA,
|
||||
ITF_NUM_CDC_SERPROG_COM,
|
||||
ITF_NUM_CDC_SERPROG_DATA,
|
||||
ITF_NUM_CDC_STDIO_COM,
|
||||
ITF_NUM_CDC_STDIO_DATA,
|
||||
ITF_NUM_VND_I2CTINYUSB,
|
||||
enum {
|
||||
ITF_NUM_HID_CMSISDAP,
|
||||
ITF_NUM_CDC_UART_COM,
|
||||
ITF_NUM_CDC_UART_DATA,
|
||||
ITF_NUM_CDC_SERPROG_COM,
|
||||
ITF_NUM_CDC_SERPROG_DATA,
|
||||
ITF_NUM_CDC_STDIO_COM,
|
||||
ITF_NUM_CDC_STDIO_DATA,
|
||||
ITF_NUM_VND_I2CTINYUSB,
|
||||
|
||||
ITF_NUM_TOTAL
|
||||
ITF_NUM_TOTAL
|
||||
};
|
||||
|
||||
#define TUD_I2CTINYUSB_LEN (9)
|
||||
#define TUD_I2CTINYUSB_DESCRIPTOR(_itfnum, _stridx) \
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, 0, 0, 0, _stridx \
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, 0, 0, 0, _stridx \
|
||||
|
||||
|
||||
/*enum {*/ static const int CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN
|
||||
enum {
|
||||
CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN
|
||||
#ifdef DBOARD_HAS_I2C
|
||||
+ TUD_I2CTINYUSB_LEN
|
||||
//+ TUD_VENDOR_DESC_LEN
|
||||
+ TUD_I2CTINYUSB_LEN
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_UART
|
||||
+ TUD_CDC_DESC_LEN
|
||||
+ TUD_CDC_DESC_LEN
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_CMSISDAP
|
||||
+ TUD_HID_INOUT_DESC_LEN
|
||||
+ TUD_HID_INOUT_DESC_LEN
|
||||
#endif
|
||||
#ifdef DBOARD_HAS_SERPROG
|
||||
+ TUD_CDC_DESC_LEN
|
||||
+ TUD_CDC_DESC_LEN
|
||||
#endif
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
+ TUD_CDC_DESC_LEN
|
||||
+ 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
|
||||
#define EPNUM_CDC_UART_OUT 0x02
|
||||
#define EPNUM_CDC_UART_IN 0x82
|
||||
#define EPNUM_CDC_UART_NOTIF 0x83
|
||||
#define EPNUM_HID_CMSISDAP 0x04
|
||||
#define EPNUM_CDC_SERPROG_OUT 0x05
|
||||
#define EPNUM_CDC_SERPROG_IN 0x85
|
||||
#define EPNUM_CDC_SERPROG_NOTIF 0x86
|
||||
#define EPNUM_CDC_STDIO_OUT 0x07
|
||||
#define EPNUM_CDC_STDIO_IN 0x87
|
||||
#define EPNUM_CDC_STDIO_NOTIF 0x88
|
||||
#define EPNUM_VND_I2C_OUT 0x09
|
||||
#define EPNUM_VND_I2C_IN 0x89
|
||||
|
||||
// NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well!
|
||||
// TODO: maybe add some strings to all these interfaces
|
||||
uint8_t const desc_configuration[] =
|
||||
{
|
||||
// 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),
|
||||
uint8_t const desc_configuration[] = {
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
#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, 0/*HID_PROTOCOL_NONE*/, sizeof(desc_hid_report), EPNUM_HID_CMSISDAP, 0x80 | (EPNUM_HID_CMSISDAP+0), CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID_CMSISDAP, STRID_IF_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_I2C
|
||||
// ???
|
||||
TUD_I2CTINYUSB_DESCRIPTOR(ITF_NUM_VND_I2CTINYUSB, 0),
|
||||
//TUD_VENDOR_DESCRIPTOR(ITF_NUM_VND_I2CTINYUSB, 0, EPNUM_VND_I2C_OUT, EPNUM_VND_I2C_IN, 64),
|
||||
TUD_I2CTINYUSB_DESCRIPTOR(ITF_NUM_VND_I2CTINYUSB, STRID_IF_VND_I2CTINYUSB),
|
||||
#endif
|
||||
|
||||
#ifdef DBOARD_HAS_UART
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_UART_COM, 0, EPNUM_CDC_UART_NOTIF, 64, EPNUM_CDC_UART_OUT, EPNUM_CDC_UART_IN, 64),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_UART_COM, STRID_IF_CDC_UART, EPNUM_CDC_UART_NOTIF, 64, EPNUM_CDC_UART_OUT, EPNUM_CDC_UART_IN, 64),
|
||||
#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),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_SERPROG_COM, STRID_IF_CDC_SERPROG, EPNUM_CDC_SERPROG_NOTIF, 64, EPNUM_CDC_SERPROG_OUT, EPNUM_CDC_SERPROG_IN, 64),
|
||||
#endif
|
||||
|
||||
#ifdef USE_USBCDC_FOR_STDIO
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_STDIO_COM, 0, EPNUM_CDC_STDIO_NOTIF, 64, EPNUM_CDC_STDIO_OUT, EPNUM_CDC_STDIO_IN, 64),
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_STDIO_COM, STRID_IF_CDC_STDIO, EPNUM_CDC_STDIO_NOTIF, 64, EPNUM_CDC_STDIO_OUT, EPNUM_CDC_STDIO_IN, 64),
|
||||
#endif
|
||||
};
|
||||
|
||||
// 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)
|
||||
{
|
||||
(void) index; // for multiple configurations
|
||||
return desc_configuration;
|
||||
uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void) index; // for multiple configurations
|
||||
return desc_configuration;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -201,50 +196,55 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
|||
//--------------------------------------------------------------------+
|
||||
|
||||
// array of pointer to string descriptors
|
||||
char const* string_desc_arr [] =
|
||||
{
|
||||
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
||||
[STRID_MANUFACTURER] = "TinyUSB", // Manufacturer // TODO
|
||||
[STRID_PRODUCT] = PRODUCT_PREFIX "CMSIS-DAP", // Product // TODO
|
||||
char const* string_desc_arr [] = {
|
||||
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
|
||||
[STRID_MANUFACTURER] = INFO_MANUFACTURER, // Manufacturer
|
||||
[STRID_PRODUCT] = INFO_PRODUCT(INFO_BOARDNAME), // Product
|
||||
|
||||
[STRID_CONFIG] = "Configuration descriptor",
|
||||
// max string length check: |||||||||||||||||||||||||||||||
|
||||
[STRID_IF_HID_CMSISDAP] = "CMSIS-DAP HID interface",
|
||||
[STRID_IF_VND_I2CTINYUSB] = "I2C-Tiny-USB interface",
|
||||
[STRID_IF_CDC_UART] = "UART CDC interface",
|
||||
[STRID_IF_CDC_SERPROG] = "Serprog CDC interface",
|
||||
[STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)",
|
||||
};
|
||||
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)
|
||||
{
|
||||
(void) langid;
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
static uint16_t _desc_str[32];
|
||||
|
||||
uint8_t chr_count = 0;
|
||||
(void) langid;
|
||||
|
||||
if (STRID_LANGID == index)
|
||||
{
|
||||
memcpy(&_desc_str[1], string_desc_arr[STRID_LANGID], 2);
|
||||
chr_count = 1;
|
||||
} else if (STRID_SERIAL == index)
|
||||
{
|
||||
chr_count = get_unique_id(_desc_str + 1);
|
||||
} else
|
||||
{
|
||||
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||
uint8_t chr_count = 0;
|
||||
|
||||
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||
if (STRID_LANGID == index) {
|
||||
memcpy(&_desc_str[1], string_desc_arr[STRID_LANGID], 2);
|
||||
chr_count = 1;
|
||||
} else if (STRID_SERIAL == index) {
|
||||
chr_count = get_unique_id_u16(_desc_str + 1);
|
||||
} else {
|
||||
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||
|
||||
const char* str = string_desc_arr[index];
|
||||
if (!(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])))
|
||||
return NULL;
|
||||
|
||||
// Cap at max char
|
||||
chr_count = TU_MIN(strlen(str), 31);
|
||||
const char* str = string_desc_arr[index];
|
||||
|
||||
// Convert ASCII string into UTF-16
|
||||
for(uint8_t i=0; i<chr_count; i++)
|
||||
{
|
||||
_desc_str[1+i] = str[i];
|
||||
}
|
||||
}
|
||||
// Cap at max char
|
||||
chr_count = TU_MIN(strlen(str), 31);
|
||||
|
||||
// first byte is length (including header), second byte is string type
|
||||
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
|
||||
// Convert ASCII string into UTF-16
|
||||
for (int i = 0; i < chr_count; i++) {
|
||||
_desc_str[1+i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
return _desc_str;
|
||||
// first byte is length (including header), second byte is string type
|
||||
_desc_str[0] = (TUSB_DESC_STRING << 8) | (2*chr_count + 2);
|
||||
|
||||
return _desc_str;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue