clang formatting stuff

This commit is contained in:
Triss 2021-06-29 01:03:02 +02:00
parent 4ec3f35ccd
commit 2905ff2116
33 changed files with 1863 additions and 1793 deletions

29
.clang-format Normal file
View File

@ -0,0 +1,29 @@
---
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 100
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Left
AlignConsecutiveAssignments: AcrossComments
AlignConsecutiveBitFields: AcrossComments
AlignConsecutiveDeclarations: AcrossComments
AlignConsecutiveMacros: AcrossComments
AlignOperands: AlignAfterOperator
AlignAfterOpenBracket: DontAlign
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: true
#AllowShortIfStatementsOnASingleLine: OnlyFirstIf
AllowShortLoopsOnASingleLine: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeTernaryOperators: true
ContinuationIndentWidth: 8
SpaceInEmptyBlock: true
...

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -45,7 +46,6 @@ This information includes:
*/ */
#include "cmsis_compiler.h" #include "cmsis_compiler.h"
#include "util.h" #include "util.h"
/// Processor Clock of the Cortex-M MCU used in the Debug Unit. /// Processor Clock of the Cortex-M MCU used in the Debug Unit.
@ -83,8 +83,8 @@ This information includes:
/// Maximum Package Size for Command and Response data. /// Maximum Package Size for Command and Response data.
/// This configuration settings is used to optimize the communication performance with the /// 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, /// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or
/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB. /// 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. #define DAP_PACKET_SIZE CFG_TUD_HID_EP_BUFSIZE ///< Specifies Packet Size in bytes.
/// Maximum Package Buffers for Command and Response data. /// Maximum Package Buffers for Command and Response data.
@ -146,64 +146,76 @@ This information includes:
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) { __STATIC_INLINE uint8_t DAP_GetVendorString(char* str) {
static const char vnd[] = INFO_MANUFACTURER; static const char vnd[] = INFO_MANUFACTURER;
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i]; for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
return sizeof(vnd)-1; return sizeof(vnd) - 1;
} }
/** Get Product ID string. /** Get Product ID string.
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetProductString (char *str) { __STATIC_INLINE uint8_t DAP_GetProductString(char* str) {
static const char prd[] = INFO_PRODUCT(INFO_BOARDNAME); static const char prd[] = INFO_PRODUCT(INFO_BOARDNAME);
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i]; for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
return sizeof(prd)-1; return sizeof(prd) - 1;
} }
/** Get Serial Number string. /** Get Serial Number string.
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) { __STATIC_INLINE uint8_t DAP_GetSerNumString(char* str) { return get_unique_id_u8((uint8_t*)str); }
return get_unique_id_u8((uint8_t*)str);
}
/** Get Target Device Vendor string. /** Get Target Device Vendor string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString(char* str) {
(void)str;
return 0;
}
/** Get Target Device Name string. /** Get Target Device Name string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString(char* str) {
(void)str;
return 0;
}
/** Get Target Board Vendor string. /** Get Target Board Vendor string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString(char* str) {
(void)str;
return 0;
}
/** Get Target Board Name string. /** Get Target Board Name string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetBoardNameString(char* str) {
(void)str;
return 0;
}
/* TODO! */ /* TODO! */
/** Get Product Firmware Version string. /** Get Product Firmware Version string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString(char* str) {
(void)str;
return 0;
}
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access \defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
@ -239,7 +251,6 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided:
- \ref PIN_SWDIO_OUT to write to 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 ------------------------------ // Configure DAP I/O pins ------------------------------
/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. /** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
@ -247,165 +258,128 @@ Configures the DAP Hardware I/O pins for JTAG mode:
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level. - TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
- TDO to input mode. - TDO to input mode.
*/ */
__STATIC_INLINE void PORT_JTAG_SETUP (void) { __STATIC_INLINE void PORT_JTAG_SETUP(void) { }
}
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET. /** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode: 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. - SWCLK, SWDIO, nRESET to output mode and set to default high level.
- TDI, nTRST to HighZ mode (pins are unused in SWD mode). - TDI, nTRST to HighZ mode (pins are unused in SWD mode).
*/ */
__STATIC_INLINE void PORT_SWD_SETUP (void) { __STATIC_INLINE void PORT_SWD_SETUP(void) { }
}
/** Disable JTAG/SWD I/O Pins. /** Disable JTAG/SWD I/O Pins.
Disables the DAP Hardware I/O pins which configures: Disables the DAP Hardware I/O pins which configures:
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode. - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/ */
__STATIC_INLINE void PORT_OFF (void) { __STATIC_INLINE void PORT_OFF(void) { }
}
// SWCLK/TCK I/O pin ------------------------------------- // SWCLK/TCK I/O pin -------------------------------------
/** SWCLK/TCK I/O pin: Get Input. /** SWCLK/TCK I/O pin: Get Input.
\return Current status of the SWCLK/TCK DAP hardware I/O pin. \return Current status of the SWCLK/TCK DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) { return 0; }
return 0;
}
/** SWCLK/TCK I/O pin: Set Output to High. /** SWCLK/TCK I/O pin: Set Output to High.
Set the SWCLK/TCK DAP hardware I/O pin to high level. Set the SWCLK/TCK DAP hardware I/O pin to high level.
*/ */
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) { __STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void) { }
}
/** SWCLK/TCK I/O pin: Set Output to Low. /** SWCLK/TCK I/O pin: Set Output to Low.
Set the SWCLK/TCK DAP hardware I/O pin to low level. Set the SWCLK/TCK DAP hardware I/O pin to low level.
*/ */
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) { __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) { }
}
// SWDIO/TMS Pin I/O -------------------------------------- // SWDIO/TMS Pin I/O --------------------------------------
/** SWDIO/TMS I/O pin: Get Input. /** SWDIO/TMS I/O pin: Get Input.
\return Current status of the SWDIO/TMS DAP hardware I/O pin. \return Current status of the SWDIO/TMS DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) { return 0; }
return 0;
}
/* PIN_SWDIO_TMS_SET and PIN_SWDIO_TMS_CLR are used by SWJ_Sequence */ /* PIN_SWDIO_TMS_SET and PIN_SWDIO_TMS_CLR are used by SWJ_Sequence */
/** SWDIO/TMS I/O pin: Set Output to High. /** SWDIO/TMS I/O pin: Set Output to High.
Set the SWDIO/TMS DAP hardware I/O pin to high level. Set the SWDIO/TMS DAP hardware I/O pin to high level.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) { __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) { }
}
/** SWDIO/TMS I/O pin: Set Output to Low. /** SWDIO/TMS I/O pin: Set Output to Low.
Set the SWDIO/TMS DAP hardware I/O pin to low level. Set the SWDIO/TMS DAP hardware I/O pin to low level.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) { __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) { }
}
/** SWDIO I/O pin: Get Input (used in SWD mode only). /** SWDIO I/O pin: Get Input (used in SWD mode only).
\return Current status of the SWDIO DAP hardware I/O pin. \return Current status of the SWDIO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void) { return 0; }
return 0;
}
/** SWDIO I/O pin: Set Output (used in SWD mode only). /** SWDIO I/O pin: Set Output (used in SWD mode only).
\param bit Output value for the SWDIO DAP hardware I/O pin. \param bit Output value for the SWDIO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only). /** 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 Configure the SWDIO DAP hardware I/O pin to output mode. This function is
called prior \ref PIN_SWDIO_OUT function calls. called prior \ref PIN_SWDIO_OUT function calls.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) { }
}
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only). /** 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 Configure the SWDIO DAP hardware I/O pin to input mode. This function is
called prior \ref PIN_SWDIO_IN function calls. called prior \ref PIN_SWDIO_IN function calls.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) { }
}
// TDI Pin I/O --------------------------------------------- // TDI Pin I/O ---------------------------------------------
/** TDI I/O pin: Get Input. /** TDI I/O pin: Get Input.
\return Current status of the TDI DAP hardware I/O pin. \return Current status of the TDI DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) { return 0; }
return 0;
}
/** TDI I/O pin: Set Output. /** TDI I/O pin: Set Output.
\param bit Output value for the TDI DAP hardware I/O pin. \param bit Output value for the TDI DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
// TDO Pin I/O --------------------------------------------- // TDO Pin I/O ---------------------------------------------
/** TDO I/O pin: Get Input. /** TDO I/O pin: Get Input.
\return Current status of the TDO DAP hardware I/O pin. \return Current status of the TDO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) { return 0; }
return 0;
}
// nTRST Pin I/O ------------------------------------------- // nTRST Pin I/O -------------------------------------------
/** nTRST I/O pin: Get Input. /** nTRST I/O pin: Get Input.
\return Current status of the nTRST DAP hardware I/O pin. \return Current status of the nTRST DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) { return 0; }
return 0;
}
/** nTRST I/O pin: Set Output. /** nTRST I/O pin: Set Output.
\param bit JTAG TRST Test Reset pin status: \param bit JTAG TRST Test Reset pin status:
- 0: issue a JTAG TRST Test Reset. - 0: issue a JTAG TRST Test Reset.
- 1: release JTAG TRST Test Reset. - 1: release JTAG TRST Test Reset.
*/ */
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
// nRESET Pin I/O------------------------------------------ // nRESET Pin I/O------------------------------------------
/** nRESET I/O pin: Get Input. /** nRESET I/O pin: Get Input.
\return Current status of the nRESET DAP hardware I/O pin. \return Current status of the nRESET DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) { return 0; }
return 0;
}
/** nRESET I/O pin: Set Output. /** nRESET I/O pin: Set Output.
\param bit target device hardware reset pin status: \param bit target device hardware reset pin status:
- 0: issue a device hardware reset. - 0: issue a device hardware reset.
- 1: release device hardware reset. - 1: release device hardware reset.
*/ */
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs \defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
@ -424,22 +398,17 @@ It is recommended to provide the following LEDs for status indication:
- 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit. - 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. - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
*/ */
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) { __STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
/** Debug Unit: Set status Target Running LED. /** Debug Unit: Set status Target Running LED.
\param bit status of the Target Running LED. \param bit status of the Target Running LED.
- 1: Target Running LED ON: program execution in target started. - 1: Target Running LED ON: program execution in target started.
- 0: Target Running LED OFF: program execution in target stopped. - 0: Target Running LED OFF: program execution in target stopped.
*/ */
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) { __STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) { (void)bit; }
(void)bit;
}
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp \defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
@ -447,15 +416,16 @@ __STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
@{ @{
Access function for Test Domain Timer. 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 The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET.
default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK. By default, the DWT timer is used. The frequency of this timer is configured with \ref
TIMESTAMP_CLOCK.
*/ */
/** Get timestamp of Test Domain Timer. /** Get timestamp of Test Domain Timer.
\return Current timestamp value. \return Current timestamp value.
*/ */
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) { __STATIC_INLINE uint32_t TIMESTAMP_GET(void) {
#if TIMESTAMP_CLOCK > 0 #if TIMESTAMP_CLOCK > 0
return (DWT->CYCCNT); return (DWT->CYCCNT);
#else #else
@ -465,7 +435,6 @@ __STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization \defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
@ -483,8 +452,7 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
- for nTRST, nRESET a weak pull-up (if available) is enabled. - for nTRST, nRESET a weak pull-up (if available) is enabled.
- LED output pins are enabled and LEDs are turned off. - LED output pins are enabled and LEDs are turned off.
*/ */
__STATIC_INLINE void DAP_SETUP (void) { __STATIC_INLINE void DAP_SETUP(void) { }
}
/** Reset Target Device with custom specific I/O pin or command sequence. /** Reset Target Device with custom specific I/O pin or command sequence.
This function allows the optional implementation of a device specific reset sequence. This function allows the optional implementation of a device specific reset sequence.
@ -493,7 +461,7 @@ when a device needs a time-critical unlock sequence that enables the debug port.
\return 0 = no device specific reset sequence is implemented.\n \return 0 = no device specific reset sequence is implemented.\n
1 = a device specific reset sequence is implemented. 1 = a device specific reset sequence is implemented.
*/ */
__STATIC_INLINE uint8_t RESET_TARGET (void) { __STATIC_INLINE uint8_t RESET_TARGET(void) {
return (0U); // change to '1' when a device reset sequence is implemented return (0U); // change to '1' when a device reset sequence is implemented
} }

View File

@ -1,11 +1,10 @@
// vim: set et:
#include "protos.h" #include "protos.h"
void cdc_uart_init(void) { void cdc_uart_init(void) { }
}
void cdc_uart_task(void) { void cdc_uart_task(void) { }
}
void cdc_uart_set_hwflow(bool enable) { (void)enable; } void cdc_uart_set_hwflow(bool enable) { (void)enable; }
void cdc_uart_set_baud_rate(uint32_t brate) { (void)brate; } void cdc_uart_set_baud_rate(uint32_t brate) { (void)brate; }

View File

@ -1,8 +1,8 @@
// vim: set et:
#include "i2ctinyusb.h" #include "i2ctinyusb.h"
__attribute__((__const__)) __attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void) { return 0; }
enum ki2c_funcs i2ctu_get_func(void) { return 0; }
void i2ctu_init(void) { } void i2ctu_init(void) { }
@ -13,8 +13,8 @@ uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us) {
return 0; return 0;
} }
enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, const uint8_t* buf, size_t len) { const uint8_t* buf, size_t len) {
(void)flags; (void)flags;
(void)startstopflags; (void)startstopflags;
(void)addr; (void)addr;
@ -23,8 +23,8 @@ enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopfla
return ITU_STATUS_ADDR_NAK; return ITU_STATUS_ADDR_NAK;
} }
enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, uint8_t* buf, size_t len) { uint8_t* buf, size_t len) {
(void)flags; (void)flags;
(void)startstopflags; (void)startstopflags;
(void)addr; (void)addr;

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef PROTOCFG_H_ #ifndef PROTOCFG_H_
#define PROTOCFG_H_ #define PROTOCFG_H_
@ -14,17 +15,15 @@ enum {
HID_N__NITF HID_N__NITF
}; };
enum { enum {
/*CDC_N_UART = 0, /*CDC_N_UART = 0,
CDC_N_SERPROG,*/ CDC_N_SERPROG,*/
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO
CDC_N_STDIO, CDC_N_STDIO,
#endif #endif
CDC_N__NITF CDC_N__NITF
}; };
enum { enum { VND_N__NITF = 0 };
VND_N__NITF = 0
};
#define CFG_TUD_HID 0 #define CFG_TUD_HID 0
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO

View File

@ -1,3 +1,4 @@
// vim: set et:
#include "protos.h" #include "protos.h"
#include "serprog.h" #include "serprog.h"

