diff --git a/.gitignore b/.gitignore
index 26578c7..f2ff998 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ cmake-build/
build/
ex/
compile_commands.json
+_old/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 565a4ac..5c24df3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,22 +56,18 @@ endif()
target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/libco/libco.S
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/DAP.c
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/JTAG_DP.c
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/DAP_vendor.c
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/cdc_uart.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/i2c_tinyusb.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/spi_serprog.c
- ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/tempsensor.c
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/DAP.c
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/JTAG_DP.c
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/DAP_vendor.c
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SWO.c
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Source/SW_DP.c
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/unique.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_serprog.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/vnd_i2ctinyusb.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/rtconf.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/tempsensor.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/modeset.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/thread.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/tusb_plt.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/vnd_cfg.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/m_default/0def.c
)
if(USE_USBCDC_FOR_STDIO)
target_sources(${PROJECT} PUBLIC
@@ -81,8 +77,8 @@ endif()
target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/
${CMAKE_CURRENT_SOURCE_DIR}/libco/
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Include/
- ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/Core/Include/
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/DAP/Firmware/Include/
+# ${CMAKE_CURRENT_SOURCE_DIR}/CMSIS_5/CMSIS/Core/Include/
${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/
${CMAKE_CURRENT_SOURCE_DIR}/bsp/default/
)
diff --git a/bsp/default/DAP_config.h b/bsp/default/DAP_config.h
deleted file mode 100644
index b75191f..0000000
--- a/bsp/default/DAP_config.h
+++ /dev/null
@@ -1,470 +0,0 @@
-// vim: set et:
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2021 Peter Lawrence
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
-This DAP_config provides a CMSIS-DAP alternative to picoprobe and raspberrypi-swd.cfg
-*/
-
-#ifndef __DAP_CONFIG_H__
-#define __DAP_CONFIG_H__
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
-\ingroup DAP_ConfigIO_gr
-@{
-Provides definitions about the hardware and configuration of the Debug Unit.
-
-This information includes:
- - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit.
- - Debug Unit Identification strings (Vendor, Product, Serial Number).
- - Debug Unit communication packet size.
- - Debug Access Port supported modes and settings (JTAG/SWD and SWO).
- - Optional information about a connected Target Device (for Evaluation Boards).
-*/
-
-#include "cmsis_compiler.h"
-#include "util.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.
-
-/// Number of processor cycles for I/O Port write operations.
-/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
-/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors
-/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses
-/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be
-/// required.
-#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0.
-
-/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available.
-
-/// Indicate that JTAG communication mode is available at the Debug Port.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available.
-
-/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port.
-/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255.
-#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain.
-
-/// Default communication mode on the Debug Access Port.
-/// Used for the command \ref DAP_Connect when Port Default mode is selected.
-#define DAP_DEFAULT_PORT 2U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
-
-/// Default communication speed on the Debug Access Port for SWD and JTAG mode.
-/// Used to initialize the default SWD/JTAG clock frequency.
-/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting.
-#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz.
-
-/// Maximum Package Size for Command and Response data.
-/// This configuration settings is used to optimize the communication performance with the
-/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or
-/// WinUSB, 1024 for High-speed USB HID and 512 for High-speed USB WinUSB.
-#define DAP_PACKET_SIZE CFG_TUD_HID_EP_BUFSIZE ///< Specifies Packet Size in bytes.
-
-/// Maximum Package Buffers for Command and Response data.
-/// This configuration settings is used to optimize the communication performance with the
-/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the
-/// setting can be reduced (valid range is 1 .. 255).
-#define DAP_PACKET_COUNT 1U ///< Specifies number of packets buffered.
-
-/// Indicate that UART Serial Wire Output (SWO) trace is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available.
-
-/// Maximum SWO UART Baudrate.
-#define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz.
-
-/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
-
-/// SWO Trace Buffer Size.
-#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n).
-
-/// SWO Streaming Trace.
-#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available.
-
-/// Indicate that UART Communication Port is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available.
-
-/// USART Driver instance number for the UART Communication Port.
-#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#).
-
-/// UART Receive Buffer Size.
-#define DAP_UART_RX_BUFFER_SIZE 64U ///< Uart Receive Buffer Size in bytes (must be 2^n).
-
-/// UART Transmit Buffer Size.
-#define DAP_UART_TX_BUFFER_SIZE 64U ///< Uart Transmit Buffer Size in bytes (must be 2^n).
-
-/// Indicate that UART Communication via USB COM Port is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#ifdef USE_USBCDC_FOR_STDIO
-#define DAP_UART_USB_COM_PORT 1 ///< USB COM Port: 1 = available, 0 = not available.
-#else
-#define DAP_UART_USB_COM_PORT 0
-#endif
-
-/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
-#define TIMESTAMP_CLOCK 0U ///< Timestamp clock in Hz (0 = timestamps not supported).
-
-/// Debug Unit is connected to fixed Target Device.
-/// The Debug Unit may be part of an evaluation board and always connected to a fixed
-/// known device. In this case a Device Vendor and Device Name string is stored which
-/// may be used by the debugger or IDE to configure device parameters.
-#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
-
-#include "DAP.h"
-
-/** Get Vendor ID string.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetVendorString(char* str) {
- static const 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.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetProductString(char* str) {
- static const 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.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetSerNumString(char* str) { return get_unique_id_u8((uint8_t*)str); }
-
-/** Get Target Device Vendor string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Device Name string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Board Vendor string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Board Name string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString(char* str) {
- (void)str;
- return 0;
-}
-
-/* TODO! */
-/** Get Product Firmware Version string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString(char* str) {
- (void)str;
- return 0;
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
-\ingroup DAP_ConfigIO_gr
-@{
-
-Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode
-and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug
-interface of a device. The following I/O Pins are provided:
-
-JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
----------------------------- | -------------------- | ---------------------------------------------
-TCK: Test Clock | SWCLK: Clock | Output Push/Pull
-TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
-TDI: Test Data Input | | Output Push/Pull
-TDO: Test Data Output | | Input
-nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
-nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
-
-
-DAP Hardware I/O Pin Access Functions
--------------------------------------
-The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to
-these I/O Pins.
-
-For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only.
-This functions are provided to achieve faster I/O that is possible with some advanced GPIO
-peripherals that can independently write/read a single I/O pin without affecting any other pins
-of the same I/O port. The following SWDIO I/O Pin functions are provided:
- - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware.
- - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware.
- - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed.
- - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed.
-*/
-
-// Configure DAP I/O pins ------------------------------
-
-/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
-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.
-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) { }
-
-// SWCLK/TCK I/O pin -------------------------------------
-
-/** SWCLK/TCK I/O pin: Get Input.
-\return Current status of the SWCLK/TCK DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) { return 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) { }
-
-/** 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) { }
-
-// SWDIO/TMS Pin I/O --------------------------------------
-
-/** SWDIO/TMS I/O pin: Get Input.
-\return Current status of the SWDIO/TMS DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) { return 0; }
-
-/* PIN_SWDIO_TMS_SET and PIN_SWDIO_TMS_CLR are used by SWJ_Sequence */
-
-/** 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 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) { (void)bit; }
-
-/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
-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).
-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) { }
-
-// TDI Pin I/O ---------------------------------------------
-
-/** TDI I/O pin: Get Input.
-\return Current status of the TDI DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) { return 0; }
-
-/** 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; }
-
-// TDO Pin I/O ---------------------------------------------
-
-/** TDO I/O pin: Get Input.
-\return Current status of the TDO DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) { return 0; }
-
-// nTRST Pin I/O -------------------------------------------
-
-/** nTRST I/O pin: Get Input.
-\return Current status of the nTRST DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) { return 0; }
-
-/** nTRST I/O pin: Set Output.
-\param bit JTAG TRST Test Reset pin status:
- - 0: issue a JTAG TRST Test Reset.
- - 1: release JTAG TRST Test Reset.
-*/
-__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) { (void)bit; }
-
-// nRESET Pin I/O------------------------------------------
-
-/** nRESET I/O pin: Get Input.
-\return Current status of the nRESET DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) { return 0; }
-
-/** nRESET I/O pin: Set Output.
-\param bit target device hardware reset pin status:
- - 0: issue a device hardware reset.
- - 1: release device hardware reset.
-*/
-__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) { (void)bit; }
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
-\ingroup DAP_ConfigIO_gr
-@{
-
-CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit.
-
-It is recommended to provide the following LEDs for status indication:
- - Connect LED: is active when the DAP hardware is connected to a debugger.
- - Running LED: is active when the debugger has put the target device into running state.
-*/
-
-/** Debug Unit: Set status of Connected LED.
-\param bit status of the Connect LED.
- - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
- - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
-*/
-__STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) { (void)bit; }
-
-/** Debug Unit: Set status Target Running LED.
-\param bit status of the Target Running LED.
- - 1: Target Running LED ON: program execution in target started.
- - 0: Target Running LED OFF: program execution in target stopped.
-*/
-__STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) { (void)bit; }
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
-\ingroup DAP_ConfigIO_gr
-@{
-Access function for Test Domain Timer.
-
-The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET.
-By default, the DWT timer is used. The frequency of this timer is configured with \ref
-TIMESTAMP_CLOCK.
-
-*/
-
-/** Get timestamp of Test Domain Timer.
-\return Current timestamp value.
-*/
-__STATIC_INLINE uint32_t TIMESTAMP_GET(void) {
-#if TIMESTAMP_CLOCK > 0
- return (DWT->CYCCNT);
-#else
- return 0;
-#endif
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
-\ingroup DAP_ConfigIO_gr
-@{
-
-CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP.
-*/
-
-/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized).
-This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the
-Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set:
- - I/O clock system enabled.
- - all I/O pins: input buffer enabled, output pins are set to HighZ mode.
- - for nTRST, nRESET a weak pull-up (if available) is enabled.
- - 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.
-This function allows the optional implementation of a device specific reset sequence.
-It is called when the command \ref DAP_ResetTarget and is for example required
-when a device needs a time-critical unlock sequence that enables the debug port.
-\return 0 = no device specific reset sequence is implemented.\n
- 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
-}
-
-///@}
-
-#endif /* __DAP_CONFIG_H__ */
diff --git a/bsp/default/cdc_uart.c b/bsp/default/cdc_uart.c
deleted file mode 100644
index 20ffd20..0000000
--- a/bsp/default/cdc_uart.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// vim: set et:
-
-#include "protos.h"
-
-void cdc_uart_init(void) { }
-
-void cdc_uart_task(void) { }
-
-void cdc_uart_set_hwflow(bool enable) { (void)enable; }
-void cdc_uart_set_baud_rate(uint32_t brate) { (void)brate; }
-
diff --git a/bsp/default/i2c_tinyusb.c b/bsp/default/i2c_tinyusb.c
deleted file mode 100644
index 0f15073..0000000
--- a/bsp/default/i2c_tinyusb.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// vim: set et:
-
-#include "i2ctinyusb.h"
-
-__attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void) { return 0; }
-
-void i2ctu_init(void) { }
-
-uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us) {
- (void)freq;
- (void)us;
-
- return 0;
-}
-
-enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- const uint8_t* buf, size_t len) {
- (void)flags;
- (void)startstopflags;
- (void)addr;
- (void)buf;
- (void)len;
-
- return ITU_STATUS_ADDR_NAK;
-}
-enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- uint8_t* buf, size_t len) {
- (void)flags;
- (void)startstopflags;
- (void)addr;
- (void)buf;
- (void)len;
-
- return ITU_STATUS_ADDR_NAK;
-}
-
diff --git a/bsp/default/protocfg.h b/bsp/default/protocfg.h
deleted file mode 100644
index 5a4744c..0000000
--- a/bsp/default/protocfg.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// vim: set et:
-
-#ifndef PROTOCFG_H_
-#define PROTOCFG_H_
-
-/*#define DBOARD_HAS_UART
-#define DBOARD_HAS_CMSISDAP
-#define DBOARD_HAS_SERPROG
-#define DBOARD_HAS_I2C
-#define DBOARD_HAS_TEMPSENSOR*/
-
-enum {
- /*HID_N_CMSISDAP = 0,*/
-
- HID_N__NITF
-};
-enum {
-/*CDC_N_UART = 0,
-CDC_N_SERPROG,*/
-#ifdef USE_USBCDC_FOR_STDIO
- CDC_N_STDIO,
-#endif
-
- CDC_N__NITF
-};
-enum { VND_N__NITF = 0 };
-
-#define CFG_TUD_HID 0
-#ifdef USE_USBCDC_FOR_STDIO
-#define CFG_TUD_CDC 1
-#else
-#define CFG_TUD_CDC 0
-#endif
-#define CFG_TUD_VENDOR 0
-
-/*#define USB_VID 0x2e8a*/ /* Raspberry Pi */
-#define USB_VID 0xcafe /* TinyUSB */
-/*#define USB_VID 0x1209*/ /* Generic */
-/*#define USB_VID 0x1d50*/ /* OpenMoko */
-#define USB_PID 0x1312
-
-#define INFO_BOARDNAME "Unknown"
-
-#endif
-
diff --git a/bsp/default/spi_serprog.c b/bsp/default/spi_serprog.c
deleted file mode 100644
index ce79052..0000000
--- a/bsp/default/spi_serprog.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// vim: set et:
-
-#include "protos.h"
-#include "serprog.h"
-
-void sp_spi_init(void) { }
-
-uint32_t __not_in_flash_func(sp_spi_set_freq)(uint32_t freq_wanted) {
- (void)freq_wanted;
- return 0;
-}
-
-void __not_in_flash_func(sp_spi_cs_deselect)(void) { }
-void __not_in_flash_func(sp_spi_cs_select)(void) { }
-void __not_in_flash_func(sp_spi_op_begin)(void) { }
-void __not_in_flash_func(sp_spi_op_end)(void) { }
-
-void __not_in_flash_func(sp_spi_op_write)(uint32_t write_len, const uint8_t* write_data) {
- (void)write_len;
- (void)write_data;
-}
-void __not_in_flash_func(sp_spi_op_read)(uint32_t read_len, uint8_t* read_data) {
- (void)read_len;
- (void)read_data;
-}
-
diff --git a/bsp/default/tempsensor.c b/bsp/default/tempsensor.c
deleted file mode 100644
index 6e067a3..0000000
--- a/bsp/default/tempsensor.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// vim: set et:
-
-#include "tempsensor.h"
-
-void tempsense_dev_init(void) { }
-
-// clang-format off
-// 8.4
-int16_t tempsense_dev_get_temp (void) { return 0 << 4; }
-int16_t tempsense_dev_get_lower(void) { return trunc_8fix4(float2fix( 0)); }
-int16_t tempsense_dev_get_upper(void) { return trunc_8fix4(float2fix( 0)); }
-int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 0)); }
-// clang-format on
-
diff --git a/bsp/rp2040/DAP_config.h b/bsp/rp2040/DAP_config.h
deleted file mode 100644
index 6e323b0..0000000
--- a/bsp/rp2040/DAP_config.h
+++ /dev/null
@@ -1,625 +0,0 @@
-// vim: set et:
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2021 Peter Lawrence
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
-This DAP_config provides a CMSIS-DAP alternative to picoprobe and raspberrypi-swd.cfg
-*/
-
-#ifndef __DAP_CONFIG_H__
-#define __DAP_CONFIG_H__
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
-\ingroup DAP_ConfigIO_gr
-@{
-Provides definitions about the hardware and configuration of the Debug Unit.
-
-This information includes:
- - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit.
- - Debug Unit Identification strings (Vendor, Product, Serial Number).
- - Debug Unit communication packet size.
- - Debug Access Port supported modes and settings (JTAG/SWD and SWO).
- - Optional information about a connected Target Device (for Evaluation Boards).
-*/
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "bsp/board.h"
-#include "cmsis_compiler.h"
-#include "pinout.h"
-#include "protos.h"
-#include "util.h"
-
-#define PINOUT_SWCLK PINOUT_JTAG_TCK
-#define PINOUT_SWDIO PINOUT_JTAG_TMS
-
-#define PINOUT_SWCLK_MASK (1UL << PINOUT_SWCLK)
-#define PINOUT_SWDIO_MASK (1UL << PINOUT_SWDIO)
-
-#define PINOUT_TCK_MASK (1UL << PINOUT_JTAG_TCK)
-#define PINOUT_TMS_MASK (1UL << PINOUT_JTAG_TMS)
-#define PINOUT_TDI_MASK (1UL << PINOUT_JTAG_TDI)
-#define PINOUT_TDO_MASK (1UL << PINOUT_JTAG_TDO)
-#define PINOUT_nTRST_MASK (1UL << PINOUT_JTAG_nTRST)
-#define PINOUT_nRESET_MASK (1UL << PINOUT_JTAG_nRESET)
-
-#define PINOUT_LED_MASK (1UL << PINOUT_LED)
-
-/// 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.
-
-/// Number of processor cycles for I/O Port write operations.
-/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
-/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors
-/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses
-/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be
-/// required.
-#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0.
-
-/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available.
-
-/// Indicate that JTAG communication mode is available at the Debug Port.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available.
-
-/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port.
-/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255.
-#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain.
-
-/// Default communication mode on the Debug Access Port.
-/// Used for the command \ref DAP_Connect when Port Default mode is selected.
-#define DAP_DEFAULT_PORT 2U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
-
-/// Default communication speed on the Debug Access Port for SWD and JTAG mode.
-/// Used to initialize the default SWD/JTAG clock frequency.
-/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting.
-#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz.
-
-/// Maximum Package Size for Command and Response data.
-/// This configuration settings is used to optimize the communication performance with the
-/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or
-/// WinUSB, 1024 for High-speed USB HID and 512 for High-speed USB WinUSB.
-#define DAP_PACKET_SIZE CFG_TUD_HID_EP_BUFSIZE ///< Specifies Packet Size in bytes.
-
-/// Maximum Package Buffers for Command and Response data.
-/// This configuration settings is used to optimize the communication performance with the
-/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the
-/// setting can be reduced (valid range is 1 .. 255).
-#define DAP_PACKET_COUNT 1U ///< Specifies number of packets buffered.
-
-/// Indicate that UART Serial Wire Output (SWO) trace is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available.
-
-/// Maximum SWO UART Baudrate.
-#define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz.
-
-/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
-
-/// SWO Trace Buffer Size.
-#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n).
-
-/// SWO Streaming Trace.
-#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available.
-
-/// Indicate that UART Communication Port is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available.
-
-/// USART Driver instance number for the UART Communication Port.
-#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#).
-
-/// UART Receive Buffer Size.
-#define DAP_UART_RX_BUFFER_SIZE 64U ///< Uart Receive Buffer Size in bytes (must be 2^n).
-
-/// UART Transmit Buffer Size.
-#define DAP_UART_TX_BUFFER_SIZE 64U ///< Uart Transmit Buffer Size in bytes (must be 2^n).
-
-/// Indicate that UART Communication via USB COM Port is available.
-/// This information is returned by the command \ref DAP_Info as part of Capabilities.
-#ifdef USE_USBCDC_FOR_STDIO
-#define DAP_UART_USB_COM_PORT 1 ///< USB COM Port: 1 = available, 0 = not available.
-#else
-#define DAP_UART_USB_COM_PORT 0
-#endif
-
-/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
-#define TIMESTAMP_CLOCK 0U ///< Timestamp clock in Hz (0 = timestamps not supported).
-
-/// Debug Unit is connected to fixed Target Device.
-/// The Debug Unit may be part of an evaluation board and always connected to a fixed
-/// known device. In this case a Device Vendor and Device Name string is stored which
-/// may be used by the debugger or IDE to configure device parameters.
-#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
-
-#if TARGET_DEVICE_FIXED
-#define TARGET_DEVICE_VENDOR "Raspberry Pi" ///< String indicating the Silicon Vendor
-#define TARGET_DEVICE_NAME "Pico" ///< String indicating the Target Device
-#endif
-
-#include "DAP.h"
-
-/** Get Vendor ID string.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetVendorString(char* str) {
- static const 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.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetProductString(char* str) {
- static const 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.
-\param str Pointer to buffer to store the string.
-\return String length.
-*/
-__STATIC_INLINE uint8_t DAP_GetSerNumString(char* str) { return get_unique_id_u8((uint8_t*)str); }
-
-/** Get Target Device Vendor string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Device Name string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Board Vendor string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString(char* str) {
- (void)str;
- return 0;
-}
-
-/** Get Target Board Name string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString(char* str) {
- (void)str;
- return 0;
-}
-
-/* TODO! */
-/** Get Product Firmware Version string.
-\param str Pointer to buffer to store the string (max 60 characters).
-\return String length (including terminating NULL character) or 0 (no string).
-*/
-__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString(char* str) {
- (void)str;
- return 0;
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
-\ingroup DAP_ConfigIO_gr
-@{
-
-Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode
-and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug
-interface of a device. The following I/O Pins are provided:
-
-JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
----------------------------- | -------------------- | ---------------------------------------------
-TCK: Test Clock | SWCLK: Clock | Output Push/Pull
-TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
-TDI: Test Data Input | | Output Push/Pull
-TDO: Test Data Output | | Input
-nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
-nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
-
-
-DAP Hardware I/O Pin Access Functions
--------------------------------------
-The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to
-these I/O Pins.
-
-For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only.
-This functions are provided to achieve faster I/O that is possible with some advanced GPIO
-peripherals that can independently write/read a single I/O pin without affecting any other pins
-of the same I/O port. The following SWDIO I/O Pin functions are provided:
- - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware.
- - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware.
- - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed.
- - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed.
-*/
-
-// Configure DAP I/O pins ------------------------------
-
-/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
-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);
-
- /* set to default high level */
- sio_hw->gpio_oe_set = PINOUT_TCK_MASK | PINOUT_TMS_MASK | PINOUT_TDI_MASK | PINOUT_nTRST_MASK |
- PINOUT_nRESET_MASK;
- sio_hw->gpio_set = PINOUT_TCK_MASK | PINOUT_TMS_MASK | PINOUT_TDI_MASK | PINOUT_nTRST_MASK |
- PINOUT_nRESET_MASK;
- /* TDO needs to be an input */
- sio_hw->gpio_oe_clr = PINOUT_TDO_MASK;
-
- hw_write_masked(&padsbank0_hw->io[PINOUT_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[PINOUT_JTAG_TMS], PADS_BANK0_GPIO0_IE_BITS,
- PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TDI], PADS_BANK0_GPIO0_IE_BITS,
- PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- hw_write_masked(&padsbank0_hw->io[PINOUT_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[PINOUT_JTAG_nTRST], PADS_BANK0_GPIO0_IE_BITS,
- PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- hw_write_masked(&padsbank0_hw->io[PINOUT_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
-
- // set pin modes to general IO (SIO)
- iobank0_hw->io[PINOUT_JTAG_TCK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
- iobank0_hw->io[PINOUT_JTAG_TMS].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
- iobank0_hw->io[PINOUT_JTAG_TDI].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
- iobank0_hw->io[PINOUT_JTAG_TDO].ctrl = (GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
- /*| (GPIO_OVERRIDE_LOW << IO_BANK0_GPIO0_CTRL_OEOVER_LSB)*/;
- iobank0_hw->io[PINOUT_JTAG_nTRST].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
- iobank0_hw->io[PINOUT_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);
-
- /* set to default high level */
- sio_hw->gpio_oe_set = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK;
- sio_hw->gpio_set = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK;
-
- hw_write_masked(&padsbank0_hw->io[PINOUT_SWCLK], PADS_BANK0_GPIO0_IE_BITS,
- PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- hw_write_masked(&padsbank0_hw->io[PINOUT_SWDIO], PADS_BANK0_GPIO0_IE_BITS,
- PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- iobank0_hw->io[PINOUT_SWCLK].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
- iobank0_hw->io[PINOUT_SWDIO].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
-}
-
-/** Disable JTAG/SWD I/O Pins.
-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 = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK |
- PINOUT_TDI_MASK //| PINOUT_TDO_MASK
- | PINOUT_nTRST_MASK | PINOUT_nRESET_MASK;
-}
-
-// SWCLK/TCK I/O pin -------------------------------------
-
-/** SWCLK/TCK I/O pin: Get Input.
-\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 & PINOUT_SWCLK_MASK) >> PINOUT_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 = PINOUT_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 = PINOUT_SWCLK_MASK; }
-
-// SWDIO/TMS Pin I/O --------------------------------------
-
-/** SWDIO/TMS I/O pin: Get Input.
-\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 & PINOUT_SWDIO_MASK) >> PINOUT_SWDIO;
-}
-
-/* PIN_SWDIO_TMS_SET and PIN_SWDIO_TMS_CLR are used by SWJ_Sequence */
-
-/** 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) { sio_hw->gpio_set = PINOUT_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 = PINOUT_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 & PINOUT_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 = PINOUT_SWDIO_MASK;
- else
- sio_hw->gpio_clr = PINOUT_SWDIO_MASK;
-}
-
-/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
-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 = PINOUT_SWDIO_MASK; }
-
-/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
-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 = PINOUT_SWDIO_MASK; }
-
-// TDI Pin I/O ---------------------------------------------
-
-/** TDI I/O pin: Get Input.
-\return Current status of the TDI DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) {
- return (sio_hw->gpio_in & PINOUT_TDI_MASK) >> PINOUT_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 = PINOUT_TDI_MASK;
- else
- sio_hw->gpio_clr = PINOUT_TDI_MASK;
-}
-
-// TDO Pin I/O ---------------------------------------------
-
-/** TDO I/O pin: Get Input.
-\return Current status of the TDO DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) {
- return (sio_hw->gpio_in & PINOUT_TDO_MASK) >> PINOUT_JTAG_TDO;
-}
-
-// nTRST Pin I/O -------------------------------------------
-
-/** nTRST I/O pin: Get Input.
-\return Current status of the nTRST DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) {
- return (sio_hw->gpio_in & PINOUT_nTRST_MASK) >> PINOUT_JTAG_nTRST;
-}
-
-/** nTRST I/O pin: Set Output.
-\param bit JTAG TRST Test Reset pin status:
- - 0: issue a JTAG TRST Test Reset.
- - 1: release JTAG TRST Test Reset.
-*/
-__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) {
- if (bit & 1)
- sio_hw->gpio_set = PINOUT_nTRST_MASK;
- else
- sio_hw->gpio_clr = PINOUT_nTRST_MASK;
-}
-
-// nRESET Pin I/O------------------------------------------
-
-/** nRESET I/O pin: Get Input.
-\return Current status of the nRESET DAP hardware I/O pin.
-*/
-__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) {
- return (sio_hw->gpio_in & PINOUT_nRESET_MASK) >> PINOUT_JTAG_nRESET;
-}
-
-/** nRESET I/O pin: Set Output.
-\param bit target device hardware reset pin status:
- - 0: issue a device hardware reset.
- - 1: release device hardware reset.
-*/
-__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) {
- if (bit & 1)
- sio_hw->gpio_set = PINOUT_nRESET_MASK;
- else
- sio_hw->gpio_clr = PINOUT_nRESET_MASK;
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
-\ingroup DAP_ConfigIO_gr
-@{
-
-CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit.
-
-It is recommended to provide the following LEDs for status indication:
- - Connect LED: is active when the DAP hardware is connected to a debugger.
- - Running LED: is active when the debugger has put the target device into running state.
-*/
-
-/** Debug Unit: Set status of Connected LED.
-\param bit status of the Connect LED.
- - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
- - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
-*/
-__STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) {
-#if PINOUT_LED_CONNECTED
- if (bit & 1)
- sio_hw->gpio_set = PINOUT_LED_MASK;
- else
- sio_hw->gpio_clr = PINOUT_LED_MASK;
-#else
- (void)bit;
-#endif
-}
-
-/** Debug Unit: Set status Target Running LED.
-\param bit status of the Target Running LED.
- - 1: Target Running LED ON: program execution in target started.
- - 0: Target Running LED OFF: program execution in target stopped.
-*/
-__STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) {
-#if PINOUT_LED_RUNNING
- if (bit & 1)
- sio_hw->gpio_set = PINOUT_LED_MASK;
- else
- sio_hw->gpio_clr = PINOUT_LED_MASK;
-#else
- (void)bit;
-#endif
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
-\ingroup DAP_ConfigIO_gr
-@{
-Access function for Test Domain Timer.
-
-The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET.
-By default, the DWT timer is used. The frequency of this timer is configured with \ref
-TIMESTAMP_CLOCK.
-
-*/
-
-/** Get timestamp of Test Domain Timer.
-\return Current timestamp value.
-*/
-__STATIC_INLINE uint32_t TIMESTAMP_GET(void) {
-#if TIMESTAMP_CLOCK > 0
- return (DWT->CYCCNT);
-#else
- return 0;
-#endif
-}
-
-///@}
-
-//**************************************************************************************************
-/**
-\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
-\ingroup DAP_ConfigIO_gr
-@{
-
-CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP.
-*/
-
-/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized).
-This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the
-Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set:
- - I/O clock system enabled.
- - all I/O pins: input buffer enabled, output pins are set to HighZ mode.
- - for nTRST, nRESET a weak pull-up (if available) is enabled.
- - LED output pins are enabled and LEDs are turned off.
-*/
-__STATIC_INLINE void DAP_SETUP(void) {
- sio_hw->gpio_oe_set = PINOUT_LED_MASK;
- sio_hw->gpio_clr = PINOUT_LED_MASK;
-
- hw_write_masked(
- &padsbank0_hw->io[PINOUT_LED], 0, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
- iobank0_hw->io[PINOUT_LED].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
-
- bi_decl(bi_2pins_with_names(PINOUT_JTAG_TCK, "TCK / SWCLK", PINOUT_JTAG_TMS, "TMS / SWDIO"));
- bi_decl(bi_4pins_with_names(PINOUT_JTAG_TDI, "TDI", PINOUT_JTAG_TDO, "TDO", PINOUT_JTAG_nTRST,
- "nTRST", PINOUT_JTAG_nRESET, "nRESET"));
-}
-
-/** Reset Target Device with custom specific I/O pin or command sequence.
-This function allows the optional implementation of a device specific reset sequence.
-It is called when the command \ref DAP_ResetTarget and is for example required
-when a device needs a time-critical unlock sequence that enables the debug port.
-\return 0 = no device specific reset sequence is implemented.\n
- 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
-}
-
-///@}
-
-#endif /* __DAP_CONFIG_H__ */
diff --git a/bsp/rp2040/cdc_stdio.c b/bsp/rp2040/cdc_stdio.c
index a4e4754..d632a7f 100644
--- a/bsp/rp2040/cdc_stdio.c
+++ b/bsp/rp2040/cdc_stdio.c
@@ -7,8 +7,8 @@
#include
#include
-#include "pinout.h"
-#include "protocfg.h"
+//#include "pinout.h"
+//#include "protocfg.h"
#include "tusb.h"
#ifndef PICO_STDIO_USB_STDOUT_TIMEOUT_US
@@ -18,6 +18,7 @@
// *mostly* the same as the SDK code, *except* we have to explicitely pass the
// CDC interface number to the tusb functions, making the SDK code itself very
// non-reusable >__>
+#define CDC_N_STDIO 0
static mutex_t stdio_usb_mutex;
diff --git a/bsp/rp2040/cdc_uart.c b/bsp/rp2040/cdc_uart.c
deleted file mode 100644
index 239c239..0000000
--- a/bsp/rp2040/cdc_uart.c
+++ /dev/null
@@ -1,72 +0,0 @@
-// vim: set et:
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-#include
-#include
-
-#include "pinout.h"
-#include "protos.h"
-#include "tusb.h"
-
-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(PINOUT_UART_TX, GPIO_FUNC_UART);
- gpio_set_function(PINOUT_UART_RX, GPIO_FUNC_UART);
- uart_init(PINOUT_UART_INTERFACE, PINOUT_UART_BAUDRATE);
-
- bi_decl(bi_2pins_with_func(PINOUT_UART_TX, PINOUT_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(PINOUT_UART_INTERFACE) && (rx_len < sizeof(rx_buf))) {
- rx_buf[rx_len++] = uart_getc(PINOUT_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_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(PINOUT_UART_INTERFACE, tx_buf, tx_len);
- }
- }
-}
-
-void cdc_uart_set_hwflow(bool enable) { uart_set_hw_flow(PINOUT_UART_INTERFACE, enable, enable); }
-
-void cdc_uart_set_baudrate(uint32_t brate) {
- uart_init(PINOUT_UART_INTERFACE, brate);
-}
-
diff --git a/bsp/rp2040/i2c_tinyusb.c b/bsp/rp2040/i2c_tinyusb.c
deleted file mode 100644
index f7303f5..0000000
--- a/bsp/rp2040/i2c_tinyusb.c
+++ /dev/null
@@ -1,449 +0,0 @@
-// vim: set et:
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "i2ctinyusb.h"
-#include "pinout.h"
-#include "protocfg.h"
-
-static int delay = 10, delay2 = 5;
-
-// I2C bitbang reimpl because ugh, synopsys
-// (mostly inspired by original I2CTinyUSB AVR firmware)
-__attribute__((__always_inline__)) inline static void i2cio_set_sda(bool hi) {
- if (hi) {
- sio_hw->gpio_oe_clr = (1 << PINOUT_I2C_SDA); // SDA is input
- // => pullup configured, so it'll go high
- } else {
- sio_hw->gpio_oe_set = (1 << PINOUT_I2C_SDA); // SDA is output
- sio_hw->gpio_clr = (1 << PINOUT_I2C_SDA); // and drive it low
- }
-}
-__attribute__((__always_inline__)) inline static bool i2cio_get_sda(void) {
- return (sio_hw->gpio_in & (1 << PINOUT_I2C_SDA)) != 0;
-}
-__attribute__((__always_inline__)) inline static void i2cio_set_scl(bool hi) {
- busy_wait_us_32(delay2);
- sio_hw->gpio_oe_set = (1 << PINOUT_I2C_SCL); // SCL is output
- if (hi)
- sio_hw->gpio_set = (1 << PINOUT_I2C_SCL); // SCL is high
- else
- sio_hw->gpio_clr = (1 << PINOUT_I2C_SCL); // SCL is low
- busy_wait_us_32(delay2);
-}
-
-__attribute__((__always_inline__)) inline static void i2cio_scl_toggle(void) {
- i2cio_set_scl(true);
- i2cio_set_scl(false);
-}
-
-static void __no_inline_not_in_flash_func(i2cio_start)(void) { // start condition
- i2cio_set_sda(false);
- i2cio_set_scl(false);
-}
-static void __no_inline_not_in_flash_func(i2cio_repstart)(void) { // repstart condition
- i2cio_set_sda(true);
- i2cio_set_scl(true);
-
- i2cio_set_sda(false);
- i2cio_set_scl(false);
-}
-static void __no_inline_not_in_flash_func(i2cio_stop)(void) { // stop condition
- i2cio_set_sda(false);
- i2cio_set_scl(true);
- i2cio_set_sda(true);
-}
-
-static bool __no_inline_not_in_flash_func(i2cio_write7)(
- uint8_t v) { // return value: acked? // needed for 10bitaddr xfers
- for (int i = 6; i >= 0; --i) {
- i2cio_set_sda((v & (1 << i)) != 0);
- i2cio_scl_toggle();
- }
-
- i2cio_set_sda(true);
- i2cio_set_scl(true);
-
- bool ack = !i2cio_get_sda();
- i2cio_set_scl(false);
-
- return ack;
-}
-static bool __no_inline_not_in_flash_func(i2cio_write8)(uint8_t v) { // return value: acked?
- for (int i = 7; i >= 0; --i) {
- i2cio_set_sda((v & (1 << i)) != 0);
- i2cio_scl_toggle();
- }
-
- i2cio_set_sda(true);
- i2cio_set_scl(true);
-
- bool ack = !i2cio_get_sda();
- i2cio_set_scl(false);
-
- return ack;
-}
-static uint8_t __no_inline_not_in_flash_func(i2cio_read8)(bool last) {
- i2cio_set_sda(true);
- i2cio_set_scl(false);
-
- uint8_t rv = 0;
- for (int i = 7; i >= 0; --i) {
- i2cio_set_scl(true);
- bool c = i2cio_get_sda();
- rv <<= 1;
- if (c) rv |= 1;
- i2cio_set_scl(false);
- }
-
- if (last)
- i2cio_set_sda(true);
- else
- i2cio_set_sda(false);
-
- i2cio_scl_toggle();
- i2cio_set_sda(true);
-
- return rv;
-}
-
-// replicating/rewriting some SDK functions because they don't do what I want
-// so I'm making better ones
-
-static int __no_inline_not_in_flash_func(i2cex_probe_address)(uint16_t addr, bool a10bit) {
- // I2C pins to SIO
- gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_SIO);
- gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_SIO);
-
- int rv;
- i2cio_start();
-
- if (a10bit) {
- // A10 magic higher 2 addr bits r/#w bit
- uint8_t addr1 = 0x70 | (((addr >> 8) & 3) << 1) | 0, addr2 = addr & 0xff;
-
- if (i2cio_write7(addr1)) {
- if (i2cio_write8(addr2))
- rv = 0;
- else
- rv = PICO_ERROR_GENERIC;
- } else
- rv = PICO_ERROR_GENERIC;
- } else {
- if (i2cio_write8((addr << 1) & 0xff))
- rv = 0; // acked: ok
- else
- rv = PICO_ERROR_GENERIC; // nak :/
- }
- i2cio_stop();
-
- // I2C back to I2C
- gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C);
- gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C);
-
- return rv;
-}
-
-inline static void i2cex_abort_xfer(i2c_inst_t* i2c) {
-#if 1
- // may be bugged??? so doesnt do anything for now
- (void)i2c;
- return;
-#else
- // now do the abort
- i2c->hw->enable = 1 /*| (1<<2)*/ | (1 << 1);
- // wait for M_TX_ABRT irq
- do {
- /*if (timeout_check) {
- timeout = timeout_check(ts);
- abort |= timeout;
- }*/
- tight_loop_contents();
- } while (/*!timeout &&*/ !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS));
- // reset irq
- // if (!timeout)
- (void)i2c->hw->clr_tx_abrt;
-#endif
-}
-
-static int i2cex_write_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit,
- const uint8_t* src, size_t len, bool nostop, absolute_time_t until) {
- timeout_state_t ts_;
-
- struct timeout_state* ts = &ts_;
-
- check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until);
-
- if ((int)len < 0) return PICO_ERROR_GENERIC;
- if (a10bit) { // addr too high
- if (addr & ~(uint16_t)((1 << 10) - 1)) return PICO_ERROR_GENERIC;
- } else if (addr & 0x80)
- return PICO_ERROR_GENERIC;
-
- if (len == 0) return i2cex_probe_address(addr, a10bit);
-
- bool abort = false, timeout = false;
- uint32_t abort_reason = 0;
- int byte_ctr;
-
- i2c->hw->enable = 0;
- // enable 10bit mode if requested
- // clang-format off
- hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS,
- (a10bit ? I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_10BITS
- : I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_7BITS)
- << I2C_IC_CON_IC_10BITADDR_MASTER_LSB);
- // clang-format on
- i2c->hw->tar = addr;
- i2c->hw->enable = 1;
-
- for (byte_ctr = 0; byte_ctr < (int)len; ++byte_ctr) {
- bool first = byte_ctr == 0, last = byte_ctr == (int)len - 1;
-
- i2c->hw->data_cmd = (bool_to_bit(first && i2c->restart_on_next) << I2C_IC_DATA_CMD_RESTART_LSB)
- | (bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB)
- | *src++;
-
- do {
- if (timeout_check) {
- timeout = timeout_check(ts);
- abort |= timeout;
- }
- tight_loop_contents();
- } while (!timeout && !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_EMPTY_BITS));
-
- if (!timeout) {
- abort_reason = i2c->hw->tx_abrt_source;
- if (abort_reason) {
- (void)i2c->hw->clr_tx_abrt;
- abort = true;
- }
-
- if (abort || (last && !nostop)) {
- do {
- if (timeout_check) {
- timeout = timeout_check(ts);
- abort |= timeout;
- }
- tight_loop_contents();
- // clang-format off
- } while (!timeout && !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS));
- // clang-format on
-
- if (!timeout)
- (void)i2c->hw->clr_stop_det;
- else
- // if we had a timeout, send an abort request to the hardware,
- // so that the bus gets released
- i2cex_abort_xfer(i2c);
- }
- } else
- i2cex_abort_xfer(i2c);
-
- if (abort) break;
- }
-
- int rval;
-
- if (abort) {
- // clang-format off
- const int addr_noack = I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS
- | I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_BITS
- | I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS;
- // clang-format on
-
- if (timeout)
- rval = PICO_ERROR_TIMEOUT;
- else if (!abort_reason || (abort_reason & addr_noack))
- rval = PICO_ERROR_GENERIC;
- else if (abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS)
- rval = byte_ctr;
- else
- rval = PICO_ERROR_GENERIC;
- } else
- rval = byte_ctr;
-
- i2c->restart_on_next = nostop;
- return rval;
-}
-static int i2cex_read_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit, uint8_t* dst,
- size_t len, bool nostop, absolute_time_t until) {
- timeout_state_t ts_;
- struct timeout_state* ts = &ts_;
- check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until);
-
- if ((int)len < 0) return PICO_ERROR_GENERIC;
- if (a10bit) { // addr too high
- if (addr & ~(uint16_t)((1 << 10) - 1)) return PICO_ERROR_GENERIC;
- } else if (addr & 0x80)
- return PICO_ERROR_GENERIC;
-
- i2c->hw->enable = 0;
- // enable 10bit mode if requested
- hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS,
- (a10bit ? I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_10BITS
- : I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_7BITS)
- << I2C_IC_CON_IC_10BITADDR_MASTER_LSB);
- i2c->hw->tar = addr;
- i2c->hw->enable = 1;
-
- if (len == 0) return i2cex_probe_address(addr, a10bit);
-
- bool abort = false, timeout = false;
- uint32_t abort_reason = 0;
- int byte_ctr;
-
- for (byte_ctr = 0; byte_ctr < (int)len; ++byte_ctr) {
- bool first = byte_ctr == 0;
- bool last = byte_ctr == (int)len - 1;
-
- while (!i2c_get_write_available(i2c) && !abort) {
- tight_loop_contents();
- // ?
- if (timeout_check) {
- timeout = timeout_check(ts);
- abort |= timeout;
- }
- }
-
- if (timeout) {
- // if we had a timeout, send an abort request to the hardware,
- // so that the bus gets released
- i2cex_abort_xfer(i2c);
- }
- if (abort) break;
-
- i2c->hw->data_cmd = bool_to_bit(first && i2c->restart_on_next)
- << I2C_IC_DATA_CMD_RESTART_LSB |
- bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB |
- I2C_IC_DATA_CMD_CMD_BITS; // -> 1 for read
-
- do {
- abort_reason = i2c->hw->tx_abrt_source;
- abort = (bool)i2c->hw->clr_tx_abrt;
-
- if (timeout_check) {
- timeout = timeout_check(ts);
- abort |= timeout;
- }
- tight_loop_contents(); // ?
- } while (!abort && !i2c_get_read_available(i2c));
-
- if (timeout) {
- // if we had a timeout, send an abort request to the hardware,
- // so that the bus gets released
- i2cex_abort_xfer(i2c);
- }
- if (abort) break;
-
- uint8_t v = (uint8_t)i2c->hw->data_cmd;
- // printf("\ngot read %02x\n", v);
- *dst++ = v;
- }
-
- int rval;
-
- if (abort) {
- // printf("\ngot abrt: ");
- const int addr_noack = I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS |
- I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK_BITS |
- I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS;
-
- if (timeout) { /*printf("timeout\n");*/
- rval = PICO_ERROR_TIMEOUT;
- } else if (!abort_reason || (abort_reason & addr_noack)) { // printf("disconn\n");
- rval = PICO_ERROR_GENERIC;
- } else { /*printf("unk\n");*/
- rval = PICO_ERROR_GENERIC;
- }
- } else
- rval = byte_ctr;
-
- i2c->restart_on_next = nostop;
- return rval;
-}
-static inline int i2cex_write_timeout_us(i2c_inst_t* i2c, uint16_t addr, bool a10bit,
- const uint8_t* src, size_t len, bool nostop, uint32_t timeout_us) {
- absolute_time_t t = make_timeout_time_us(timeout_us);
- return i2cex_write_blocking_until(i2c, addr, a10bit, src, len, nostop, t);
-}
-static inline int i2cex_read_timeout_us(i2c_inst_t* i2c, uint16_t addr, bool a10bit, uint8_t* dst,
- size_t len, bool nostop, uint32_t timeout_us) {
- absolute_time_t t = make_timeout_time_us(timeout_us);
- return i2cex_read_blocking_until(i2c, addr, a10bit, dst, len, nostop, t);
-}
-
-__attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void) {
- // TODO: SMBUS_EMUL_ALL => I2C_M_RECV_LEN
- // TODO: maybe also PROTOCOL_MANGLING, NOSTART
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
-}
-
-void i2ctu_init(void) {
- // default to 100 kHz (SDK example default so should be ok)
- delay = 10;
- delay2 = 5;
- i2c_init(PINOUT_I2C_DEV, 100 * 1000);
-
- gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C);
- gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C);
- gpio_pull_up(PINOUT_I2C_SCL);
- gpio_pull_up(PINOUT_I2C_SDA);
-
- bi_decl(bi_2pins_with_func(PINOUT_I2C_SCL, PINOUT_I2C_SDA, GPIO_FUNC_I2C));
-}
-
-uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us) {
- delay = us;
- delay2 = us >> 1;
- if (!delay2) delay2 = 1;
-
- return i2c_set_baudrate(PINOUT_I2C_DEV, freq);
-}
-
-enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- const uint8_t* buf, size_t len) {
- bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END);
- bool bit10 = flags & I2C_M_TEN;
-
- /*if (len == 0) {
- // do a read, that's less hazardous
- uint8_t stuff = 0;
- int rv = i2cex_read_timeout_us(PINOUT_I2C_DEV, addr, bit10, &stuff, 1,
- nostop, 1000*1000);
- if (rv < 0) return ITU_STATUS_ADDR_NAK;
- return ITU_STATUS_ADDR_ACK;
- } else*/
- {
- int rv = i2cex_write_timeout_us(PINOUT_I2C_DEV, addr, bit10, buf, len, nostop, 1000 * 1000);
- if (rv < 0 || (size_t)rv < len) return ITU_STATUS_ADDR_NAK;
- return ITU_STATUS_ADDR_ACK;
- }
-}
-enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- uint8_t* buf, size_t len) {
- bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END);
- bool bit10 = flags & I2C_M_TEN;
-
- /*if (len == 0) {
- uint8_t stuff = 0;
- int rv = i2cex_read_timeout_us(PINOUT_I2C_DEV, addr, bit10, &stuff, 1,
- nostop, 1000*1000);
- if (rv < 0) return ITU_STATUS_ADDR_NAK;
- return ITU_STATUS_ADDR_ACK;
- } else*/
- {
- int rv = i2cex_read_timeout_us(PINOUT_I2C_DEV, addr, bit10, buf, len, nostop, 1000 * 1000);
- // printf("p le rv=%d buf=%02x ", rv, buf[0]);
- if (rv < 0 || (size_t)rv < len) return ITU_STATUS_ADDR_NAK;
- return ITU_STATUS_ADDR_ACK;
- }
-}
-
diff --git a/bsp/rp2040/pinout.h b/bsp/rp2040/pinout.h
deleted file mode 100644
index 639f88a..0000000
--- a/bsp/rp2040/pinout.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// vim: set et:
-
-#ifndef PINOUT_H_
-#define PINOUT_H_
-
-// UART config
-#define PINOUT_UART_TX 4
-#define PINOUT_UART_RX 5
-#define PINOUT_UART_CTS 10
-#define PINOUT_UART_RTS 11
-#define PINOUT_UART_INTERFACE uart1
-#define PINOUT_UART_BAUDRATE 115200
-
-// JTAG config
-#define PINOUT_JTAG_TCK 2 // == SWCLK
-#define PINOUT_JTAG_TMS 3 // == SWDIO
-#define PINOUT_JTAG_TDI 6
-#define PINOUT_JTAG_TDO 7
-#define PINOUT_JTAG_nTRST 8
-#define PINOUT_JTAG_nRESET 9
-
-// SPI config
-#define PINOUT_SPI_DEV spi1
-#define PINOUT_SPI_SCLK 14
-#define PINOUT_SPI_MOSI 15
-#define PINOUT_SPI_MISO 12
-#define PINOUT_SPI_nCS 13
-
-// I2C config
-#define PINOUT_I2C_DEV i2c0
-#define PINOUT_I2C_SCL 21
-#define PINOUT_I2C_SDA 20
-
-// LED config
-
-// you can change these two as you like
-#define PINOUT_LED_CONNECTED 1
-#define PINOUT_LED_RUNNING 0
-
-#ifndef PINOUT_LED
-#ifndef PICO_DEFAULT_LED_PIN
-#error "PICO_DEFAULT_LED_PIN is not defined, run PICOPROBE_LED= cmake"
-#elif PICO_DEFAULT_LED_PIN == -1
-#error "PICO_DEFAULT_LED_PIN is defined as -1, run PICOPROBE_LED= cmake"
-#else
-#define PINOUT_LED PICO_DEFAULT_LED_PIN
-#endif
-#endif /* PICOPROBE_LED */
-
-#endif
-
diff --git a/bsp/rp2040/protocfg.h b/bsp/rp2040/protocfg.h
index 2a709dd..f9f852d 100644
--- a/bsp/rp2040/protocfg.h
+++ b/bsp/rp2040/protocfg.h
@@ -3,38 +3,6 @@
#ifndef PROTOCFG_H_
#define PROTOCFG_H_
-#define DBOARD_HAS_UART
-#define DBOARD_HAS_CMSISDAP
-#define DBOARD_HAS_SERPROG
-#define DBOARD_HAS_I2C
-#define DBOARD_HAS_TEMPSENSOR
-
-enum {
- HID_N_CMSISDAP = 0,
-
- HID_N__NITF
-};
-enum {
- CDC_N_UART = 0,
- CDC_N_SERPROG,
-#ifdef USE_USBCDC_FOR_STDIO
- CDC_N_STDIO,
-#endif
-
- CDC_N__NITF
-};
-enum {
- VND_N__NITF = 0
-};
-
-#define CFG_TUD_HID 1
-#ifdef USE_USBCDC_FOR_STDIO
-#define CFG_TUD_CDC 3
-#else
-#define CFG_TUD_CDC 2
-#endif
-#define CFG_TUD_VENDOR 0
-
/*#define USB_VID 0x2e8a*/ /* Raspberry Pi */
#define USB_VID 0xcafe /* TinyUSB */
/*#define USB_VID 0x1209*/ /* Generic */
@@ -45,4 +13,3 @@ enum {
#define INFO_BOARDNAME "RP2040 Pico"
#endif
-
diff --git a/bsp/rp2040/spi_serprog.c b/bsp/rp2040/spi_serprog.c
deleted file mode 100644
index 9f6b7f9..0000000
--- a/bsp/rp2040/spi_serprog.c
+++ /dev/null
@@ -1,72 +0,0 @@
-// vim: set et:
-
-#include
-
-#include
-#include
-#include
-
-#include "pinout.h"
-#include "protos.h"
-#include "serprog.h"
-
-static bool cs_asserted;
-
-void sp_spi_init(void) {
- cs_asserted = false;
-
- spi_init(PINOUT_SPI_DEV, 512 * 1000); // default to 512 kHz
-
- gpio_set_function(PINOUT_SPI_MISO, GPIO_FUNC_SPI);
- gpio_set_function(PINOUT_SPI_MOSI, GPIO_FUNC_SPI);
- gpio_set_function(PINOUT_SPI_SCLK, GPIO_FUNC_SPI);
-
- // gpio_set_function(PINOUT_SPI_nCS, GPIO_FUNC_SIO);
- gpio_init(PINOUT_SPI_nCS);
- gpio_put(PINOUT_SPI_nCS, 1);
- gpio_set_dir(PINOUT_SPI_nCS, GPIO_OUT);
-
- bi_decl(bi_3pins_with_func(PINOUT_SPI_MISO, PINOUT_SPI_MOSI, PINOUT_SPI_SCLK, GPIO_FUNC_SPI));
- bi_decl(bi_1pin_with_name(PINOUT_SPI_nCS, "SPI #CS"));
-}
-uint32_t __not_in_flash_func(sp_spi_set_freq)(uint32_t freq_wanted) {
- return spi_set_baudrate(PINOUT_SPI_DEV, freq_wanted);
-}
-void __not_in_flash_func(sp_spi_cs_deselect)(void) {
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- gpio_put(PINOUT_SPI_nCS, 1);
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- cs_asserted = false;
-}
-void __not_in_flash_func(sp_spi_cs_select)(void) {
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- gpio_put(PINOUT_SPI_nCS, 0);
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- cs_asserted = true;
-}
-
-void __not_in_flash_func(sp_spi_op_begin)(void) {
- // sp_spi_cs_select();
- if (!cs_asserted) {
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- gpio_put(PINOUT_SPI_nCS, 0);
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- }
-}
-void __not_in_flash_func(sp_spi_op_end)(void) {
- // sp_spi_cs_deselect();
- if (!cs_asserted) { // YES, this condition is the intended one!
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- gpio_put(PINOUT_SPI_nCS, 1);
- asm volatile("nop\nnop\nnop"); // idk if this is needed
- }
-}
-
-// TODO: use dma?
-void __not_in_flash_func(sp_spi_op_write)(uint32_t write_len, const uint8_t* write_data) {
- spi_write_blocking(PINOUT_SPI_DEV, write_data, write_len);
-}
-void __not_in_flash_func(sp_spi_op_read)(uint32_t read_len, uint8_t* read_data) {
- spi_read_blocking(PINOUT_SPI_DEV, 0, read_data, read_len);
-}
-
diff --git a/bsp/rp2040/tempsensor.c b/bsp/rp2040/tempsensor.c
deleted file mode 100644
index d9fbce2..0000000
--- a/bsp/rp2040/tempsensor.c
+++ /dev/null
@@ -1,51 +0,0 @@
-// vim: set et:
-
-#include "tempsensor.h"
-
-#include
-
-#define T_SLOPE (-0.001721f)
-#define T_BIAS (0.706f)
-#define V_MAX (3.3f)
-#define D_RANGE (4096)
-#define T_OFF (27)
-
-// convert float to x.4 fixed format
-#define float2fix(x) (int)((x) * (1 << 4))
-
-// convert x.4 fixed to 8.4 fixed
-__attribute__((__const__)) inline static int16_t trunc_8fix4(int fix) {
- // clang-format off
- if (fix > 4095) fix = 4095;
- if (fix < -4096) fix = -4096;
- // clang-format on
- return fix;
-}
-
-void tempsense_dev_init(void) {
- adc_init();
- adc_set_temp_sensor_enabled(true);
-}
-// 8.4
-int16_t tempsense_dev_get_temp(void) {
- adc_select_input(4); // select temp sensor
- uint16_t result = adc_read();
-
- float voltage = result * (V_MAX / D_RANGE);
-
- float tempf = T_OFF + (voltage - T_BIAS) / T_SLOPE;
-
- // FIXME: use fixed point instead! but something's wrong with the formula below
- /*int temperature = float2fix(T_OFF - T_BIAS / T_SLOPE)
- + (int)result * float2fix(V_MAX / (D_RANGE * T_SLOPE));*/
-
- return trunc_8fix4(/*temperature*/ float2fix(tempf));
-}
-
-// RP2040 absolute min/max are -20/85
-// clang-format off
-int16_t tempsense_dev_get_lower(void) { return trunc_8fix4(float2fix(-15)); }
-int16_t tempsense_dev_get_upper(void) { return trunc_8fix4(float2fix( 75)); }
-int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 80)); }
-// clang-format on
-
diff --git a/libco/libco.S b/libco/libco.S
index 9a349fe..85ad0d9 100644
--- a/libco/libco.S
+++ b/libco/libco.S
@@ -84,6 +84,7 @@ co_switch:@(cothread_t handle r0)
ldmia r0!, {r4-r7}
ldr r2, [r0, #(0x28-0x10)] @ pc
+ @ldr r0, [r0, #(0x2c-0x10)] @ ud/r0 / retval
mov pc, r2
bx lr
@@ -94,9 +95,11 @@ co_switch:@(cothread_t handle r0)
.type co_derive, %function
.thumb_func
.global co_derive
-co_derive:@(void* memory r0, unsigned int size r1, void(*entrypoint)(void) r2)
+co_derive:@(void* memory r0, unsigned int size r1, void(*entrypoint)(void*) r2, void* ud r3)
push {r4}
+ @mov r12, r3 @ save ud for later
+
@ if (!co_active_handle) co_active_handle = &co_active_buffer
ldr r3, =co_active_handle
ldr r4, [r3]
@@ -117,8 +120,9 @@ co_derive:@(void* memory r0, unsigned int size r1, void(*entrypoint)(void) r2)
@ p(r3) = handle(r0) + offset(r3)
add r3, r0
@ initialize stack, entrypoint
- str r3, [r0, #( 9*4)]
- str r2, [r0, #(10*4)]
+ @str r12, [r0, #(11*4)] @ init r0: user argument
+ str r3 , [r0, #( 9*4)] @ init sp/r13
+ str r2 , [r0, #(10*4)] @ init pc/r15
.Lret:
pop {r4}
diff --git a/libco/libco.h b/libco/libco.h
index d9cddca..a787b9c 100644
--- a/libco/libco.h
+++ b/libco/libco.h
@@ -8,8 +8,8 @@
typedef void* cothread_t;
cothread_t co_active(void);
-cothread_t co_derive(void* memory, unsigned int heapsize, void (*coentry)(void));
-void co_switch(cothread_t);
+cothread_t co_derive(void* memory, unsigned int heapsize, void (*coentry)(void/***/)/*, void* ud*/);
+void co_switch(cothread_t); // should we make this return void* (and thus `ud`)?
int co_serializable(void);
#endif
diff --git a/src/cdc_serprog.c b/src/cdc_serprog.c
deleted file mode 100644
index 4da9993..0000000
--- a/src/cdc_serprog.c
+++ /dev/null
@@ -1,242 +0,0 @@
-// vim: set et:
-
-#include
-
-#include "protocfg.h"
-#include "tusb.h"
-
-#ifdef DBOARD_HAS_SERPROG
-
-#include "protos.h"
-#include "rtconf.h"
-#include "serprog.h"
-#include "util.h"
-
-// TODO: refactor some of this stuff into another header & split off serprog
-// protocol handling from the SPI stuff. one thing we should think about
-// when performing this refactor is, would other boards support
-// parallell, LPC, or FWH, or only SPI? if only SPI, the entire proto
-// handler can just be made reusable verbatim.
-
-// kinda refactored this already but it still has a good note for non-SPI stuff,
-// so leaving it here for now
-
-// clang-format off
-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, // 4<0..47
- 0, // 48..4f
- (1 << 3), // 50..57: enable 0x53
- 0, // 58..5f
- 0, // rest is 0
-};
-// clang-format on
-static const char serprog_pgmname[16] = INFO_PRODUCT_BARE;
-
-static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
-static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
-
-static uint32_t rxavail, rxpos;
-
-void cdc_serprog_init(void) {
- rxavail = 0;
- rxpos = 0;
-
- 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;
- }
-
- rxpos = 0;
- rxavail = tud_cdc_n_read(CDC_N_SERPROG, rx_buf, sizeof rx_buf);
-
- if (rxavail == 0) thread_yield();
- }
-
- uint8_t rv = rx_buf[rxpos];
- ++rxpos;
- --rxavail;
- return rv;
-}
-
-static void handle_cmd(void) {
- uint32_t nresp = 0;
-
- 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;
-
- case S_CMD_SPIOP: {
- uint32_t slen, rlen;
-
- // clang-format off
- 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;
- // clang-format on
-
- sp_spi_op_begin();
- size_t this_batch;
-
- // 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;
-
- for (size_t i = 0; i < this_batch; ++i) tx_buf[i] = read_byte();
- sp_spi_op_write(this_batch, tx_buf);
-
- slen -= this_batch;
- }
-
- // 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;
-
- // now do in batches of 64
- while (rlen > 0) {
- this_batch = sizeof(tx_buf);
- if (this_batch > rlen) this_batch = rlen;
-
- sp_spi_op_read(this_batch, tx_buf);
- tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch);
-
- rlen -= this_batch;
- }
- tud_cdc_n_write_flush(CDC_N_SERPROG);
-
- // 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;
- // clang-format off
- freq = (uint32_t)read_byte();
- freq |= (uint32_t)read_byte() << 8;
- freq |= (uint32_t)read_byte() << 16;
- freq |= (uint32_t)read_byte() << 24;
- // clang-format on
-
- 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();
-
- tx_buf[0] = S_ACK;
- 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:
- 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);
- }
-}
-
-void cdc_serprog_task(void) { handle_cmd(); }
-
-#endif /* DBOARD_HAS_SERPROG */
-
diff --git a/src/i2ctinyusb.h b/src/i2ctinyusb.h
deleted file mode 100644
index 7171625..0000000
--- a/src/i2ctinyusb.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// vim: set et:
-
-#ifndef I2CTINYUSB_H_
-#define I2CTINYUSB_H_
-
-#include
-#include
-#include
-
-#include "protocfg.h"
-
-enum itu_command {
- ITU_CMD_ECHO = 0,
- ITU_CMD_GET_FUNC = 1,
- ITU_CMD_SET_DELAY = 2,
- ITU_CMD_GET_STATUS = 3,
-
- ITU_CMD_I2C_IO_BEGIN_F = (1 << 0),
- ITU_CMD_I2C_IO_END_F = (1 << 1),
- ITU_CMD_I2C_IO_DIR_MASK = ITU_CMD_I2C_IO_BEGIN_F | ITU_CMD_I2C_IO_END_F,
-
- ITU_CMD_I2C_IO = 4,
- ITU_CMD_I2C_IO_BEGIN = 4 | ITU_CMD_I2C_IO_BEGIN_F,
- ITU_CMD_I2C_IO_END = 4 | ITU_CMD_I2C_IO_END_F,
- ITU_CMD_I2C_IO_BEGINEND = 4 | ITU_CMD_I2C_IO_BEGIN_F | ITU_CMD_I2C_IO_END_F,
-};
-
-enum itu_status { ITU_STATUS_IDLE = 0, ITU_STATUS_ADDR_ACK = 1, ITU_STATUS_ADDR_NAK = 2 };
-
-// these two are lifted straight from the linux kernel, lmao
-enum ki2c_flags {
- I2C_M_RD = 0x0001, /* guaranteed to be 0x0001! */
- I2C_M_TEN = 0x0010, /* use only if I2C_FUNC_10BIT_ADDR */
- I2C_M_DMA_SAFE = 0x0200, /* use only in kernel space */
- I2C_M_RECV_LEN = 0x0400, /* use only if I2C_FUNC_SMBUS_READ_BLOCK_DATA */
- I2C_M_NO_RD_ACK = 0x0800, /* use only if I2C_FUNC_PROTOCOL_MANGLING */
- I2C_M_IGNORE_NAK = 0x1000, /* use only if I2C_FUNC_PROTOCOL_MANGLING */
- I2C_M_REV_DIR_ADDR = 0x2000, /* use only if I2C_FUNC_PROTOCOL_MANGLING */
- I2C_M_NOSTART = 0x4000, /* use only if I2C_FUNC_NOSTART */
- I2C_M_STOP = 0x8000, /* use only if I2C_FUNC_PROTOCOL_MANGLING */
-};
-
-enum ki2c_funcs {
- I2C_FUNC_I2C = 0x00000001,
- I2C_FUNC_10BIT_ADDR = 0x00000002, /* required for I2C_M_TEN */
- I2C_FUNC_PROTOCOL_MANGLING = 0x00000004, /* required for I2C_M_IGNORE_NAK etc. */
- I2C_FUNC_SMBUS_PEC = 0x00000008,
- I2C_FUNC_NOSTART = 0x00000010, /* required for I2C_M_NOSTART */
- I2C_FUNC_SLAVE = 0x00000020,
- I2C_FUNC_SMBUS_BLOCK_PROC_CALL = 0x00008000, /* SMBus 2.0 or later */
- I2C_FUNC_SMBUS_QUICK = 0x00010000,
- I2C_FUNC_SMBUS_READ_BYTE = 0x00020000,
- I2C_FUNC_SMBUS_WRITE_BYTE = 0x00040000,
- I2C_FUNC_SMBUS_READ_BYTE_DATA = 0x00080000,
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA = 0x00100000,
- I2C_FUNC_SMBUS_READ_WORD_DATA = 0x00200000,
- I2C_FUNC_SMBUS_WRITE_WORD_DATA = 0x00400000,
- I2C_FUNC_SMBUS_PROC_CALL = 0x00800000,
- I2C_FUNC_SMBUS_READ_BLOCK_DATA = 0x01000000, /* required for I2C_M_RECV_LEN */
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA = 0x02000000,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK = 0x04000000, /* I2C-like block xfer */
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK = 0x08000000, /* w/ 1-byte reg. addr. */
- I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 = 0x10000000, /* I2C-like block xfer */
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 = 0x20000000, /* w/ 2-byte reg. addr. */
- I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC = 0x40000000, /* SMBus 2.0 or later */
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC = 0x80000000, /* SMBus 2.0 or later */
-
- I2C_FUNC_SMBUS_BYTE = (I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE),
- I2C_FUNC_SMBUS_BYTE_DATA = (I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA),
- I2C_FUNC_SMBUS_WORD_DATA = (I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA),
- I2C_FUNC_SMBUS_BLOCK_DATA = (I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA),
- I2C_FUNC_SMBUS_I2C_BLOCK = (I2C_FUNC_SMBUS_READ_I2C_BLOCK | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK),
-
- I2C_FUNC_SMBUS_EMUL = (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL |
- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK |
- I2C_FUNC_SMBUS_PEC),
-
- /* if I2C_M_RECV_LEN is also supported */
- I2C_FUNC_SMBUS_EMUL_ALL =
- (I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL),
-};
-
-__attribute__((__packed__)) struct itu_cmd {
- uint16_t flags;
- uint16_t addr;
- uint16_t len;
- uint8_t cmd;
-};
-
-#ifdef DBOARD_HAS_I2C
-__attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void);
-void i2ctu_init(void);
-uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us); // returns selected frequency, or 0 on error
-enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- const uint8_t* buf, size_t len);
-enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
- uint8_t* buf, size_t len);
-#endif
-
-#endif
-
diff --git a/src/m_default/0def.c b/src/m_default/0def.c
new file mode 100644
index 0000000..1cff5f3
--- /dev/null
+++ b/src/m_default/0def.c
@@ -0,0 +1,257 @@
+// vim: set et:
+
+#include
+
+#include "mode.h"
+#include "vnd_cfg.h"
+
+#include "protocfg.h"
+#include "util.h"
+
+void enter_cb(void) {
+ // TODO: init hw
+}
+void leave_cb(void) {
+ // TODO: deinit hw
+}
+
+void task_cb(void) {
+ // TODO: do stuff
+}
+
+void handle_cmd_cb(uint8_t cmd) {
+ uint8_t resp = 0;
+
+ switch (cmd) {
+ case mode_cmd_get_features:
+ vnd_cfg_write_resp(cfg_resp_ok, 1, &resp);
+ break;
+ default:
+ vnd_cfg_write_resp(cfg_resp_illcmd, 0, NULL);
+ break;
+ }
+}
+
+#define USB_BCD_BASE 0x8000
+#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
+#define USB_BCD \
+ (USB_BCD_BASE | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 3) | _PID_MAP(HID, 6) | _PID_MAP(MIDI, 9) | \
+ _PID_MAP(VENDOR, 12)) \
+
+
+enum {
+ STRID_LANGID = 0,
+ STRID_MANUFACTURER,
+ STRID_PRODUCT,
+ STRID_SERIAL,
+
+ STRID_CONFIG,
+
+ STRID_IF_VND_CFG,
+ STRID_IF_CDC_STDIO,
+};
+enum {
+ ITF_NUM_VND_CFG,
+//#ifdef USE_USBCDC_FOR_STDIO
+ ITF_NUM_CDC_STDIO_COM,
+ ITF_NUM_CDC_STDIO_DATA,
+//#endif
+
+ ITF_NUM__TOTAL
+};
+enum {
+ CONFIG_TOTAL_LEN
+ = TUD_CONFIG_DESC_LEN
+ + TUD_VENDOR_DESC_LEN
+//#ifdef USE_USBCDC_FOR_STDIO
+ + TUD_CDC_DESC_LEN
+//#endif
+};
+
+#define EPNUM_CDC_STDIO_OUT 0x03
+#define EPNUM_CDC_STDIO_IN 0x83
+#define EPNUM_CDC_STDIO_NOTIF 0x84
+
+// TODO: are these ok numbers?
+#define EPNUM_VND_CFG_OUT 0x02
+#define EPNUM_VND_CFG_IN 0x82
+
+// clang-format off
+static const tusb_desc_device_t 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 = USB_VID,
+ .idProduct = USB_PID,
+ .bcdDevice = USB_BCD,
+
+ .iManufacturer = STRID_MANUFACTURER,
+ .iProduct = STRID_PRODUCT,
+ .iSerialNumber = STRID_SERIAL,
+
+ .bNumConfigurations = 0x01
+};
+
+static const uint8_t desc_hid_report[] = {
+#if CFG_TUD_HID > 0
+ TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)
+#else
+ 0
+#endif
+};
+
+static const uint8_t desc_configuration[] = {
+ TUD_CONFIG_DESCRIPTOR(1, ITF_NUM__TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN,
+ TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
+
+ TUD_VENDOR_DESCRIPTOR(ITF_NUM_VND_CFG, STRID_IF_VND_CFG, EPNUM_VND_CFG_OUT,
+ EPNUM_VND_CFG_IN, 64),
+
+//#ifdef USE_USBCDC_FOR_STDIO
+ 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
+};
+static const char* string_desc_arr[] = {
+ [STRID_LANGID] = (const char[]){0x09, 0x04}, // supported language is English (0x0409)
+ [STRID_MANUFACTURER] = "BLAHAJ CTF", // Manufacturer
+ [STRID_PRODUCT] = "Dragnbus (RP2040 Pico)", // Product
+
+ [STRID_CONFIG] = "Configuration descriptor",
+ // max string length check: |||||||||||||||||||||||||||||||
+ [STRID_IF_VND_CFG ] = "Device cfg/ctl interface",
+ [STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)",
+};
+// clang-format on
+
+// tinyusb callbacks
+
+#if CFG_TUD_HID > 0
+// 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
+static uint16_t hid_get_report_cb(uint8_t instance, uint8_t report_id,
+ hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
+ (void)instance;
+ (void)report_id;
+ (void)report_type;
+ (void)buffer;
+ (void)reqlen;
+
+ return 0;
+}
+static void 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;
+
+ tud_hid_report(0, TxDataBuffer, response_size);
+}
+#endif
+static void cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) {
+ (void)itf;
+ (void)line_coding;
+}
+static bool vendor_control_xfer_cb(uint8_t rhport, uint8_t ep_addr,
+ tusb_control_request_t const* req) {
+ (void)rhport;
+ (void)ep_addr;
+ (void)req;
+
+ return true;
+}
+
+// Invoked when received GET HID REPORT DESCRIPTOR
+// Application return pointer to descriptor
+// Descriptor contents must exist long enough for transfer to complete
+static const uint8_t* hid_descriptor_report_cb(uint8_t instance) {
+ (void)instance;
+
+ return desc_hid_report;
+}
+// Invoked when received GET DEVICE DESCRIPTOR
+// Application return pointer to descriptor
+static const uint8_t* descriptor_device_cb(void) {
+ return (const uint8_t*)&desc_device;
+}
+// Invoked when received GET CONFIGURATION DESCRIPTOR
+// Application return pointer to descriptor
+// Descriptor contents must exist long enough for transfer to complete
+static const uint8_t* descriptor_configuration_cb(uint8_t index) {
+ (void)index; // for multiple configurations
+
+ return desc_configuration;
+}
+// Invoked when received GET STRING DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to
+// complete
+static const uint16_t* descriptor_string_cb(uint8_t index, uint16_t langid) {
+ static uint16_t _desc_str[32];
+
+ (void)langid;
+
+ uint8_t chr_count = 0;
+
+ 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
+
+ if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL;
+
+ const char* str = string_desc_arr[index];
+
+ // Cap at max char
+ chr_count = TU_MIN(strlen(str), 31);
+
+ // Convert ASCII string into UTF-16
+ for (int i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; }
+ }
+
+ // 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;
+}
+
+
+extern struct mode m_01_default;
+// clang-format off
+struct mode m_01_default = {
+ .name = "Default mode with misc features",
+ .usb_desc = desc_configuration,
+ .version = 0x0010,
+
+ .enter = enter_cb,
+ .leave = leave_cb,
+ .task = task_cb,
+ .handle_cmd = handle_cmd_cb,
+
+#if CFG_TUD_HID > 0
+ .tud_hid_get_report_cb = hid_get_report_cb,
+ .tud_hid_set_report_cb = hid_set_report_cb,
+#endif
+ .tud_cdc_line_coding_cb = cdc_line_coding_cb,
+ .tud_vendor_control_xfer_cb = vendor_control_xfer_cb,
+
+ .tud_hid_descriptor_report_cb = hid_descriptor_report_cb,
+ .tud_descriptor_device_cb = descriptor_device_cb,
+ .tud_descriptor_configuration_cb = descriptor_configuration_cb,
+ .tud_descriptor_string_cb = descriptor_string_cb,
+};
+// clang-format on
+
diff --git a/src/main.c b/src/main.c
index 8278f15..dc9e0d9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,169 +1,61 @@
// vim: set et:
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-#include
-#include
-#include
+#include
-// include order is sensitive here
-// clang-format off
#include "tusb_config.h"
-
#include "bsp/board.h" /* a tinyusb header */
#include "tusb.h"
-#include "DAP_config.h" /* ARM code *assumes* this is included prior to DAP.h */
-#include "DAP.h"
+#include "mode.h"
+#include "thread.h"
+#include "vnd_cfg.h"
-#include "util.h"
-#include "protocfg.h"
-#include "protos.h"
-#include "libco.h"
-// clang-format on
+static cothread_t vndcfg_thread;
+static uint8_t vndcfg_stack[THREAD_STACK_SIZE];
-#ifdef PICO_BOARD
-#include
+#ifdef USE_USBCDC_FOR_STDIO
+void stdio_usb_init(void);
#endif
-static cothread_t mainthread;
-
-void thread_yield(void) { 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();
+static void vndcfg_thread_fn(void) {
+ vnd_cfg_init();
thread_yield();
while (1) {
- cdc_uart_task();
+ vnd_cfg_task();
thread_yield();
}
}
-#endif
-#ifdef DBOARD_HAS_SERPROG
-static cothread_t serprogthread;
-static uint8_t serprogstack[DEFAULT_STACK_SIZE];
+int main() {
+ thread_init();
-static void serprog_thread_fn(void) {
- cdc_serprog_init();
- thread_yield();
- while (1) {
- cdc_serprog_task();
- thread_yield();
- }
-}
-#endif
+ board_init(); // tinyusb hardware support function
-// 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;
+ vndcfg_thread = co_derive(vndcfg_stack, sizeof vndcfg_stack, vndcfg_thread_fn);
+ co_switch(vndcfg_thread);
-int main(void) {
- mainthread = co_active();
-
- // 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));
-#endif
- 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
-#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_CMSISDAP
- DAP_Setup();
-#endif
+ modes_init();
+ if (mode_current) mode_current->enter();
tusb_init();
+ // FIXME: put elsewhere?
#ifdef USE_USBCDC_FOR_STDIO
stdio_usb_init();
#endif
while (1) {
- tud_task(); // tinyusb device task
-#ifdef DBOARD_HAS_UART
- co_switch(uartthread);
-#endif
+ tud_task();
+ if (mode_current) mode_current->task();
- tud_task(); // tinyusb device task
-#ifdef DBOARD_HAS_SERPROG
- co_switch(serprogthread);
-#endif
+ tud_task();
+ co_switch(vndcfg_thread);
+
+ // do this here instead of in a callback or in the vnd_cfg_task fn
+ if (mode_next_id != -1) {
+ modes_switch(mode_next_id);
+ mode_next_id = -1;
+ }
}
-
- return 0;
-}
-
-//--------------------------------------------------------------------+
-// USB HID
-//--------------------------------------------------------------------+
-
-// 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;
-
- 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);
-
- // 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);
-#endif
-
- tud_hid_report(0, TxDataBuffer, response_size);
}
diff --git a/src/mode.h b/src/mode.h
new file mode 100644
index 0000000..dd9195d
--- /dev/null
+++ b/src/mode.h
@@ -0,0 +1,59 @@
+// vim: set et:
+
+#ifndef MODE_H_
+#define MODE_H_
+
+#include
+#include
+
+#include "tusb_config.h"
+#include
+
+// clang-format off
+
+struct mode {
+ const char* name;
+ const uint8_t* usb_desc;
+ uint16_t version;
+
+ void (*enter)(void); // claim required hardware. no tusb calls here please
+ void (*leave)(void); // release current in-use hardware. no tusb calls here please
+ void (*task )(void);
+ void (*handle_cmd)(uint8_t cmd); // handle a command coming from the vnd_cfg itf
+
+ // tinyusb callbacks
+#if CFG_TUD_HID > 0
+ 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);
+ void (*tud_hid_set_report_cb)(uint8_t instance, uint8_t report_id,
+ hid_report_type_t report_type, uint8_t const* rxbuf, uint16_t bufsize);
+#endif
+#if CFG_TUD_CDC > 0
+ void (*tud_cdc_line_coding_cb)(uint8_t itf, cdc_line_coding_t const* line_coding);
+#endif
+#if CFG_TUD_VENDOR > 0
+ bool (*tud_vendor_control_xfer_cb)(uint8_t rhport, uint8_t ep_addr,
+ tusb_control_request_t const* req);
+#endif
+
+ uint8_t const* (*tud_hid_descriptor_report_cb)(uint8_t instance);
+ uint8_t const* (*tud_descriptor_device_cb)(void);
+ uint8_t const* (*tud_descriptor_configuration_cb)(uint8_t index);
+ uint16_t const* (*tud_descriptor_string_cb)(uint8_t index, uint16_t langid);
+};
+
+// call this BEFORE tusb_init!
+void modes_init(void);
+
+void modes_switch(uint8_t newmode);
+
+extern int mode_current_id;
+extern int mode_next_id;
+extern const struct mode* mode_list[16];
+#define mode_default (mode_list[1])
+#define mode_current (((mode_current_id)==-1)?NULL:(mode_list[mode_current_id]))
+
+// clang-format on
+
+#endif
+
diff --git a/src/modeset.c b/src/modeset.c
new file mode 100644
index 0000000..845614e
--- /dev/null
+++ b/src/modeset.c
@@ -0,0 +1,112 @@
+// vim: set et:
+
+#include "mode.h"
+
+extern struct mode m_01_default;
+
+// clang-format off
+const struct mode* mode_list[16] = {
+ NULL, // dummy 0 entry
+ &m_01_default,
+ NULL, // terminating entry
+
+};
+// clang-format on
+
+int mode_current_id = 1;
+int mode_next_id = -1;
+
+extern void* tusb_got[];
+
+enum tusbgot_index {
+ tusbgot_hid_get_report = 0,
+ tusbgot_hid_set_report,
+ tusbgot_cdc_line_coding,
+ tusbgot_vendor_control_xfer,
+ tusbgot_hid_descriptor_report,
+ tusbgot_descriptor_device,
+ tusbgot_descriptor_configuration,
+ tusbgot_descriptor_string
+};
+
+void modes_init(void) {
+ // switch to the default mode, but without doing a USB reboot thing
+ mode_current_id = &mode_default - mode_list;
+ mode_next_id = -1;
+
+ if (!mode_default) return;
+
+ // clang-format off
+#if CFG_TUD_HID > 0
+ tusb_got[tusbgot_hid_get_report ] = mode_default->tud_hid_get_report_cb;
+ tusb_got[tusbgot_hid_set_report ] = mode_default->tud_hid_set_report_cb;
+#else
+ tusb_got[tusbgot_hid_get_report ] = NULL;
+ tusb_got[tusbgot_hid_set_report ] = NULL;
+#endif
+#if CFG_TUD_CDC > 0
+ tusb_got[tusbgot_cdc_line_coding ] = mode_default->tud_cdc_line_coding_cb;
+#else
+ tusb_got[tusbgot_cdc_line_coding ] = NULL;
+#endif
+#if CFG_TUD_VENDOR > 0
+ tusb_got[tusbgot_vendor_control_xfer] = mode_default->tud_vendor_control_xfer_cb;
+#else
+ tusb_got[tusbgot_vendor_control_xfer] = NULL;
+#endif
+
+ tusb_got[tusbgot_hid_descriptor_report ] = mode_default->tud_hid_descriptor_report_cb;
+ tusb_got[tusbgot_descriptor_device ] = mode_default->tud_descriptor_device_cb;
+ tusb_got[tusbgot_descriptor_configuration] = mode_default->tud_descriptor_configuration_cb;
+ tusb_got[tusbgot_descriptor_string ] = mode_default->tud_descriptor_string_cb;
+ // clang-format on
+}
+void modes_switch(uint8_t newmode) {
+ if (mode_current) mode_current->leave();
+
+ // to force a reconfig from the device, we basically have to kill the USB
+ // physical connection for a while
+ tud_disconnect();
+
+ // maybe wait a second or so for the host to notice this
+ sleep_ms(750);
+
+ // now apply the new tusb settings
+ mode_current_id = (newmode >= 16 || newmode == 0) ? (-1) : newmode;
+ //mode_next_id = -1;
+ if (mode_current) {
+ // clang-format off
+#if CFG_TUD_HID > 0
+ tusb_got[tusbgot_hid_get_report ] = mode_current->tud_hid_get_report_cb;
+ tusb_got[tusbgot_hid_set_report ] = mode_current->tud_hid_set_report_cb;
+#else
+ tusb_got[tusbgot_hid_get_report ] = NULL;
+ tusb_got[tusbgot_hid_set_report ] = NULL;
+#endif
+#if CFG_TUD_CDC > 0
+ tusb_got[tusbgot_cdc_line_coding ] = mode_current->tud_cdc_line_coding_cb;
+#else
+ tusb_got[tusbgot_cdc_line_coding ] = NULL;
+#endif
+#if CFG_TUD_VENDOR > 0
+ tusb_got[tusbgot_vendor_control_xfer] = mode_current->tud_vendor_control_xfer_cb;
+#else
+ tusb_got[tusbgot_vendor_control_xfer] = NULL;
+#endif
+
+ tusb_got[tusbgot_hid_descriptor_report ] = mode_current->tud_hid_descriptor_report_cb;
+ tusb_got[tusbgot_descriptor_device ] = mode_current->tud_descriptor_device_cb;
+ tusb_got[tusbgot_descriptor_configuration] = mode_current->tud_descriptor_configuration_cb;
+ tusb_got[tusbgot_descriptor_string ] = mode_current->tud_descriptor_string_cb;
+ // clang-format on
+ } else {
+ // TODO: invalid mode???
+ }
+
+ // and reconnect
+ tud_connect();
+ while (!tud_mounted()) sleep_ms(5);
+
+ if (mode_current) mode_current->enter();
+}
+
diff --git a/src/protos.h b/src/protos.h
deleted file mode 100644
index 06d8fb8..0000000
--- a/src/protos.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// vim: set et:
-
-#ifndef PROTOS_H_
-#define PROTOS_H_
-
-#include
-#include
-
-#include "protocfg.h"
-
-#define INFO_MANUFACTURER "BLAHAJ CTF"
-#define INFO_PRODUCT_BARE "Dragnbus"
-#define INFO_PRODUCT(board) "Dragnbus (" board ")"
-
-#ifdef DBOARD_HAS_UART
-void cdc_uart_init(void);
-void cdc_uart_task(void);
-
-void cdc_uart_set_hwflow(bool enable);
-void cdc_uart_set_baudrate(uint32_t brate);
-#endif
-
-#ifdef DBOARD_HAS_SERPROG
-void cdc_serprog_init(void);
-void cdc_serprog_task(void);
-#endif
-
-#ifdef USE_USBCDC_FOR_STDIO
-//#ifdef PICO_BOARD
-bool stdio_usb_init(void);
-//#endif
-#endif
-
-#ifdef DBOARD_HAS_I2C
-void itu_init(void);
-void itu_task(void);
-#endif
-
-#endif
-
diff --git a/src/rtconf.c b/src/rtconf.c
deleted file mode 100644
index 1eb6bfa..0000000
--- a/src/rtconf.c
+++ /dev/null
@@ -1,58 +0,0 @@
-// vim: set et:
-
-#include "rtconf.h"
-
-#include
-#include
-
-#include "protos.h"
-#include "tempsensor.h"
-
-enum {
- implmap_val = 0
-#ifdef DBOARD_HAS_CMSISDAP
- | 1
-#endif
-#ifdef DBOARD_HAS_UART
- | 2
-#endif
-#ifdef DBOARD_HAS_SERPROG
- | 4
-#endif
-#ifdef DBOARD_HAS_I2C
- | 4
-#endif
-#ifdef DBOARD_HAS_TEMPSENSOR
- | 8
-#endif
-
-#ifdef USE_USBCDC_FOR_STDIO
- | 128
-#endif
-};
-
-uint8_t rtconf_do(uint8_t a, uint8_t b) {
- switch ((enum rtconf_opt)a) {
-#ifdef DBOARD_HAS_UART
- case opt_uart_hwfc_endis: cdc_uart_set_hwflow(b != 0); return 0;
-#endif
-#ifdef DBOARD_HAS_TEMPSENSOR
- case opt_tempsense_enaddr: {
- bool act = tempsense_get_active();
- uint8_t addr = tempsense_get_addr();
- printf("act=%c addr=%02x arg=%02x\n", act ? 't' : 'f', addr, b);
- uint8_t rv = tempsense_get_active() ? tempsense_get_addr() : 0xff;
- if (b == 0x00)
- return rv;
- else if (b == 0xff)
- tempsense_set_active(false);
- else
- tempsense_set_addr(b);
- return rv;
- }
-#endif
- case opt_get_implmap: return implmap_val;
- default: return 0xff;
- }
-}
-
diff --git a/src/rtconf.h b/src/rtconf.h
deleted file mode 100644
index 7e71a86..0000000
--- a/src/rtconf.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// vim: set et:
-
-#ifndef RTCONF_H_
-#define RTCONF_H_
-
-#include
-
-#include "protocfg.h"
-
-enum rtconf_opt {
-#ifdef DBOARD_HAS_UART
- // enable_disable UART flow control
- // b: 0 -> disable, nonzero -> enable
- // return: 0
- opt_uart_hwfc_endis = 1,
-#endif
-#ifdef DBOARD_HAS_TEMPSENSOR
- // 0x00: get I2C address or enable/disable status
- // 0xff: disable
- // other: set I2C address
- opt_tempsense_enaddr = 2,
-#endif
-
- opt_get_implmap = 0xff
-};
-
-uint8_t rtconf_do(uint8_t a, uint8_t b);
-
-#endif
-
diff --git a/src/serprog.h b/src/serprog.h
deleted file mode 100644
index d62e81f..0000000
--- a/src/serprog.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// vim: set et:
-
-#ifndef SERPROG_H_
-#define SERPROG_H_
-
-enum serprog_cmd {
- S_CMD_NOP = 0x00,
- S_CMD_Q_IFACE = 0x01,
- S_CMD_Q_CMDMAP = 0x02,
- S_CMD_Q_PGMNAME = 0x03,
- S_CMD_Q_SERBUF = 0x04,
- S_CMD_Q_BUSTYPE = 0x05,
- S_CMD_Q_CHIPSIZE = 0x06,
- S_CMD_Q_OPBUF = 0x07,
- S_CMD_Q_WRNMAXLEN = 0x08,
- S_CMD_R_BYTE = 0x09,
- S_CMD_R_NBYTES = 0x0a,
- S_CMD_O_INIT = 0x0b,
- S_CMD_O_WRITEB = 0x0c,
- S_CMD_O_WRITEN = 0x0d,
- S_CMD_O_DELAY = 0x0e,
- S_CMD_O_EXEC = 0x0f,
- S_CMD_SYNCNOP = 0x10,
- S_CMD_Q_RDNMAXLEN = 0x11,
- S_CMD_S_BUSTYPE = 0x12,
- S_CMD_SPIOP = 0x13,
- S_CMD_S_SPI_FREQ = 0x14,
- S_CMD_S_PINSTATE = 0x15,
-
- S_CMD_MAGIC_SETTINGS = 0x53
-};
-
-enum serprog_response { S_ACK = 0x06, S_NAK = 0x15 };
-
-#define SERPROG_IFACE_VERSION 0x0001
-
-uint32_t /*freq_applied*/ sp_spi_set_freq(uint32_t freq_wanted);
-
-void sp_spi_init(void);
-void sp_spi_cs_deselect(void);
-void sp_spi_cs_select(void);
-void sp_spi_op_begin(void);
-void sp_spi_op_write(uint32_t write_len, const uint8_t* write_data);
-void sp_spi_op_read(uint32_t read_len, uint8_t* read_data);
-void sp_spi_op_end(void);
-
-static inline void sp_spi_op_do(
- uint32_t write_len, const uint8_t* write_data, uint32_t read_len, uint8_t* read_data) {
- sp_spi_op_begin();
- sp_spi_op_write(write_len, write_data);
- sp_spi_op_write(read_len, read_data);
- sp_spi_op_end();
-}
-
-#endif
-
diff --git a/src/t/.gitignore b/src/t/.gitignore
deleted file mode 100644
index 8206030..0000000
--- a/src/t/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tstest
diff --git a/src/t/tstest.c b/src/t/tstest.c
deleted file mode 100644
index ce19c1e..0000000
--- a/src/t/tstest.c
+++ /dev/null
@@ -1,73 +0,0 @@
-
-#define DBOARD_HAS_TEMPSENSOR
-#define VERY_FAKE
-
-#include
-
-static inline void tempsense_dev_init(void) { }
-static inline int16_t tempsense_dev_get_temp(void) { return 42 << 4; }
-
-static inline int16_t tempsense_dev_get_lower(void) { return 0 << 4; }
-static inline int16_t tempsense_dev_get_upper(void) { return 75 << 4; }
-static inline int16_t tempsense_dev_get_crit(void) { return 80 << 4; }
-
-#include "../tempsensor.c"
-
-static int do_pkt(uint8_t cmd, bool read, uint16_t addr, uint16_t len, uint8_t* buf) {
- int rv;
-
- if (cmd & 1) tempsense_do_start();
-
- if (read) {
- rv = tempsense_do_read(len, buf);
- } else {
- rv = tempsense_do_write(len, buf);
- }
-
- if (cmd & 2) tempsense_do_stop();
-
- printf("-> %d: %s\n", rv, (rv < 0 || rv != len) ? "nak" : "ack");
-
- return rv;
-}
-
-static void pbuf(size_t len, const uint8_t* buf) {
- printf("--> ");
- size_t i;
- for (i = 0; i < len; ++i) {
- printf("%02x ", buf[i]);
- if ((i & 0xf) == 0xf) printf("%c", '\n');
- }
- if ((i & 0xf) != 0x0) printf("%c", '\n');
-}
-
-int main(int argc, char* argv[]) {
- tempsense_init();
-
- tempsense_set_addr(0x18);
-
- // initial probe
- uint8_t pk1[1] = {0};
- do_pkt(0x05, false, 0x18, 1, pk1);
- uint8_t pk2[2];
- do_pkt(0x06, true, 0x18, 2, pk2);
- pbuf(2, pk2);
-
- uint8_t pk3[1] = {1};
- do_pkt(0x05, false, 0x18, 1, pk3);
- uint8_t pk4[2];
- do_pkt(0x06, true, 0x18, 2, pk4);
- pbuf(2, pk4);
-
- // sensor data get
-
- // out 0x05 cmd5
- // in 2byte cmd6
- // out 0x04 cmd5
- // in 2byte cmd6
- // out 0x03 cmd5
- // in 2byte cmd6
- // out 0x02 cmd5
- // in 2byte cmd6
-}
-
diff --git a/src/tempsensor.c b/src/tempsensor.c
deleted file mode 100644
index ea2eecc..0000000
--- a/src/tempsensor.c
+++ /dev/null
@@ -1,245 +0,0 @@
-// vim: set et:
-
-#include
-#include
-#include
-#include
-
-#ifndef VERY_FAKE
-#include "protocfg.h"
-// clang-format off
-#define printf(fmt, ...) do { } while (0) \
-
-// clang-format on
-#endif
-
-#ifdef DBOARD_HAS_TEMPSENSOR
-
-#include "tempsensor.h"
-
-static bool active;
-static uint8_t addr;
-static uint8_t reg;
-static size_t index;
-static bool instartstop, hasreg;
-
-enum regid { cap = 0, config, t_upper, t_lower, t_crit, t_a, manuf_id, dev_idrev, reso };
-
-#define MANUF_ID 0x0054
-#define DEV_IDREV 0x0400
-
-struct {
- uint16_t config;
- uint16_t t_upper, t_lower, t_crit;
- uint8_t reso;
-} mcp9808;
-
-#define float2fix(x) (int)((x) * (1 << 4))
-__attribute__((__const__)) inline static int16_t trunc_8fix4(int fix) {
- // clang-format off
- if (fix > 4095) fix = 4095;
- if (fix < -4096) fix = -4096;
- // clang-format on
- return fix;
-}
-void tempsense_init(void) {
- active = false;
- addr = 0xff;
- reg = 0;
- index = 0;
- instartstop = false;
- hasreg = false;
-
- tempsense_dev_init();
-
- // clang-format off
- mcp9808.t_lower = tempsense_dev_get_lower();
- mcp9808.t_upper = tempsense_dev_get_upper();
- mcp9808.t_crit = tempsense_dev_get_crit ();
- // clang-format on
-}
-
-bool tempsense_get_active(void) { return active; }
-void tempsense_set_active(bool act) {
- active = act;
- if (!act) addr = 0xff;
-}
-uint8_t tempsense_get_addr(void) { return addr; }
-void tempsense_set_addr(uint8_t a) {
- addr = a;
- active = addr >= 0x8 && addr <= 0x77;
- printf("set: ad=%02x ac=%c\n", addr, active ? 't' : 'f');
-}
-
-void tempsense_do_start(void) {
- printf("ts start\n");
- // reg = 0;
- index = 0;
- instartstop = true;
- hasreg = false;
-}
-void tempsense_do_stop(void) {
- printf("ts stop\n");
- instartstop = false;
-}
-
-int tempsense_do_read(int length, uint8_t* buf) {
- printf("read l=%d reg=%02x ", length, reg);
-
- if (!instartstop || length < 0) return -1; // nak
- if (length == 0) return 0; // ack
- // if (!hasreg) return -1; // nak
-
- int i;
- for (i = 0; i < length; ++i, ++index) {
- switch (reg) {
- // TODO: big or little endian? seems to be big
- case cap: buf[index] = 0; break;
- case config:
- if (index == 0)
- buf[0] = (mcp9808.config >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (mcp9808.config >> 0) & 0xff;
- else
- return index;
- break;
- case t_upper:
- if (index == 0)
- buf[0] = (mcp9808.t_upper >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (mcp9808.t_upper >> 0) & 0xff;
- else
- return index;
- break;
- case t_lower:
- if (index == 0)
- buf[0] = (mcp9808.t_lower >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (mcp9808.t_lower >> 0) & 0xff;
- else
- return index;
- break;
- case t_crit:
- if (index == 0)
- buf[0] = (mcp9808.t_crit >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (mcp9808.t_crit >> 0) & 0xff;
- else
- return index;
- break;
- case t_a: {
- static uint16_t temp;
- if (index == 0) {
- int16_t res = tempsense_dev_get_temp();
-
- // clang-format off
- uint32_t tup = mcp9808.t_upper & 0x1ffc;
- if (tup & 0x1000) tup |= 0xffffe000; // make negative
- uint32_t tlo = mcp9808.t_lower & 0x1ffc;
- if (tlo & 0x1000) tlo |= 0xffffe000; // make negative
- uint32_t tcr = mcp9808.t_crit & 0x1ffc;
- if (tcr & 0x1000) tcr |= 0xffffe000; // make negative
- // clang-format on
-
- temp = res & 0x1fff; // data bits and sign bit
-
- if ((int32_t)tlo > res) temp |= 0x2000;
- if ((int32_t)tup < res) temp |= 0x4000;
- if ((int32_t)tcr < res) temp |= 0x8000;
-
- buf[0] = (temp >> 8) & 0xff;
- } else if (index == 1)
- buf[1] = (temp >> 0) & 0xff;
- else
- return index;
- } break;
- case manuf_id:
- if (index == 0)
- buf[0] = (MANUF_ID >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (MANUF_ID >> 0) & 0xff;
- else
- return index;
- break;
- case dev_idrev:
- if (index == 0)
- buf[0] = (DEV_IDREV >> 8) & 0xff;
- else if (index == 1)
- buf[1] = (DEV_IDREV >> 0) & 0xff;
- else
- return index;
- break;
- case reso:
- if (index == 0)
- buf[0] = mcp9808.reso;
- else
- return index;
- break;
- default: return -1;
- }
- }
-
- return i;
-}
-int tempsense_do_write(int length, const uint8_t* buf) {
- printf("write l=%d reg=%02x iss=%c ", length, reg, instartstop ? 't' : 'f');
-
- if (!instartstop || length < 0) return -1; // nak
- if (length == 0) return 0; // ack
-
- if (!hasreg) {
- printf("get reg %02x ", reg);
-
- reg = *buf & 0xf;
- ++buf;
- --length;
- hasreg = true;
- }
-
- if (length == 0) return 1; // ack, probably a read following
-
- int i;
- for (i = 0; i < length; ++i, ++index) {
- switch (reg) {
- case config:
- if (index == 0) {
- mcp9808.config = (mcp9808.config & 0x00ff) | ((uint16_t)buf[0] << 8);
- } else if (index == 1) {
- mcp9808.config = (mcp9808.config & 0xff00) | ((uint16_t)buf[1] << 0);
- } else
- return index;
- break;
- case t_upper:
- if (index == 0) {
- mcp9808.t_upper = (mcp9808.t_upper & 0x00ff) | ((uint16_t)buf[0] << 8);
- } else if (index == 1) {
- mcp9808.t_upper = (mcp9808.t_upper & 0xff00) | ((uint16_t)buf[1] << 0);
- } else
- return index;
- break;
- case t_lower:
- if (index == 0) {
- mcp9808.t_lower = (mcp9808.t_lower & 0x00ff) | ((uint16_t)buf[0] << 8);
- } else if (index == 1) {
- mcp9808.t_lower = (mcp9808.t_lower & 0xff00) | ((uint16_t)buf[1] << 0);
- } else
- return index;
- break;
- case t_crit:
- if (index == 0) {
- mcp9808.t_crit = (mcp9808.t_crit & 0x00ff) | ((uint16_t)buf[0] << 8);
- } else if (index == 1) {
- mcp9808.t_crit = (mcp9808.t_crit & 0xff00) | ((uint16_t)buf[1] << 0);
- } else
- return index;
- break;
- case reso: mcp9808.reso = buf[index]; break;
- default: printf("unk reg\n"); return -1;
- }
- }
-
- return i;
-}
-
-#endif
-
diff --git a/src/tempsensor.h b/src/tempsensor.h
deleted file mode 100644
index 6bf2e22..0000000
--- a/src/tempsensor.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// vim: set et:
-
-#ifndef TEMPSENSOR_H_
-#define TEMPSENSOR_H_
-
-#include
-#include
-
-void tempsense_init(void);
-
-bool tempsense_get_active(void);
-void tempsense_set_active(bool active);
-uint8_t tempsense_get_addr(void);
-void tempsense_set_addr(uint8_t addr);
-
-void tempsense_do_start(void); // start cond
-int tempsense_do_read(int length, uint8_t* buf);
-int tempsense_do_write(int length, const uint8_t* buf);
-void tempsense_do_stop(void); // stop cond
-
-#ifdef DBOARD_HAS_TEMPSENSOR
-void tempsense_dev_init(void);
-// 8.4
-int16_t tempsense_dev_get_temp(void);
-
-int16_t tempsense_dev_get_lower(void);
-int16_t tempsense_dev_get_upper(void);
-int16_t tempsense_dev_get_crit(void);
-#endif
-
-#endif
-
diff --git a/src/thread.c b/src/thread.c
new file mode 100644
index 0000000..f528974
--- /dev/null
+++ b/src/thread.c
@@ -0,0 +1,16 @@
+// vim: set et:
+
+#include
+
+#include "thread.h"
+
+extern uint32_t co_active_buffer[64];
+uint32_t co_active_buffer[64];
+extern cothread_t co_active_handle;
+cothread_t co_active_handle;
+
+static cothread_t mainthread;
+
+void thread_init (void) { mainthread = co_active(); }
+void thread_yield(void) { co_switch(mainthread); }
+
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..2664774
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,14 @@
+// vim: set et:
+
+#ifndef THREAD_H_
+#define THREAD_H_
+
+#include
+
+#define THREAD_STACK_SIZE 1024
+
+void thread_init (void);
+void thread_yield(void);
+
+#endif
+
diff --git a/src/tusb_config.h b/src/tusb_config.h
index 3f36553..99059ac 100644
--- a/src/tusb_config.h
+++ b/src/tusb_config.h
@@ -31,7 +31,7 @@
extern "C" {
#endif
-#include "protocfg.h"
+//#include "protocfg.h"
//--------------------------------------------------------------------
// COMMON CONFIGURATION
@@ -108,12 +108,21 @@ extern "C" {
#define CFG_TUD_MIDI 0
#define CFG_TUD_NET 0
// see also: bsp//protocfg.h
+#define CFG_TUD_HID 0
+#ifdef USE_USBCDC_FOR_STDIO
+#define CFG_TUD_CDC 1
+#else
+#define CFG_TUD_CDC 0
+#endif
+#define CFG_TUD_VENDOR 1
#define CFG_TUD_HID_EP_BUFSIZE 64
// 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/tusb_plt.S b/src/tusb_plt.S
new file mode 100644
index 0000000..a90d72c
--- /dev/null
+++ b/src/tusb_plt.S
@@ -0,0 +1,108 @@
+@ vim: set ft=armv5:
+
+.cpu cortex-m0
+.thumb
+
+.section .data.tusb_gotplt, "awx", %progbits
+.global tusb_plt
+tusb_plt:
+
+ @ sigh, thumb...
+.type tud_hid_get_report_cb, %function
+.global tud_hid_get_report_cb
+tud_hid_get_report_cb:
+ push {r0}
+ ldr r0, .Lhid_get_report
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_hid_set_report_cb, %function
+.global tud_hid_set_report_cb
+tud_hid_set_report_cb:
+ push {r0}
+ ldr r0, .Lhid_set_report
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_cdc_line_coding_cb, %function
+.global tud_cdc_line_coding_cb
+tud_cdc_line_coding_cb:
+ push {r0}
+ ldr r0, .Lcdc_line_coding
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_vendor_control_xfer_cb, %function
+.global tud_vendor_control_xfer_cb
+tud_vendor_control_xfer_cb:
+ push {r0}
+ ldr r0, .Lvendor_control_xfer
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+
+
+.type tud_hid_descriptor_report_cb, %function
+.global tud_hid_descriptor_report_cb
+tud_hid_descriptor_report_cb:
+ push {r0}
+ ldr r0, .Lhid_descriptor_report
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_descriptor_device_cb, %function
+.global tud_descriptor_device_cb
+tud_descriptor_device_cb:
+ push {r0}
+ ldr r0, .Ldescriptor_device
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_descriptor_configuration_cb, %function
+.global tud_descriptor_configuration_cb
+tud_descriptor_configuration_cb:
+ push {r0}
+ ldr r0, .Ldescriptor_configuration
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+.type tud_descriptor_string_cb, %function
+.global tud_descriptor_string_cb
+tud_descriptor_string_cb:
+ push {r0}
+ ldr r0, .Ldescriptor_string
+ mov r12, r0
+ pop {r0}
+ bx r12
+
+
+
+.type tusb_got, %object
+.size tusb_got, 4*8
+.global tusb_got
+tusb_got:
+.Lhid_get_report:
+ .4byte 0 @ tud_hid_get_report_cb
+.Lhid_set_report:
+ .4byte 0 @ tud_hid_set_report_cb
+.Lcdc_line_coding:
+ .4byte 0 @ tud_cdc_line_coding_cb
+.Lvendor_control_xfer:
+ .4byte 0 @ tud_vendor_control_xfer_cb
+
+.Lhid_descriptor_report:
+ .4byte 0 @ tud_hid_descriptor_report_cb
+.Ldescriptor_device:
+ .4byte 0 @ tud_descriptor_device_cb
+.Ldescriptor_configuration:
+ .4byte 0 @ tud_descriptor_configuration_cb
+.Ldescriptor_string:
+ .4byte 0 @ tud_descriptor_string_cb
+
diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c
deleted file mode 100644
index 5f9f881..0000000
--- a/src/usb_descriptors.c
+++ /dev/null
@@ -1,277 +0,0 @@
-// vim: set et:
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-#include "protos.h"
-#include "tusb.h"
-#include "util.h"
-
-/* 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_BCD_BASE 0x6000
-#else
-#define USB_BCD_BASE 0x4000
-#endif
-#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
-#define USB_BCD \
- (USB_BCD_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,
-
- STRID_CONFIG,
-
- STRID_IF_HID_CMSISDAP,
- STRID_IF_VND_I2CTINYUSB,
- STRID_IF_CDC_UART,
- STRID_IF_CDC_SERPROG,
- STRID_IF_CDC_STDIO,
-};
-
-//--------------------------------------------------------------------+
-// Device Descriptors
-//--------------------------------------------------------------------+
-// clang-format off
-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 = USB_VID,
- .idProduct = USB_PID,
- .bcdDevice = USB_BCD,
-
- .iManufacturer = STRID_MANUFACTURER,
- .iProduct = STRID_PRODUCT,
- .iSerialNumber = STRID_SERIAL,
-
- .bNumConfigurations = 0x01
-};
-// clang-format on
-
-// 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; }
-
-//--------------------------------------------------------------------+
-// HID Report Descriptor
-//--------------------------------------------------------------------+
-
-// clang-format off
-static uint8_t const desc_hid_report[] = {
- TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)
-};
-// clang-format on
-
-// 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;
-
- return desc_hid_report;
-}
-
-//--------------------------------------------------------------------+
-// Configuration Descriptor
-//--------------------------------------------------------------------+
-
-enum {
-#ifdef DBOARD_HAS_I2C
- ITF_NUM_VND_I2CTINYUSB,
-#endif
-#ifdef DBOARD_HAS_CMSISDAP
- ITF_NUM_HID_CMSISDAP,
-#endif
-#ifdef DBOARD_HAS_UART
- ITF_NUM_CDC_UART_COM,
- ITF_NUM_CDC_UART_DATA,
-#endif
-#ifdef DBOARD_HAS_SERPROG
- ITF_NUM_CDC_SERPROG_COM,
- ITF_NUM_CDC_SERPROG_DATA,
-#endif
-#ifdef USE_USBCDC_FOR_STDIO
- ITF_NUM_CDC_STDIO_COM,
- ITF_NUM_CDC_STDIO_DATA,
-#endif
-
- 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 \
-
-
-enum {
- CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN
-#ifdef DBOARD_HAS_I2C
- + TUD_I2CTINYUSB_LEN
-#endif
-#ifdef DBOARD_HAS_UART
- + TUD_CDC_DESC_LEN
-#endif
-#ifdef DBOARD_HAS_CMSISDAP
- + TUD_HID_INOUT_DESC_LEN
-#endif
-#ifdef DBOARD_HAS_SERPROG
- + TUD_CDC_DESC_LEN
-#endif
-#ifdef USE_USBCDC_FOR_STDIO
- + TUD_CDC_DESC_LEN
-#endif
-};
-
-#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
-
-// 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
-// clang-format off
-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
- 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, STRID_IF_VND_I2CTINYUSB),
-#endif
-
-#ifdef DBOARD_HAS_UART
- 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
- 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
- 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
-};
-// clang-format on
-
-// 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;
-}
-
-//--------------------------------------------------------------------+
-// String Descriptors
-//--------------------------------------------------------------------+
-
-// array of pointer to string descriptors
-// clang-format off
-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)",
-};
-// clang-format on
-
-// 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) {
- static uint16_t _desc_str[32];
-
- (void)langid;
-
- uint8_t chr_count = 0;
-
- 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
-
- if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL;
-
- const char* str = string_desc_arr[index];
-
- // Cap at max char
- chr_count = TU_MIN(strlen(str), 31);
-
- // Convert ASCII string into UTF-16
- for (int i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; }
- }
-
- // 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;
-}
-
-void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) {
- if (itf == CDC_N_UART) { cdc_uart_set_baudrate(line_coding->bit_rate); }
-}
-
diff --git a/src/util.h b/src/util.h
index dc07bb0..ae47e2d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -10,8 +10,6 @@ static inline char nyb2hex(int x) {
return 'A' + (x - 0xa);
}
-void thread_yield(void);
-
// clang-format off
uint8_t get_unique_id_u8 (uint8_t * desc_str);
uint8_t get_unique_id_u16(uint16_t* desc_str);
diff --git a/src/vnd_cfg.c b/src/vnd_cfg.c
new file mode 100644
index 0000000..52ef925
--- /dev/null
+++ b/src/vnd_cfg.c
@@ -0,0 +1,143 @@
+// vim: set et:
+
+#include
+#include
+
+#include "mode.h"
+#include "vnd_cfg.h"
+
+#include "thread.h"
+
+static uint8_t rx_buf[CFG_TUD_VENDOR_TX_BUFSIZE];
+static uint8_t tx_buf[CFG_TUD_VENDOR_TX_BUFSIZE];
+
+static uint32_t rxavail, rxpos, txpos;
+
+void vnd_cfg_init(void) {
+ rxavail = 0;
+ rxpos = 0;
+ txpos = 0;
+}
+
+uint8_t vnd_cfg_read_byte(void) {
+ while (rxavail <= 0) {
+ if (!tud_vendor_n_mounted(0) && !tud_vendor_n_available(0)) {
+ thread_yield();
+ continue;
+ }
+
+ rxpos = 0;
+ rxavail = tud_vendor_n_read(0, rx_buf, sizeof rx_buf);
+
+ if (rxavail == 0) thread_yield();
+ }
+
+ uint8_t rv = rx_buf[rxpos];
+ ++rxpos;
+ --rxavail;
+
+ return rv;
+}
+void vnd_cfg_write_flush(void) {
+ // TODO: is this needed?
+ while (tud_vendor_n_write_available(0) < txpos) {
+ thread_yield();
+ }
+
+ tud_vendor_n_write(0, tx_buf, txpos);
+ txpos = 0;
+}
+void vnd_cfg_write_byte(uint8_t v) {
+ if (txpos == CFG_TUD_VENDOR_TX_BUFSIZE) {
+ vnd_cfg_write_flush();
+ }
+
+ tx_buf[txpos] = v;
+ ++txpos;
+}
+void vnd_cfg_write_resp(enum cfg_resp stat, uint16_t len, const void* data) {
+ if (len > 0x7fff) len = 0x7fff; // aaaaaaaaaaaaaaaaa // TODO: throw some kind of error
+
+ vnd_cfg_write_byte(stat);
+ if (len < 0x80) {
+ vnd_cfg_write_byte(len);
+ } else {
+ vnd_cfg_write_byte((len & 0x7f) | 0x80);
+ vnd_cfg_write_byte(len >> 7);
+ }
+
+ for (size_t i = 0; i < len; ++i) {
+ vnd_cfg_write_byte(((const uint8_t*)data)[i]);
+ }
+
+ vnd_cfg_write_flush();
+}
+
+void vnd_cfg_task(void) {
+ uint8_t cmd = vnd_cfg_read_byte();
+ uint8_t verbuf[2];
+
+ if (cmd & 0xf0) {
+ uint8_t mode = (uint8_t)(cmd & 0xf0) >> 4;
+ uint8_t mcmd = cmd & 0x0f;
+ if (mode != mode_current_id && mcmd > mode_cmd_get_features) {
+ vnd_cfg_write_resp(cfg_resp_badmode, 0, NULL);
+ } else if (mode_list[mode] == NULL) {
+ vnd_cfg_write_resp(cfg_resp_nosuchmode, 0, NULL);
+ } else {
+ switch (mcmd) {
+ case mode_cmd_get_name:
+ vnd_cfg_write_resp(cfg_resp_ok, strlen(mode_list[mode]->name),
+ mode_list[mode]->name);
+ break;
+ case mode_cmd_get_version:
+ verbuf[0] = (mode_list[mode]->version >> 0) & 0xff;
+ verbuf[1] = (mode_list[mode]->version >> 8) & 0xff;
+
+ vnd_cfg_write_resp(cfg_resp_ok, 2, verbuf);
+ break;
+ default:
+ mode_list[mode]->handle_cmd(mcmd);
+ break;
+ }
+ }
+ } else {
+ switch (cmd) {
+ case cfg_cmd_get_version:
+ verbuf[0] = (VND_CFG_PROTO_VER >> 0) & 0xff;
+ verbuf[1] = (VND_CFG_PROTO_VER >> 8) & 0xff;
+
+ vnd_cfg_write_resp(cfg_resp_ok, 2, verbuf);
+ break;
+ case cfg_cmd_get_modes:
+ verbuf[0] = 0x01;
+ for (size_t i = 1; i < 16; ++i) {
+ if (mode_list[i] != NULL) verbuf[0] |= 1 << i;
+ }
+
+ vnd_cfg_write_resp(cfg_resp_ok, 1, verbuf);
+ break;
+ case cfg_cmd_get_cur_mode:
+ verbuf[0] = mode_current_id;
+ vnd_cfg_write_resp(cfg_resp_ok, 1, verbuf);
+ break;
+ case cfg_cmd_set_cur_mode:
+ verbuf[0] = vnd_cfg_read_byte();
+ if (verbuf[0] == 0 || verbuf[0] >= 0x10 || mode_list[verbuf[0]] == NULL) {
+ vnd_cfg_write_resp(cfg_resp_nosuchmode, 0, NULL);
+ } else {
+ // will be handled later so the USB stack won't break, whcih might happen if reconfig would happen now
+ mode_next_id = verbuf[0];
+ vnd_cfg_write_resp(cfg_resp_ok, 0, NULL);
+ }
+ break;
+ case cfg_cmd_get_infostr:
+ vnd_cfg_write_resp(cfg_resp_ok, strlen("Dragnbus"), "Dragnbus");
+ break;
+ default:
+ vnd_cfg_write_resp(cfg_resp_illcmd, 0, NULL);
+ break;
+ }
+ }
+}
+
diff --git a/src/vnd_cfg.h b/src/vnd_cfg.h
new file mode 100644
index 0000000..3769a2f
--- /dev/null
+++ b/src/vnd_cfg.h
@@ -0,0 +1,79 @@
+// vim: set et:
+
+#ifndef VND_CFG_H_
+#define VND_CFG_H_
+
+#include
+
+/* the configuration vendor interface must always be the first vendor itf. */
+
+#define VND_CFG_PROTO_VER 0x0010
+
+void vnd_cfg_init(void);
+void vnd_cfg_task(void);
+
+// commands meant for configuring and initializing the device
+enum cfg_cmd {
+ cfg_cmd_get_version = 0x00,
+ cfg_cmd_get_modes = 0x01,
+ cfg_cmd_get_cur_mode = 0x02,
+ cfg_cmd_set_cur_mode = 0x03,
+ cfg_cmd_get_infostr = 0x04,
+};
+
+// common commands for every mode
+// for non-active modes, only these three can be used, others will result in a
+// 'badmode' error
+enum mode_cmd {
+ mode_cmd_get_name = 0x00,
+ mode_cmd_get_version = 0x01,
+ mode_cmd_get_features = 0x02,
+};
+
+enum cfg_resp {
+ cfg_resp_ok = 0x00,
+ cfg_resp_illcmd = 0x01,
+ cfg_resp_badmode = 0x02,
+ cfg_resp_nosuchmode = 0x03,
+};
+
+uint8_t vnd_cfg_read_byte (void);
+void vnd_cfg_write_flush(void);
+void vnd_cfg_write_byte(uint8_t v);
+void vnd_cfg_write_resp(enum cfg_resp stat, uint16_t len, const void* data);
+
+/*
+ * wire protocol:
+ * host sends messages, device sends replies. the device never initiates a xfer
+ *
+ * the first byte of a command is the combination of the mode it is meant for
+ * in the high nybble, and the command number itself in the low nybble. optional
+ * extra command bytes may follow, depending on the command itself.
+ * a high nybble is 0 signifies a general configuration command, not meant for
+ * a particular mode
+ *
+ * a response consists of a response status byte (enum cfg_resp), followed by
+ * a 7- or 15-bit VLQ int (little-endian) for the payload length, followed by
+ * the payload itself.
+ *
+ * general commands:
+ * * get vesion (0x00): returns a payload of 2 bytes with version data. should
+ * currently be 0x10 0x00 (00.10h)
+ * * get modes (0x01): returns 2 bytes with a bitmap containing all supported
+ * modes (bit 0 is for general cfg and must always be 1)
+ * * get cur mode (0x02): returns a single byte containing the current mode number
+ * * set cur mode (0x03): sets the current mode. one extra request byte, no
+ * response payload
+ * * get info string (0x04): get a string containing human-readable info about
+ * the device. for display only
+ *
+ * common mode commands:
+ * * get name (0x00): returns a name or other descriptive string in the payload.
+ * for display only
+ * * get version (0x01): returns a 2-byte version number in the payload
+ * * get_features (0x02): gets a bitmap of supported features. length and meaning
+ * of the bits depends on the mode
+ */
+
+#endif
+
diff --git a/src/vnd_i2ctinyusb.c b/src/vnd_i2ctinyusb.c
deleted file mode 100644
index cfa9afa..0000000
--- a/src/vnd_i2ctinyusb.c
+++ /dev/null
@@ -1,266 +0,0 @@
-
-#include "protos.h"
-
-#ifdef DBOARD_HAS_I2C
-
-// clang-format off
-#include
-#include
-#include
-
-#include
-
-#include "tusb.h"
-#include "device/usbd_pvt.h"
-
-#include "protocfg.h"
-#include "pinout.h"
-
-#include "i2ctinyusb.h"
-
-#include "tempsensor.h"
-// clang-format on
-
-static uint8_t itf_num;
-
-static enum itu_status status;
-static struct itu_cmd curcmd;
-
-static uint8_t rxbuf[128];
-static uint8_t txbuf[128];
-
-static void iub_init(void) {
- status = ITU_STATUS_IDLE;
- memset(&curcmd, 0, sizeof curcmd);
-
- i2ctu_init();
-#ifdef DBOARD_HAS_TEMPSENSOR
- tempsense_init();
-#endif
-}
-
-static void iub_reset(uint8_t rhport) {
- (void)rhport;
-
- status = ITU_STATUS_IDLE;
- memset(&curcmd, 0, sizeof curcmd);
-
- i2ctu_init();
-#ifdef DBOARD_HAS_TEMPSENSOR
- tempsense_init();
-#endif
-
- itf_num = 0;
-}
-
-static uint16_t iub_open(uint8_t rhport, tusb_desc_interface_t const* itf_desc, uint16_t max_len) {
- (void)rhport;
-
- // clang-format off
- TU_VERIFY(itf_desc->bInterfaceClass == 0
- && itf_desc->bInterfaceSubClass == 0
- && itf_desc->bInterfaceProtocol == 0,
- 0);
- // clang-format on
-
- const uint16_t drv_len = sizeof(tusb_desc_interface_t);
- TU_VERIFY(max_len >= drv_len, 0);
-
- itf_num = itf_desc->bInterfaceNumber;
-
- return drv_len;
-}
-
-static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t const* req) {
- (void)rhport;
-
- /*static char* stages[]={"SETUP","DATA","ACK"};
- static char* types[]={"STD","CLS","VND","INV"};
-
- printf("ctl req stage=%s rt=%s, wIndex=%04x, bReq=%02x, wValue=%04x wLength=%04x\n",
- stages[stage], types[req->bmRequestType_bit.type],
- req->wIndex, req->bRequest, req->wValue, req->wLength);*/
-
- if (req->bmRequestType_bit.type != TUSB_REQ_TYPE_VENDOR) return true;
-
- if (stage == CONTROL_STAGE_DATA) {
- struct itu_cmd cmd = curcmd;
-
- if (req->bRequest >= ITU_CMD_I2C_IO && req->bRequest <= ITU_CMD_I2C_IO_BEGINEND &&
- cmd.cmd == req->bRequest && cmd.flags == req->wValue && cmd.addr == req->wIndex &&
- cmd.len == req->wLength) {
- // printf("WDATA a=%04hx l=%04hx ", cmd.addr, cmd.len);
-
- // printf("data=%02x %02x...\n", rxbuf[0], rxbuf[1]);
-#ifdef DBOARD_HAS_TEMPSENSOR
- if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
- if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
- // FIXME: fix status handling
- int rv = tempsense_do_write(cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len, rxbuf);
- if (rv < 0 || rv != cmd.len)
- status = ITU_STATUS_ADDR_NAK;
- else
- status = ITU_STATUS_ADDR_ACK;
- if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
- } else
-#endif
- {
- status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, cmd.addr, rxbuf,
- cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len);
- }
-
- // cancel curcmd
- curcmd.cmd = 0xff;
- }
- return true;
- } else if (stage == CONTROL_STAGE_SETUP) {
- switch (req->bRequest) {
- case ITU_CMD_ECHO: { // flags to be echoed back, addr unused, len=2
-
- if (req->wLength != 2) return false; // bad length -> let's stall
-
- uint8_t rv[2];
- rv[0] = req->wValue & 0xff;
- rv[1] = (req->wValue >> 8) & 0xff;
- return tud_control_xfer(rhport, req, rv, sizeof rv);
- } break;
- case ITU_CMD_GET_FUNC: { // flags unused, addr unused, len=4
- if (req->wLength != 4) return false;
-
- const uint32_t func = i2ctu_get_func();
- txbuf[0] = func & 0xff;
- txbuf[1] = (func >> 8) & 0xff;
- txbuf[2] = (func >> 16) & 0xff;
- txbuf[3] = (func >> 24) & 0xff;
- return tud_control_xfer(rhport, req, txbuf, 4);
- } break;
- case ITU_CMD_SET_DELAY: { // flags=delay, addr unused, len=0
- if (req->wLength != 0) return false;
-
- uint32_t us = req->wValue ? req->wValue : 1;
- uint32_t freq = 1000 * 1000 / us;
-
- // printf("set freq us=%u freq=%u\n", us, freq);
- if (i2ctu_set_freq(freq, us) != 0) // returned an ok frequency
- return tud_control_status(rhport, req);
- else
- return false;
- } break;
- case ITU_CMD_GET_STATUS: { // flags unused, addr unused, len=1
- if (req->wLength != 1) return false;
-
- uint8_t rv = status;
- return tud_control_xfer(rhport, req, &rv, 1);
- } break;
-
- case ITU_CMD_I2C_IO: // flags: ki2c_flags
- case ITU_CMD_I2C_IO_BEGIN: // addr: I2C address
- case ITU_CMD_I2C_IO_END: // len: transfer size
- case ITU_CMD_I2C_IO_BEGINEND: { // (transfer dir is in flags)
- struct itu_cmd cmd;
- cmd.flags = req->wValue;
- cmd.addr = req->wIndex;
- cmd.len = req->wLength;
- cmd.cmd = req->bRequest;
-
- if (cmd.flags & I2C_M_RD) { // read from I2C device
- // printf("read addr=%04hx len=%04hx ", cmd.addr, cmd.len);
-#ifdef DBOARD_HAS_TEMPSENSOR
- if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
- if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
- int rv = tempsense_do_read(
- cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len, txbuf);
- if (rv < 0 || rv != cmd.len)
- status = ITU_STATUS_ADDR_NAK;
- else
- status = ITU_STATUS_ADDR_ACK;
- if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
- } else
-#endif
- {
- status = i2ctu_read(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, cmd.addr,
- txbuf, cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len);
- }
- // printf("data=%02x %02x...\n", txbuf[0], txbuf[1]);
- return tud_control_xfer(
- rhport, req, txbuf, cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len);
- } else { // write
- // printf("write addr=%04hx len=%04hx ", cmd.addr, cmd.len);
- if (cmd.len == 0) { // address probe -> do this here
- uint8_t bleh = 0;
-#ifdef DBOARD_HAS_TEMPSENSOR
- if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
- if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
- int rv = tempsense_do_write(0, &bleh);
- if (rv < 0 || rv != cmd.len)
- status = ITU_STATUS_ADDR_NAK;
- else
- status = ITU_STATUS_ADDR_ACK;
- if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
- } else
-#endif
- {
- status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK,
- cmd.addr, &bleh, 0);
- }
- // printf("probe -> %d\n", status);
- return tud_control_status(rhport, req);
- } else {
- // handled in DATA stage!
- curcmd = cmd;
- bool rv = tud_control_xfer(rhport, req, rxbuf,
- cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len);
- return rv;
- }
- }
- } break;
- default:
- // printf("I2C-Tiny-USB: unknown command %02x\n", req->bRequest);
- return false;
- }
- } else
- return true; // other stage...
-}
-
-// never actually called fsr
-static bool iub_xfer(
- uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
- (void)rhport;
- (void)ep_addr;
- (void)result;
- (void)xferred_bytes;
-
- return true;
-}
-
-// interfacing stuff for TinyUSB API, actually defines the driver
-
-// clang-format off
-static usbd_class_driver_t const i2ctinyusb_driver = {
-#if CFG_TUSB_DEBUG >= 2
- .name = "i2c-tiny-usb",
-#endif
-
- .init = iub_init,
- .reset = iub_reset,
- .open = iub_open,
- .control_xfer_cb = iub_ctl_req,
- .xfer_cb = iub_xfer,
- .sof = NULL
-};
-// clang-format on
-
-usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) {
- *driver_count = 1;
- return &i2ctinyusb_driver;
-}
-
-// we need to implement this one, because tinyusb uses hardcoded stuff for
-// endpoint 0, which is what the i2c-tiny-usb kernel module uses
-bool tud_vendor_control_xfer_cb(
- uint8_t rhport, uint8_t ep_addr, tusb_control_request_t const* req) {
- return iub_ctl_req(rhport, ep_addr, req);
-}
-
-#endif /* DBOARD_HAS_I2C */
-