Compare commits

...

24 Commits

Author SHA1 Message Date
ffadab05a3 Update STABLE_VERSION 2019-08-15 19:35:54 +08:00
2423154fee fix warning 2019-08-15 18:07:40 +08:00
cf79b7865d small fix 2019-08-15 17:50:16 +08:00
6f0cf99c92 PPS implementation 2019-08-15 17:50:16 +08:00
7ef68fd5d3 Merge pull request #265 from solokeys/fix_cdc_interfaces
Fix cdc interfaces
2019-08-15 17:49:53 +08:00
3be8611fcf remove duplicate from merge 2019-08-15 17:44:09 +08:00
21489658a7 Merge branch 'master' into fix_cdc_interfaces 2019-08-15 17:38:57 +08:00
a07a3dee8d refactor user_presence handling 2019-08-15 17:36:35 +08:00
416da63a9a not for bootloader 2019-08-15 17:36:35 +08:00
027fa791a3 only 1 user presence auth per button press 2019-08-15 17:36:35 +08:00
3e52d7b42b cache button press for 2s 2019-08-15 17:36:35 +08:00
301e18c6a2 add some int0 logic to main cycle 2019-08-14 14:32:03 +08:00
44205141eb add one place for int0 2019-08-14 14:32:03 +08:00
6e1110ca9b fix bug with ams_wait_for_tx 2019-08-14 14:32:03 +08:00
9105b988e2 fix some warnings 2019-08-14 14:32:03 +08:00
14c94ea8f5 minor typo 2019-08-14 14:26:45 +08:00
435b908c17 Merge pull request #241 from Wesseldr/feature/STM32L432_documentation_update
Added OsX arm install, updated FIDO2 test site links
2019-08-14 14:23:41 +08:00
78280e570b adjust whitespace 2019-08-12 16:18:47 +08:00
36aec9f20b separate interface into two and add "IAD" descriptor 2019-08-12 16:18:30 +08:00
b5d3276df6 not for bootloader 2019-08-11 18:16:58 +08:00
ffd854a303 only 1 user presence auth per button press 2019-08-11 18:05:08 +08:00
349a84dcec cache button press for 2s 2019-08-11 17:59:31 +08:00
6c6a9bc5b6 Merge pull request #260 from solokeys/all-contributors/add-szszszsz
docs: add szszszsz as a contributor
2019-08-08 01:14:36 +02:00
02a51454b7 Added OsX arm install, updated FIDO2 test site links 2019-08-07 18:35:41 +02:00
10 changed files with 1978 additions and 205 deletions

View File

@ -1 +1 @@
2.4.2 2.4.3

View File