View File

@ -1,11 +1,14 @@
// vim: set et:
#include "tempsensor.h" #include "tempsensor.h"
void tempsense_dev_init(void) { } void tempsense_dev_init(void) { }
// clang-format off
// 8.4 // 8.4
int16_t tempsense_dev_get_temp (void) { return 0 << 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_lower(void) { return trunc_8fix4(float2fix( 0)); }
int16_t tempsense_dev_get_upper(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)); } int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 0)); }
// clang-format on

View File

@ -1,3 +1,5 @@
// vim: set et:
#include <stdint.h> #include <stdint.h>
#include "util.h" #include "util.h"

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -44,21 +45,21 @@ This information includes:
- Optional information about a connected Target Device (for Evaluation Boards). - Optional information about a connected Target Device (for Evaluation Boards).
*/ */
#include "cmsis_compiler.h"
#include "bsp/board.h"
#include <stdint.h> #include <stdint.h>
#include <hardware/regs/resets.h>
#include <hardware/structs/resets.h>
#include <hardware/regs/sio.h>
#include <hardware/structs/sio.h>
#include <hardware/regs/pads_bank0.h>
#include <hardware/structs/padsbank0.h>
#include <hardware/regs/io_bank0.h>
#include <hardware/structs/iobank0.h>
#include <hardware/gpio.h> #include <hardware/gpio.h>
#include <hardware/regs/io_bank0.h>
#include <hardware/regs/pads_bank0.h>
#include <hardware/regs/resets.h>
#include <hardware/regs/sio.h>
#include <hardware/structs/iobank0.h>
#include <hardware/structs/padsbank0.h>
#include <hardware/structs/resets.h>
#include <hardware/structs/sio.h>
#include <pico/binary_info.h> #include <pico/binary_info.h>
#include "bsp/board.h"
#include "cmsis_compiler.h"
#include "pinout.h" #include "pinout.h"
#include "protos.h" #include "protos.h"
#include "util.h" #include "util.h"
@ -113,8 +114,8 @@ This information includes:
/// Maximum Package Size for Command and Response data. /// Maximum Package Size for Command and Response data.
/// This configuration settings is used to optimize the communication performance with the /// 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, /// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or
/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB. /// 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. #define DAP_PACKET_SIZE CFG_TUD_HID_EP_BUFSIZE ///< Specifies Packet Size in bytes.
/// Maximum Package Buffers for Command and Response data. /// Maximum Package Buffers for Command and Response data.
@ -181,64 +182,76 @@ This information includes:
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) { __STATIC_INLINE uint8_t DAP_GetVendorString(char* str) {
static const char vnd[] = INFO_MANUFACTURER; static const char vnd[] = INFO_MANUFACTURER;
for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i]; for (size_t i = 0; i < sizeof(vnd); ++i) str[i] = vnd[i];
return sizeof(vnd)-1; return sizeof(vnd) - 1;
} }
/** Get Product ID string. /** Get Product ID string.
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetProductString (char *str) { __STATIC_INLINE uint8_t DAP_GetProductString(char* str) {
static const char prd[] = INFO_PRODUCT(INFO_BOARDNAME); static const char prd[] = INFO_PRODUCT(INFO_BOARDNAME);
for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i]; for (size_t i = 0; i < sizeof(prd); ++i) str[i] = prd[i];
return sizeof(prd)-1; return sizeof(prd) - 1;
} }
/** Get Serial Number string. /** Get Serial Number string.
\param str Pointer to buffer to store the string. \param str Pointer to buffer to store the string.
\return String length. \return String length.
*/ */
__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) { __STATIC_INLINE uint8_t DAP_GetSerNumString(char* str) { return get_unique_id_u8((uint8_t*)str); }
return get_unique_id_u8((uint8_t*)str);
}
/** Get Target Device Vendor string. /** Get Target Device Vendor string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString(char* str) {
(void)str;
return 0;
}
/** Get Target Device Name string. /** Get Target Device Name string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString(char* str) {
(void)str;
return 0;
}
/** Get Target Board Vendor string. /** Get Target Board Vendor string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString(char* str) {
(void)str;
return 0;
}
/** Get Target Board Name string. /** Get Target Board Name string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetTargetBoardNameString(char* str) {
(void)str;
return 0;
}
/* TODO! */ /* TODO! */
/** Get Product Firmware Version string. /** Get Product Firmware Version string.
\param str Pointer to buffer to store the string (max 60 characters). \param str Pointer to buffer to store the string (max 60 characters).
\return String length (including terminating NULL character) or 0 (no string). \return String length (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString (char *str) { (void)str; return 0; } __STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString(char* str) {
(void)str;
return 0;
}
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access \defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
@ -274,7 +287,6 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided:
- \ref PIN_SWDIO_OUT to write to 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 ------------------------------ // Configure DAP I/O pins ------------------------------
/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. /** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
@ -282,32 +294,32 @@ Configures the DAP Hardware I/O pins for JTAG mode:
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level. - TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
- TDO to input mode. - TDO to input mode.
*/ */
__STATIC_INLINE void PORT_JTAG_SETUP (void) { __STATIC_INLINE void PORT_JTAG_SETUP(void) {
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS); resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
/* set to default high level */ /* 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_oe_set = PINOUT_TCK_MASK | PINOUT_TMS_MASK | PINOUT_TDI_MASK | PINOUT_nTRST_MASK |
sio_hw->gpio_set = PINOUT_TCK_MASK | PINOUT_TMS_MASK | PINOUT_TDI_MASK | PINOUT_nTRST_MASK | PINOUT_nRESET_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 */ /* TDO needs to be an input */
sio_hw->gpio_oe_clr = PINOUT_TDO_MASK; sio_hw->gpio_oe_clr = PINOUT_TDO_MASK;
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TCK], hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TCK],
PADS_BANK0_GPIO0_IE_BITS, // bits to set: input enable 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 PADS_BANK0_GPIO0_IE_BITS |
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TMS], PADS_BANK0_GPIO0_OD_BITS); // bits to mask out: input enable, output disable
PADS_BANK0_GPIO0_IE_BITS, hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TMS], PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TDI], hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TDI], PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_TDO], 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, // TDO needs to have its output disabled
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_nTRST], hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_nTRST], PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_nRESET], hw_write_masked(&padsbank0_hw->io[PINOUT_JTAG_nRESET], PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS,
PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS); PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS);
// NOTE: hiZ: ctrl = (ctrl & ~(CTRL_OEOVER_BITS)) | (GPIO_OVERRIDE_LOW << CTRL_OEOVER_LSB); // NOTE: hiZ: ctrl = (ctrl & ~(CTRL_OEOVER_BITS)) | (GPIO_OVERRIDE_LOW << CTRL_OEOVER_LSB);
@ -328,15 +340,17 @@ 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. - SWCLK, SWDIO, nRESET to output mode and set to default high level.
- TDI, nTRST to HighZ mode (pins are unused in SWD mode). - TDI, nTRST to HighZ mode (pins are unused in SWD mode).
*/ */
__STATIC_INLINE void PORT_SWD_SETUP (void) { __STATIC_INLINE void PORT_SWD_SETUP(void) {
resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS); resets_hw->reset &= ~(RESETS_RESET_IO_BANK0_BITS | RESETS_RESET_PADS_BANK0_BITS);
/* set to default high level */ /* set to default high level */
sio_hw->gpio_oe_set = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK; sio_hw->gpio_oe_set = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK;
sio_hw->gpio_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_SWCLK], PADS_BANK0_GPIO0_IE_BITS,
hw_write_masked(&padsbank0_hw->io[PINOUT_SWDIO], PADS_BANK0_GPIO0_IE_BITS, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_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_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; iobank0_hw->io[PINOUT_SWDIO].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
} }
@ -345,43 +359,37 @@ __STATIC_INLINE void PORT_SWD_SETUP (void) {
Disables the DAP Hardware I/O pins which configures: Disables the DAP Hardware I/O pins which configures:
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode. - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/ */
__STATIC_INLINE void PORT_OFF (void) { __STATIC_INLINE void PORT_OFF(void) {
sio_hw->gpio_oe_clr = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK sio_hw->gpio_oe_clr = PINOUT_SWCLK_MASK | PINOUT_SWDIO_MASK |
| PINOUT_TDI_MASK //| PINOUT_TDO_MASK PINOUT_TDI_MASK //| PINOUT_TDO_MASK
| PINOUT_nTRST_MASK | PINOUT_nRESET_MASK; | PINOUT_nTRST_MASK | PINOUT_nRESET_MASK;
} }
// SWCLK/TCK I/O pin ------------------------------------- // SWCLK/TCK I/O pin -------------------------------------
/** SWCLK/TCK I/O pin: Get Input. /** SWCLK/TCK I/O pin: Get Input.
\return Current status of the SWCLK/TCK DAP hardware I/O pin. \return Current status of the SWCLK/TCK DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) {
return (sio_hw->gpio_in & PINOUT_SWCLK_MASK) >> PINOUT_SWCLK; return (sio_hw->gpio_in & PINOUT_SWCLK_MASK) >> PINOUT_SWCLK;
} }
/** SWCLK/TCK I/O pin: Set Output to High. /** SWCLK/TCK I/O pin: Set Output to High.
Set the SWCLK/TCK DAP hardware I/O pin to high level. Set the SWCLK/TCK DAP hardware I/O pin to high level.
*/ */
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) { __STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void) { sio_hw->gpio_set = PINOUT_SWCLK_MASK; }
sio_hw->gpio_set = PINOUT_SWCLK_MASK;
}
/** SWCLK/TCK I/O pin: Set Output to Low. /** SWCLK/TCK I/O pin: Set Output to Low.
Set the SWCLK/TCK DAP hardware I/O pin to low level. Set the SWCLK/TCK DAP hardware I/O pin to low level.
*/ */
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) { __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) { sio_hw->gpio_clr = PINOUT_SWCLK_MASK; }
sio_hw->gpio_clr = PINOUT_SWCLK_MASK;
}
// SWDIO/TMS Pin I/O -------------------------------------- // SWDIO/TMS Pin I/O --------------------------------------
/** SWDIO/TMS I/O pin: Get Input. /** SWDIO/TMS I/O pin: Get Input.
\return Current status of the SWDIO/TMS DAP hardware I/O pin. \return Current status of the SWDIO/TMS DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) {
return (sio_hw->gpio_in & PINOUT_SWDIO_MASK) >> PINOUT_SWDIO; return (sio_hw->gpio_in & PINOUT_SWDIO_MASK) >> PINOUT_SWDIO;
} }
@ -390,28 +398,24 @@ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
/** SWDIO/TMS I/O pin: Set Output to High. /** SWDIO/TMS I/O pin: Set Output to High.
Set the SWDIO/TMS DAP hardware I/O pin to high level. Set the SWDIO/TMS DAP hardware I/O pin to high level.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) { __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) { sio_hw->gpio_set = PINOUT_SWDIO_MASK; }
sio_hw->gpio_set = PINOUT_SWDIO_MASK;
}
/** SWDIO/TMS I/O pin: Set Output to Low. /** SWDIO/TMS I/O pin: Set Output to Low.
Set the SWDIO/TMS DAP hardware I/O pin to low level. Set the SWDIO/TMS DAP hardware I/O pin to low level.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) { __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) { sio_hw->gpio_clr = PINOUT_SWDIO_MASK; }
sio_hw->gpio_clr = PINOUT_SWDIO_MASK;
}
/** SWDIO I/O pin: Get Input (used in SWD mode only). /** SWDIO I/O pin: Get Input (used in SWD mode only).
\return Current status of the SWDIO DAP hardware I/O pin. \return Current status of the SWDIO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void) {
return (sio_hw->gpio_in & PINOUT_SWDIO_MASK) ? 1U : 0U; return (sio_hw->gpio_in & PINOUT_SWDIO_MASK) ? 1U : 0U;
} }
/** SWDIO I/O pin: Set Output (used in SWD mode only). /** SWDIO I/O pin: Set Output (used in SWD mode only).
\param bit Output value for the SWDIO DAP hardware I/O pin. \param bit Output value for the SWDIO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) {
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_SWDIO_MASK; sio_hw->gpio_set = PINOUT_SWDIO_MASK;
else else
@ -422,55 +426,48 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) {
Configure the SWDIO DAP hardware I/O pin to output mode. This function is Configure the SWDIO DAP hardware I/O pin to output mode. This function is
called prior \ref PIN_SWDIO_OUT function calls. called prior \ref PIN_SWDIO_OUT function calls.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) { sio_hw->gpio_oe_set = PINOUT_SWDIO_MASK; }
sio_hw->gpio_oe_set = PINOUT_SWDIO_MASK;
}
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only). /** 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 Configure the SWDIO DAP hardware I/O pin to input mode. This function is
called prior \ref PIN_SWDIO_IN function calls. called prior \ref PIN_SWDIO_IN function calls.
*/ */
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) { __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) { sio_hw->gpio_oe_clr = PINOUT_SWDIO_MASK; }
sio_hw->gpio_oe_clr = PINOUT_SWDIO_MASK;
}
// TDI Pin I/O --------------------------------------------- // TDI Pin I/O ---------------------------------------------
/** TDI I/O pin: Get Input. /** TDI I/O pin: Get Input.
\return Current status of the TDI DAP hardware I/O pin. \return Current status of the TDI DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) {
return (sio_hw->gpio_in & PINOUT_TDI_MASK) >> PINOUT_JTAG_TDI; return (sio_hw->gpio_in & PINOUT_TDI_MASK) >> PINOUT_JTAG_TDI;
} }
/** TDI I/O pin: Set Output. /** TDI I/O pin: Set Output.
\param bit Output value for the TDI DAP hardware I/O pin. \param bit Output value for the TDI DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) {
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_TDI_MASK; sio_hw->gpio_set = PINOUT_TDI_MASK;
else else
sio_hw->gpio_clr = PINOUT_TDI_MASK; sio_hw->gpio_clr = PINOUT_TDI_MASK;
} }
// TDO Pin I/O --------------------------------------------- // TDO Pin I/O ---------------------------------------------
/** TDO I/O pin: Get Input. /** TDO I/O pin: Get Input.
\return Current status of the TDO DAP hardware I/O pin. \return Current status of the TDO DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) {
return (sio_hw->gpio_in & PINOUT_TDO_MASK) >> PINOUT_JTAG_TDO; return (sio_hw->gpio_in & PINOUT_TDO_MASK) >> PINOUT_JTAG_TDO;
} }
// nTRST Pin I/O ------------------------------------------- // nTRST Pin I/O -------------------------------------------
/** nTRST I/O pin: Get Input. /** nTRST I/O pin: Get Input.
\return Current status of the nTRST DAP hardware I/O pin. \return Current status of the nTRST DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) {
return (sio_hw->gpio_in & PINOUT_nTRST_MASK) >> PINOUT_JTAG_nTRST; return (sio_hw->gpio_in & PINOUT_nTRST_MASK) >> PINOUT_JTAG_nTRST;
} }
@ -479,7 +476,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
- 0: issue a JTAG TRST Test Reset. - 0: issue a JTAG TRST Test Reset.
- 1: release JTAG TRST Test Reset. - 1: release JTAG TRST Test Reset.
*/ */
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) {
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_nTRST_MASK; sio_hw->gpio_set = PINOUT_nTRST_MASK;
else else
@ -491,7 +488,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
/** nRESET I/O pin: Get Input. /** nRESET I/O pin: Get Input.
\return Current status of the nRESET DAP hardware I/O pin. \return Current status of the nRESET DAP hardware I/O pin.
*/ */
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) { __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) {
return (sio_hw->gpio_in & PINOUT_nRESET_MASK) >> PINOUT_JTAG_nRESET; return (sio_hw->gpio_in & PINOUT_nRESET_MASK) >> PINOUT_JTAG_nRESET;
} }
@ -500,7 +497,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
- 0: issue a device hardware reset. - 0: issue a device hardware reset.
- 1: release device hardware reset. - 1: release device hardware reset.
*/ */
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) { __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) {
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_nRESET_MASK; sio_hw->gpio_set = PINOUT_nRESET_MASK;
else else
@ -509,7 +506,6 @@ __STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs \defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
@ -528,7 +524,7 @@ It is recommended to provide the following LEDs for status indication:
- 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit. - 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. - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
*/ */
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) { __STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) {
#if PINOUT_LED_CONNECTED #if PINOUT_LED_CONNECTED
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_LED_MASK; sio_hw->gpio_set = PINOUT_LED_MASK;
@ -544,7 +540,7 @@ __STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {
- 1: Target Running LED ON: program execution in target started. - 1: Target Running LED ON: program execution in target started.
- 0: Target Running LED OFF: program execution in target stopped. - 0: Target Running LED OFF: program execution in target stopped.
*/ */
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) { __STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) {
#if PINOUT_LED_RUNNING #if PINOUT_LED_RUNNING
if (bit & 1) if (bit & 1)
sio_hw->gpio_set = PINOUT_LED_MASK; sio_hw->gpio_set = PINOUT_LED_MASK;
@ -557,7 +553,6 @@ __STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp \defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
@ -565,15 +560,16 @@ __STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {
@{ @{
Access function for Test Domain Timer. 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 The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET.
default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK. By default, the DWT timer is used. The frequency of this timer is configured with \ref
TIMESTAMP_CLOCK.
*/ */
/** Get timestamp of Test Domain Timer. /** Get timestamp of Test Domain Timer.
\return Current timestamp value. \return Current timestamp value.
*/ */
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) { __STATIC_INLINE uint32_t TIMESTAMP_GET(void) {
#if TIMESTAMP_CLOCK > 0 #if TIMESTAMP_CLOCK > 0
return (DWT->CYCCNT); return (DWT->CYCCNT);
#else #else
@ -583,7 +579,6 @@ __STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
///@} ///@}
//************************************************************************************************** //**************************************************************************************************
/** /**
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization \defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
@ -601,23 +596,17 @@ Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled an
- for nTRST, nRESET a weak pull-up (if available) is enabled. - for nTRST, nRESET a weak pull-up (if available) is enabled.
- LED output pins are enabled and LEDs are turned off. - LED output pins are enabled and LEDs are turned off.
*/ */
__STATIC_INLINE void DAP_SETUP (void) { __STATIC_INLINE void DAP_SETUP(void) {
sio_hw->gpio_oe_set = PINOUT_LED_MASK; sio_hw->gpio_oe_set = PINOUT_LED_MASK;
sio_hw->gpio_clr = 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); 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; iobank0_hw->io[PINOUT_LED].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB;
bi_decl(bi_2pins_with_names( bi_decl(bi_2pins_with_names(PINOUT_JTAG_TCK, "TCK / SWCLK", PINOUT_JTAG_TMS, "TMS / SWDIO"));
PINOUT_JTAG_TCK, "TCK / SWCLK", bi_decl(bi_4pins_with_names(PINOUT_JTAG_TDI, "TDI", PINOUT_JTAG_TDO, "TDO", PINOUT_JTAG_nTRST,
PINOUT_JTAG_TMS, "TMS / SWDIO" "nTRST", PINOUT_JTAG_nRESET, "nRESET"));
));
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. /** Reset Target Device with custom specific I/O pin or command sequence.
@ -627,7 +616,7 @@ when a device needs a time-critical unlock sequence that enables the debug port.
\return 0 = no device specific reset sequence is implemented.\n \return 0 = no device specific reset sequence is implemented.\n
1 = a device specific reset sequence is implemented. 1 = a device specific reset sequence is implemented.
*/ */
__STATIC_INLINE uint8_t RESET_TARGET (void) { __STATIC_INLINE uint8_t RESET_TARGET(void) {
return (0U); // change to '1' when a device reset sequence is implemented return (0U); // change to '1' when a device reset sequence is implemented
} }

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -40,7 +41,8 @@ extern "C" {
#define BUTTON_BOOTSEL #define BUTTON_BOOTSEL
#define BUTTON_STATE_ACTIVE 0 #define BUTTON_STATE_ACTIVE 0
#if !defined(USE_USBCDC_FOR_STDIO) && defined(PICO_DEFAULT_UART_TX_PIN) && defined(PICO_DEFAULT_UART_RX_PIN) && defined(PICO_DEFAULT_UART) #if !defined(USE_USBCDC_FOR_STDIO) && defined(PICO_DEFAULT_UART_TX_PIN) && \
defined(PICO_DEFAULT_UART_RX_PIN) && defined(PICO_DEFAULT_UART)
#define UART_DEV PICO_DEFAULT_UART #define UART_DEV PICO_DEFAULT_UART
#define UART_TX_PIN PICO_DEFAULT_UART_TX_PIN #define UART_TX_PIN PICO_DEFAULT_UART_TX_PIN
#define UART_RX_PIN PICO_DEFAULT_UART_RX_PIN #define UART_RX_PIN PICO_DEFAULT_UART_RX_PIN

View File

@ -1,15 +1,15 @@
// vim: set et:
#include <pico/time.h> #include <hardware/irq.h>
#include <pico/stdio.h>
#include <pico/stdio/driver.h>
#include <pico/binary_info.h> #include <pico/binary_info.h>
#include <pico/mutex.h> #include <pico/mutex.h>
#include <hardware/irq.h> #include <pico/stdio.h>
#include <pico/stdio/driver.h>
#include "tusb.h" #include <pico/time.h>
#include "pinout.h" #include "pinout.h"
#include "protocfg.h" #include "protocfg.h"
#include "tusb.h"
#ifndef PICO_STDIO_USB_STDOUT_TIMEOUT_US #ifndef PICO_STDIO_USB_STDOUT_TIMEOUT_US
#define PICO_STDIO_USB_STDOUT_TIMEOUT_US 500000 #define PICO_STDIO_USB_STDOUT_TIMEOUT_US 500000
@ -31,13 +31,13 @@ static void stdio_usb_out_chars(const char* buf, int length) {
} }
if (tud_cdc_n_connected(CDC_N_STDIO)) { if (tud_cdc_n_connected(CDC_N_STDIO)) {
for (int i = 0; i < length; ) { for (int i = 0; i < length;) {
int n = length - i; int n = length - i;
int avail = tud_cdc_n_write_available(CDC_N_STDIO); int avail = tud_cdc_n_write_available(CDC_N_STDIO);
if (n > avail) n = avail; if (n > avail) n = avail;
if (n) { if (n) {
int n2 = tud_cdc_n_write(CDC_N_STDIO, buf+i, n); int n2 = tud_cdc_n_write(CDC_N_STDIO, buf + i, n);
tud_task(); tud_task();
tud_cdc_n_write_flush(CDC_N_STDIO); tud_cdc_n_write_flush(CDC_N_STDIO);
i += n2; i += n2;
@ -47,8 +47,8 @@ static void stdio_usb_out_chars(const char* buf, int length) {
tud_cdc_n_write_flush(CDC_N_STDIO); tud_cdc_n_write_flush(CDC_N_STDIO);
if (!tud_cdc_n_connected(CDC_N_STDIO) || if (!tud_cdc_n_connected(CDC_N_STDIO) ||
(!tud_cdc_n_write_available(CDC_N_STDIO) (!tud_cdc_n_write_available(CDC_N_STDIO) &&
&& time_us_64() > last_avail_time + PICO_STDIO_USB_STDOUT_TIMEOUT_US)) { time_us_64() > last_avail_time + PICO_STDIO_USB_STDOUT_TIMEOUT_US)) {
break; break;
} }
} }
@ -73,6 +73,7 @@ static int stdio_usb_in_chars(char* buf, int length) {
if (tud_cdc_n_connected(CDC_N_STDIO) && tud_cdc_n_available(CDC_N_STDIO)) { if (tud_cdc_n_connected(CDC_N_STDIO) && tud_cdc_n_available(CDC_N_STDIO)) {
int count = tud_cdc_n_read(CDC_N_STDIO, buf, length); int count = tud_cdc_n_read(CDC_N_STDIO, buf, length);
rc = count ? count : PICO_ERROR_NO_DATA; rc = count ? count : PICO_ERROR_NO_DATA;
} }
@ -82,18 +83,20 @@ static int stdio_usb_in_chars(char* buf, int length) {
} }
extern stdio_driver_t stdio_usb; extern stdio_driver_t stdio_usb;
// clang-format off
stdio_driver_t stdio_usb = { stdio_driver_t stdio_usb = {
.out_chars = stdio_usb_out_chars, .out_chars = stdio_usb_out_chars,
. in_chars = stdio_usb_in_chars , .in_chars = stdio_usb_in_chars,
#if PICO_STDIO_ENABLE_CRLF_SUPPORT #if PICO_STDIO_ENABLE_CRLF_SUPPORT
.crlf_enabled = PICO_STDIO_DEFAULT_CRLF .crlf_enabled = PICO_STDIO_DEFAULT_CRLF
#endif #endif
}; };
// clang-format on
bool stdio_usb_init(void) { bool stdio_usb_init(void) {
//#if !PICO_NO_BI_STDIO_USB //#if !PICO_NO_BI_STDIO_USB
bi_decl_if_func_used(bi_program_feature("USB stdin / stdout")); bi_decl_if_func_used(bi_program_feature("USB stdin / stdout"));
//#endif //#endif
mutex_init(&stdio_usb_mutex); mutex_init(&stdio_usb_mutex);

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -23,13 +24,12 @@
* *
*/ */
#include <pico/stdlib.h>
#include <pico/binary_info.h> #include <pico/binary_info.h>
#include <pico/stdlib.h>
#include "tusb.h"
#include "pinout.h" #include "pinout.h"
#include "protos.h" #include "protos.h"
#include "tusb.h"
static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE]; static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE]; static uint8_t tx_buf[CFG_TUD_CDC_TX_BUFSIZE];
@ -52,9 +52,7 @@ void cdc_uart_task(void) {
if (tud_cdc_n_connected(CDC_N_UART)) { if (tud_cdc_n_connected(CDC_N_UART)) {
// Do we have anything to display on the host's terminal? // Do we have anything to display on the host's terminal?
if (rx_len) { if (rx_len) {
for (uint i = 0; i < rx_len; i++) { for (uint i = 0; i < rx_len; i++) { tud_cdc_n_write_char(CDC_N_UART, rx_buf[i]); }
tud_cdc_n_write_char(CDC_N_UART, rx_buf[i]);
}
tud_cdc_n_write_flush(CDC_N_UART); tud_cdc_n_write_flush(CDC_N_UART);
} }
@ -66,9 +64,7 @@ void cdc_uart_task(void) {
} }
} }
void cdc_uart_set_hwflow(bool enable) { void cdc_uart_set_hwflow(bool enable) { uart_set_hw_flow(PINOUT_UART_INTERFACE, enable, enable); }
uart_set_hw_flow(PINOUT_UART_INTERFACE, enable, enable);
}
void cdc_uart_set_baud_rate(uint32_t brate) { void cdc_uart_set_baud_rate(uint32_t brate) {
uart_init(PINOUT_UART_INTERFACE, line_coding->bit_rate); uart_init(PINOUT_UART_INTERFACE, line_coding->bit_rate);

View File

@ -1,16 +1,17 @@
// vim: set et:
#include <stdio.h> #include <stdio.h>
#include <pico/stdlib.h> #include <hardware/clocks.h>
#include <pico/binary_info.h>
#include <hardware/i2c.h> #include <hardware/i2c.h>
#include <hardware/resets.h> #include <hardware/resets.h>
#include <hardware/clocks.h> #include <pico/binary_info.h>
#include <pico/stdlib.h>
#include <pico/timeout_helper.h> #include <pico/timeout_helper.h>
#include "protocfg.h"
#include "pinout.h"
#include "i2ctinyusb.h" #include "i2ctinyusb.h"
#include "pinout.h"
#include "protocfg.h"
static int delay = 10, delay2 = 5; static int delay = 10, delay2 = 5;
@ -18,28 +19,28 @@ static int delay = 10, delay2 = 5;
// (mostly inspired by original I2CTinyUSB AVR firmware) // (mostly inspired by original I2CTinyUSB AVR firmware)
__attribute__((__always_inline__)) inline static void i2cio_set_sda(bool hi) { __attribute__((__always_inline__)) inline static void i2cio_set_sda(bool hi) {
if (hi) { if (hi) {
sio_hw->gpio_oe_clr = (1<<PINOUT_I2C_SDA); // SDA is input sio_hw->gpio_oe_clr = (1 << PINOUT_I2C_SDA); // SDA is input
// => pullup configured, so it'll go high // => pullup configured, so it'll go high
} else { } else {
sio_hw->gpio_oe_set = (1<<PINOUT_I2C_SDA); // SDA is output sio_hw->gpio_oe_set = (1 << PINOUT_I2C_SDA); // SDA is output
sio_hw->gpio_clr = (1<<PINOUT_I2C_SDA); // and drive it low sio_hw->gpio_clr = (1 << PINOUT_I2C_SDA); // and drive it low
} }
} }
__attribute__((__always_inline__)) inline static bool i2cio_get_sda(void) { __attribute__((__always_inline__)) inline static bool i2cio_get_sda(void) {
return (sio_hw->gpio_in & (1<<PINOUT_I2C_SDA)) != 0; return (sio_hw->gpio_in & (1 << PINOUT_I2C_SDA)) != 0;
} }
__attribute__((__always_inline__)) inline static void i2cio_set_scl(bool hi) { __attribute__((__always_inline__)) inline static void i2cio_set_scl(bool hi) {
busy_wait_us_32(delay2); busy_wait_us_32(delay2);
sio_hw->gpio_oe_set = (1<<PINOUT_I2C_SCL); // SCL is output sio_hw->gpio_oe_set = (1 << PINOUT_I2C_SCL); // SCL is output
if (hi) if (hi)
sio_hw->gpio_set = (1<<PINOUT_I2C_SCL); // SCL is high sio_hw->gpio_set = (1 << PINOUT_I2C_SCL); // SCL is high
else else
sio_hw->gpio_clr = (1<<PINOUT_I2C_SCL); // SCL is low sio_hw->gpio_clr = (1 << PINOUT_I2C_SCL); // SCL is low
busy_wait_us_32(delay2); busy_wait_us_32(delay2);
} }
__attribute__((__always_inline__)) inline static void i2cio_scl_toggle(void) { __attribute__((__always_inline__)) inline static void i2cio_scl_toggle(void) {
i2cio_set_scl(true ); i2cio_set_scl(true);
i2cio_set_scl(false); i2cio_set_scl(false);
} }
@ -56,13 +57,14 @@ static void __no_inline_not_in_flash_func(i2cio_repstart)(void) { // repstart co
} }
static void __no_inline_not_in_flash_func(i2cio_stop)(void) { // stop condition static void __no_inline_not_in_flash_func(i2cio_stop)(void) { // stop condition
i2cio_set_sda(false); i2cio_set_sda(false);
i2cio_set_scl(true ); i2cio_set_scl(true);
i2cio_set_sda(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 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) { for (int i = 6; i >= 0; --i) {
i2cio_set_sda((v & (1<<i)) != 0); i2cio_set_sda((v & (1 << i)) != 0);
i2cio_scl_toggle(); i2cio_scl_toggle();
} }
@ -76,7 +78,7 @@ static bool __no_inline_not_in_flash_func(i2cio_write7)(uint8_t v) { // return v
} }
static bool __no_inline_not_in_flash_func(i2cio_write8)(uint8_t v) { // return value: acked? static bool __no_inline_not_in_flash_func(i2cio_write8)(uint8_t v) { // return value: acked?
for (int i = 7; i >= 0; --i) { for (int i = 7; i >= 0; --i) {
i2cio_set_sda((v & (1<<i)) != 0); i2cio_set_sda((v & (1 << i)) != 0);
i2cio_scl_toggle(); i2cio_scl_toggle();
} }
@ -89,7 +91,7 @@ static bool __no_inline_not_in_flash_func(i2cio_write8)(uint8_t v) { // return v
return ack; return ack;
} }
static uint8_t __no_inline_not_in_flash_func(i2cio_read8)(bool last) { static uint8_t __no_inline_not_in_flash_func(i2cio_read8)(bool last) {
i2cio_set_sda(true ); i2cio_set_sda(true);
i2cio_set_scl(false); i2cio_set_scl(false);
uint8_t rv = 0; uint8_t rv = 0;
@ -101,8 +103,10 @@ static uint8_t __no_inline_not_in_flash_func(i2cio_read8)(bool last) {
i2cio_set_scl(false); i2cio_set_scl(false);
} }
if (last) i2cio_set_sda(true); if (last)
else i2cio_set_sda(false); i2cio_set_sda(true);
else
i2cio_set_sda(false);
i2cio_scl_toggle(); i2cio_scl_toggle();
i2cio_set_sda(true); i2cio_set_sda(true);
@ -123,16 +127,20 @@ static int __no_inline_not_in_flash_func(i2cex_probe_address)(uint16_t addr, boo
if (a10bit) { if (a10bit) {
// A10 magic higher 2 addr bits r/#w bit // A10 magic higher 2 addr bits r/#w bit
uint8_t addr1 = 0x70 | (((addr >> 8) & 3) << 1) | 0, uint8_t addr1 = 0x70 | (((addr >> 8) & 3) << 1) | 0, addr2 = addr & 0xff;
addr2 = addr & 0xff;
if (i2cio_write7(addr1)) { if (i2cio_write7(addr1)) {
if (i2cio_write8(addr2)) rv = 0; if (i2cio_write8(addr2))
else rv = PICO_ERROR_GENERIC; rv = 0;
} else rv = PICO_ERROR_GENERIC; else
rv = PICO_ERROR_GENERIC;
} else
rv = PICO_ERROR_GENERIC;
} else { } else {
if (i2cio_write8((addr << 1) & 0xff)) rv = 0; // acked: ok if (i2cio_write8((addr << 1) & 0xff))
else rv = PICO_ERROR_GENERIC; // nak :/ rv = 0; // acked: ok
else
rv = PICO_ERROR_GENERIC; // nak :/
} }
i2cio_stop(); i2cio_stop();
@ -150,7 +158,7 @@ inline static void i2cex_abort_xfer(i2c_inst_t* i2c) {
return; return;
#else #else
// now do the abort // now do the abort
i2c->hw->enable = 1 /*| (1<<2)*/ | (1<<1); i2c->hw->enable = 1 /*| (1<<2)*/ | (1 << 1);
// wait for M_TX_ABRT irq // wait for M_TX_ABRT irq
do { do {
/*if (timeout_check) { /*if (timeout_check) {
@ -160,7 +168,7 @@ inline static void i2cex_abort_xfer(i2c_inst_t* i2c) {
tight_loop_contents(); tight_loop_contents();
} while (/*!timeout &&*/ !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS)); } while (/*!timeout &&*/ !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_TX_ABRT_BITS));
// reset irq // reset irq
//if (!timeout) // if (!timeout)
(void)i2c->hw->clr_tx_abrt; (void)i2c->hw->clr_tx_abrt;
#endif #endif
} }
@ -168,12 +176,14 @@ inline static void i2cex_abort_xfer(i2c_inst_t* i2c) {
static int i2cex_write_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit, 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) { const uint8_t* src, size_t len, bool nostop, absolute_time_t until) {
timeout_state_t ts_; timeout_state_t ts_;
struct timeout_state* ts = &ts_; struct timeout_state* ts = &ts_;
check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until); check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until);
if ((int)len < 0) return PICO_ERROR_GENERIC; if ((int)len < 0) return PICO_ERROR_GENERIC;
if (a10bit) { // addr too high if (a10bit) { // addr too high
if (addr & ~(uint16_t)((1<<10)-1)) return PICO_ERROR_GENERIC; if (addr & ~(uint16_t)((1 << 10) - 1)) return PICO_ERROR_GENERIC;
} else if (addr & 0x80) } else if (addr & 0x80)
return PICO_ERROR_GENERIC; return PICO_ERROR_GENERIC;
@ -185,20 +195,21 @@ static int i2cex_write_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bi
i2c->hw->enable = 0; i2c->hw->enable = 0;
// enable 10bit mode if requested // enable 10bit mode if requested
hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS, (a10bit // clang-format off
? I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_10BITS hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS,
: I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_7BITS ) << I2C_IC_CON_IC_10BITADDR_MASTER_LSB); (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->tar = addr;
i2c->hw->enable = 1; i2c->hw->enable = 1;
for (byte_ctr = 0; byte_ctr < (int)len; ++byte_ctr) { for (byte_ctr = 0; byte_ctr < (int)len; ++byte_ctr) {
bool first = byte_ctr == 0, bool first = byte_ctr == 0, last = byte_ctr == (int)len - 1;
last = byte_ctr == (int)len - 1;
i2c->hw->data_cmd = i2c->hw->data_cmd = (bool_to_bit(first && i2c->restart_on_next) << I2C_IC_DATA_CMD_RESTART_LSB)
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)
bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB | | *src++;
*src++;
do { do {
if (timeout_check) { if (timeout_check) {
@ -222,15 +233,19 @@ static int i2cex_write_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bi
abort |= timeout; abort |= timeout;
} }
tight_loop_contents(); tight_loop_contents();
// clang-format off
} while (!timeout && !(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS)); } 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; if (!timeout)
(void)i2c->hw->clr_stop_det;
else else
// if we had a timeout, send an abort request to the hardware, // if we had a timeout, send an abort request to the hardware,
// so that the bus gets released // so that the bus gets released
i2cex_abort_xfer(i2c); i2cex_abort_xfer(i2c);
} }
} else i2cex_abort_xfer(i2c); } else
i2cex_abort_xfer(i2c);
if (abort) break; if (abort) break;
} }
@ -238,38 +253,44 @@ static int i2cex_write_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bi
int rval; int rval;
if (abort) { if (abort) {
// clang-format off
const int addr_noack = I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS 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_10ADDR1_NOACK_BITS
| I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS; | I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS;
// clang-format on
if (timeout) rval = PICO_ERROR_TIMEOUT; if (timeout)
rval = PICO_ERROR_TIMEOUT;
else if (!abort_reason || (abort_reason & addr_noack)) else if (!abort_reason || (abort_reason & addr_noack))
rval = PICO_ERROR_GENERIC; rval = PICO_ERROR_GENERIC;
else if (abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS) else if (abort_reason & I2C_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK_BITS)
rval = byte_ctr; rval = byte_ctr;
else rval = PICO_ERROR_GENERIC; else
} else rval = byte_ctr; rval = PICO_ERROR_GENERIC;
} else
rval = byte_ctr;
i2c->restart_on_next = nostop; i2c->restart_on_next = nostop;
return rval; return rval;
} }
static int i2cex_read_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit, static int i2cex_read_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit, uint8_t* dst,
uint8_t* dst, size_t len, bool nostop, absolute_time_t until) { size_t len, bool nostop, absolute_time_t until) {
timeout_state_t ts_; timeout_state_t ts_;
struct timeout_state* ts = &ts_; struct timeout_state* ts = &ts_;
check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until); check_timeout_fn timeout_check = init_single_timeout_until(&ts_, until);
if ((int)len < 0) return PICO_ERROR_GENERIC; if ((int)len < 0) return PICO_ERROR_GENERIC;
if (a10bit) { // addr too high if (a10bit) { // addr too high
if (addr & ~(uint16_t)((1<<10)-1)) return PICO_ERROR_GENERIC; if (addr & ~(uint16_t)((1 << 10) - 1)) return PICO_ERROR_GENERIC;
} else if (addr & 0x80) } else if (addr & 0x80)
return PICO_ERROR_GENERIC; return PICO_ERROR_GENERIC;
i2c->hw->enable = 0; i2c->hw->enable = 0;
// enable 10bit mode if requested // enable 10bit mode if requested
hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS, (a10bit hw_write_masked(&i2c->hw->con, I2C_IC_CON_IC_10BITADDR_MASTER_BITS,
? I2C_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_10BITS (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_IC_CON_IC_10BITADDR_MASTER_VALUE_ADDR_7BITS)
<< I2C_IC_CON_IC_10BITADDR_MASTER_LSB);
i2c->hw->tar = addr; i2c->hw->tar = addr;
i2c->hw->enable = 1; i2c->hw->enable = 1;
@ -299,8 +320,8 @@ static int i2cex_read_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit
} }
if (abort) break; if (abort) break;
i2c->hw->data_cmd = i2c->hw->data_cmd = bool_to_bit(first && i2c->restart_on_next)
bool_to_bit(first && i2c->restart_on_next) << I2C_IC_DATA_CMD_RESTART_LSB | << I2C_IC_DATA_CMD_RESTART_LSB |
bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB | bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB |
I2C_IC_DATA_CMD_CMD_BITS; // -> 1 for read I2C_IC_DATA_CMD_CMD_BITS; // -> 1 for read
@ -323,23 +344,27 @@ static int i2cex_read_blocking_until(i2c_inst_t* i2c, uint16_t addr, bool a10bit
if (abort) break; if (abort) break;
uint8_t v = (uint8_t)i2c->hw->data_cmd; uint8_t v = (uint8_t)i2c->hw->data_cmd;
//printf("\ngot read %02x\n", v); // printf("\ngot read %02x\n", v);
*dst++ = v; *dst++ = v;
} }
int rval; int rval;
if (abort) { if (abort) {
//printf("\ngot abrt: "); // printf("\ngot abrt: ");
const int addr_noack = I2C_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK_BITS 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_10ADDR1_NOACK_BITS |
| I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS; I2C_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK_BITS;
if (timeout) { /*printf("timeout\n");*/ rval = PICO_ERROR_TIMEOUT; } if (timeout) { /*printf("timeout\n");*/
else if (!abort_reason || (abort_reason & addr_noack)) {//printf("disconn\n"); rval = PICO_ERROR_TIMEOUT;
rval = PICO_ERROR_GENERIC; } } else if (!abort_reason || (abort_reason & addr_noack)) { // printf("disconn\n");
else {/*printf("unk\n");*/ rval = PICO_ERROR_GENERIC;} rval = PICO_ERROR_GENERIC;
} else rval = byte_ctr; } else { /*printf("unk\n");*/
rval = PICO_ERROR_GENERIC;
}
} else
rval = byte_ctr;
i2c->restart_on_next = nostop; i2c->restart_on_next = nostop;
return rval; return rval;
@ -349,14 +374,13 @@ static inline int i2cex_write_timeout_us(i2c_inst_t* i2c, uint16_t addr, bool a1
absolute_time_t t = make_timeout_time_us(timeout_us); absolute_time_t t = make_timeout_time_us(timeout_us);
return i2cex_write_blocking_until(i2c, addr, a10bit, src, len, nostop, t); 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, static inline int i2cex_read_timeout_us(i2c_inst_t* i2c, uint16_t addr, bool a10bit, uint8_t* dst,
uint8_t* dst, size_t len, bool nostop, uint32_t timeout_us) { size_t len, bool nostop, uint32_t timeout_us) {
absolute_time_t t = make_timeout_time_us(timeout_us); absolute_time_t t = make_timeout_time_us(timeout_us);
return i2cex_read_blocking_until(i2c, addr, a10bit, dst, len, nostop, t); return i2cex_read_blocking_until(i2c, addr, a10bit, dst, len, nostop, t);
} }
__attribute__((__const__)) __attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void) {
enum ki2c_funcs i2ctu_get_func(void) {
// TODO: SMBUS_EMUL_ALL => I2C_M_RECV_LEN // TODO: SMBUS_EMUL_ALL => I2C_M_RECV_LEN
// TODO: maybe also PROTOCOL_MANGLING, NOSTART // TODO: maybe also PROTOCOL_MANGLING, NOSTART
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
@ -364,8 +388,9 @@ enum ki2c_funcs i2ctu_get_func(void) {
void i2ctu_init(void) { void i2ctu_init(void) {
// default to 100 kHz (SDK example default so should be ok) // default to 100 kHz (SDK example default so should be ok)
delay = 10; delay2 = 5; delay = 10;
i2c_init(PINOUT_I2C_DEV, 100*1000); delay2 = 5;
i2c_init(PINOUT_I2C_DEV, 100 * 1000);
gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C); gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C);
gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C); gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C);
@ -383,10 +408,9 @@ uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us) {
return i2c_set_baudrate(PINOUT_I2C_DEV, freq); return i2c_set_baudrate(PINOUT_I2C_DEV, freq);
} }
enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, const uint8_t* buf, size_t len) { const uint8_t* buf, size_t len) {
bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END); bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END);
//printf("nostop=%c ", nostop?'t':'f');
bool bit10 = flags & I2C_M_TEN; bool bit10 = flags & I2C_M_TEN;
/*if (len == 0) { /*if (len == 0) {
@ -396,17 +420,16 @@ enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopfla
nostop, 1000*1000); nostop, 1000*1000);
if (rv < 0) return ITU_STATUS_ADDR_NAK; if (rv < 0) return ITU_STATUS_ADDR_NAK;
return ITU_STATUS_ADDR_ACK; return ITU_STATUS_ADDR_ACK;
} else*/ { } else*/
int rv = i2cex_write_timeout_us(PINOUT_I2C_DEV, addr, bit10, buf, len, {
nostop, 1000*1000); 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; if (rv < 0 || (size_t)rv < len) return ITU_STATUS_ADDR_NAK;
return ITU_STATUS_ADDR_ACK; return ITU_STATUS_ADDR_ACK;
} }
} }
enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, uint8_t* buf, size_t len) { uint8_t* buf, size_t len) {
bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END); bool nostop = !(startstopflags & ITU_CMD_I2C_IO_END);
//printf("nostop=%c ", nostop?'t':'f');
bool bit10 = flags & I2C_M_TEN; bool bit10 = flags & I2C_M_TEN;
/*if (len == 0) { /*if (len == 0) {
@ -415,10 +438,10 @@ enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflag
nostop, 1000*1000); nostop, 1000*1000);
if (rv < 0) return ITU_STATUS_ADDR_NAK; if (rv < 0) return ITU_STATUS_ADDR_NAK;
return ITU_STATUS_ADDR_ACK; return ITU_STATUS_ADDR_ACK;
} else*/ { } else*/
int rv = i2cex_read_timeout_us(PINOUT_I2C_DEV, addr, bit10, buf, len, {
nostop, 1000*1000); 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]); // printf("p le rv=%d buf=%02x ", rv, buf[0]);
if (rv < 0 || (size_t)rv < len) return ITU_STATUS_ADDR_NAK; if (rv < 0 || (size_t)rv < len) return ITU_STATUS_ADDR_NAK;
return ITU_STATUS_ADDR_ACK; return ITU_STATUS_ADDR_ACK;
} }

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef PINOUT_H_ #ifndef PINOUT_H_
#define PINOUT_H_ #define PINOUT_H_

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef PROTOCFG_H_ #ifndef PROTOCFG_H_
#define PROTOCFG_H_ #define PROTOCFG_H_

