diff --git a/fido2/ctap.c b/fido2/ctap.c index e3f76a1..3dcb98b 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -458,7 +458,7 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au int but; - but = ctap_user_presence_test(); + but = ctap_user_presence_test(CTAP2_UP_DELAY_MS); if (!but) { @@ -696,7 +696,7 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt } if (MC.pinAuthEmpty) { - if (!ctap_user_presence_test()) + if (!ctap_user_presence_test(CTAP2_UP_DELAY_MS)) { return CTAP2_ERR_OPERATION_DENIED; } @@ -1132,7 +1132,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) if (GA.pinAuthEmpty) { - if (!ctap_user_presence_test()) + if (!ctap_user_presence_test(CTAP2_UP_DELAY_MS)) { return CTAP2_ERR_OPERATION_DENIED; } @@ -1641,7 +1641,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) break; case CTAP_RESET: printf1(TAG_CTAP,"CTAP_RESET\n"); - if (ctap_user_presence_test()) + if (ctap_user_presence_test(CTAP2_UP_DELAY_MS)) { ctap_reset(); } @@ -1759,7 +1759,7 @@ void ctap_init() exit(1); } - if (! device_is_nfc()) + if (device_is_nfc() != NFC_IS_ACTIVE) { ctap_reset_key_agreement(); } diff --git a/fido2/ctap.h b/fido2/ctap.h index 9677d87..51a5c11 100644 --- a/fido2/ctap.h +++ b/fido2/ctap.h @@ -131,6 +131,8 @@ #define PIN_LOCKOUT_ATTEMPTS 8 // Number of attempts total #define PIN_BOOT_ATTEMPTS 3 // number of attempts per boot +#define CTAP2_UP_DELAY_MS 5000 + typedef struct { uint8_t id[USER_ID_MAX_SIZE]; diff --git a/fido2/device.h b/fido2/device.h index e13ea51..dfb95ec 100644 --- a/fido2/device.h +++ b/fido2/device.h @@ -53,11 +53,11 @@ int device_is_button_pressed(); // Test for user presence // Return 1 for user is present, 0 user not present, -1 if cancel is requested. -extern int ctap_user_presence_test(); +int ctap_user_presence_test(uint32_t delay); // Generate @num bytes of random numbers to @dest // return 1 if success, error otherwise -extern int ctap_generate_rng(uint8_t * dst, size_t num); +int ctap_generate_rng(uint8_t * dst, size_t num); // Increment atomic counter and return it. // Must support two counters, @sel selects counter0 or counter1. @@ -65,11 +65,11 @@ uint32_t ctap_atomic_count(int sel); // Verify the user // return 1 if user is verified, 0 if not -extern int ctap_user_verification(uint8_t arg); +int ctap_user_verification(uint8_t arg); // Must be implemented by application // data is HID_MESSAGE_SIZE long in bytes -extern void ctaphid_write_block(uint8_t * data); +void ctaphid_write_block(uint8_t * data); // Resident key @@ -99,9 +99,12 @@ typedef enum { // 2: fastest clock rate. Generally for USB interface. void device_set_clock_rate(DEVICE_CLOCK_RATE param); -// Returns 1 if operating in NFC mode. -// 0 otherwise. -bool device_is_nfc(); +// Returns NFC_IS_NA, NFC_IS_ACTIVE, or NFC_IS_AVAILABLE +#define NFC_IS_NA 0 +#define NFC_IS_ACTIVE 1 +#define NFC_IS_AVAILABLE 2 +int device_is_nfc(); +void device_init_button(); #endif diff --git a/fido2/extensions/wallet.c b/fido2/extensions/wallet.c index a03d74e..537b359 100644 --- a/fido2/extensions/wallet.c +++ b/fido2/extensions/wallet.c @@ -85,7 +85,7 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a return CTAP2_ERR_NOT_ALLOWED; } - if (!ctap_user_presence_test()) + if (!ctap_user_presence_test(5000)) { return CTAP2_ERR_OPERATION_DENIED; } @@ -111,7 +111,7 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a return CTAP2_ERR_NOT_ALLOWED; } - if (!ctap_user_presence_test()) + if (!ctap_user_presence_test(5000)) { return CTAP2_ERR_OPERATION_DENIED; } @@ -133,7 +133,7 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a return CTAP2_ERR_NOT_ALLOWED; } - if (!ctap_user_presence_test()) + if (!ctap_user_presence_test(5000)) { return CTAP2_ERR_OPERATION_DENIED; } @@ -359,7 +359,7 @@ int16_t bridge_to_wallet(uint8_t * keyh, uint8_t klen) } } - if (ctap_user_presence_test()) + if (ctap_user_presence_test(5000)) { printf1(TAG_WALLET,"Reseting device!\n"); ctap_reset(); diff --git a/fido2/u2f.c b/fido2/u2f.c index e711ea1..14cb848 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -7,6 +7,7 @@ #include #include "u2f.h" #include "ctap.h" +#include "ctaphid.h" #include "crypto.h" #include "log.h" #include "device.h" @@ -95,6 +96,8 @@ void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPO #endif } + device_set_status(CTAPHID_STATUS_IDLE); + end: if (rcode != U2F_SW_NO_ERROR) { @@ -202,7 +205,6 @@ int8_t u2f_authenticate_credential(struct u2f_key_handle * kh, uint8_t * appid) } - static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control) { @@ -238,9 +240,9 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c if (control == U2F_AUTHENTICATE_SIGN_NO_USER) up = 0; - if(!device_is_nfc() && up) + if(up) { - if (ctap_user_presence_test() == 0) + if (ctap_user_presence_test(750) == 0) { return U2F_SW_CONDITIONS_NOT_SATISFIED; } @@ -286,12 +288,9 @@ static int16_t u2f_register(struct u2f_register_request * req) const uint16_t attest_size = attestation_cert_der_size; - if(!device_is_nfc()) + if ( ! ctap_user_presence_test(750)) { - if ( ! ctap_user_presence_test()) - { - return U2F_SW_CONDITIONS_NOT_SATISFIED; - } + return U2F_SW_CONDITIONS_NOT_SATISFIED; } if ( u2f_new_keypair(&key_handle, req->app, pubkey) == -1) @@ -326,8 +325,6 @@ static int16_t u2f_register(struct u2f_register_request * req) dump_signature_der(sig); - /*printf1(TAG_U2F, "dersig: "); dump_hex1(TAG_U2F,sig,74);*/ - return U2F_SW_NO_ERROR; } diff --git a/pc/device.c b/pc/device.c index 3f2265d..2a0e166 100644 --- a/pc/device.c +++ b/pc/device.c @@ -293,7 +293,7 @@ void ctaphid_write_block(uint8_t * data) } -int ctap_user_presence_test() +int ctap_user_presence_test(uint32_t d) { return 1; } @@ -624,7 +624,7 @@ void device_wink() printf("*WINK*\n"); } -bool device_is_nfc() +int device_is_nfc() { return 0; } diff --git a/targets/stm32l432/bootloader/main.c b/targets/stm32l432/bootloader/main.c index a6103c3..c3bf736 100644 --- a/targets/stm32l432/bootloader/main.c +++ b/targets/stm32l432/bootloader/main.c @@ -83,6 +83,8 @@ int main() init_debug_uart(); #endif + device_init_button(); + printf1(TAG_GEN,"init device\n"); t1 = millis(); diff --git a/targets/stm32l432/build/application.mk b/targets/stm32l432/build/application.mk index 92abd43..e482f87 100644 --- a/targets/stm32l432/build/application.mk +++ b/targets/stm32l432/build/application.mk @@ -2,7 +2,7 @@ include build/common.mk # ST related SRC = src/main.c src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c -SRC += src/fifo.c src/crypto.c src/attestation.c src/nfc.c src/ams.c +SRC += src/fifo.c src/crypto.c src/attestation.c src/nfc.c src/ams.c src/sense.c SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c SRC += $(DRIVER_LIBS) $(USB_LIB) diff --git a/targets/stm32l432/build/bootloader.mk b/targets/stm32l432/build/bootloader.mk index bf6edd8..4fa4513 100644 --- a/targets/stm32l432/build/bootloader.mk +++ b/targets/stm32l432/build/bootloader.mk @@ -3,7 +3,7 @@ include build/common.mk # ST related SRC = bootloader/main.c bootloader/bootloader.c SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c -SRC += src/fifo.c src/crypto.c src/attestation.c +SRC += src/fifo.c src/crypto.c src/attestation.c src/sense.c SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c SRC += $(DRIVER_LIBS) $(USB_LIB) diff --git a/targets/stm32l432/lib/stm32l4xx_hal_tsc.h b/targets/stm32l432/lib/stm32l4xx_hal_tsc.h new file mode 100644 index 0000000..a3b0cec --- /dev/null +++ b/targets/stm32l432/lib/stm32l4xx_hal_tsc.h @@ -0,0 +1,844 @@ +/** + ****************************************************************************** + * @file stm32l4xx_hal_tsc.h + * @author MCD Application Team + * @brief Header file of TSC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32L4xx_HAL_TSC_H +#define STM32L4xx_HAL_TSC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal_def.h" + +/** @addtogroup STM32L4xx_HAL_Driver + * @{ + */ + +/** @addtogroup TSC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TSC_Exported_Types TSC Exported Types + * @{ + */ + +/** + * @brief TSC state structure definition + */ +typedef enum +{ + HAL_TSC_STATE_RESET = 0x00UL, /*!< TSC registers have their reset value */ + HAL_TSC_STATE_READY = 0x01UL, /*!< TSC registers are initialized or acquisition is completed with success */ + HAL_TSC_STATE_BUSY = 0x02UL, /*!< TSC initialization or acquisition is on-going */ + HAL_TSC_STATE_ERROR = 0x03UL /*!< Acquisition is completed with max count error */ +} HAL_TSC_StateTypeDef; + +/** + * @brief TSC group status structure definition + */ +typedef enum +{ + TSC_GROUP_ONGOING = 0x00UL, /*!< Acquisition on group is on-going or not started */ + TSC_GROUP_COMPLETED = 0x01UL /*!< Acquisition on group is completed with success (no max count error) */ +} TSC_GroupStatusTypeDef; + +/** + * @brief TSC init structure definition + */ +typedef struct +{ + uint32_t CTPulseHighLength; /*!< Charge-transfer high pulse length + This parameter can be a value of @ref TSC_CTPulseHL_Config */ + uint32_t CTPulseLowLength; /*!< Charge-transfer low pulse length + This parameter can be a value of @ref TSC_CTPulseLL_Config */ + uint32_t SpreadSpectrum; /*!< Spread spectrum activation + This parameter can be a value of @ref TSC_CTPulseLL_Config */ + uint32_t SpreadSpectrumDeviation; /*!< Spread spectrum deviation + This parameter must be a number between Min_Data = 0 and Max_Data = 127 */ + uint32_t SpreadSpectrumPrescaler; /*!< Spread spectrum prescaler + This parameter can be a value of @ref TSC_SpreadSpec_Prescaler */ + uint32_t PulseGeneratorPrescaler; /*!< Pulse generator prescaler + This parameter can be a value of @ref TSC_PulseGenerator_Prescaler */ + uint32_t MaxCountValue; /*!< Max count value + This parameter can be a value of @ref TSC_MaxCount_Value */ + uint32_t IODefaultMode; /*!< IO default mode + This parameter can be a value of @ref TSC_IO_Default_Mode */ + uint32_t SynchroPinPolarity; /*!< Synchro pin polarity + This parameter can be a value of @ref TSC_Synchro_Pin_Polarity */ + uint32_t AcquisitionMode; /*!< Acquisition mode + This parameter can be a value of @ref TSC_Acquisition_Mode */ + uint32_t MaxCountInterrupt; /*!< Max count interrupt activation + This parameter can be set to ENABLE or DISABLE. */ + uint32_t ChannelIOs; /*!< Channel IOs mask */ + uint32_t ShieldIOs; /*!< Shield IOs mask */ + uint32_t SamplingIOs; /*!< Sampling IOs mask */ +} TSC_InitTypeDef; + +/** + * @brief TSC IOs configuration structure definition + */ +typedef struct +{ + uint32_t ChannelIOs; /*!< Channel IOs mask */ + uint32_t ShieldIOs; /*!< Shield IOs mask */ + uint32_t SamplingIOs; /*!< Sampling IOs mask */ +} TSC_IOConfigTypeDef; + +/** + * @brief TSC handle Structure definition + */ +typedef struct __TSC_HandleTypeDef +{ + TSC_TypeDef *Instance; /*!< Register base address */ + TSC_InitTypeDef Init; /*!< Initialization parameters */ + __IO HAL_TSC_StateTypeDef State; /*!< Peripheral state */ + HAL_LockTypeDef Lock; /*!< Lock feature */ + __IO uint32_t ErrorCode; /*!< I2C Error code */ + +#if (USE_HAL_TSC_REGISTER_CALLBACKS == 1) + void (* ConvCpltCallback)(struct __TSC_HandleTypeDef *htsc); /*!< TSC Conversion complete callback */ + void (* ErrorCallback)(struct __TSC_HandleTypeDef *htsc); /*!< TSC Error callback */ + + void (* MspInitCallback)(struct __TSC_HandleTypeDef *htsc); /*!< TSC Msp Init callback */ + void (* MspDeInitCallback)(struct __TSC_HandleTypeDef *htsc); /*!< TSC Msp DeInit callback */ + +#endif /* USE_HAL_TSC_REGISTER_CALLBACKS */ +} TSC_HandleTypeDef; + +/** + * @brief TSC Group Index Structure definition + */ +typedef enum +{ + TSC_GROUP1_IDX = 0x00UL, + TSC_GROUP2_IDX, + TSC_GROUP3_IDX, + TSC_GROUP4_IDX, +#if defined(TSC_IOCCR_G5_IO1) + TSC_GROUP5_IDX, +#endif +#if defined(TSC_IOCCR_G6_IO1) + TSC_GROUP6_IDX, +#endif +#if defined(TSC_IOCCR_G7_IO1) + TSC_GROUP7_IDX, +#endif +#if defined(TSC_IOCCR_G8_IO1) + TSC_GROUP8_IDX, +#endif + TSC_NB_OF_GROUPS +}TSC_GroupIndexTypeDef; + +#if (USE_HAL_TSC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL TSC Callback ID enumeration definition + */ +typedef enum +{ + HAL_TSC_CONV_COMPLETE_CB_ID = 0x00UL, /*!< TSC Conversion completed callback ID */ + HAL_TSC_ERROR_CB_ID = 0x01UL, /*!< TSC Error callback ID */ + + HAL_TSC_MSPINIT_CB_ID = 0x02UL, /*!< TSC Msp Init callback ID */ + HAL_TSC_MSPDEINIT_CB_ID = 0x03UL /*!< TSC Msp DeInit callback ID */ + +} HAL_TSC_CallbackIDTypeDef; + +/** + * @brief HAL TSC Callback pointer definition + */ +typedef void (*pTSC_CallbackTypeDef)(TSC_HandleTypeDef *htsc); /*!< pointer to an TSC callback function */ + +#endif /* USE_HAL_TSC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TSC_Exported_Constants TSC Exported Constants + * @{ + */ + +/** @defgroup TSC_Error_Code_definition TSC Error Code definition + * @brief TSC Error Code definition + * @{ + */ +#define HAL_TSC_ERROR_NONE 0x00000000UL /*!< No error */ +#if (USE_HAL_TSC_REGISTER_CALLBACKS == 1) +#define HAL_TSC_ERROR_INVALID_CALLBACK 0x00000001UL /*!< Invalid Callback error */ +#endif /* USE_HAL_TSC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup TSC_CTPulseHL_Config CTPulse High Length + * @{ + */ +#define TSC_CTPH_1CYCLE 0x00000000UL /*!< Charge transfer pulse high during 1 cycle (PGCLK) */ +#define TSC_CTPH_2CYCLES TSC_CR_CTPH_0 /*!< Charge transfer pulse high during 2 cycles (PGCLK) */ +#define TSC_CTPH_3CYCLES TSC_CR_CTPH_1 /*!< Charge transfer pulse high during 3 cycles (PGCLK) */ +#define TSC_CTPH_4CYCLES (TSC_CR_CTPH_1 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 4 cycles (PGCLK) */ +#define TSC_CTPH_5CYCLES TSC_CR_CTPH_2 /*!< Charge transfer pulse high during 5 cycles (PGCLK) */ +#define TSC_CTPH_6CYCLES (TSC_CR_CTPH_2 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 6 cycles (PGCLK) */ +#define TSC_CTPH_7CYCLES (TSC_CR_CTPH_2 | TSC_CR_CTPH_1) /*!< Charge transfer pulse high during 7 cycles (PGCLK) */ +#define TSC_CTPH_8CYCLES (TSC_CR_CTPH_2 | TSC_CR_CTPH_1 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 8 cycles (PGCLK) */ +#define TSC_CTPH_9CYCLES TSC_CR_CTPH_3 /*!< Charge transfer pulse high during 9 cycles (PGCLK) */ +#define TSC_CTPH_10CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 10 cycles (PGCLK) */ +#define TSC_CTPH_11CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_1) /*!< Charge transfer pulse high during 11 cycles (PGCLK) */ +#define TSC_CTPH_12CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_1 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 12 cycles (PGCLK) */ +#define TSC_CTPH_13CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_2) /*!< Charge transfer pulse high during 13 cycles (PGCLK) */ +#define TSC_CTPH_14CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_2 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 14 cycles (PGCLK) */ +#define TSC_CTPH_15CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_2 | TSC_CR_CTPH_1) /*!< Charge transfer pulse high during 15 cycles (PGCLK) */ +#define TSC_CTPH_16CYCLES (TSC_CR_CTPH_3 | TSC_CR_CTPH_2 | TSC_CR_CTPH_1 | TSC_CR_CTPH_0) /*!< Charge transfer pulse high during 16 cycles (PGCLK) */ +/** + * @} + */ + +/** @defgroup TSC_CTPulseLL_Config CTPulse Low Length + * @{ + */ +#define TSC_CTPL_1CYCLE 0x00000000UL /*!< Charge transfer pulse low during 1 cycle (PGCLK) */ +#define TSC_CTPL_2CYCLES TSC_CR_CTPL_0 /*!< Charge transfer pulse low during 2 cycles (PGCLK) */ +#define TSC_CTPL_3CYCLES TSC_CR_CTPL_1 /*!< Charge transfer pulse low during 3 cycles (PGCLK) */ +#define TSC_CTPL_4CYCLES (TSC_CR_CTPL_1 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 4 cycles (PGCLK) */ +#define TSC_CTPL_5CYCLES TSC_CR_CTPL_2 /*!< Charge transfer pulse low during 5 cycles (PGCLK) */ +#define TSC_CTPL_6CYCLES (TSC_CR_CTPL_2 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 6 cycles (PGCLK) */ +#define TSC_CTPL_7CYCLES (TSC_CR_CTPL_2 | TSC_CR_CTPL_1) /*!< Charge transfer pulse low during 7 cycles (PGCLK) */ +#define TSC_CTPL_8CYCLES (TSC_CR_CTPL_2 | TSC_CR_CTPL_1 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 8 cycles (PGCLK) */ +#define TSC_CTPL_9CYCLES TSC_CR_CTPL_3 /*!< Charge transfer pulse low during 9 cycles (PGCLK) */ +#define TSC_CTPL_10CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 10 cycles (PGCLK) */ +#define TSC_CTPL_11CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_1) /*!< Charge transfer pulse low during 11 cycles (PGCLK) */ +#define TSC_CTPL_12CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_1 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 12 cycles (PGCLK) */ +#define TSC_CTPL_13CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_2) /*!< Charge transfer pulse low during 13 cycles (PGCLK) */ +#define TSC_CTPL_14CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_2 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 14 cycles (PGCLK) */ +#define TSC_CTPL_15CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_2 | TSC_CR_CTPL_1) /*!< Charge transfer pulse low during 15 cycles (PGCLK) */ +#define TSC_CTPL_16CYCLES (TSC_CR_CTPL_3 | TSC_CR_CTPL_2 | TSC_CR_CTPL_1 | TSC_CR_CTPL_0) /*!< Charge transfer pulse low during 16 cycles (PGCLK) */ +/** + * @} + */ + +/** @defgroup TSC_SpreadSpec_Prescaler Spread Spectrum Prescaler + * @{ + */ +#define TSC_SS_PRESC_DIV1 0x00000000UL /*!< Spread Spectrum Prescaler Div1 */ +#define TSC_SS_PRESC_DIV2 TSC_CR_SSPSC /*!< Spread Spectrum Prescaler Div2 */ +/** + * @} + */ + +/** @defgroup TSC_PulseGenerator_Prescaler Pulse Generator Prescaler + * @{ + */ +#define TSC_PG_PRESC_DIV1 0x00000000UL /*!< Pulse Generator HCLK Div1 */ +#define TSC_PG_PRESC_DIV2 TSC_CR_PGPSC_0 /*!< Pulse Generator HCLK Div2 */ +#define TSC_PG_PRESC_DIV4 TSC_CR_PGPSC_1 /*!< Pulse Generator HCLK Div4 */ +#define TSC_PG_PRESC_DIV8 (TSC_CR_PGPSC_1 | TSC_CR_PGPSC_0) /*!< Pulse Generator HCLK Div8 */ +#define TSC_PG_PRESC_DIV16 TSC_CR_PGPSC_2 /*!< Pulse Generator HCLK Div16 */ +#define TSC_PG_PRESC_DIV32 (TSC_CR_PGPSC_2 | TSC_CR_PGPSC_0) /*!< Pulse Generator HCLK Div32 */ +#define TSC_PG_PRESC_DIV64 (TSC_CR_PGPSC_2 | TSC_CR_PGPSC_1) /*!< Pulse Generator HCLK Div64 */ +#define TSC_PG_PRESC_DIV128 (TSC_CR_PGPSC_2 | TSC_CR_PGPSC_1 | TSC_CR_PGPSC_0) /*!< Pulse Generator HCLK Div128 */ +/** + * @} + */ + +/** @defgroup TSC_MaxCount_Value Max Count Value + * @{ + */ +#define TSC_MCV_255 0x00000000UL /*!< 255 maximum number of charge transfer pulses */ +#define TSC_MCV_511 TSC_CR_MCV_0 /*!< 511 maximum number of charge transfer pulses */ +#define TSC_MCV_1023 TSC_CR_MCV_1 /*!< 1023 maximum number of charge transfer pulses */ +#define TSC_MCV_2047 (TSC_CR_MCV_1 | TSC_CR_MCV_0) /*!< 2047 maximum number of charge transfer pulses */ +#define TSC_MCV_4095 TSC_CR_MCV_2 /*!< 4095 maximum number of charge transfer pulses */ +#define TSC_MCV_8191 (TSC_CR_MCV_2 | TSC_CR_MCV_0) /*!< 8191 maximum number of charge transfer pulses */ +#define TSC_MCV_16383 (TSC_CR_MCV_2 | TSC_CR_MCV_1) /*!< 16383 maximum number of charge transfer pulses */ +/** + * @} + */ + +/** @defgroup TSC_IO_Default_Mode IO Default Mode + * @{ + */ +#define TSC_IODEF_OUT_PP_LOW 0x00000000UL /*!< I/Os are forced to output push-pull low */ +#define TSC_IODEF_IN_FLOAT TSC_CR_IODEF /*!< I/Os are in input floating */ +/** + * @} + */ + +/** @defgroup TSC_Synchro_Pin_Polarity Synchro Pin Polarity + * @{ + */ +#define TSC_SYNC_POLARITY_FALLING 0x00000000UL /*!< Falling edge only */ +#define TSC_SYNC_POLARITY_RISING TSC_CR_SYNCPOL /*!< Rising edge and high level */ +/** + * @} + */ + +/** @defgroup TSC_Acquisition_Mode Acquisition Mode + * @{ + */ +#define TSC_ACQ_MODE_NORMAL 0x00000000UL /*!< Normal acquisition mode (acquisition starts as soon as START bit is set) */ +#define TSC_ACQ_MODE_SYNCHRO TSC_CR_AM /*!< Synchronized acquisition mode (acquisition starts if START bit is set and when the selected signal is detected on the SYNC input pin) */ +/** + * @} + */ + +/** @defgroup TSC_interrupts_definition Interrupts definition + * @{ + */ +#define TSC_IT_EOA TSC_IER_EOAIE /*!< End of acquisition interrupt enable */ +#define TSC_IT_MCE TSC_IER_MCEIE /*!< Max count error interrupt enable */ +/** + * @} + */ + +/** @defgroup TSC_flags_definition Flags definition + * @{ + */ +#define TSC_FLAG_EOA TSC_ISR_EOAF /*!< End of acquisition flag */ +#define TSC_FLAG_MCE TSC_ISR_MCEF /*!< Max count error flag */ +/** + * @} + */ + +/** @defgroup TSC_Group_definition Group definition + * @{ + */ +#define TSC_GROUP1 (uint32_t)(0x1UL << TSC_GROUP1_IDX) +#define TSC_GROUP2 (uint32_t)(0x1UL << TSC_GROUP2_IDX) +#define TSC_GROUP3 (uint32_t)(0x1UL << TSC_GROUP3_IDX) +#define TSC_GROUP4 (uint32_t)(0x1UL << TSC_GROUP4_IDX) +#if defined(TSC_IOCCR_G5_IO1) +#define TSC_GROUP5 (uint32_t)(0x1UL << TSC_GROUP5_IDX) +#endif +#if defined(TSC_IOCCR_G6_IO1) +#define TSC_GROUP6 (uint32_t)(0x1UL << TSC_GROUP6_IDX) +#endif +#if defined(TSC_IOCCR_G7_IO1) +#define TSC_GROUP7 (uint32_t)(0x1UL << TSC_GROUP7_IDX) +#endif +#if defined(TSC_IOCCR_G8_IO1) +#define TSC_GROUP8 (uint32_t)(0x1UL << TSC_GROUP8_IDX) +#endif + +#define TSC_GROUPX_NOT_SUPPORTED 0xFF000000UL /*!< TSC GroupX not supported */ + +#define TSC_GROUP1_IO1 TSC_IOCCR_G1_IO1 /*!< TSC Group1 IO1 */ +#define TSC_GROUP1_IO2 TSC_IOCCR_G1_IO2 /*!< TSC Group1 IO2 */ +#define TSC_GROUP1_IO3 TSC_IOCCR_G1_IO3 /*!< TSC Group1 IO3 */ +#define TSC_GROUP1_IO4 TSC_IOCCR_G1_IO4 /*!< TSC Group1 IO4 */ + +#define TSC_GROUP2_IO1 TSC_IOCCR_G2_IO1 /*!< TSC Group2 IO1 */ +#define TSC_GROUP2_IO2 TSC_IOCCR_G2_IO2 /*!< TSC Group2 IO2 */ +#define TSC_GROUP2_IO3 TSC_IOCCR_G2_IO3 /*!< TSC Group2 IO3 */ +#define TSC_GROUP2_IO4 TSC_IOCCR_G2_IO4 /*!< TSC Group2 IO4 */ + +#define TSC_GROUP3_IO1 TSC_IOCCR_G3_IO1 /*!< TSC Group3 IO1 */ +#define TSC_GROUP3_IO2 TSC_IOCCR_G3_IO2 /*!< TSC Group3 IO2 */ +#define TSC_GROUP3_IO3 TSC_IOCCR_G3_IO3 /*!< TSC Group3 IO3 */ +#define TSC_GROUP3_IO4 TSC_IOCCR_G3_IO4 /*!< TSC Group3 IO4 */ + +#define TSC_GROUP4_IO1 TSC_IOCCR_G4_IO1 /*!< TSC Group4 IO1 */ +#define TSC_GROUP4_IO2 TSC_IOCCR_G4_IO2 /*!< TSC Group4 IO2 */ +#define TSC_GROUP4_IO3 TSC_IOCCR_G4_IO3 /*!< TSC Group4 IO3 */ +#define TSC_GROUP4_IO4 TSC_IOCCR_G4_IO4 /*!< TSC Group4 IO4 */ +#if defined(TSC_IOCCR_G5_IO1) + +#define TSC_GROUP5_IO1 TSC_IOCCR_G5_IO1 /*!< TSC Group5 IO1 */ +#define TSC_GROUP5_IO2 TSC_IOCCR_G5_IO2 /*!< TSC Group5 IO2 */ +#define TSC_GROUP5_IO3 TSC_IOCCR_G5_IO3 /*!< TSC Group5 IO3 */ +#define TSC_GROUP5_IO4 TSC_IOCCR_G5_IO4 /*!< TSC Group5 IO4 */ +#else + +#define TSC_GROUP5_IO1 (uint32_t)(0x00000010UL | TSC_GROUPX_NOT_SUPPORTED) /*!< TSC Group5 IO1 not supported */ +#define TSC_GROUP5_IO2 TSC_GROUP5_IO1 /*!< TSC Group5 IO2 not supported */ +#define TSC_GROUP5_IO3 TSC_GROUP5_IO1 /*!< TSC Group5 IO3 not supported */ +#define TSC_GROUP5_IO4 TSC_GROUP5_IO1 /*!< TSC Group5 IO4 not supported */ +#endif +#if defined(TSC_IOCCR_G6_IO1) + +#define TSC_GROUP6_IO1 TSC_IOCCR_G6_IO1 /*!< TSC Group6 IO1 */ +#define TSC_GROUP6_IO2 TSC_IOCCR_G6_IO2 /*!< TSC Group6 IO2 */ +#define TSC_GROUP6_IO3 TSC_IOCCR_G6_IO3 /*!< TSC Group6 IO3 */ +#define TSC_GROUP6_IO4 TSC_IOCCR_G6_IO4 /*!< TSC Group6 IO4 */ +#else + +#define TSC_GROUP6_IO1 (uint32_t)(0x00000020UL | TSC_GROUPX_NOT_SUPPORTED) /*!< TSC Group6 IO1 not supported */ +#define TSC_GROUP6_IO2 TSC_GROUP6_IO1 /*!< TSC Group6 IO2 not supported */ +#define TSC_GROUP6_IO3 TSC_GROUP6_IO1 /*!< TSC Group6 IO3 not supported */ +#define TSC_GROUP6_IO4 TSC_GROUP6_IO1 /*!< TSC Group6 IO4 not supported */ +#endif +#if defined(TSC_IOCCR_G7_IO1) + +#define TSC_GROUP7_IO1 TSC_IOCCR_G7_IO1 /*!< TSC Group7 IO1 */ +#define TSC_GROUP7_IO2 TSC_IOCCR_G7_IO2 /*!< TSC Group7 IO2 */ +#define TSC_GROUP7_IO3 TSC_IOCCR_G7_IO3 /*!< TSC Group7 IO3 */ +#define TSC_GROUP7_IO4 TSC_IOCCR_G7_IO4 /*!< TSC Group7 IO4 */ +#else + +#define TSC_GROUP7_IO1 (uint32_t)(0x00000040UL | TSC_GROUPX_NOT_SUPPORTED) /*!< TSC Group7 IO1 not supported */ +#define TSC_GROUP7_IO2 TSC_GROUP7_IO1 /*!< TSC Group7 IO2 not supported */ +#define TSC_GROUP7_IO3 TSC_GROUP7_IO1 /*!< TSC Group7 IO3 not supported */ +#define TSC_GROUP7_IO4 TSC_GROUP7_IO1 /*!< TSC Group7 IO4 not supported */ +#endif +#if defined(TSC_IOCCR_G8_IO1) + +#define TSC_GROUP8_IO1 TSC_IOCCR_G8_IO1 /*!< TSC Group8 IO1 */ +#define TSC_GROUP8_IO2 TSC_IOCCR_G8_IO2 /*!< TSC Group8 IO2 */ +#define TSC_GROUP8_IO3 TSC_IOCCR_G8_IO3 /*!< TSC Group8 IO3 */ +#define TSC_GROUP8_IO4 TSC_IOCCR_G8_IO4 /*!< TSC Group8 IO4 */ +#else + +#define TSC_GROUP8_IO1 (uint32_t)(0x00000080UL | TSC_GROUPX_NOT_SUPPORTED) /*!< TSC Group8 IO1 not supported */ +#define TSC_GROUP8_IO2 TSC_GROUP8_IO1 /*!< TSC Group8 IO2 not supported */ +#define TSC_GROUP8_IO3 TSC_GROUP8_IO1 /*!< TSC Group8 IO3 not supported */ +#define TSC_GROUP8_IO4 TSC_GROUP8_IO1 /*!< TSC Group8 IO4 not supported */ +#endif +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup TSC_Exported_Macros TSC Exported Macros + * @{ + */ + +/** @brief Reset TSC handle state. + * @param __HANDLE__ TSC handle + * @retval None + */ +#if (USE_HAL_TSC_REGISTER_CALLBACKS == 1) +#define __HAL_TSC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_TSC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_TSC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_TSC_STATE_RESET) +#endif + +/** + * @brief Enable the TSC peripheral. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= TSC_CR_TSCE) + +/** + * @brief Disable the TSC peripheral. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= (uint32_t)(~TSC_CR_TSCE)) + +/** + * @brief Start acquisition. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_START_ACQ(__HANDLE__) ((__HANDLE__)->Instance->CR |= TSC_CR_START) + +/** + * @brief Stop acquisition. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_STOP_ACQ(__HANDLE__) ((__HANDLE__)->Instance->CR &= (uint32_t)(~TSC_CR_START)) + +/** + * @brief Set IO default mode to output push-pull low. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_SET_IODEF_OUTPPLOW(__HANDLE__) ((__HANDLE__)->Instance->CR &= (uint32_t)(~TSC_CR_IODEF)) + +/** + * @brief Set IO default mode to input floating. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_SET_IODEF_INFLOAT(__HANDLE__) ((__HANDLE__)->Instance->CR |= TSC_CR_IODEF) + +/** + * @brief Set synchronization polarity to falling edge. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_SET_SYNC_POL_FALL(__HANDLE__) ((__HANDLE__)->Instance->CR &= (uint32_t)(~TSC_CR_SYNCPOL)) + +/** + * @brief Set synchronization polarity to rising edge and high level. + * @param __HANDLE__ TSC handle + * @retval None + */ +#define __HAL_TSC_SET_SYNC_POL_RISE_HIGH(__HANDLE__) ((__HANDLE__)->Instance->CR |= TSC_CR_SYNCPOL) + +/** + * @brief Enable TSC interrupt. + * @param __HANDLE__ TSC handle + * @param __INTERRUPT__ TSC interrupt + * @retval None + */ +#define __HAL_TSC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disable TSC interrupt. + * @param __HANDLE__ TSC handle + * @param __INTERRUPT__ TSC interrupt + * @retval None + */ +#define __HAL_TSC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (uint32_t)(~(__INTERRUPT__))) + +/** @brief Check whether the specified TSC interrupt source is enabled or not. + * @param __HANDLE__ TSC Handle + * @param __INTERRUPT__ TSC interrupt + * @retval SET or RESET + */ +#define __HAL_TSC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** + * @brief Check whether the specified TSC flag is set or not. + * @param __HANDLE__ TSC handle + * @param __FLAG__ TSC flag + * @retval SET or RESET + */ +#define __HAL_TSC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** + * @brief Clear the TSC's pending flag. + * @param __HANDLE__ TSC handle + * @param __FLAG__ TSC flag + * @retval None + */ +#define __HAL_TSC_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enable schmitt trigger hysteresis on a group of IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_ENABLE_HYSTERESIS(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOHCR |= (__GX_IOY_MASK__)) + +/** + * @brief Disable schmitt trigger hysteresis on a group of IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_DISABLE_HYSTERESIS(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOHCR &= (uint32_t)(~(__GX_IOY_MASK__))) + +/** + * @brief Open analog switch on a group of IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_OPEN_ANALOG_SWITCH(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOASCR &= (uint32_t)(~(__GX_IOY_MASK__))) + +/** + * @brief Close analog switch on a group of IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_CLOSE_ANALOG_SWITCH(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOASCR |= (__GX_IOY_MASK__)) + +/** + * @brief Enable a group of IOs in channel mode. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_ENABLE_CHANNEL(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOCCR |= (__GX_IOY_MASK__)) + +/** + * @brief Disable a group of channel IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_DISABLE_CHANNEL(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOCCR &= (uint32_t)(~(__GX_IOY_MASK__))) + +/** + * @brief Enable a group of IOs in sampling mode. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_ENABLE_SAMPLING(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOSCR |= (__GX_IOY_MASK__)) + +/** + * @brief Disable a group of sampling IOs. + * @param __HANDLE__ TSC handle + * @param __GX_IOY_MASK__ IOs mask + * @retval None + */ +#define __HAL_TSC_DISABLE_SAMPLING(__HANDLE__, __GX_IOY_MASK__) ((__HANDLE__)->Instance->IOSCR &= (uint32_t)(~(__GX_IOY_MASK__))) + +/** + * @brief Enable acquisition groups. + * @param __HANDLE__ TSC handle + * @param __GX_MASK__ Groups mask + * @retval None + */ +#define __HAL_TSC_ENABLE_GROUP(__HANDLE__, __GX_MASK__) ((__HANDLE__)->Instance->IOGCSR |= (__GX_MASK__)) + +/** + * @brief Disable acquisition groups. + * @param __HANDLE__ TSC handle + * @param __GX_MASK__ Groups mask + * @retval None + */ +#define __HAL_TSC_DISABLE_GROUP(__HANDLE__, __GX_MASK__) ((__HANDLE__)->Instance->IOGCSR &= (uint32_t)(~(__GX_MASK__))) + +/** @brief Gets acquisition group status. + * @param __HANDLE__ TSC Handle + * @param __GX_INDEX__ Group index + * @retval SET or RESET + */ +#define __HAL_TSC_GET_GROUP_STATUS(__HANDLE__, __GX_INDEX__) \ +((((__HANDLE__)->Instance->IOGCSR & (uint32_t)(1UL << (((__GX_INDEX__) & (uint32_t)TSC_NB_OF_GROUPS) + 16UL))) == (uint32_t)(1UL << (((__GX_INDEX__) & (uint32_t)TSC_NB_OF_GROUPS) + 16UL))) ? TSC_GROUP_COMPLETED : TSC_GROUP_ONGOING) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup TSC_Private_Macros TSC Private Macros + * @{ + */ + +#define IS_TSC_CTPH(__VALUE__) (((__VALUE__) == TSC_CTPH_1CYCLE) || \ + ((__VALUE__) == TSC_CTPH_2CYCLES) || \ + ((__VALUE__) == TSC_CTPH_3CYCLES) || \ + ((__VALUE__) == TSC_CTPH_4CYCLES) || \ + ((__VALUE__) == TSC_CTPH_5CYCLES) || \ + ((__VALUE__) == TSC_CTPH_6CYCLES) || \ + ((__VALUE__) == TSC_CTPH_7CYCLES) || \ + ((__VALUE__) == TSC_CTPH_8CYCLES) || \ + ((__VALUE__) == TSC_CTPH_9CYCLES) || \ + ((__VALUE__) == TSC_CTPH_10CYCLES) || \ + ((__VALUE__) == TSC_CTPH_11CYCLES) || \ + ((__VALUE__) == TSC_CTPH_12CYCLES) || \ + ((__VALUE__) == TSC_CTPH_13CYCLES) || \ + ((__VALUE__) == TSC_CTPH_14CYCLES) || \ + ((__VALUE__) == TSC_CTPH_15CYCLES) || \ + ((__VALUE__) == TSC_CTPH_16CYCLES)) + +#define IS_TSC_CTPL(__VALUE__) (((__VALUE__) == TSC_CTPL_1CYCLE) || \ + ((__VALUE__) == TSC_CTPL_2CYCLES) || \ + ((__VALUE__) == TSC_CTPL_3CYCLES) || \ + ((__VALUE__) == TSC_CTPL_4CYCLES) || \ + ((__VALUE__) == TSC_CTPL_5CYCLES) || \ + ((__VALUE__) == TSC_CTPL_6CYCLES) || \ + ((__VALUE__) == TSC_CTPL_7CYCLES) || \ + ((__VALUE__) == TSC_CTPL_8CYCLES) || \ + ((__VALUE__) == TSC_CTPL_9CYCLES) || \ + ((__VALUE__) == TSC_CTPL_10CYCLES) || \ + ((__VALUE__) == TSC_CTPL_11CYCLES) || \ + ((__VALUE__) == TSC_CTPL_12CYCLES) || \ + ((__VALUE__) == TSC_CTPL_13CYCLES) || \ + ((__VALUE__) == TSC_CTPL_14CYCLES) || \ + ((__VALUE__) == TSC_CTPL_15CYCLES) || \ + ((__VALUE__) == TSC_CTPL_16CYCLES)) + +#define IS_TSC_SS(__VALUE__) (((FunctionalState)(__VALUE__) == DISABLE) || ((FunctionalState)(__VALUE__) == ENABLE)) + +#define IS_TSC_SSD(__VALUE__) (((__VALUE__) == 0UL) || (((__VALUE__) > 0UL) && ((__VALUE__) < 128UL))) + +#define IS_TSC_SS_PRESC(__VALUE__) (((__VALUE__) == TSC_SS_PRESC_DIV1) || ((__VALUE__) == TSC_SS_PRESC_DIV2)) + +#define IS_TSC_PG_PRESC(__VALUE__) (((__VALUE__) == TSC_PG_PRESC_DIV1) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV2) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV4) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV8) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV16) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV32) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV64) || \ + ((__VALUE__) == TSC_PG_PRESC_DIV128)) + +#define IS_TSC_MCV(__VALUE__) (((__VALUE__) == TSC_MCV_255) || \ + ((__VALUE__) == TSC_MCV_511) || \ + ((__VALUE__) == TSC_MCV_1023) || \ + ((__VALUE__) == TSC_MCV_2047) || \ + ((__VALUE__) == TSC_MCV_4095) || \ + ((__VALUE__) == TSC_MCV_8191) || \ + ((__VALUE__) == TSC_MCV_16383)) + +#define IS_TSC_IODEF(__VALUE__) (((__VALUE__) == TSC_IODEF_OUT_PP_LOW) || ((__VALUE__) == TSC_IODEF_IN_FLOAT)) + +#define IS_TSC_SYNC_POL(__VALUE__) (((__VALUE__) == TSC_SYNC_POLARITY_FALLING) || ((__VALUE__) == TSC_SYNC_POLARITY_RISING)) + +#define IS_TSC_ACQ_MODE(__VALUE__) (((__VALUE__) == TSC_ACQ_MODE_NORMAL) || ((__VALUE__) == TSC_ACQ_MODE_SYNCHRO)) + +#define IS_TSC_MCE_IT(__VALUE__) (((FunctionalState)(__VALUE__) == DISABLE) || ((FunctionalState)(__VALUE__) == ENABLE)) + +#define IS_TSC_GROUP_INDEX(__VALUE__) (((__VALUE__) == 0UL) || (((__VALUE__) > 0UL) && ((__VALUE__) < (uint32_t)TSC_NB_OF_GROUPS))) + + +#define IS_TSC_GROUP(__VALUE__) ((((__VALUE__) & TSC_GROUPX_NOT_SUPPORTED) != TSC_GROUPX_NOT_SUPPORTED) && \ + ((((__VALUE__) & TSC_GROUP1_IO1) == TSC_GROUP1_IO1) ||\ + (((__VALUE__) & TSC_GROUP1_IO2) == TSC_GROUP1_IO2) ||\ + (((__VALUE__) & TSC_GROUP1_IO3) == TSC_GROUP1_IO3) ||\ + (((__VALUE__) & TSC_GROUP1_IO4) == TSC_GROUP1_IO4) ||\ + (((__VALUE__) & TSC_GROUP2_IO1) == TSC_GROUP2_IO1) ||\ + (((__VALUE__) & TSC_GROUP2_IO2) == TSC_GROUP2_IO2) ||\ + (((__VALUE__) & TSC_GROUP2_IO3) == TSC_GROUP2_IO3) ||\ + (((__VALUE__) & TSC_GROUP2_IO4) == TSC_GROUP2_IO4) ||\ + (((__VALUE__) & TSC_GROUP3_IO1) == TSC_GROUP3_IO1) ||\ + (((__VALUE__) & TSC_GROUP3_IO2) == TSC_GROUP3_IO2) ||\ + (((__VALUE__) & TSC_GROUP3_IO3) == TSC_GROUP3_IO3) ||\ + (((__VALUE__) & TSC_GROUP3_IO4) == TSC_GROUP3_IO4) ||\ + (((__VALUE__) & TSC_GROUP4_IO1) == TSC_GROUP4_IO1) ||\ + (((__VALUE__) & TSC_GROUP4_IO2) == TSC_GROUP4_IO2) ||\ + (((__VALUE__) & TSC_GROUP4_IO3) == TSC_GROUP4_IO3) ||\ + (((__VALUE__) & TSC_GROUP4_IO4) == TSC_GROUP4_IO4) ||\ + (((__VALUE__) & TSC_GROUP5_IO1) == TSC_GROUP5_IO1) ||\ + (((__VALUE__) & TSC_GROUP5_IO2) == TSC_GROUP5_IO2) ||\ + (((__VALUE__) & TSC_GROUP5_IO3) == TSC_GROUP5_IO3) ||\ + (((__VALUE__) & TSC_GROUP5_IO4) == TSC_GROUP5_IO4) ||\ + (((__VALUE__) & TSC_GROUP6_IO1) == TSC_GROUP6_IO1) ||\ + (((__VALUE__) & TSC_GROUP6_IO2) == TSC_GROUP6_IO2) ||\ + (((__VALUE__) & TSC_GROUP6_IO3) == TSC_GROUP6_IO3) ||\ + (((__VALUE__) & TSC_GROUP6_IO4) == TSC_GROUP6_IO4) ||\ + (((__VALUE__) & TSC_GROUP7_IO1) == TSC_GROUP7_IO1) ||\ + (((__VALUE__) & TSC_GROUP7_IO2) == TSC_GROUP7_IO2) ||\ + (((__VALUE__) & TSC_GROUP7_IO3) == TSC_GROUP7_IO3) ||\ + (((__VALUE__) & TSC_GROUP7_IO4) == TSC_GROUP7_IO4) ||\ + (((__VALUE__) & TSC_GROUP8_IO1) == TSC_GROUP8_IO1) ||\ + (((__VALUE__) & TSC_GROUP8_IO2) == TSC_GROUP8_IO2) ||\ + (((__VALUE__) & TSC_GROUP8_IO3) == TSC_GROUP8_IO3) ||\ + (((__VALUE__) & TSC_GROUP8_IO4) == TSC_GROUP8_IO4))) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TSC_Exported_Functions + * @{ + */ + +/** @addtogroup TSC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_TSC_Init(TSC_HandleTypeDef *htsc); +HAL_StatusTypeDef HAL_TSC_DeInit(TSC_HandleTypeDef *htsc); +void HAL_TSC_MspInit(TSC_HandleTypeDef *htsc); +void HAL_TSC_MspDeInit(TSC_HandleTypeDef *htsc); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_TSC_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_TSC_RegisterCallback(TSC_HandleTypeDef *htsc, HAL_TSC_CallbackIDTypeDef CallbackID, pTSC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_TSC_UnRegisterCallback(TSC_HandleTypeDef *htsc, HAL_TSC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_TSC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup TSC_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_TSC_Start(TSC_HandleTypeDef *htsc); +HAL_StatusTypeDef HAL_TSC_Start_IT(TSC_HandleTypeDef *htsc); +HAL_StatusTypeDef HAL_TSC_Stop(TSC_HandleTypeDef *htsc); +HAL_StatusTypeDef HAL_TSC_Stop_IT(TSC_HandleTypeDef *htsc); +HAL_StatusTypeDef HAL_TSC_PollForAcquisition(TSC_HandleTypeDef *htsc); +TSC_GroupStatusTypeDef HAL_TSC_GroupGetStatus(TSC_HandleTypeDef *htsc, uint32_t gx_index); +uint32_t HAL_TSC_GroupGetValue(TSC_HandleTypeDef *htsc, uint32_t gx_index); +/** + * @} + */ + +/** @addtogroup TSC_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_TSC_IOConfig(TSC_HandleTypeDef *htsc, TSC_IOConfigTypeDef *config); +HAL_StatusTypeDef HAL_TSC_IODischarge(TSC_HandleTypeDef *htsc, uint32_t choice); +/** + * @} + */ + +/** @addtogroup TSC_Exported_Functions_Group4 Peripheral State and Errors functions + * @{ + */ +/* Peripheral State and Error functions ***************************************/ +HAL_TSC_StateTypeDef HAL_TSC_GetState(TSC_HandleTypeDef *htsc); +/** + * @} + */ + +/** @addtogroup TSC_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ +/******* TSC IRQHandler and Callbacks used in Interrupt mode */ +void HAL_TSC_IRQHandler(TSC_HandleTypeDef *htsc); +void HAL_TSC_ConvCpltCallback(TSC_HandleTypeDef *htsc); +void HAL_TSC_ErrorCallback(TSC_HandleTypeDef *htsc); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32L4xx_HAL_TSC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/stm32l432/src/ams.c b/targets/stm32l432/src/ams.c index 335758f..9212d53 100644 --- a/targets/stm32l432/src/ams.c +++ b/targets/stm32l432/src/ams.c @@ -270,7 +270,7 @@ void ams_print_int1(uint8_t int0) #endif } -void ams_init() +int ams_init() { LL_GPIO_SetPinMode(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN,LL_GPIO_MODE_OUTPUT); LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN); @@ -283,6 +283,13 @@ void ams_init() // delay(10); SELECT(); delay(1); + + uint8_t productType = ams_read_reg(AMS_REG_PRODUCT_TYPE); + if (productType == 0x14) + { + return 1; + } + return 0; } void ams_configure() diff --git a/targets/stm32l432/src/ams.h b/targets/stm32l432/src/ams.h index ef701bf..8828eaa 100644 --- a/targets/stm32l432/src/ams.h +++ b/targets/stm32l432/src/ams.h @@ -39,7 +39,7 @@ typedef union #define SELECT() LL_GPIO_ResetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN) #define UNSELECT() LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN) -void ams_init(); +int ams_init(); void ams_configure(); void ams_read_buffer(uint8_t * data, int len); diff --git a/targets/stm32l432/src/device.c b/targets/stm32l432/src/device.c index 1ae5297..ae441fc 100644 --- a/targets/stm32l432/src/device.c +++ b/targets/stm32l432/src/device.c @@ -29,6 +29,7 @@ #include "usbd_cdc_if.h" #include "nfc.h" #include "init.h" +#include "sense.h" #define LOW_FREQUENCY 1 #define HIGH_FREQUENCY 0 @@ -40,10 +41,21 @@ uint32_t __90_ms = 0; uint32_t __device_status = 0; uint32_t __last_update = 0; extern PCD_HandleTypeDef hpcd; -static bool haveNFC = 0; +static int _NFC_status = 0; static bool isLowFreq = 0; -#define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)) +// #define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)) +static int is_physical_button_pressed() +{ + return (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)); +} + +static int is_touch_button_pressed() +{ + return tsc_read_button(0) || tsc_read_button(1); +} + +int (*IS_BUTTON_PRESSED)() = is_physical_button_pressed; // Timer6 overflow handler. happens every ~90ms. void TIM6_DAC_IRQHandler() @@ -51,7 +63,7 @@ void TIM6_DAC_IRQHandler() // timer is only 16 bits, so roll it over here TIM6->SR = 0; __90_ms += 1; - if ((millis() - __last_update) > 8) + if ((millis() - __last_update) > 90) { if (__device_status != CTAPHID_STATUS_IDLE) { @@ -60,7 +72,7 @@ void TIM6_DAC_IRQHandler() } #ifndef IS_BOOTLOADER // NFC sending WTX if needs - if (device_is_nfc()) + if (device_is_nfc() == NFC_IS_ACTIVE) { WTX_timer_exec(); } @@ -93,6 +105,7 @@ void device_set_status(uint32_t status) int device_is_button_pressed() { + return IS_BUTTON_PRESSED(); } @@ -107,23 +120,41 @@ void device_reboot() NVIC_SystemReset(); } +void device_init_button() +{ + if (tsc_sensor_exists()) + { + tsc_init(); + IS_BUTTON_PRESSED = is_touch_button_pressed; + } + else + { + IS_BUTTON_PRESSED = is_physical_button_pressed; + } +} + void device_init(int argc, char *argv[]) { hw_init(LOW_FREQUENCY); - haveNFC = nfc_init(); + if (! tsc_sensor_exists()) + { + _NFC_status = nfc_init(); + } - if (haveNFC) + if (_NFC_status == NFC_IS_ACTIVE) { printf1(TAG_NFC, "Have NFC\r\n"); isLowFreq = 1; + IS_BUTTON_PRESSED = is_physical_button_pressed; } else { printf1(TAG_NFC, "Have NO NFC\r\n"); hw_init(HIGH_FREQUENCY); isLowFreq = 0; + device_init_button(); } usbhid_init(); @@ -139,9 +170,9 @@ void device_init(int argc, char *argv[]) } -bool device_is_nfc() +int device_is_nfc() { - return haveNFC; + return _NFC_status; } void wait_for_usb_tether() @@ -433,7 +464,7 @@ void device_manage() } #endif #ifndef IS_BOOTLOADER - // if(device_is_nfc()) + if(device_is_nfc()) nfc_loop(); #endif } @@ -457,10 +488,10 @@ static int handle_packets() return 0; } -int ctap_user_presence_test() +int ctap_user_presence_test(uint32_t up_delay) { int ret; - if (device_is_nfc()) + if (device_is_nfc() == NFC_IS_ACTIVE) { return 1; } @@ -482,22 +513,26 @@ int ctap_user_presence_test() uint32_t t1 = millis(); led_rgb(0xff3520); -while (IS_BUTTON_PRESSED()) +if (IS_BUTTON_PRESSED == is_touch_button_pressed) { - if (t1 + 5000 < millis()) + // Wait for user to release touch button if it's already pressed + while (IS_BUTTON_PRESSED()) { - printf1(TAG_GEN,"Button not pressed\n"); - goto fail; + if (t1 + up_delay < millis()) + { + printf1(TAG_GEN,"Button not pressed\n"); + goto fail; + } + ret = handle_packets(); + if (ret) return ret; } - ret = handle_packets(); - if (ret) return ret; } t1 = millis(); do { - if (t1 + 5000 < millis()) + if (t1 + up_delay < millis()) { goto fail; } diff --git a/targets/stm32l432/src/init.c b/targets/stm32l432/src/init.c index e415ce9..e7fa953 100644 --- a/targets/stm32l432/src/init.c +++ b/targets/stm32l432/src/init.c @@ -31,6 +31,7 @@ #include "usbd_cdc_if.h" #include "device.h" #include "init.h" +#include "sense.h" #include APP_CONFIG // KHz @@ -94,8 +95,6 @@ void hw_init(int lowfreq) SystemClock_Config(); } - - if (!lowfreq) { init_pwm(); @@ -108,6 +107,7 @@ void hw_init(int lowfreq) #endif init_rng(); + init_spi(); } diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 5b72940..51e34bb 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -55,11 +55,12 @@ void nfc_state_init() NFC_STATE.block_num = 1; } -bool nfc_init() +int nfc_init() { uint32_t t1; + int init; nfc_state_init(); - ams_init(); + init = ams_init(); // Detect if we are powered by NFC field by listening for a message for // first 10 ms. @@ -67,13 +68,18 @@ bool nfc_init() while ((millis() - t1) < 10) { if (nfc_loop() > 0) - return 1; + return NFC_IS_ACTIVE; } // Under USB power. Configure AMS chip. ams_configure(); - return 0; + if (init) + { + return NFC_IS_AVAILABLE; + } + + return NFC_IS_NA; } void process_int0(uint8_t int0) diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index a8627a2..9871537 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -8,7 +8,7 @@ // Return number of bytes read if any. int nfc_loop(); -bool nfc_init(); +int nfc_init(); typedef struct { diff --git a/targets/stm32l432/src/sense.c b/targets/stm32l432/src/sense.c new file mode 100644 index 0000000..7e898ae --- /dev/null +++ b/targets/stm32l432/src/sense.c @@ -0,0 +1,136 @@ +#include "sense.h" +#include "device.h" +#include "log.h" + +#include "stm32l4xx_ll_gpio.h" +#include "stm32l4xx_hal_tsc.h" + +#define ELECTRODE_0 TSC_GROUP2_IO1 +#define ELECTRODE_1 TSC_GROUP2_IO2 + +void tsc_init() +{ + LL_GPIO_InitTypeDef GPIO_InitStruct; + // Enable TSC clock + RCC->AHB1ENR |= (1<<16); + + /** TSC GPIO Configuration + PA4 ------> Channel 1 + PA5 ------> Channel 2 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_5|LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_9; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /** TSC GPIO Configuration + PA6 ------> sampling cap + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + // Channel IOs + uint32_t channel_ios = TSC_GROUP2_IO1 | TSC_GROUP2_IO2; + + // enable + TSC->CR = TSC_CR_TSCE; + + TSC->CR |= (TSC_CTPH_8CYCLES | + TSC_CTPL_10CYCLES | + (uint32_t)(1 << TSC_CR_SSD_Pos) | + TSC_SS_PRESC_DIV1 | + TSC_PG_PRESC_DIV16 | + TSC_MCV_16383 | + TSC_SYNC_POLARITY_FALLING | + TSC_ACQ_MODE_NORMAL); + + // Spread spectrum + if (0) + { + TSC->CR |= TSC_CR_SSE; + } + + // Schmitt trigger and hysteresis + TSC->IOHCR = (uint32_t)(~(channel_ios | 0 | TSC_GROUP2_IO3)); + + // Sampling IOs + TSC->IOSCR = TSC_GROUP2_IO3; + + // Groups + uint32_t grps = 0x02; + TSC->IOGCSR = grps; + + TSC->IER &= (uint32_t)(~(TSC_IT_EOA | TSC_IT_MCE)); + TSC->ICR = (TSC_FLAG_EOA | TSC_FLAG_MCE); + +} + +void tsc_set_electrode(uint32_t channel_ids) +{ + TSC->IOCCR = (channel_ids); +} + +void tsc_start_acq() +{ + TSC->CR &= ~(TSC_CR_START); + + TSC->ICR = TSC_FLAG_EOA | TSC_FLAG_MCE; + + // Set IO output to output push-pull low + TSC->CR &= (~TSC_CR_IODEF); + + TSC->CR |= TSC_CR_START; +} + +void tsc_wait_on_acq() +{ + while ( ! (TSC->ISR & TSC_FLAG_EOA) ) + ; + if ( TSC->ISR & TSC_FLAG_MCE ) + { + printf1(TAG_ERR,"Max count reached\r\n"); + } +} + +uint32_t tsc_read(uint32_t indx) +{ + return TSC->IOGXCR[indx]; +} + +uint32_t tsc_read_button(uint32_t index) +{ + switch(index) + { + case 0: + tsc_set_electrode(ELECTRODE_0); + break; + case 1: + tsc_set_electrode(ELECTRODE_1); + break; + } + tsc_start_acq(); + tsc_wait_on_acq(); + return tsc_read(1) < 45; +} + +int tsc_sensor_exists() +{ + static uint8_t does = 0; + if (does) return 1; + + LL_GPIO_SetPinMode(GPIOB, (1 << 1), LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(GPIOB, (1 << 1), LL_GPIO_PULL_UP); + + // Short delay before reading pin + asm("nop"); asm("nop"); asm("nop"); asm("nop"); + + does = (LL_GPIO_ReadInputPort(GPIOB) & (1 << 1)) == 0; + + LL_GPIO_SetPinPull(GPIOB, 1, LL_GPIO_PULL_NO); + + return does; +} diff --git a/targets/stm32l432/src/sense.h b/targets/stm32l432/src/sense.h new file mode 100644 index 0000000..cbf85f3 --- /dev/null +++ b/targets/stm32l432/src/sense.h @@ -0,0 +1,14 @@ +#ifndef _SENSE_H_ +#define _SENSE_H_ + +#include + +void tsc_init(); + +int tsc_sensor_exists(); + +// Read button0 or button1 +// Returns 1 if pressed, 0 if not. +uint32_t tsc_read_button(uint32_t index); + +#endif