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)
{