diff --git a/bsp/default/DAP_config.h b/bsp/default/DAP_config.h index 380e914..e0491aa 100644 --- a/bsp/default/DAP_config.h +++ b/bsp/default/DAP_config.h @@ -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 } ///@} diff --git a/bsp/default/protocfg.h b/bsp/default/protocfg.h index b04867f..66551c3 100644 --- a/bsp/default/protocfg.h +++ b/bsp/default/protocfg.h @@ -7,5 +7,7 @@ /*#define DBOARD_HAS_SERPROG*/ /*#define DBOARD_HAS_TINYI2C*/ +#define INFO_BOARDNAME "unknown" + #endif diff --git a/bsp/default/unique.h b/bsp/default/unique.h index 3125331..884775a 100644 --- a/bsp/default/unique.h +++ b/bsp/default/unique.h @@ -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 #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__ */ diff --git a/bsp/rp2040/board.h b/bsp/rp2040/board.h index 90cbe8b..8696038 100644 --- a/bsp/rp2040/board.h +++ b/bsp/rp2040/board.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_ */ diff --git a/bsp/rp2040/cdc_uart.c b/bsp/rp2040/cdc_uart.c index 461d212..23e5bec 100644 --- a/bsp/rp2040/cdc_uart.c +++ b/bsp/rp2040/cdc_uart.c @@ -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); } diff --git a/bsp/rp2040/protocfg.h b/bsp/rp2040/protocfg.h index 0dc4009..692c551 100644 --- a/bsp/rp2040/protocfg.h +++ b/bsp/rp2040/protocfg.h @@ -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 diff --git a/bsp/rp2040/unique.h b/bsp/rp2040/unique.h index 49d2df9..0e7c6b8 100644 --- a/bsp/rp2040/unique.h +++ b/bsp/rp2040/unique.h @@ -1,26 +1,44 @@ #include -#include "pico/stdlib.h" -#include "pico/unique_id.h" +#include +#include #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 " diff --git a/bsp/stm32f072disco/DAP_config.h b/bsp/stm32f072disco/DAP_config.h index a5525df..3393a4c 100644 --- a/bsp/stm32f072disco/DAP_config.h +++ b/bsp/stm32f072disco/DAP_config.h @@ -51,6 +51,9 @@ This information includes: #include +#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 } ///@} diff --git a/bsp/stm32f072disco/cdc_uart.c b/bsp/stm32f072disco/cdc_uart.c index 6c8f495..54feaf2 100644 --- a/bsp/stm32f072disco/cdc_uart.c +++ b/bsp/stm32f072disco/cdc_uart.c @@ -1,7 +1,6 @@ -void cdc_uart_init(void) -{ + +void cdc_uart_init(void) { } -void cdc_uart_task(void) -{ +void cdc_uart_task(void) { } diff --git a/bsp/stm32f072disco/protocfg.h b/bsp/stm32f072disco/protocfg.h index b04867f..fa3de2f 100644 --- a/bsp/stm32f072disco/protocfg.h +++ b/bsp/stm32f072disco/protocfg.h @@ -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 diff --git a/bsp/stm32f072disco/unique.h b/bsp/stm32f072disco/unique.h index 7aa76b3..b3dc093 100644 --- a/bsp/stm32f072disco/unique.h +++ b/bsp/stm32f072disco/unique.h @@ -1,20 +1,36 @@ #include #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 " diff --git a/i2c-tiny-usb-misc/i2c-tiny-usb.c b/i2c-tiny-usb-misc/i2c-tiny-usb.c index 01a44b4..d41990a 100644 --- a/i2c-tiny-usb-misc/i2c-tiny-usb.c +++ b/i2c-tiny-usb-misc/i2c-tiny-usb.c @@ -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); diff --git a/src/cdc_serprog.c b/src/cdc_serprog.c index ce8f177..2b71176 100644 --- a/src/cdc_serprog.c +++ b/src/cdc_serprog.c @@ -1,4 +1,3 @@ -// vim: set et: #include @@ -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 */ diff --git a/src/i2ctinyusb.c b/src/i2ctinyusb.c index 212323f..0ba584b 100644 --- a/src/i2ctinyusb.c +++ b/src/i2ctinyusb.c @@ -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; } } } diff --git a/src/main.c b/src/main.c index de7daaf..f8168f1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -45,34 +45,32 @@ #include #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); } + diff --git a/src/protos.h b/src/protos.h index 67e3dd4..c03a390 100644 --- a/src/protos.h +++ b/src/protos.h @@ -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); diff --git a/src/rtconf.c b/src/rtconf.c index 2dba1e2..1180509 100644 --- a/src/rtconf.c +++ b/src/rtconf.c @@ -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: diff --git a/src/tusb_config.h b/src/tusb_config.h index 30b6d60..0f476bf 100644 --- a/src/tusb_config.h +++ b/src/tusb_config.h @@ -27,7 +27,7 @@ #define _TUSB_CONFIG_H__ #ifdef __cplusplus - extern "C" { +extern "C" { #endif //-------------------------------------------------------------------- @@ -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 } diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 9f10540..204e82b 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -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