diff --git a/docs/solo/building.md b/docs/solo/building.md index ee7a335..084e2c4 100644 --- a/docs/solo/building.md +++ b/docs/solo/building.md @@ -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 installing prerequisites `pip3 install -r tools/requirements.txt` - 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 diff --git a/docs/solo/nucleo32-board.md b/docs/solo/nucleo32-board.md index e48312d..ac579d2 100644 --- a/docs/solo/nucleo32-board.md +++ b/docs/solo/nucleo32-board.md @@ -66,7 +66,7 @@ Environment: Fedora 29 x64, Linux 4.19.9 See 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]. @@ -75,6 +75,13 @@ See for the original guide. Here detai 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`. +### Install ARM tools OsX using brew package manager + +```bash +brew tap ArmMbed/homebrew-formulae +brew install arm-none-eabi-gcc +``` + ### Install flashing software 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 # while in the main project directory # create Python virtual environment with required packages, and activate -make env3 -. env3/bin/activate +make venv +. venv/bin/activate # Run flashing cd ./targets/stm32l432 make flash @@ -178,8 +185,8 @@ make fido2-test #### FIDO2 test sites -1. -2. +1. +2. 3. #### U2F test sites diff --git a/targets/stm32l432/src/device.c b/targets/stm32l432/src/device.c index d211bdd..d1cc41c 100644 --- a/targets/stm32l432/src/device.c +++ b/targets/stm32l432/src/device.c @@ -39,6 +39,7 @@ void wait_for_usb_tether(); 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 __last_update = 0; extern PCD_HandleTypeDef hpcd; @@ -76,6 +77,21 @@ void TIM6_DAC_IRQHandler() 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 // NFC sending WTX if needs if (device_is_nfc() == NFC_IS_ACTIVE) @@ -90,6 +106,21 @@ void EXTI0_IRQHandler(void) __last_button_press_time = millis(); } +// 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 void USB_IRQHandler(void) { @@ -499,6 +530,41 @@ static int handle_packets() 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 ret; @@ -506,12 +572,7 @@ int ctap_user_presence_test(uint32_t up_delay) { return 1; } - // "cache" button presses for 2 seconds. - if (millis() - __last_button_press_time < 2000) - { - __last_button_press_time = 0; - return 1; - } + #if SKIP_BUTTON_CHECK_WITH_DELAY int i=500; while(i--) @@ -524,53 +585,41 @@ int ctap_user_presence_test(uint32_t up_delay) #elif SKIP_BUTTON_CHECK_FAST delay(2); ret = handle_packets(); - if (ret) return ret; + if (ret) + return ret; goto done; #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); -if (IS_BUTTON_PRESSED == is_touch_button_pressed) -{ - // 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; - } -} - -t1 = millis(); - -do -{ - if (t1 + up_delay < millis()) - { - goto fail; - } - delay(1); - ret = handle_packets(); + // Block and wait for some time. + ret = wait_for_button_activate(up_delay); + if (ret) return ret; + ret = wait_for_button_release(up_delay); if (ret) return ret; -} -while (! IS_BUTTON_PRESSED()); -led_rgb(0x001040); - -delay(50); + // If button was pressed within last [2] seconds, succeed. + if (__last_button_press_time && (millis() - __last_button_press_time < 2000)) + { + goto done; + } + + + return 0; -#if SKIP_BUTTON_CHECK_WITH_DELAY || SKIP_BUTTON_CHECK_FAST done: -#endif -return 1; + ret = wait_for_button_release(up_delay); + __last_button_press_time = 0; + return 1; -fail: -return 0; } int ctap_generate_rng(uint8_t * dst, size_t num) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index a223378..cdcaa8f 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -92,19 +92,27 @@ int nfc_init() return NFC_IS_NA; } +static uint8_t gl_int0 = 0; void process_int0(uint8_t int0) { - + gl_int0 = int0; } 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(); while (tstart + timeout_ms > millis()) { uint8_t int0 = ams_read_reg(AMS_REG_INT0); - if (int0) process_int0(int0); - if (int0 & AMS_INT_TXE) + process_int0(int0); + if (int0 & AMS_INT_TXE || int0 & AMS_INT_RXE) return true; 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(); while (tstart + timeout_ms > millis()) { - uint8_t int0 = ams_read_reg(AMS_REG_INT0); - if (int0) process_int0(int0); + uint8_t int0 = 0; + 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); 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) { uint8_t res[32 + 2]; - int sendlen = 0; uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 0x0f); 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); nfc_write_frame(res, len + block_offset); } else { + int sendlen = 0; do { // transmit I block 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; // wait for transmit (32 bytes aprox 2,5ms) - // if (!ams_wait_for_tx(10)) - // { - // printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen); - // break; - // } + if (!ams_wait_for_tx(5)) + { + printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen); + break; + } // if needs to receive R block (not a last block) if (res[0] & 0x10) @@ -316,7 +329,7 @@ bool WTX_off() void WTX_timer_exec() { // condition: (timer on) or (not expired[300ms]) - if ((WTX_timer <= 0) || WTX_timer + 300 > millis()) + if ((WTX_timer == 0) || WTX_timer + 300 > millis()) return; WTX_process(10); @@ -327,12 +340,12 @@ void WTX_timer_exec() // read timeout must be 10 ms to call from interrupt bool WTX_process(int read_timeout) { - uint8_t wtx[] = {0xf2, 0x01}; if (WTX_fail) return false; if (!WTX_sent) { + uint8_t wtx[] = {0xf2, 0x01}; nfc_write_frame(wtx, sizeof(wtx)); WTX_sent = true; return true; @@ -618,7 +631,7 @@ void nfc_process_iblock(uint8_t * buf, int len) if (!WTX_off()) return; - printf1(TAG_NFC, "CTAP resp: 0x%02� 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) { @@ -779,6 +792,8 @@ int nfc_loop() 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; if (state != AMS_STATE_SELECTED && state != AMS_STATE_SELECTEDX) @@ -792,7 +807,7 @@ int nfc_loop() // if (state != AMS_STATE_SENSE) // 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(); } @@ -801,7 +816,7 @@ int nfc_loop() // 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) {