@ -32,7 +32,7 @@ Source code can be downloaded from:
- from python programs [repository](https://pypi.org/project/solo-python/) `pip install solo-python` - from python programs [repository](https://pypi.org/project/solo-python/) `pip install solo-python`
- from installing prerequisites `pip3 install -r tools/requirements.txt` - from installing prerequisites `pip3 install -r tools/requirements.txt`
- github repository: [repository](https://github.com/solokeys/solo-python) - github repository: [repository](https://github.com/solokeys/solo-python)
- installation python enviroment witn command `make venv` from root directory of source code - installation python enviroment with command `make venv` from root directory of source code
## Compilation ## Compilation

View File

@ -66,7 +66,7 @@ Environment: Fedora 29 x64, Linux 4.19.9
See <https://docs.solokeys.io/solo/building/> for the original guide. Here details not included there will be covered. See <https://docs.solokeys.io/solo/building/> for the original guide. Here details not included there will be covered.
### Install ARM tools ### Install ARM tools Linux
1. Download current [ARM tools] package: [gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2]. 1. Download current [ARM tools] package: [gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2].
@ -75,6 +75,13 @@ See <https://docs.solokeys.io/solo/building/> for the original guide. Here detai
3. Add full path to the `./bin` directory as first entry to the `$PATH` variable, 3. Add full path to the `./bin` directory as first entry to the `$PATH` variable,
as in `~/gcc-arm/gcc-arm-none-eabi-8-2018-q4-major/bin/:$PATH`. as in `~/gcc-arm/gcc-arm-none-eabi-8-2018-q4-major/bin/:$PATH`.
### Install ARM tools OsX using brew package manager
```bash
brew tap ArmMbed/homebrew-formulae
brew install arm-none-eabi-gcc
```
### Install flashing software ### Install flashing software
ST provides a CLI flashing tool - `STM32_Programmer_CLI`. It can be downloaded directly from the vendor's site: ST provides a CLI flashing tool - `STM32_Programmer_CLI`. It can be downloaded directly from the vendor's site:
@ -114,8 +121,8 @@ Do not use it, if you do not plan to do so.
```bash ```bash
# while in the main project directory # while in the main project directory
# create Python virtual environment with required packages, and activate # create Python virtual environment with required packages, and activate
make env3 make venv
. env3/bin/activate . venv/bin/activate
# Run flashing # Run flashing
cd ./targets/stm32l432 cd ./targets/stm32l432
make flash make flash
@ -178,8 +185,8 @@ make fido2-test
#### FIDO2 test sites #### FIDO2 test sites
1. <https://webauthn.bin.coffee/> 1. <https://www.passwordless.dev/overview>
2. <https://github.com/apowers313/fido2-server-demo/> 2. <https://webauthn.bin.coffee/>
3. <https://webauthn.org/> 3. <https://webauthn.org/>
#### U2F test sites #### U2F test sites

View File

@ -6,7 +6,7 @@ AR=$(PREFIX)arm-none-eabi-ar
DRIVER_LIBS := lib/stm32l4xx_hal_pcd.c lib/stm32l4xx_hal_pcd_ex.c lib/stm32l4xx_ll_gpio.c \ DRIVER_LIBS := lib/stm32l4xx_hal_pcd.c lib/stm32l4xx_hal_pcd_ex.c lib/stm32l4xx_ll_gpio.c \
lib/stm32l4xx_ll_rcc.c lib/stm32l4xx_ll_rng.c lib/stm32l4xx_ll_tim.c \ lib/stm32l4xx_ll_rcc.c lib/stm32l4xx_ll_rng.c lib/stm32l4xx_ll_tim.c \
lib/stm32l4xx_ll_usb.c lib/stm32l4xx_ll_utils.c lib/stm32l4xx_ll_pwr.c \ lib/stm32l4xx_ll_usb.c lib/stm32l4xx_ll_utils.c lib/stm32l4xx_ll_pwr.c \
lib/stm32l4xx_ll_usart.c lib/stm32l4xx_ll_spi.c lib/stm32l4xx_ll_usart.c lib/stm32l4xx_ll_spi.c lib/stm32l4xx_ll_exti.c
USB_LIB := lib/usbd/usbd_cdc.c lib/usbd/usbd_cdc_if.c lib/usbd/usbd_composite.c \ USB_LIB := lib/usbd/usbd_cdc.c lib/usbd/usbd_cdc_if.c lib/usbd/usbd_composite.c \
lib/usbd/usbd_conf.c lib/usbd/usbd_core.c lib/usbd/usbd_ioreq.c \ lib/usbd/usbd_conf.c lib/usbd/usbd_core.c lib/usbd/usbd_ioreq.c \

View File

@ -0,0 +1,290 @@
/**
******************************************************************************
* @file stm32l4xx_ll_exti.c
* @author MCD Application Team
* @brief EXTI LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#if defined(USE_FULL_LL_DRIVER)
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_ll_exti.h"
#ifdef USE_FULL_ASSERT
#include "stm32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup STM32L4xx_LL_Driver
* @{
*/
#if defined (EXTI)
/** @defgroup EXTI_LL EXTI
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup EXTI_LL_Private_Macros
* @{
*/
#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U)
#define IS_LL_EXTI_LINE_32_63(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_32_63) == 0x00000000U)
#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
|| ((__VALUE__) == LL_EXTI_MODE_EVENT) \
|| ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
|| ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup EXTI_LL_Exported_Functions
* @{
*/
/** @addtogroup EXTI_LL_EF_Init
* @{
*/
/**
* @brief De-initialize the EXTI registers to their default reset values.
* @retval An ErrorStatus enumeration value:
* - 0x00: EXTI registers are de-initialized
*/
uint32_t LL_EXTI_DeInit(void)
{
/* Interrupt mask register set to default reset values */
LL_EXTI_WriteReg(IMR1, 0xFF820000U);
/* Event mask register set to default reset values */
LL_EXTI_WriteReg(EMR1, 0x00000000U);
/* Rising Trigger selection register set to default reset values */
LL_EXTI_WriteReg(RTSR1, 0x00000000U);
/* Falling Trigger selection register set to default reset values */
LL_EXTI_WriteReg(FTSR1, 0x00000000U);
/* Software interrupt event register set to default reset values */
LL_EXTI_WriteReg(SWIER1, 0x00000000U);
/* Pending register clear */
LL_EXTI_WriteReg(PR1, 0x007DFFFFU);
/* Interrupt mask register 2 set to default reset values */
#if defined(LL_EXTI_LINE_40)
LL_EXTI_WriteReg(IMR2, 0x00000187U);
#else
LL_EXTI_WriteReg(IMR2, 0x00000087U);
#endif
/* Event mask register 2 set to default reset values */
LL_EXTI_WriteReg(EMR2, 0x00000000U);
/* Rising Trigger selection register 2 set to default reset values */
LL_EXTI_WriteReg(RTSR2, 0x00000000U);
/* Falling Trigger selection register 2 set to default reset values */
LL_EXTI_WriteReg(FTSR2, 0x00000000U);
/* Software interrupt event register 2 set to default reset values */
LL_EXTI_WriteReg(SWIER2, 0x00000000U);
/* Pending register 2 clear */
LL_EXTI_WriteReg(PR2, 0x00000078U);
return 0x00u;
}
/**
* @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
* @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
* @retval An ErrorStatus enumeration value:
* - 0x00: EXTI registers are initialized
* - any other calue : wrong configuration
*/
uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
{
uint32_t status = 0x00u;
/* Check the parameters */
assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31));
assert_param(IS_LL_EXTI_LINE_32_63(EXTI_InitStruct->Line_32_63));
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
/* ENABLE LineCommand */
if (EXTI_InitStruct->LineCommand != DISABLE)
{
assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
/* Configure EXTI Lines in range from 0 to 31 */
if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE)
{
switch (EXTI_InitStruct->Mode)
{
case LL_EXTI_MODE_IT:
/* First Disable Event on provided Lines */
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
/* Then Enable IT on provided Lines */
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
break;
case LL_EXTI_MODE_EVENT:
/* First Disable IT on provided Lines */
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
/* Then Enable Event on provided Lines */
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
break;
case LL_EXTI_MODE_IT_EVENT:
/* Directly Enable IT & Event on provided Lines */
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
break;
default:
status = 0x01u;
break;
}
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
{
switch (EXTI_InitStruct->Trigger)
{
case LL_EXTI_TRIGGER_RISING:
/* First Disable Falling Trigger on provided Lines */
LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
/* Then Enable Rising Trigger on provided Lines */
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
break;
case LL_EXTI_TRIGGER_FALLING:
/* First Disable Rising Trigger on provided Lines */
LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
/* Then Enable Falling Trigger on provided Lines */
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
break;
case LL_EXTI_TRIGGER_RISING_FALLING:
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
break;
default:
status |= 0x02u;
break;
}
}
}
/* Configure EXTI Lines in range from 32 to 63 */
if (EXTI_InitStruct->Line_32_63 != LL_EXTI_LINE_NONE)
{
switch (EXTI_InitStruct->Mode)
{
case LL_EXTI_MODE_IT:
/* First Disable Event on provided Lines */
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
/* Then Enable IT on provided Lines */
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
break;
case LL_EXTI_MODE_EVENT:
/* First Disable IT on provided Lines */
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
/* Then Enable Event on provided Lines */
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
break;
case LL_EXTI_MODE_IT_EVENT:
/* Directly Enable IT & Event on provided Lines */
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
break;
default:
status |= 0x04u;
break;
}
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
{
switch (EXTI_InitStruct->Trigger)
{
case LL_EXTI_TRIGGER_RISING:
/* First Disable Falling Trigger on provided Lines */
LL_EXTI_DisableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
/* Then Enable IT on provided Lines */
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
break;
case LL_EXTI_TRIGGER_FALLING:
/* First Disable Rising Trigger on provided Lines */
LL_EXTI_DisableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
/* Then Enable Falling Trigger on provided Lines */
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
break;
case LL_EXTI_TRIGGER_RISING_FALLING:
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
break;
default:
status = ERROR;
break;
}
}
}
}
/* DISABLE LineCommand */
else
{
/* De-configure EXTI Lines in range from 0 to 31 */
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
/* De-configure EXTI Lines in range from 32 to 63 */
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
}
return status;
}
/**
* @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
* @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
* @retval None
*/
void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
{
EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE;
EXTI_InitStruct->Line_32_63 = LL_EXTI_LINE_NONE;
EXTI_InitStruct->LineCommand = DISABLE;
EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (EXTI) */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@ -26,16 +26,18 @@ static uint8_t *USBD_Composite_GetOtherSpeedCfgDesc (uint16_t *length);
static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length); static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);
#define NUM_INTERFACES 2 #define NUM_CLASSES 2
#define NUM_INTERFACES 3
#if NUM_INTERFACES>1 #if NUM_INTERFACES>1
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90) #define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90 + 8+9 + 4)
#else #else
#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41) #define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41)
#endif #endif
#define HID_INTF_NUM 0 #define HID_INTF_NUM 0
#define CDC_INTF_NUM 1 #define CDC_MASTER_INTF_NUM 1
#define CDC_SLAVE_INTF_NUM 2
__ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END = __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END =
{ {
/*Configuration Descriptor*/ /*Configuration Descriptor*/
@ -43,7 +45,7 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */ COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */
0x00, 0x00,
NUM_INTERFACES, /* bNumInterfaces: 1 interface */ NUM_INTERFACES, /* bNumInterfaces */
0x01, /* bConfigurationValue: Configuration value */ 0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0x80, /* bmAttributes: self powered */ 0x80, /* bmAttributes: self powered */
@ -92,22 +94,28 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
0x00, 0x00,
HID_BINTERVAL, /*bInterval: Polling Interval */ HID_BINTERVAL, /*bInterval: Polling Interval */
#if NUM_INTERFACES > 1 #if NUM_INTERFACES > 1
/* */ /* */
/* CDC */ /* CDC */
/* */ /* */
// This "IAD" is needed for Windows since it ignores the standard Union Functional Descriptor
0x08, // bLength
0x0B, // IAD type
CDC_MASTER_INTF_NUM, // First interface
CDC_SLAVE_INTF_NUM, // Next interface
0x02, // bInterfaceClass of the first interface
0x02, // bInterfaceSubClass of the first interface
0x00, // bInterfaceProtocol of the first interface
0x00, // Interface string index
/*Interface Descriptor */ /*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */ 0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */ /* Interface descriptor type */
/*!*/ CDC_INTF_NUM, /* bInterfaceNumber: Number of Interface */ /*!*/ CDC_MASTER_INTF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */ 0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */ 0x01, /* bNumEndpoints: 1 endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x02, /* bInterfaceSubClass: Abstract Control Model */
0x00, /* bInterfaceProtocol: Common AT commands */ 0x00, /* bInterfaceProtocol: Common AT commands */
@ -125,7 +133,7 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
0x24, /* bDescriptorType: CS_INTERFACE */ 0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */ 0x00, /* bmCapabilities: D0+D1 */
/*!*/ CDC_INTF_NUM, /* bDataInterface: 0 */ /*!*/ CDC_SLAVE_INTF_NUM, /* bDataInterface: 0 */
/*ACM Functional Descriptor*/ /*ACM Functional Descriptor*/
0x04, /* bFunctionLength */ 0x04, /* bFunctionLength */
@ -137,10 +145,10 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
0x05, /* bFunctionLength */ 0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */ 0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */ 0x06, /* bDescriptorSubtype: Union func desc */
/*!*/ CDC_INTF_NUM, /* bMasterInterface: Communication class interface */ /*!*/ CDC_MASTER_INTF_NUM, /* bMasterInterface: Communication class interface */
/*!*/ CDC_INTF_NUM, /* bSlaveInterface0: Data Class Interface */ /*!*/ CDC_SLAVE_INTF_NUM, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/ /* Control Endpoint Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */ 0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */ CDC_CMD_EP, /* bEndpointAddress */
@ -149,6 +157,17 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
HIBYTE(CDC_CMD_PACKET_SIZE), HIBYTE(CDC_CMD_PACKET_SIZE),
0x10, /* bInterval: */ 0x10, /* bInterval: */
/* Interface descriptor */
0x09, /* bLength */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
CDC_SLAVE_INTF_NUM, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x0A, /* bInterfaceClass: Communication class data */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00,
/*Endpoint OUT Descriptor*/ /*Endpoint OUT Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */ 0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
@ -167,10 +186,13 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
0x00, /* bInterval: ignore for Bulk transfer */ 0x00, /* bInterval: ignore for Bulk transfer */
4, /* Descriptor size */
3, /* Descriptor type */
0x09,
0x04,
#endif #endif
}; };
USBD_ClassTypeDef USBD_Composite = USBD_ClassTypeDef USBD_Composite =
{ {
USBD_Composite_Init, USBD_Composite_Init,
@ -195,14 +217,27 @@ int in_endpoint_to_class[MAX_ENDPOINTS];
int out_endpoint_to_class[MAX_ENDPOINTS]; int out_endpoint_to_class[MAX_ENDPOINTS];
void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1) { void USBD_Composite_Set_Classes(USBD_ClassTypeDef *hid_class, USBD_ClassTypeDef *cdc_class) {
USBD_Classes[0] = class0; USBD_Classes[0] = hid_class;
USBD_Classes[1] = class1; USBD_Classes[1] = cdc_class;
}
static USBD_ClassTypeDef * getClass(uint8_t index)
{
switch(index)
{
case HID_INTF_NUM:
return USBD_Classes[0];
case CDC_MASTER_INTF_NUM:
case CDC_SLAVE_INTF_NUM:
return USBD_Classes[1];
}
return NULL;
} }
static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
int i; int i;
for(i = 0; i < NUM_INTERFACES; i++) { for(i = 0; i < NUM_CLASSES; i++) {
if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) { if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) {
return USBD_FAIL; return USBD_FAIL;
} }
@ -213,7 +248,7 @@ static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
int i; int i;
for(i = 0; i < NUM_INTERFACES; i++) { for(i = 0; i < NUM_CLASSES; i++) {
if (USBD_Classes[i]->DeInit(pdev, cfgidx) != USBD_OK) { if (USBD_Classes[i]->DeInit(pdev, cfgidx) != USBD_OK) {
return USBD_FAIL; return USBD_FAIL;
} }
@ -224,10 +259,13 @@ static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) {
int i; int i;
USBD_ClassTypeDef * device_class;
device_class = getClass(req->wIndex);
switch (req->bmRequest & USB_REQ_TYPE_MASK) { switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS : case USB_REQ_TYPE_CLASS :
if (req->wIndex < NUM_INTERFACES) if (device_class != NULL)
return USBD_Classes[req->wIndex]->Setup(pdev, req); return device_class->Setup(pdev, req);
else else
return USBD_FAIL; return USBD_FAIL;
@ -236,7 +274,7 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
switch (req->bRequest) { switch (req->bRequest) {
case USB_REQ_GET_DESCRIPTOR : case USB_REQ_GET_DESCRIPTOR :
for(i = 0; i < NUM_INTERFACES; i++) { for(i = 0; i < NUM_CLASSES; i++) {
if (USBD_Classes[i]->Setup(pdev, req) != USBD_OK) { if (USBD_Classes[i]->Setup(pdev, req) != USBD_OK) {
return USBD_FAIL; return USBD_FAIL;
} }
@ -246,8 +284,8 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType
case USB_REQ_GET_INTERFACE : case USB_REQ_GET_INTERFACE :
case USB_REQ_SET_INTERFACE : case USB_REQ_SET_INTERFACE :
if (req->wIndex < NUM_INTERFACES) if (device_class != NULL)
return USBD_Classes[req->wIndex]->Setup(pdev, req); return device_class->Setup(pdev, req);
else else
return USBD_FAIL; return USBD_FAIL;
} }
@ -274,7 +312,7 @@ static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) { static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) {
int i; int i;
for(i = 0; i < NUM_INTERFACES; i++) { for(i = 0; i < NUM_CLASSES; i++) {
if (USBD_Classes[i]->EP0_RxReady != NULL) { if (USBD_Classes[i]->EP0_RxReady != NULL) {
if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) { if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) {
return USBD_FAIL; return USBD_FAIL;

View File

@ -38,6 +38,8 @@ void wait_for_usb_tether();
uint32_t __90_ms = 0; uint32_t __90_ms = 0;
uint32_t __last_button_press_time = 0;
uint32_t __last_button_bounce_time = 0;
uint32_t __device_status = 0; uint32_t __device_status = 0;
uint32_t __last_update = 0; uint32_t __last_update = 0;
extern PCD_HandleTypeDef hpcd; extern PCD_HandleTypeDef hpcd;
@ -75,6 +77,21 @@ void TIM6_DAC_IRQHandler()
ctaphid_update_status(__device_status); ctaphid_update_status(__device_status);
} }
} }
if (is_touch_button_pressed == IS_BUTTON_PRESSED)
{
if (IS_BUTTON_PRESSED())
{
// Only allow 1 press per 25 ms.
if ((millis() - __last_button_bounce_time) > 25)
{
__last_button_press_time = millis();
}
__last_button_bounce_time = millis();
}
}
#ifndef IS_BOOTLOADER #ifndef IS_BOOTLOADER
// NFC sending WTX if needs // NFC sending WTX if needs
if (device_is_nfc() == NFC_IS_ACTIVE) if (device_is_nfc() == NFC_IS_ACTIVE)
@ -84,6 +101,21 @@ void TIM6_DAC_IRQHandler()
#endif #endif
} }
// Interrupt on rising edge of button (button released)
void EXTI0_IRQHandler(void)
{
EXTI->PR1 = EXTI->PR1;
if (is_physical_button_pressed == IS_BUTTON_PRESSED)
{
// Only allow 1 press per 25 ms.
if ((millis() - __last_button_bounce_time) > 25)
{
__last_button_press_time = millis();
}
__last_button_bounce_time = millis();
}
}
// Global USB interrupt handler // Global USB interrupt handler
void USB_IRQHandler(void) void USB_IRQHandler(void)
{ {
@ -493,6 +525,41 @@ static int handle_packets()
return 0; return 0;
} }
static int wait_for_button_activate(uint32_t wait)
{
int ret;
uint32_t start = millis();
do
{
if ((start + wait) < millis())
{
return 0;
}
delay(1);
ret = handle_packets();
if (ret)
return ret;
} while (!IS_BUTTON_PRESSED());
return 0;
}
static int wait_for_button_release(uint32_t wait)
{
int ret;
uint32_t start = millis();
do
{
if ((start + wait) < millis())
{
return 0;
}
delay(1);
ret = handle_packets();
if (ret)
return ret;
} while (IS_BUTTON_PRESSED());
return 0;
}
int ctap_user_presence_test(uint32_t up_delay) int ctap_user_presence_test(uint32_t up_delay)
{ {
int ret; int ret;
@ -500,6 +567,7 @@ int ctap_user_presence_test(uint32_t up_delay)
{ {
return 1; return 1;
} }
#if SKIP_BUTTON_CHECK_WITH_DELAY #if SKIP_BUTTON_CHECK_WITH_DELAY
int i=500; int i=500;
while(i--) while(i--)
@ -512,53 +580,41 @@ int ctap_user_presence_test(uint32_t up_delay)
#elif SKIP_BUTTON_CHECK_FAST #elif SKIP_BUTTON_CHECK_FAST
delay(2); delay(2);
ret = handle_packets(); ret = handle_packets();
if (ret) return ret; if (ret)
return ret;
goto done; goto done;
#endif #endif
uint32_t t1 = millis();
// If button was pressed within last [2] seconds, succeed.
if (__last_button_press_time && (millis() - __last_button_press_time < 2000))
{
goto done;
}
// Set LED status and wait.
led_rgb(0xff3520); led_rgb(0xff3520);
if (IS_BUTTON_PRESSED == is_touch_button_pressed) // Block and wait for some time.
{ ret = wait_for_button_activate(up_delay);
// Wait for user to release touch button if it's already pressed
while (IS_BUTTON_PRESSED())
{
if (t1 + up_delay < millis())
{
printf1(TAG_GEN,"Button not pressed\n");
goto fail;
}
ret = handle_packets();
if (ret) return ret; if (ret) return ret;
} ret = wait_for_button_release(up_delay);
}
t1 = millis();
do
{
if (t1 + up_delay < millis())
{
goto fail;
}
delay(1);
ret = handle_packets();
if (ret) return ret; if (ret) return ret;
// If button was pressed within last [2] seconds, succeed.
if (__last_button_press_time && (millis() - __last_button_press_time < 2000))
{
goto done;
} }
while (! IS_BUTTON_PRESSED());
led_rgb(0x001040);
delay(50);
#if SKIP_BUTTON_CHECK_WITH_DELAY || SKIP_BUTTON_CHECK_FAST return 0;
done: done:
#endif ret = wait_for_button_release(up_delay);
__last_button_press_time = 0;
return 1; return 1;
fail:
return 0;
} }
int ctap_generate_rng(uint8_t * dst, size_t num) int ctap_generate_rng(uint8_t * dst, size_t num)

View File

@ -20,6 +20,7 @@
#include "stm32l4xx_ll_rng.h" #include "stm32l4xx_ll_rng.h"
#include "stm32l4xx_ll_spi.h" #include "stm32l4xx_ll_spi.h"
#include "stm32l4xx_ll_usb.h" #include "stm32l4xx_ll_usb.h"
#include "stm32l4xx_ll_exti.h"
#include "stm32l4xx_hal_pcd.h" #include "stm32l4xx_hal_pcd.h"
#include "stm32l4xx_hal.h" #include "stm32l4xx_hal.h"
@ -849,19 +850,17 @@ void init_gpio(void)
LL_GPIO_SetPinMode(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_MODE_INPUT); LL_GPIO_SetPinMode(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinPull(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_PULL_UP); LL_GPIO_SetPinPull(SOLO_BUTTON_PORT,SOLO_BUTTON_PIN,LL_GPIO_PULL_UP);
#ifdef SOLO_AMS_IRQ_PORT #ifndef IS_BOOTLOADER
// SAVE POWER LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE0);
// LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); LL_EXTI_InitTypeDef EXTI_InitStruct;
// /**/ EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_0; // GPIOA_0
// LL_GPIO_InitTypeDef GPIO_InitStruct; EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
// GPIO_InitStruct.Pin = SOLO_AMS_IRQ_PIN; EXTI_InitStruct.LineCommand = ENABLE;
// GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
// GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
// LL_GPIO_Init(SOLO_AMS_IRQ_PORT, &GPIO_InitStruct); LL_EXTI_Init(&EXTI_InitStruct);
//
// NVIC_EnableIRQ(EXTI0_IRQn);
// LL_GPIO_SetPinMode(SOLO_AMS_IRQ_PORT,SOLO_AMS_IRQ_PIN,LL_GPIO_MODE_INPUT);
// LL_GPIO_SetPinPull(SOLO_AMS_IRQ_PORT,SOLO_AMS_IRQ_PIN,LL_GPIO_PULL_UP);
#endif #endif
} }

View File

@ -92,19 +92,27 @@ int nfc_init()
return NFC_IS_NA; return NFC_IS_NA;
} }
static uint8_t gl_int0 = 0;
void process_int0(uint8_t int0) void process_int0(uint8_t int0)
{ {
gl_int0 = int0;
} }
bool ams_wait_for_tx(uint32_t timeout_ms) bool ams_wait_for_tx(uint32_t timeout_ms)
{ {
if (gl_int0 & AMS_INT_TXE) {
uint8_t int0 = ams_read_reg(AMS_REG_INT0);
process_int0(int0);
return true;
}
uint32_t tstart = millis(); uint32_t tstart = millis();
while (tstart + timeout_ms > millis()) while (tstart + timeout_ms > millis())
{ {
uint8_t int0 = ams_read_reg(AMS_REG_INT0); uint8_t int0 = ams_read_reg(AMS_REG_INT0);
if (int0) process_int0(int0); process_int0(int0);
if (int0 & AMS_INT_TXE) if (int0 & AMS_INT_TXE || int0 & AMS_INT_RXE)
return true; return true;
delay(1); delay(1);
@ -121,8 +129,13 @@ bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, i
uint32_t tstart = millis(); uint32_t tstart = millis();
while (tstart + timeout_ms > millis()) while (tstart + timeout_ms > millis())
{ {
uint8_t int0 = ams_read_reg(AMS_REG_INT0); uint8_t int0 = 0;
if (int0) process_int0(int0); if (gl_int0 & AMS_INT_RXE) {
int0 = gl_int0;
} else {
int0 = ams_read_reg(AMS_REG_INT0);
process_int0(int0);
}
uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2); uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2);
if (buffer_status2 && (int0 & AMS_INT_RXE)) if (buffer_status2 && (int0 & AMS_INT_RXE))
@ -196,7 +209,6 @@ bool nfc_write_response(uint8_t req0, uint16_t resp)
void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len) void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
{ {
uint8_t res[32 + 2]; uint8_t res[32 + 2];
int sendlen = 0;
uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f); uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f);
uint8_t block_offset = p14443_block_offset(req0); uint8_t block_offset = p14443_block_offset(req0);
@ -208,6 +220,7 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
memcpy(&res[block_offset], data, len); memcpy(&res[block_offset], data, len);
nfc_write_frame(res, len + block_offset); nfc_write_frame(res, len + block_offset);
} else { } else {
int sendlen = 0;
do { do {
// transmit I block // transmit I block
int vlen = MIN(32 - block_offset, len - sendlen); int vlen = MIN(32 - block_offset, len - sendlen);
@ -227,11 +240,11 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
sendlen += vlen; sendlen += vlen;
// wait for transmit (32 bytes aprox 2,5ms) // wait for transmit (32 bytes aprox 2,5ms)
// if (!ams_wait_for_tx(10)) if (!ams_wait_for_tx(5))
// { {
// printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen); printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen);
// break; break;
// } }
// if needs to receive R block (not a last block) // if needs to receive R block (not a last block)
if (res[0] & 0x10) if (res[0] & 0x10)
@ -316,7 +329,7 @@ bool WTX_off()
void WTX_timer_exec() void WTX_timer_exec()
{ {
// condition: (timer on) or (not expired[300ms]) // condition: (timer on) or (not expired[300ms])
if ((WTX_timer <= 0) || WTX_timer + 300 > millis()) if ((WTX_timer == 0) || WTX_timer + 300 > millis())
return; return;
WTX_process(10); WTX_process(10);
@ -327,12 +340,12 @@ void WTX_timer_exec()
// read timeout must be 10 ms to call from interrupt // read timeout must be 10 ms to call from interrupt
bool WTX_process(int read_timeout) bool WTX_process(int read_timeout)
{ {
uint8_t wtx[] = {0xf2, 0x01};
if (WTX_fail) if (WTX_fail)
return false; return false;
if (!WTX_sent) if (!WTX_sent)
{ {
uint8_t wtx[] = {0xf2, 0x01};
nfc_write_frame(wtx, sizeof(wtx)); nfc_write_frame(wtx, sizeof(wtx));
WTX_sent = true; WTX_sent = true;
return true; return true;
@ -618,7 +631,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
if (!WTX_off()) if (!WTX_off())
return; return;
printf1(TAG_NFC, "CTAP resp: 0x%02<EFBFBD> len: %d\r\n", status, ctap_resp.length); printf1(TAG_NFC, "CTAP resp: 0x%02x len: %d\r\n", status, ctap_resp.length);
if (status == CTAP1_ERR_SUCCESS) if (status == CTAP1_ERR_SUCCESS)
{ {
@ -687,7 +700,14 @@ void nfc_process_block(uint8_t * buf, unsigned int len)
if (IS_PPSS_CMD(buf[0])) if (IS_PPSS_CMD(buf[0]))
{ {
printf1(TAG_NFC, "NFC_CMD_PPSS\r\n"); printf1(TAG_NFC, "NFC_CMD_PPSS [%d] 0x%02x\r\n", len, (len > 2) ? buf[2] : 0);
if (buf[1] == 0x11 && (buf[2] & 0x0f) == 0x00) {
nfc_write_frame(buf, 1); // ack with correct start byte
} else {
printf1(TAG_NFC, "NFC_CMD_PPSS ERROR!!!\r\n");
nfc_write_frame((uint8_t*)"\x00", 1); // this should not happend. but iso14443-4 dont have NACK here, so just 0x00
}
} }
else if (IS_IBLOCK(buf[0])) else if (IS_IBLOCK(buf[0]))
{ {
@ -779,6 +799,8 @@ int nfc_loop()
read_reg_block(&ams); read_reg_block(&ams);
uint8_t old_int0 = gl_int0;
process_int0(ams.regs.int0);
uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status; uint8_t state = AMS_STATE_MASK & ams.regs.rfid_status;
if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX) if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX)
@ -792,7 +814,7 @@ int nfc_loop()
// if (state != AMS_STATE_SENSE) // if (state != AMS_STATE_SENSE)
// printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state); // printf1(TAG_NFC," %s x%02x\r\n", ams_get_state_string(ams.regs.rfid_status), state);
} }
if (ams.regs.int0 & AMS_INT_INIT) if (ams.regs.int0 & AMS_INT_INIT || old_int0 & AMS_INT_INIT)
{ {
nfc_state_init(); nfc_state_init();
} }
@ -801,7 +823,7 @@ int nfc_loop()
// ams_print_int1(ams.regs.int1); // ams_print_int1(ams.regs.int1);
} }
if ((ams.regs.int0 & AMS_INT_RXE)) if (ams.regs.int0 & AMS_INT_RXE || old_int0 & AMS_INT_RXE)
{ {
if (ams.regs.buffer_status2) if (ams.regs.buffer_status2)
{ {