View File

@ -1,29 +1,27 @@
// vim: set et:
#include <stdio.h> #include <stdio.h>
#include <pico/stdlib.h>
#include <pico/binary_info.h>
#include <hardware/spi.h> #include <hardware/spi.h>
#include <pico/binary_info.h>
#include <pico/stdlib.h>
#include "pinout.h" #include "pinout.h"
#include "protos.h" #include "protos.h"
#include "serprog.h" #include "serprog.h"
static bool cs_asserted; static bool cs_asserted;
void sp_spi_init(void) { void sp_spi_init(void) {
//printf("spi init!\n");
cs_asserted = false; cs_asserted = false;
spi_init(PINOUT_SPI_DEV, 512*1000); // default to 512 kHz 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_MISO, GPIO_FUNC_SPI);
gpio_set_function(PINOUT_SPI_MOSI, 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_SCLK, GPIO_FUNC_SPI);
//gpio_set_function(PINOUT_SPI_nCS, GPIO_FUNC_SIO); // gpio_set_function(PINOUT_SPI_nCS, GPIO_FUNC_SIO);
gpio_init(PINOUT_SPI_nCS); gpio_init(PINOUT_SPI_nCS);
gpio_put(PINOUT_SPI_nCS, 1); gpio_put(PINOUT_SPI_nCS, 1);
gpio_set_dir(PINOUT_SPI_nCS, GPIO_OUT); gpio_set_dir(PINOUT_SPI_nCS, GPIO_OUT);
@ -48,7 +46,7 @@ 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_begin)(void) {
//sp_spi_cs_select(); // sp_spi_cs_select();
if (!cs_asserted) { if (!cs_asserted) {
asm volatile("nop\nnop\nnop"); // idk if this is needed asm volatile("nop\nnop\nnop"); // idk if this is needed
gpio_put(PINOUT_SPI_nCS, 0); gpio_put(PINOUT_SPI_nCS, 0);
@ -56,7 +54,7 @@ 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_end)(void) {
//sp_spi_cs_deselect(); // sp_spi_cs_deselect();
if (!cs_asserted) { // YES, this condition is the intended one! if (!cs_asserted) { // YES, this condition is the intended one!
asm volatile("nop\nnop\nnop"); // idk if this is needed asm volatile("nop\nnop\nnop"); // idk if this is needed
gpio_put(PINOUT_SPI_nCS, 1); gpio_put(PINOUT_SPI_nCS, 1);

View File

@ -1,8 +1,9 @@
// vim: set et:
#include <hardware/adc.h>
#include "tempsensor.h" #include "tempsensor.h"
#include <hardware/adc.h>
#define T_SLOPE (-0.001721f) #define T_SLOPE (-0.001721f)
#define T_BIAS (0.706f) #define T_BIAS (0.706f)
#define V_MAX (3.3f) #define V_MAX (3.3f)
@ -10,13 +11,14 @@
#define T_OFF (27) #define T_OFF (27)
// convert float to x.4 fixed format // convert float to x.4 fixed format
#define float2fix(x) (int)((x)*(1<<4)) #define float2fix(x) (int)((x) * (1 << 4))
// convert x.4 fixed to 8.4 fixed // convert x.4 fixed to 8.4 fixed
__attribute__((__const__)) __attribute__((__const__)) inline static int16_t trunc_8fix4(int fix) {
inline static int16_t trunc_8fix4(int fix) { // clang-format off
if (fix > 4095) fix = 4095; if (fix > 4095) fix = 4095;
if (fix < -4096) fix = -4096; if (fix < -4096) fix = -4096;
// clang-format on
return fix; return fix;
} }
@ -37,11 +39,13 @@ int16_t tempsense_dev_get_temp(void) {
/*int temperature = float2fix(T_OFF - T_BIAS / T_SLOPE) /*int temperature = float2fix(T_OFF - T_BIAS / T_SLOPE)
+ (int)result * float2fix(V_MAX / (D_RANGE * T_SLOPE));*/ + (int)result * float2fix(V_MAX / (D_RANGE * T_SLOPE));*/
return trunc_8fix4(/*temperature*/float2fix(tempf)); return trunc_8fix4(/*temperature*/ float2fix(tempf));
} }
// RP2040 absolute min/max are -20/85 // 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_lower(void) { return trunc_8fix4(float2fix(-15)); }
int16_t tempsense_dev_get_upper(void) { return trunc_8fix4(float2fix( 75)); } int16_t tempsense_dev_get_upper(void) { return trunc_8fix4(float2fix( 75)); }
int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 80)); } int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 80)); }
// clang-format on

