diff --git a/.travis.yml b/.travis.yml index 8c61b8aa..011e4ddc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -dist: xenial +dist: bionic language: c compiler: gcc addons: @@ -8,13 +8,14 @@ addons: packages: - gcc-8 - cppcheck + - python3-venv + - wget services: - docker before_install: - - sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa - - sudo apt-get update -q - - sudo apt-get install -y gcc-arm-embedded python3-venv + - wget -O gcc-arm.tar.bz2 'https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=6e63531f-8cb1-40b9-bbfc-8a57cdfc01b4&la=en&hash=F761343D43A0587E8AC0925B723C04DBFB848339' + - sudo tar -jxf gcc-arm.tar.bz2 --strip-components=1 -C / + - rm gcc-arm.tar.bz2 script: - export CC=gcc-8 - - pyenv shell 3.6.7 - make travis diff --git a/Makefile b/Makefile index 9259be73..d903bd37 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ venv: python3 -m venv venv venv/bin/pip -q install --upgrade pip venv/bin/pip -q install --upgrade -r tools/requirements.txt - venv/bin/pip -q install --upgrade black + venv/bin/pip -q install --upgrade black==19.3b0 # Versions newer than this require regex, which fails to compile # selectively reformat our own code black: venv @@ -110,7 +110,8 @@ CPPCHECK_FLAGS=--quiet --error-exitcode=2 cppcheck: cppcheck $(CPPCHECK_FLAGS) crypto/aes-gcm cppcheck $(CPPCHECK_FLAGS) crypto/sha256 - cppcheck $(CPPCHECK_FLAGS) fido2 + cppcheck $(CPPCHECK_FLAGS) fido2 -DAPP_CONFIG=app.h + cppcheck $(CPPCHECK_FLAGS) fido2 -DAPP_CONFIG=bootloader.h cppcheck $(CPPCHECK_FLAGS) pc clean: @@ -135,4 +136,4 @@ test-docker: travis: $(MAKE) test VENV=". ../../venv/bin/activate;" $(MAKE) test-docker - $(MAKE) black \ No newline at end of file + $(MAKE) black diff --git a/targets/stm32l432/build/bootloader.mk b/targets/stm32l432/build/bootloader.mk index db7aff25..896c6526 100644 --- a/targets/stm32l432/build/bootloader.mk +++ b/targets/stm32l432/build/bootloader.mk @@ -3,9 +3,13 @@ include build/common.mk # ST related SRC = bootloader/main.c bootloader/bootloader.c SRC += bootloader/pubkey_bootloader.c bootloader/version_check.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/attestation.c src/sense.c SRC += src/startup_stm32l432xx.s src/system_stm32l4xx.c +# Important: device.c must come after startup_stm32l432xx.s to work around +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83967. If the order is switched, +# compilation will succeed but the output will be missing overridden weak +# symbols. +SRC += src/init.c src/redirect.c src/flash.c src/rng.c src/led.c src/device.c SRC += $(DRIVER_LIBS) $(USB_LIB) # FIDO2 lib @@ -34,6 +38,11 @@ CFLAGS= $(INC) TARGET=bootloader HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb +ifeq (${DEBUG},1) + LTO_FLAG= +else + LTO_FLAG=-flto +endif # Solo or Nucleo board CHIP=STM32L432xx @@ -45,8 +54,8 @@ endif DEFINES = -DDEBUG_LEVEL=$(DEBUG) -D$(CHIP) -DAES256=1 -DUSE_FULL_LL_DRIVER -DAPP_CONFIG=\"bootloader.h\" $(EXTRA_DEFINES) # DEFINES += -DTEST_SOLO_STM32 -DTEST -DTEST_FIFO=1 -CFLAGS=$(INC) -c $(DEFINES) -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fdata-sections -ffunction-sections $(HW) -g $(VERSION_FLAGS) -LDFLAGS_LIB=$(HW) $(SEARCH) -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -lnosys +CFLAGS=$(INC) -c $(DEFINES) -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fdata-sections -ffunction-sections $(HW) -g $(VERSION_FLAGS) ${LTO_FLAG} +LDFLAGS_LIB=$(HW) $(SEARCH) -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -lnosys ${LTO_FLAG} LDFLAGS=$(HW) $(LDFLAGS_LIB) -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,-Bstatic diff --git a/targets/stm32l432/src/device.c b/targets/stm32l432/src/device.c index 1a83ebc5..eb0caf7a 100644 --- a/targets/stm32l432/src/device.c +++ b/targets/stm32l432/src/device.c @@ -290,10 +290,7 @@ void device_init() hw_init(LOW_FREQUENCY); - if (! tsc_sensor_exists()) - { - _NFC_status = nfc_init(); - } + _NFC_status = nfc_init(); if (_NFC_status == NFC_IS_ACTIVE) { diff --git a/targets/stm32l432/src/sense.c b/targets/stm32l432/src/sense.c index 37a16561..f38e123a 100644 --- a/targets/stm32l432/src/sense.c +++ b/targets/stm32l432/src/sense.c @@ -5,8 +5,20 @@ #include "stm32l4xx_ll_gpio.h" #include "stm32l4xx_hal_tsc.h" -#define ELECTRODE_0 TSC_GROUP2_IO1 -#define ELECTRODE_1 TSC_GROUP2_IO2 +/** +USB A Nano & USB C Touch TSC GPIO Configuration: +PB4 ------> Channel 1 (electrode 1) +PB5 ------> Channel 2 (electrode 2) +PB6 ------> Channel 3 (sampling capacitor) +PB7 ------> Channel 4 (unused) +*/ +#define get_sampling_cap_io() TSC_GROUP2_IO3 +#define get_sampling_cap_pin() LL_GPIO_PIN_6 +#define get_first_electrode_io() TSC_GROUP2_IO1 +#define get_first_electrode_pin() LL_GPIO_PIN_4 +#define get_second_electrode_io() TSC_GROUP2_IO2 +#define get_second_electrode_pin() LL_GPIO_PIN_5 +#define get_tsc_threshold() 45 void tsc_init(void) { @@ -14,11 +26,7 @@ void tsc_init(void) // 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.Pin = get_first_electrode_pin() | get_second_electrode_pin(); GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; @@ -26,15 +34,12 @@ void tsc_init(void) 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.Pin = get_sampling_cap_pin(); 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; + uint32_t channel_ios = get_first_electrode_io() | get_second_electrode_io(); // enable TSC->CR = TSC_CR_TSCE; @@ -44,7 +49,7 @@ void tsc_init(void) (uint32_t)(1 << TSC_CR_SSD_Pos) | TSC_SS_PRESC_DIV1 | TSC_PG_PRESC_DIV16 | - TSC_MCV_16383 | + TSC_MCV_255 | TSC_SYNC_POLARITY_FALLING | TSC_ACQ_MODE_NORMAL); @@ -55,10 +60,10 @@ void tsc_init(void) } // Schmitt trigger and hysteresis - TSC->IOHCR = (uint32_t)(~(channel_ios | 0 | TSC_GROUP2_IO3)); + TSC->IOHCR = (uint32_t)(~(channel_ios | 0 | get_sampling_cap_io())); // Sampling IOs - TSC->IOSCR = TSC_GROUP2_IO3; + TSC->IOSCR = get_sampling_cap_io(); // Groups uint32_t grps = 0x02; @@ -106,31 +111,39 @@ uint32_t tsc_read_button(uint32_t index) switch(index) { case 0: - tsc_set_electrode(ELECTRODE_0); + tsc_set_electrode(get_first_electrode_io()); break; case 1: - tsc_set_electrode(ELECTRODE_1); + tsc_set_electrode(get_second_electrode_io()); break; } tsc_start_acq(); tsc_wait_on_acq(); - return tsc_read(1) < 45; + return tsc_read(1) < get_tsc_threshold(); } -int tsc_sensor_exists(void) -{ - static uint8_t does = 0; - if (does) return 1; +#define PIN_SHORTED_UNDEF 0 +#define PIN_SHORTED_YES 1 +#define PIN_SHORTED_NO 2 - LL_GPIO_SetPinMode(GPIOB, (1 << 1), LL_GPIO_MODE_INPUT); - LL_GPIO_SetPinPull(GPIOB, (1 << 1), LL_GPIO_PULL_UP); +int pin_grounded(GPIO_TypeDef* bank, int pin_mask) { + LL_GPIO_SetPinMode(bank, (pin_mask), LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(bank, (pin_mask), 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; + int result = (LL_GPIO_ReadInputPort(bank) & (pin_mask)) == 0; + + LL_GPIO_SetPinPull(bank, 1, LL_GPIO_PULL_NO); - LL_GPIO_SetPinPull(GPIOB, 1, LL_GPIO_PULL_NO); + return result ? PIN_SHORTED_YES : PIN_SHORTED_NO; +} - return does; +int tsc_sensor_exists(void) +{ + // PB1 is grounded in USB A nano & USB C touch + static uint8_t does = PIN_SHORTED_UNDEF; + if (does == PIN_SHORTED_UNDEF) does = pin_grounded(GPIOB, LL_GPIO_PIN_1); + return does == PIN_SHORTED_YES; }