View File

@ -1,12 +1,16 @@
// vim: set et:
#include <stdint.h> #include <stdint.h>
#include <pico/stdlib.h> #include <pico/stdlib.h>
#include <pico/unique_id.h> #include <pico/unique_id.h>
#include "tusb.h"
#include "tusb.h"
#include "util.h" #include "util.h"
uint8_t get_unique_id_u8(uint8_t *desc_str) { uint8_t get_unique_id_u8(uint8_t* desc_str) {
pico_unique_board_id_t uid; pico_unique_board_id_t uid;
uint8_t chr_count = 0; uint8_t chr_count = 0;
pico_get_unique_board_id(&uid); pico_get_unique_board_id(&uid);
@ -22,8 +26,9 @@ uint8_t get_unique_id_u8(uint8_t *desc_str) {
return chr_count; return chr_count;
} }
uint8_t get_unique_id_u16(uint16_t *desc_str) { uint8_t get_unique_id_u16(uint16_t* desc_str) {
pico_unique_board_id_t uid; pico_unique_board_id_t uid;
uint8_t chr_count = 0; uint8_t chr_count = 0;
pico_get_unique_board_id(&uid); pico_get_unique_board_id(&uid);

View File

@ -1,3 +1,4 @@
// vim: set et:
/* derived from libco v20, by byuu (ISC) */ /* derived from libco v20, by byuu (ISC) */

View File

@ -1,17 +1,16 @@
// vim: set et:
#include <stdio.h> #include <stdio.h>
#include "tusb.h"
#include "protocfg.h" #include "protocfg.h"
#include "tusb.h"
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
#include "protos.h" #include "protos.h"
#include "util.h"
#include "rtconf.h" #include "rtconf.h"
#include "serprog.h" #include "serprog.h"
#include "util.h"
// TODO: refactor some of this stuff into another header & split off serprog // TODO: refactor some of this stuff into another header & split off serprog
// protocol handling from the SPI stuff. one thing we should think about // protocol handling from the SPI stuff. one thing we should think about
@ -22,6 +21,7 @@
// kinda refactored this already but it still has a good note for non-SPI stuff, // kinda refactored this already but it still has a good note for non-SPI stuff,
// so leaving it here for now // so leaving it here for now
// clang-format off
static const uint8_t serprog_cmdmap[32] = { 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 0x3f, // cmd 00..05 not 0x06 (Q_CHIPSIZE) and 0x07 (Q_OPBUF), as this is a SPI-only device
0x01, // only cmd 08 0x01, // only cmd 08
@ -31,12 +31,13 @@ static const uint8_t serprog_cmdmap[32] = {
0, // 28..2f 0, // 28..2f
0, // 30..37 0, // 30..37
0, // 38..3f 0, // 38..3f
0, // 40..47 0, // 4<0..47
0, // 48..4f 0, // 48..4f
(1<<3), // 50..57: enable 0x53 (1 << 3), // 50..57: enable 0x53
0, // 58..5f 0, // 58..5f
0, // rest is 0 0, // rest is 0
}; };
// clang-format on
static const char serprog_pgmname[16] = INFO_PRODUCT_BARE; static const char serprog_pgmname[16] = INFO_PRODUCT_BARE;
static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE]; static uint8_t rx_buf[CFG_TUD_CDC_RX_BUFSIZE];
@ -71,9 +72,9 @@ static uint8_t read_byte(void) {
} }
static void handle_cmd(void) { static void handle_cmd(void) {
uint32_t nresp = 0; uint32_t nresp = 0;
uint8_t cmd = read_byte(); uint8_t cmd = read_byte();
switch (cmd) { switch (cmd) {
case S_CMD_NOP: case S_CMD_NOP:
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
@ -108,25 +109,25 @@ uint8_t cmd = read_byte();
break; break;
case S_CMD_Q_BUSTYPE: case S_CMD_Q_BUSTYPE:
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tx_buf[1] = 1<<3; // SPI only tx_buf[1] = 1 << 3; // SPI only
nresp = 2; nresp = 2;
break; break;
case S_CMD_Q_WRNMAXLEN: case S_CMD_Q_WRNMAXLEN:
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tx_buf[1] = (sizeof(tx_buf)-1) & 0xff; tx_buf[1] = (sizeof(tx_buf) - 1) & 0xff;
tx_buf[2] = ((sizeof(tx_buf)-1) >> 8) & 0xff; tx_buf[2] = ((sizeof(tx_buf) - 1) >> 8) & 0xff;
tx_buf[3] = ((sizeof(tx_buf)-1) >>16) & 0xff; tx_buf[3] = ((sizeof(tx_buf) - 1) >> 16) & 0xff;
nresp = 4; nresp = 4;
break; break;
case S_CMD_Q_RDNMAXLEN: case S_CMD_Q_RDNMAXLEN:
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tx_buf[1] = (sizeof(rx_buf)-1) & 0xff; tx_buf[1] = (sizeof(rx_buf) - 1) & 0xff;
tx_buf[2] = ((sizeof(rx_buf)-1) >> 8) & 0xff; tx_buf[2] = ((sizeof(rx_buf) - 1) >> 8) & 0xff;
tx_buf[3] = ((sizeof(rx_buf)-1) >>16) & 0xff; tx_buf[3] = ((sizeof(rx_buf) - 1) >> 16) & 0xff;
nresp = 4; nresp = 4;
break; break;
case S_CMD_S_BUSTYPE: case S_CMD_S_BUSTYPE:
if (read_byte()/* bus type to set */ == (1<<3)) { if (read_byte() /* bus type to set */ == (1 << 3)) {
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
} else { } else {
tx_buf[0] = S_NAK; tx_buf[0] = S_NAK;
@ -136,12 +137,15 @@ uint8_t cmd = read_byte();
case S_CMD_SPIOP: { case S_CMD_SPIOP: {
uint32_t slen, rlen; uint32_t slen, rlen;
// clang-format off
slen = (uint32_t)read_byte(); slen = (uint32_t)read_byte();
slen |= (uint32_t)read_byte() << 8; slen |= (uint32_t)read_byte() << 8;
slen |= (uint32_t)read_byte() << 16; slen |= (uint32_t)read_byte() << 16;
rlen = (uint32_t)read_byte(); rlen = (uint32_t)read_byte();
rlen |= (uint32_t)read_byte() << 8; rlen |= (uint32_t)read_byte() << 8;
rlen |= (uint32_t)read_byte() << 16; rlen |= (uint32_t)read_byte() << 16;
// clang-format on
sp_spi_op_begin(); sp_spi_op_begin();
size_t this_batch; size_t this_batch;
@ -160,11 +164,11 @@ uint8_t cmd = read_byte();
// 2. write data // 2. write data
// first, do a batch of 63, because we also need to send an ACK byte // first, do a batch of 63, because we also need to send an ACK byte
this_batch = sizeof(tx_buf)-1; this_batch = sizeof(tx_buf) - 1;
if (this_batch > rlen) this_batch = rlen; if (this_batch > rlen) this_batch = rlen;
sp_spi_op_read(this_batch, &tx_buf[1]); sp_spi_op_read(this_batch, &tx_buf[1]);
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch+1); tud_cdc_n_write(CDC_N_SERPROG, tx_buf, this_batch + 1);
rlen -= this_batch; rlen -= this_batch;
// now do in batches of 64 // now do in batches of 64
@ -182,32 +186,34 @@ uint8_t cmd = read_byte();
// that's it! // that's it!
sp_spi_op_end(); sp_spi_op_end();
nresp = 0; // we sent our own response manually nresp = 0; // we sent our own response manually
} } break;
break;
case S_CMD_S_SPI_FREQ: { case S_CMD_S_SPI_FREQ: {
uint32_t freq; uint32_t freq;
// clang-format off
freq = (uint32_t)read_byte(); freq = (uint32_t)read_byte();
freq |= (uint32_t)read_byte() << 8; freq |= (uint32_t)read_byte() << 8;
freq |= (uint32_t)read_byte() << 16; freq |= (uint32_t)read_byte() << 16;
freq |= (uint32_t)read_byte() << 24; freq |= (uint32_t)read_byte() << 24;
// clang-format on
uint32_t nfreq = sp_spi_set_freq(freq); uint32_t nfreq = sp_spi_set_freq(freq);
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tx_buf[1] = nfreq & 0xff; tx_buf[1] = nfreq & 0xff;
tx_buf[2] = (nfreq >> 8) & 0xff; tx_buf[2] = (nfreq >> 8) & 0xff;
tx_buf[3] = (nfreq >> 16) & 0xff; tx_buf[3] = (nfreq >> 16) & 0xff;
tx_buf[4] = (nfreq >> 24) & 0xff; tx_buf[4] = (nfreq >> 24) & 0xff;
nresp = 5; nresp = 5;
} } break;
break;
case S_CMD_S_PINSTATE: { case S_CMD_S_PINSTATE: {
if (read_byte() == 0) sp_spi_cs_deselect(); if (read_byte() == 0)
else sp_spi_cs_select(); sp_spi_cs_deselect();
else
sp_spi_cs_select();
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
nresp = 1; nresp = 1;
} } break;
break;
case S_CMD_MAGIC_SETTINGS: { case S_CMD_MAGIC_SETTINGS: {
uint8_t a = read_byte(); uint8_t a = read_byte();
@ -216,8 +222,7 @@ uint8_t cmd = read_byte();
tx_buf[0] = S_ACK; tx_buf[0] = S_ACK;
tx_buf[1] = rtconf_do(a, b); tx_buf[1] = rtconf_do(a, b);
nresp = 2; nresp = 2;
} } break;
break;
default: default:
tx_buf[0] = S_NAK; tx_buf[0] = S_NAK;
@ -231,9 +236,7 @@ uint8_t cmd = read_byte();
} }
} }
void cdc_serprog_task(void) { void cdc_serprog_task(void) { handle_cmd(); }
handle_cmd();
}
#endif /* DBOARD_HAS_SERPROG */ #endif /* DBOARD_HAS_SERPROG */

View File

@ -1,10 +1,11 @@
// vim: set et:
#ifndef I2CTINYUSB_H_ #ifndef I2CTINYUSB_H_
#define I2CTINYUSB_H_ #define I2CTINYUSB_H_
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "protocfg.h" #include "protocfg.h"
@ -14,21 +15,17 @@ enum itu_command {
ITU_CMD_SET_DELAY = 2, ITU_CMD_SET_DELAY = 2,
ITU_CMD_GET_STATUS = 3, ITU_CMD_GET_STATUS = 3,
ITU_CMD_I2C_IO_BEGIN_F = (1<<0), ITU_CMD_I2C_IO_BEGIN_F = (1 << 0),
ITU_CMD_I2C_IO_END_F = (1<<1), 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_DIR_MASK = ITU_CMD_I2C_IO_BEGIN_F | ITU_CMD_I2C_IO_END_F,
ITU_CMD_I2C_IO = 4, ITU_CMD_I2C_IO = 4,
ITU_CMD_I2C_IO_BEGIN = 4 | ITU_CMD_I2C_IO_BEGIN_F, 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_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, ITU_CMD_I2C_IO_BEGINEND = 4 | ITU_CMD_I2C_IO_BEGIN_F | ITU_CMD_I2C_IO_END_F,
}; };
enum itu_status { enum itu_status { ITU_STATUS_IDLE = 0, ITU_STATUS_ADDR_ACK = 1, ITU_STATUS_ADDR_NAK = 2 };
ITU_STATUS_IDLE = 0,
ITU_STATUS_ADDR_ACK = 1,
ITU_STATUS_ADDR_NAK = 2
};
// these two are lifted straight from the linux kernel, lmao // these two are lifted straight from the linux kernel, lmao
enum ki2c_flags { enum ki2c_flags {
@ -74,18 +71,17 @@ enum ki2c_funcs {
I2C_FUNC_SMBUS_BLOCK_DATA = (I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_BLOCK_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_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_EMUL = (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL |
I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_PEC), I2C_FUNC_SMBUS_PEC),
/* if I2C_M_RECV_LEN is also supported */ /* 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_EMUL_ALL =
I2C_FUNC_SMBUS_BLOCK_PROC_CALL), (I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL),
}; };
__attribute__((__packed__)) __attribute__((__packed__)) struct itu_cmd {
struct itu_cmd {
uint16_t flags; uint16_t flags;
uint16_t addr; uint16_t addr;
uint16_t len; uint16_t len;
@ -93,14 +89,13 @@ struct itu_cmd {
}; };
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
__attribute__((__const__)) __attribute__((__const__)) enum ki2c_funcs i2ctu_get_func(void);
enum ki2c_funcs i2ctu_get_func(void);
void i2ctu_init(void); void i2ctu_init(void);
uint32_t i2ctu_set_freq(uint32_t freq, uint32_t us); // returns selected frequency, or 0 on error 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, enum itu_status i2ctu_write(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, const uint8_t* buf, size_t len); const uint8_t* buf, size_t len);
enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, enum itu_status i2ctu_read(enum ki2c_flags flags, enum itu_command startstopflags, uint16_t addr,
uint16_t addr, uint8_t* buf, size_t len); uint8_t* buf, size_t len);
#endif #endif
#endif #endif

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -23,10 +24,12 @@
* *
*/ */
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
// include order is sensitive here
// clang-format off
#include "tusb_config.h" #include "tusb_config.h"
#include "bsp/board.h" /* a tinyusb header */ #include "bsp/board.h" /* a tinyusb header */
@ -39,18 +42,15 @@
#include "protocfg.h" #include "protocfg.h"
#include "protos.h" #include "protos.h"
#include "libco.h" #include "libco.h"
// clang-format on
#ifdef PICO_BOARD #ifdef PICO_BOARD
#include <pico/binary_info.h> #include <pico/binary_info.h>
/*#include <hardware/i2c.h>
#include "pinout.h"*/
#endif #endif
static cothread_t mainthread; static cothread_t mainthread;
void thread_yield(void) { void thread_yield(void) { co_switch(mainthread); }
co_switch(mainthread);
}
#define DEFAULT_STACK_SIZE 1024 #define DEFAULT_STACK_SIZE 1024
@ -95,14 +95,6 @@ int main(void) {
#if defined(PICO_BOARD) && !defined(USE_USBCDC_FOR_STDIO) #if defined(PICO_BOARD) && !defined(USE_USBCDC_FOR_STDIO)
// use hardcoded values from TinyUSB board.h // use hardcoded values from TinyUSB board.h
bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART)); bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART));
/*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));*/
#endif #endif
board_init(); board_init();
@ -125,16 +117,11 @@ int main(void) {
#endif #endif
while (1) { while (1) {
/*uint8_t val = 0x12;
i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000);*/
tud_task(); // tinyusb device task tud_task(); // tinyusb device task
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
co_switch(uartthread); co_switch(uartthread);
#endif #endif
//i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000);
tud_task(); // tinyusb device task tud_task(); // tinyusb device task
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
co_switch(serprogthread); co_switch(serprogthread);
@ -151,27 +138,27 @@ int main(void) {
// Invoked when received GET_REPORT control request // Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length. // Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request // Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type,
hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { uint8_t* buffer, uint16_t reqlen) {
// TODO not Implemented // TODO not Implemented
(void) instance; (void)instance;
(void) report_id; (void)report_id;
(void) report_type; (void)report_type;
(void) buffer; (void)buffer;
(void) reqlen; (void)reqlen;
return 0; return 0;
} }
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type,
hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize) { uint8_t const* RxDataBuffer, uint16_t bufsize) {
static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE]; static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize); uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize);
// This doesn't use multiple report and report ID // This doesn't use multiple report and report ID
(void) instance; (void)instance;
(void) report_id; (void)report_id;
(void) report_type; (void)report_type;
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); DAP_ProcessCommand(RxDataBuffer, TxDataBuffer);

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef PROTOS_H_ #ifndef PROTOS_H_
#define PROTOS_H_ #define PROTOS_H_

View File

@ -1,10 +1,11 @@
// vim: set et:
#include "rtconf.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "protos.h" #include "protos.h"
#include "rtconf.h"
#include "tempsensor.h" #include "tempsensor.h"
enum { enum {
@ -15,10 +16,9 @@ enum {
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
| 2 | 2
#endif #endif
// always true #ifdef DBOARD_HAS_SERPROG
/*#ifdef DBOARD_HAS_SERPROG
| 4 | 4
#endif*/ #endif
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
| 4 | 4
#endif #endif
@ -34,26 +34,25 @@ enum {
uint8_t rtconf_do(uint8_t a, uint8_t b) { uint8_t rtconf_do(uint8_t a, uint8_t b) {
switch ((enum rtconf_opt)a) { switch ((enum rtconf_opt)a) {
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
case opt_uart_hwfc_endis: case opt_uart_hwfc_endis: cdc_uart_set_hwflow(b != 0); return 0;
cdc_uart_set_hwflow(b != 0);
return 0;
#endif #endif
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
case opt_tempsense_enaddr: { case opt_tempsense_enaddr: {
bool act = tempsense_get_active(); bool act = tempsense_get_active();
uint8_t addr = tempsense_get_addr(); uint8_t addr = tempsense_get_addr();
printf("act=%c addr=%02x arg=%02x\n", act?'t':'f', addr, b); printf("act=%c addr=%02x arg=%02x\n", act ? 't' : 'f', addr, b);
uint8_t rv = tempsense_get_active() ? tempsense_get_addr() : 0xff; uint8_t rv = tempsense_get_active() ? tempsense_get_addr() : 0xff;
if (b == 0x00) return rv; if (b == 0x00)
else if (b == 0xff) tempsense_set_active(false); return rv;
else tempsense_set_addr(b); else if (b == 0xff)
tempsense_set_active(false);
else
tempsense_set_addr(b);
return rv; return rv;
} }
#endif #endif
case opt_get_implmap: case opt_get_implmap: return implmap_val;
return implmap_val; default: return 0xff;
default:
return 0xff;
} }
} }

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef RTCONF_H_ #ifndef RTCONF_H_
#define RTCONF_H_ #define RTCONF_H_
@ -16,7 +17,7 @@ enum rtconf_opt {
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
// 0x00: get I2C address or enable/disable status // 0x00: get I2C address or enable/disable status
// 0xff: disable // 0xff: disable
//other: set I2C address // other: set I2C address
opt_tempsense_enaddr = 2, opt_tempsense_enaddr = 2,
#endif #endif

View File

@ -1,3 +1,4 @@
// vim: set et:
#ifndef SERPROG_H_ #ifndef SERPROG_H_
#define SERPROG_H_ #define SERPROG_H_
@ -29,15 +30,13 @@ enum serprog_cmd {
S_CMD_MAGIC_SETTINGS = 0x53 S_CMD_MAGIC_SETTINGS = 0x53
}; };
enum serprog_response { enum serprog_response { S_ACK = 0x06, S_NAK = 0x15 };
S_ACK = 0x06,
S_NAK = 0x15
};
#define SERPROG_IFACE_VERSION 0x0001 #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_init(void);
uint32_t/*freq_applied*/ sp_spi_set_freq(uint32_t freq_wanted);
void sp_spi_cs_deselect(void); void sp_spi_cs_deselect(void);
void sp_spi_cs_select(void); void sp_spi_cs_select(void);
void sp_spi_op_begin(void); void sp_spi_op_begin(void);
@ -45,8 +44,8 @@ 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_read(uint32_t read_len, uint8_t* read_data);
void sp_spi_op_end(void); void sp_spi_op_end(void);
static inline void sp_spi_op_do(uint32_t write_len, const uint8_t* write_data, static inline void sp_spi_op_do(
uint32_t read_len, uint8_t* read_data) { uint32_t write_len, const uint8_t* write_data, uint32_t read_len, uint8_t* read_data) {
sp_spi_op_begin(); sp_spi_op_begin();
sp_spi_op_write(write_len, write_data); sp_spi_op_write(write_len, write_data);
sp_spi_op_write(read_len, read_data); sp_spi_op_write(read_len, read_data);

View File

@ -9,7 +9,7 @@ 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_lower(void) { return 0 << 4; }
static inline int16_t tempsense_dev_get_upper(void) { return 75 << 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; } static inline int16_t tempsense_dev_get_crit(void) { return 80 << 4; }
#include "../tempsensor.c" #include "../tempsensor.c"
@ -47,11 +47,17 @@ int main(int argc, char* argv[]) {
tempsense_set_addr(0x18); tempsense_set_addr(0x18);
// initial probe // initial probe
uint8_t pk1[1] = {0}; do_pkt(0x05, false, 0x18, 1, pk1); uint8_t pk1[1] = {0};
uint8_t pk2[2]; do_pkt(0x06, true , 0x18, 2, pk2); pbuf(2, pk2); 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 pk3[1] = {1};
uint8_t pk4[2]; do_pkt(0x06, true , 0x18, 2, pk4); pbuf(2, pk4); do_pkt(0x05, false, 0x18, 1, pk3);
uint8_t pk4[2];
do_pkt(0x06, true, 0x18, 2, pk4);
pbuf(2, pk4);
// sensor data get // sensor data get

View File

@ -1,12 +1,16 @@
// vim: set et:
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#ifndef VERY_FAKE #ifndef VERY_FAKE
#include "protocfg.h" #include "protocfg.h"
#define printf(fmt, ...) do{}while(0) // clang-format off
#define printf(fmt, ...) do { } while (0) \
// clang-format on
#endif #endif
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
@ -19,17 +23,7 @@ static uint8_t reg;
static size_t index; static size_t index;
static bool instartstop, hasreg; static bool instartstop, hasreg;
enum regid { enum regid { cap = 0, config, t_upper, t_lower, t_crit, t_a, manuf_id, dev_idrev, reso };
cap = 0,
config,
t_upper,
t_lower,
t_crit,
t_a,
manuf_id,
dev_idrev,
reso
};
#define MANUF_ID 0x0054 #define MANUF_ID 0x0054
#define DEV_IDREV 0x0400 #define DEV_IDREV 0x0400
@ -40,11 +34,12 @@ struct {
uint8_t reso; uint8_t reso;
} mcp9808; } mcp9808;
#define float2fix(x) (int)((x)*(1<<4)) #define float2fix(x) (int)((x) * (1 << 4))
__attribute__((__const__)) __attribute__((__const__)) inline static int16_t trunc_8fix4(int fix) {
inline static int16_t trunc_8fix4(int fix) { // clang-format off
if (fix > 4095) fix = 4095; if (fix > 4095) fix = 4095;
if (fix < -4096) fix = -4096; if (fix < -4096) fix = -4096;
// clang-format on
return fix; return fix;
} }
void tempsense_init(void) { void tempsense_init(void) {
@ -57,23 +52,28 @@ void tempsense_init(void) {
tempsense_dev_init(); tempsense_dev_init();
// clang-format off
mcp9808.t_lower = tempsense_dev_get_lower(); mcp9808.t_lower = tempsense_dev_get_lower();
mcp9808.t_upper = tempsense_dev_get_upper(); mcp9808.t_upper = tempsense_dev_get_upper();
mcp9808.t_crit = tempsense_dev_get_crit (); mcp9808.t_crit = tempsense_dev_get_crit ();
// clang-format on
} }
bool tempsense_get_active(void) { return active; } bool tempsense_get_active(void) { return active; }
void tempsense_set_active(bool act) { active = act; if (!act) addr = 0xff; } void tempsense_set_active(bool act) {
active = act;
if (!act) addr = 0xff;
}
uint8_t tempsense_get_addr(void) { return addr; } uint8_t tempsense_get_addr(void) { return addr; }
void tempsense_set_addr(uint8_t a) { void tempsense_set_addr(uint8_t a) {
addr = a; addr = a;
active = addr >= 0x8 && addr <= 0x77; active = addr >= 0x8 && addr <= 0x77;
printf("set: ad=%02x ac=%c\n", addr, active?'t':'f'); printf("set: ad=%02x ac=%c\n", addr, active ? 't' : 'f');
} }
void tempsense_do_start(void) { void tempsense_do_start(void) {
printf("ts start\n"); printf("ts start\n");
//reg = 0; // reg = 0;
index = 0; index = 0;
instartstop = true; instartstop = true;
hasreg = false; hasreg = false;
@ -88,46 +88,58 @@ int tempsense_do_read(int length, uint8_t* buf) {
if (!instartstop || length < 0) return -1; // nak if (!instartstop || length < 0) return -1; // nak
if (length == 0) return 0; // ack if (length == 0) return 0; // ack
//if (!hasreg) return -1; // nak // if (!hasreg) return -1; // nak
int i; int i;
for (i = 0; i < length; ++i, ++index) { for (i = 0; i < length; ++i, ++index) {
switch (reg) { switch (reg) {
// TODO: big or little endian? seems to be big // TODO: big or little endian? seems to be big
case cap: case cap: buf[index] = 0; break;
buf[index] = 0;
break;
case config: case config:
if (index == 0) buf[0] = (mcp9808.config >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (mcp9808.config >> 0) & 0xff; buf[0] = (mcp9808.config >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (mcp9808.config >> 0) & 0xff;
else
return index;
break; break;
case t_upper: case t_upper:
if (index == 0) buf[0] = (mcp9808.t_upper >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (mcp9808.t_upper >> 0) & 0xff; buf[0] = (mcp9808.t_upper >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (mcp9808.t_upper >> 0) & 0xff;
else
return index;
break; break;
case t_lower: case t_lower:
if (index == 0) buf[0] = (mcp9808.t_lower >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (mcp9808.t_lower >> 0) & 0xff; buf[0] = (mcp9808.t_lower >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (mcp9808.t_lower >> 0) & 0xff;
else
return index;
break; break;
case t_crit: case t_crit:
if (index == 0) buf[0] = (mcp9808.t_crit >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (mcp9808.t_crit >> 0) & 0xff; buf[0] = (mcp9808.t_crit >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (mcp9808.t_crit >> 0) & 0xff;
else
return index;
break; break;
case t_a: { case t_a: {
static uint16_t temp; static uint16_t temp;
if (index == 0) { if (index == 0) {
int16_t res = tempsense_dev_get_temp(); int16_t res = tempsense_dev_get_temp();
// clang-format off
uint32_t tup = mcp9808.t_upper & 0x1ffc; uint32_t tup = mcp9808.t_upper & 0x1ffc;
if (tup & 0x1000) tup |= 0xffffe000; // make negative if (tup & 0x1000) tup |= 0xffffe000; // make negative
uint32_t tlo = mcp9808.t_lower & 0x1ffc; uint32_t tlo = mcp9808.t_lower & 0x1ffc;
if (tlo & 0x1000) tlo |= 0xffffe000; // make negative if (tlo & 0x1000) tlo |= 0xffffe000; // make negative
uint32_t tcr = mcp9808.t_crit & 0x1ffc; uint32_t tcr = mcp9808.t_crit & 0x1ffc;
if (tcr & 0x1000) tcr |= 0xffffe000; // make negative if (tcr & 0x1000) tcr |= 0xffffe000; // make negative
// clang-format on
temp = res & 0x1fff; // data bits and sign bit temp = res & 0x1fff; // data bits and sign bit
@ -136,23 +148,32 @@ int tempsense_do_read(int length, uint8_t* buf) {
if ((int32_t)tcr < res) temp |= 0x8000; if ((int32_t)tcr < res) temp |= 0x8000;
buf[0] = (temp >> 8) & 0xff; buf[0] = (temp >> 8) & 0xff;
} else if (index == 1) buf[1] = (temp>>0) & 0xff; } else if (index == 1)
else return index; buf[1] = (temp >> 0) & 0xff;
} else
break; return index;
} break;
case manuf_id: case manuf_id:
if (index == 0) buf[0] = (MANUF_ID >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (MANUF_ID>>0)&0xff; buf[0] = (MANUF_ID >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (MANUF_ID >> 0) & 0xff;
else
return index;
break; break;
case dev_idrev: case dev_idrev:
if (index == 0) buf[0] = (DEV_IDREV >> 8) & 0xff; if (index == 0)
else if (index == 1) buf[1] = (DEV_IDREV>>0)&0xff; buf[0] = (DEV_IDREV >> 8) & 0xff;
else return index; else if (index == 1)
buf[1] = (DEV_IDREV >> 0) & 0xff;
else
return index;
break; break;
case reso: case reso:
if (index == 0) buf[0] = mcp9808.reso; if (index == 0)
else return index; buf[0] = mcp9808.reso;
else
return index;
break; break;
default: return -1; default: return -1;
} }
@ -161,7 +182,7 @@ int tempsense_do_read(int length, uint8_t* buf) {
return i; return i;
} }
int tempsense_do_write(int length, const uint8_t* buf) { int tempsense_do_write(int length, const uint8_t* buf) {
printf("write l=%d reg=%02x iss=%c ", length, reg, instartstop?'t':'f'); printf("write l=%d reg=%02x iss=%c ", length, reg, instartstop ? 't' : 'f');
if (!instartstop || length < 0) return -1; // nak if (!instartstop || length < 0) return -1; // nak
if (length == 0) return 0; // ack if (length == 0) return 0; // ack
@ -185,35 +206,35 @@ int tempsense_do_write(int length, const uint8_t* buf) {
mcp9808.config = (mcp9808.config & 0x00ff) | ((uint16_t)buf[0] << 8); mcp9808.config = (mcp9808.config & 0x00ff) | ((uint16_t)buf[0] << 8);
} else if (index == 1) { } else if (index == 1) {
mcp9808.config = (mcp9808.config & 0xff00) | ((uint16_t)buf[1] << 0); mcp9808.config = (mcp9808.config & 0xff00) | ((uint16_t)buf[1] << 0);
} else return index; } else
return index;
break; break;
case t_upper: case t_upper:
if (index == 0) { if (index == 0) {
mcp9808.t_upper = (mcp9808.t_upper & 0x00ff) | ((uint16_t)buf[0] << 8); mcp9808.t_upper = (mcp9808.t_upper & 0x00ff) | ((uint16_t)buf[0] << 8);
} else if (index == 1) { } else if (index == 1) {
mcp9808.t_upper = (mcp9808.t_upper & 0xff00) | ((uint16_t)buf[1] << 0); mcp9808.t_upper = (mcp9808.t_upper & 0xff00) | ((uint16_t)buf[1] << 0);
} else return index; } else
return index;
break; break;
case t_lower: case t_lower:
if (index == 0) { if (index == 0) {
mcp9808.t_lower = (mcp9808.t_lower & 0x00ff) | ((uint16_t)buf[0] << 8); mcp9808.t_lower = (mcp9808.t_lower & 0x00ff) | ((uint16_t)buf[0] << 8);
} else if (index == 1) { } else if (index == 1) {
mcp9808.t_lower = (mcp9808.t_lower & 0xff00) | ((uint16_t)buf[1] << 0); mcp9808.t_lower = (mcp9808.t_lower & 0xff00) | ((uint16_t)buf[1] << 0);
} else return index; } else
return index;
break; break;
case t_crit: case t_crit:
if (index == 0) { if (index == 0) {
mcp9808.t_crit = (mcp9808.t_crit & 0x00ff) | ((uint16_t)buf[0] << 8); mcp9808.t_crit = (mcp9808.t_crit & 0x00ff) | ((uint16_t)buf[0] << 8);
} else if (index == 1) { } else if (index == 1) {
mcp9808.t_crit = (mcp9808.t_crit & 0xff00) | ((uint16_t)buf[1] << 0); mcp9808.t_crit = (mcp9808.t_crit & 0xff00) | ((uint16_t)buf[1] << 0);
} else return index; } else
return index;
break; break;
case reso: case reso: mcp9808.reso = buf[index]; break;
mcp9808.reso = buf[index]; default: printf("unk reg\n"); return -1;
break;
default:
printf("unk reg\n");
return -1;
} }
} }

View File

@ -1,9 +1,10 @@
// vim: set et:
#ifndef TEMPSENSOR_H_ #ifndef TEMPSENSOR_H_
#define TEMPSENSOR_H_ #define TEMPSENSOR_H_
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
void tempsense_init(void); void tempsense_init(void);
@ -24,7 +25,7 @@ int16_t tempsense_dev_get_temp(void);
int16_t tempsense_dev_get_lower(void); int16_t tempsense_dev_get_lower(void);
int16_t tempsense_dev_get_upper(void); int16_t tempsense_dev_get_upper(void);
int16_t tempsense_dev_get_crit (void); int16_t tempsense_dev_get_crit(void);
#endif #endif
#endif #endif

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -38,32 +39,35 @@ extern "C" {
// defined by board.mk // defined by board.mk
#ifndef CFG_TUSB_MCU #ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
// RHPort number used for device can be defined by board.mk, default to port 0 // RHPort number used for device can be defined by board.mk, default to port 0
#ifndef BOARD_DEVICE_RHPORT_NUM #ifndef BOARD_DEVICE_RHPORT_NUM
#define BOARD_DEVICE_RHPORT_NUM 0 #define BOARD_DEVICE_RHPORT_NUM 0
#endif #endif
// RHPort max operational speed can defined by board.mk // RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise
// FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED #ifndef BOARD_DEVICE_RHPORT_SPEED
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505 || \
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED CFG_TUSB_MCU == OPT_MCU_CXD56) \
#else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
#endif #else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
#endif
#endif #endif
// Device mode with rhport and speed defined by board.mk // Device mode with rhport and speed defined by board.mk
#if BOARD_DEVICE_RHPORT_NUM == 0 #if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1 #elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#else #else
#error "Incorrect RHPort configuration" #error "Incorrect RHPort configuration"
#endif #endif
// This example doesn't use an RTOS // This example doesn't use an RTOS
@ -88,7 +92,7 @@ extern "C" {
#endif #endif
#ifndef CFG_TUSB_MEM_ALIGN #ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
#endif #endif
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -112,7 +116,7 @@ extern "C" {
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _TUSB_CONFIG_H_ */ #endif /* _TUSB_CONFIG_H_ */

View File

@ -1,3 +1,4 @@
// vim: set et:
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
@ -23,12 +24,13 @@
* *
*/ */
#include "protos.h"
#include "tusb.h" #include "tusb.h"
#include "util.h" #include "util.h"
#include "protos.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. /* A combination of interfaces must have a unique product id, since PC will save device driver after
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * 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: * Auto ProductID layout's Bitmap:
* [MSB] HID | MSC | CDC [LSB] * [MSB] HID | MSC | CDC [LSB]
@ -38,9 +40,10 @@
#else #else
#define USB_BCD_BASE 0x4000 #define USB_BCD_BASE 0x4000
#endif #endif
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) #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) | \ #define USB_BCD \
_PID_MAP(MIDI, 9) | _PID_MAP(VENDOR, 12) ) \ (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 // String Descriptor Index
@ -62,6 +65,7 @@ enum {
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Device Descriptors // Device Descriptors
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// clang-format off
tusb_desc_device_t const desc_device = { tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t), .bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE, .bDescriptorType = TUSB_DESC_DEVICE,
@ -81,26 +85,27 @@ tusb_desc_device_t const desc_device = {
.bNumConfigurations = 0x01 .bNumConfigurations = 0x01
}; };
// clang-format on
// Invoked when received GET DEVICE DESCRIPTOR // Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void) { uint8_t const* tud_descriptor_device_cb(void) { return (uint8_t const*)&desc_device; }
return (uint8_t const *) &desc_device;
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// HID Report Descriptor // HID Report Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// clang-format off
static uint8_t const desc_hid_report[] = { static uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE) TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)
}; };
// clang-format on
// Invoked when received GET HID REPORT DESCRIPTOR // Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) { uint8_t const* tud_hid_descriptor_report_cb(uint8_t instance) {
(void) instance; (void)instance;
return desc_hid_report; return desc_hid_report;
} }
@ -169,11 +174,15 @@ enum {
// NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well! // 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 // TODO: maybe add some strings to all these interfaces
// clang-format off
uint8_t const desc_configuration[] = { uint8_t const desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
#ifdef DBOARD_HAS_CMSISDAP #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), 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 #endif
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
@ -181,23 +190,27 @@ uint8_t const desc_configuration[] = {
#endif #endif
#ifdef DBOARD_HAS_UART #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), 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 #endif
#ifdef DBOARD_HAS_SERPROG #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), 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 #endif
#ifdef USE_USBCDC_FOR_STDIO #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), 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 #endif
}; };
// clang-format on
// Invoked when received GET CONFIGURATION DESCRIPTOR // Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { uint8_t const* tud_descriptor_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations (void)index; // for multiple configurations
return desc_configuration; return desc_configuration;
} }
@ -206,8 +219,9 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// array of pointer to string descriptors // array of pointer to string descriptors
char const* string_desc_arr [] = { // clang-format off
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) char const* string_desc_arr[] = {
[STRID_LANGID] = (const char[]){0x09, 0x04}, // supported language is English (0x0409)
[STRID_MANUFACTURER] = INFO_MANUFACTURER, // Manufacturer [STRID_MANUFACTURER] = INFO_MANUFACTURER, // Manufacturer
[STRID_PRODUCT] = INFO_PRODUCT(INFO_BOARDNAME), // Product [STRID_PRODUCT] = INFO_PRODUCT(INFO_BOARDNAME), // Product
@ -219,13 +233,15 @@ char const* string_desc_arr [] = {
[STRID_IF_CDC_SERPROG] = "Serprog CDC interface", [STRID_IF_CDC_SERPROG] = "Serprog CDC interface",
[STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)", [STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)",
}; };
// clang-format on
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) { uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
static uint16_t _desc_str[32]; static uint16_t _desc_str[32];
(void) langid; (void)langid;
uint8_t chr_count = 0; uint8_t chr_count = 0;
@ -238,8 +254,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // 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 // 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]))) if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL;
return NULL;
const char* str = string_desc_arr[index]; const char* str = string_desc_arr[index];
@ -247,20 +262,16 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
chr_count = TU_MIN(strlen(str), 31); chr_count = TU_MIN(strlen(str), 31);
// Convert ASCII string into UTF-16 // Convert ASCII string into UTF-16
for (int i = 0; i < chr_count; i++) { for (int i = 0; i < chr_count; i++) { _desc_str[1 + i] = str[i]; }
_desc_str[1+i] = str[i];
}
} }
// first byte is length (including header), second byte is string type // first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8) | (2*chr_count + 2); _desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * chr_count + 2);
return _desc_str; return _desc_str;
} }
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) { void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding) {
if (itf == CDC_N_UART) { if (itf == CDC_N_UART) { cdc_uart_set_baudrate(line_coding->bit_rate); }
cdc_uart_set_baudrate(line_coding->bit_rate);
}
} }

View File

@ -1,16 +1,21 @@
// vim: set et:
#ifndef UTIL_H_ #ifndef UTIL_H_
#define UTIL_H_ #define UTIL_H_
static inline char nyb2hex(int x) { static inline char nyb2hex(int x) {
if (x < 0xa) return '0'+(x-0); if (x < 0xa)
else return 'A'+(x-0xa); return '0' + (x - 0x0);
else
return 'A' + (x - 0xa);
} }
void thread_yield(void); void thread_yield(void);
// clang-format off
uint8_t get_unique_id_u8 (uint8_t * desc_str); uint8_t get_unique_id_u8 (uint8_t * desc_str);
uint8_t get_unique_id_u16(uint16_t* desc_str); uint8_t get_unique_id_u16(uint16_t* desc_str);
// clang-format on
#endif #endif

View File

@ -3,6 +3,7 @@
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
// clang-format off
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -18,6 +19,7 @@
#include "i2ctinyusb.h" #include "i2ctinyusb.h"
#include "tempsensor.h" #include "tempsensor.h"
// clang-format on
static uint8_t itf_num; static uint8_t itf_num;
@ -51,13 +53,15 @@ static void iub_reset(uint8_t rhport) {
itf_num = 0; itf_num = 0;
} }
static uint16_t iub_open(uint8_t rhport, tusb_desc_interface_t const* itf_desc, static uint16_t iub_open(uint8_t rhport, tusb_desc_interface_t const* itf_desc, uint16_t max_len) {
uint16_t max_len) {
(void)rhport; (void)rhport;
// clang-format off
TU_VERIFY(itf_desc->bInterfaceClass == 0 TU_VERIFY(itf_desc->bInterfaceClass == 0
&& itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceSubClass == 0
&& itf_desc->bInterfaceProtocol == 0, 0); && itf_desc->bInterfaceProtocol == 0,
0);
// clang-format on
const uint16_t drv_len = sizeof(tusb_desc_interface_t); const uint16_t drv_len = sizeof(tusb_desc_interface_t);
TU_VERIFY(max_len >= drv_len, 0); TU_VERIFY(max_len >= drv_len, 0);
@ -82,25 +86,27 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
if (stage == CONTROL_STAGE_DATA) { if (stage == CONTROL_STAGE_DATA) {
struct itu_cmd cmd = curcmd; struct itu_cmd cmd = curcmd;
if (req->bRequest >= ITU_CMD_I2C_IO && req->bRequest <= ITU_CMD_I2C_IO_BEGINEND if (req->bRequest >= ITU_CMD_I2C_IO && req->bRequest <= ITU_CMD_I2C_IO_BEGINEND &&
&& cmd.cmd == req->bRequest && cmd.flags == req->wValue cmd.cmd == req->bRequest && cmd.flags == req->wValue && cmd.addr == req->wIndex &&
&& cmd.addr == req->wIndex && cmd.len == req->wLength) { cmd.len == req->wLength) {
//printf("WDATA a=%04hx l=%04hx ", cmd.addr, cmd.len); // printf("WDATA a=%04hx l=%04hx ", cmd.addr, cmd.len);
//printf("data=%02x %02x...\n", rxbuf[0], rxbuf[1]); // printf("data=%02x %02x...\n", rxbuf[0], rxbuf[1]);
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) { if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start(); if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
// FIXME: fix status handling // FIXME: fix status handling
int rv = tempsense_do_write(cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len, rxbuf); 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; if (rv < 0 || rv != cmd.len)
else status = ITU_STATUS_ADDR_ACK; status = ITU_STATUS_ADDR_NAK;
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop (); else
status = ITU_STATUS_ADDR_ACK;
if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
} else } else
#endif #endif
{ {
status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, cmd.addr, rxbuf,
cmd.addr, rxbuf, cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len); cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len);
} }
// cancel curcmd // cancel curcmd
@ -110,44 +116,42 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
} else if (stage == CONTROL_STAGE_SETUP) { } else if (stage == CONTROL_STAGE_SETUP) {
switch (req->bRequest) { switch (req->bRequest) {
case ITU_CMD_ECHO: { // flags to be echoed back, addr unused, len=2 case ITU_CMD_ECHO: { // flags to be echoed back, addr unused, len=2
if (req->wLength != 2) return false; // bad length -> let's stall if (req->wLength != 2) return false; // bad length -> let's stall
uint8_t rv[2]; uint8_t rv[2];
rv[0] = req->wValue&0xff; rv[0] = req->wValue & 0xff;
rv[1] = (req->wValue>>8)&0xff; rv[1] = (req->wValue >> 8) & 0xff;
return tud_control_xfer(rhport, req, rv, sizeof rv); return tud_control_xfer(rhport, req, rv, sizeof rv);
} } break;
break;
case ITU_CMD_GET_FUNC: { // flags unused, addr unused, len=4 case ITU_CMD_GET_FUNC: { // flags unused, addr unused, len=4
if (req->wLength != 4) return false; if (req->wLength != 4) return false;
const uint32_t func = i2ctu_get_func(); const uint32_t func = i2ctu_get_func();
txbuf[0]=func&0xff; txbuf[0] = func & 0xff;
txbuf[1]=(func>>8)&0xff; txbuf[1] = (func >> 8) & 0xff;
txbuf[2]=(func>>16)&0xff; txbuf[2] = (func >> 16) & 0xff;
txbuf[3]=(func>>24)&0xff; txbuf[3] = (func >> 24) & 0xff;
return tud_control_xfer(rhport, req, txbuf, 4); return tud_control_xfer(rhport, req, txbuf, 4);
} } break;
break;
case ITU_CMD_SET_DELAY: { // flags=delay, addr unused, len=0 case ITU_CMD_SET_DELAY: { // flags=delay, addr unused, len=0
if (req->wLength != 0) return false; if (req->wLength != 0) return false;
uint32_t us = req->wValue ? req->wValue : 1; uint32_t us = req->wValue ? req->wValue : 1;
uint32_t freq = 1000*1000 / us; uint32_t freq = 1000 * 1000 / us;
//printf("set freq us=%u freq=%u\n", us, freq); // printf("set freq us=%u freq=%u\n", us, freq);
if (i2ctu_set_freq(freq, us) != 0) // returned an ok frequency if (i2ctu_set_freq(freq, us) != 0) // returned an ok frequency
return tud_control_status(rhport, req); return tud_control_status(rhport, req);
else return false; else
} return false;
break; } break;
case ITU_CMD_GET_STATUS: { // flags unused, addr unused, len=1 case ITU_CMD_GET_STATUS: { // flags unused, addr unused, len=1
if (req->wLength != 1) return false; if (req->wLength != 1) return false;
uint8_t rv = status; uint8_t rv = status;
return tud_control_xfer(rhport, req, &rv, 1); return tud_control_xfer(rhport, req, &rv, 1);
} } break;
break;
case ITU_CMD_I2C_IO: // flags: ki2c_flags case ITU_CMD_I2C_IO: // flags: ki2c_flags
case ITU_CMD_I2C_IO_BEGIN: // addr: I2C address case ITU_CMD_I2C_IO_BEGIN: // addr: I2C address
@ -160,41 +164,46 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
cmd.cmd = req->bRequest; cmd.cmd = req->bRequest;
if (cmd.flags & I2C_M_RD) { // read from I2C device if (cmd.flags & I2C_M_RD) { // read from I2C device
//printf("read addr=%04hx len=%04hx ", cmd.addr, cmd.len); // printf("read addr=%04hx len=%04hx ", cmd.addr, cmd.len);
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) { if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start(); 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); int rv = tempsense_do_read(
if (rv < 0 || rv != cmd.len) status = ITU_STATUS_ADDR_NAK; cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len, txbuf);
else status = ITU_STATUS_ADDR_ACK; if (rv < 0 || rv != cmd.len)
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop (); status = ITU_STATUS_ADDR_NAK;
else
status = ITU_STATUS_ADDR_ACK;
if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
} else } else
#endif #endif
{ {
status = i2ctu_read(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, status = i2ctu_read(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, cmd.addr,
cmd.addr, txbuf, cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len); txbuf, cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len);
} }
//printf("data=%02x %02x...\n", txbuf[0], txbuf[1]); // printf("data=%02x %02x...\n", txbuf[0], txbuf[1]);
return tud_control_xfer(rhport, req, txbuf, return tud_control_xfer(
cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len); rhport, req, txbuf, cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len);
} else { // write } else { // write
//printf("write addr=%04hx len=%04hx ", cmd.addr, cmd.len); // printf("write addr=%04hx len=%04hx ", cmd.addr, cmd.len);
if (cmd.len == 0) { // address probe -> do this here if (cmd.len == 0) { // address probe -> do this here
uint8_t bleh = 0; uint8_t bleh = 0;
#ifdef DBOARD_HAS_TEMPSENSOR #ifdef DBOARD_HAS_TEMPSENSOR
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) { if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start(); if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
int rv = tempsense_do_write(0, &bleh); int rv = tempsense_do_write(0, &bleh);
if (rv < 0 || rv != cmd.len) status = ITU_STATUS_ADDR_NAK; if (rv < 0 || rv != cmd.len)
else status = ITU_STATUS_ADDR_ACK; status = ITU_STATUS_ADDR_NAK;
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop (); else
status = ITU_STATUS_ADDR_ACK;
if (cmd.cmd & ITU_CMD_I2C_IO_END_F) tempsense_do_stop();
} else } else
#endif #endif
{ {
status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK, status = i2ctu_write(cmd.flags, cmd.cmd & ITU_CMD_I2C_IO_DIR_MASK,
cmd.addr, &bleh, 0); cmd.addr, &bleh, 0);
} }
//printf("probe -> %d\n", status); // printf("probe -> %d\n", status);
return tud_control_status(rhport, req); return tud_control_status(rhport, req);
} else { } else {
// handled in DATA stage! // handled in DATA stage!
@ -204,17 +213,18 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
return rv; return rv;
} }
} }
} } break;
break;
default: default:
//printf("I2C-Tiny-USB: unknown command %02x\n", req->bRequest); // printf("I2C-Tiny-USB: unknown command %02x\n", req->bRequest);
return false; return false;
} }
} else return true; // other stage... } else
return true; // other stage...
} }
// never actually called fsr // never actually called fsr
static bool iub_xfer(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { static bool iub_xfer(
uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
(void)rhport; (void)rhport;
(void)ep_addr; (void)ep_addr;
(void)result; (void)result;
@ -225,6 +235,7 @@ static bool iub_xfer(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
// interfacing stuff for TinyUSB API, actually defines the driver // interfacing stuff for TinyUSB API, actually defines the driver
// clang-format off
static usbd_class_driver_t const i2ctinyusb_driver = { static usbd_class_driver_t const i2ctinyusb_driver = {
#if CFG_TUSB_DEBUG >= 2 #if CFG_TUSB_DEBUG >= 2
.name = "i2c-tiny-usb", .name = "i2c-tiny-usb",
@ -237,6 +248,7 @@ static usbd_class_driver_t const i2ctinyusb_driver = {
.xfer_cb = iub_xfer, .xfer_cb = iub_xfer,
.sof = NULL .sof = NULL
}; };
// clang-format on
usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) { usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) {
*driver_count = 1; *driver_count = 1;
@ -245,7 +257,8 @@ usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) {
// we need to implement this one, because tinyusb uses hardcoded stuff for // we need to implement this one, because tinyusb uses hardcoded stuff for
// endpoint 0, which is what the i2c-tiny-usb kernel module uses // 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) { 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); return iub_ctl_req(rhport, ep_addr, req);
} }