diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader index d995298631..02614ca4fc 100644 --- a/core/SConscript.boardloader +++ b/core/SConscript.boardloader @@ -37,21 +37,22 @@ SOURCE_MOD += [ ] SOURCE_STMHAL = [ + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c', @@ -64,12 +65,14 @@ SOURCE_BOARDLOADER = [ SOURCE_TREZORHAL = [ 'embed/trezorhal/common.c', + 'embed/trezorhal/dma.c', 'embed/trezorhal/image.c', 'embed/trezorhal/flash.c', 'embed/trezorhal/lowlevel.c', 'embed/trezorhal/mini_printf.c', 'embed/trezorhal/sdcard.c', 'embed/trezorhal/stm32.c', + 'embed/trezorhal/systick.c', 'embed/trezorhal/rng.c', 'embed/trezorhal/util.s', 'embed/trezorhal/vectortable.s', diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index 5dc8f3049d..f81cf67667 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -47,21 +47,21 @@ SOURCE_MOD += [ ] SOURCE_STMHAL = [ + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', - 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c', @@ -88,6 +88,7 @@ SOURCE_TREZORHAL = [ 'embed/trezorhal/mpu.c', 'embed/trezorhal/rng.c', 'embed/trezorhal/stm32.c', + 'embed/trezorhal/systick.c', 'embed/trezorhal/touch.c', 'embed/trezorhal/usb.c', 'embed/trezorhal/usbd_conf.c', diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 1f7ac440e3..53af7b5d17 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -310,6 +310,7 @@ SOURCE_FIRMWARE = [ SOURCE_TREZORHAL = [ 'embed/trezorhal/common.c', + 'embed/trezorhal/delay.c', 'embed/trezorhal/dma.c', 'embed/trezorhal/flash.c', 'embed/trezorhal/mini_printf.c', diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index e8ea6d05ca..73f63cdadb 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#include STM32_HAL_H + #include #include #include diff --git a/core/embed/firmware/mpconfigport.h b/core/embed/firmware/mpconfigport.h index 9e0befdbfc..d9ea164878 100644 --- a/core/embed/firmware/mpconfigport.h +++ b/core/embed/firmware/mpconfigport.h @@ -184,25 +184,7 @@ typedef long mp_off_t; #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) -// We have inlined IRQ functions for efficiency (they are generally -// 1 machine instruction). -// -// Note on IRQ state: you should not need to know the specific -// value of the state variable, but rather just pass the return -// value from disable_irq back to enable_irq. If you really need -// to know the machine-specific values, see irq.h. - -#include STM32_HAL_H - -static inline void enable_irq(mp_uint_t state) { - __set_PRIMASK(state); -} - -static inline mp_uint_t disable_irq(void) { - mp_uint_t state = __get_PRIMASK(); - __disable_irq(); - return state; -} +#include "irq.h" #define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq() #define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state) diff --git a/core/embed/trezorhal/delay.c b/core/embed/trezorhal/delay.c new file mode 100644 index 0000000000..0c4c267c32 --- /dev/null +++ b/core/embed/trezorhal/delay.c @@ -0,0 +1,118 @@ +// clang-format off + +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "irq.h" + +extern __IO uint32_t uwTick; + +// We provide our own version of HAL_Delay that calls __WFI while waiting, +// and works when interrupts are disabled. This function is intended to be +// used only by the ST HAL functions. +void HAL_Delay(uint32_t Delay) { + if (query_irq() == IRQ_STATE_ENABLED) { + // IRQs enabled, so can use systick counter to do the delay + uint32_t start = uwTick; + // Wraparound of tick is taken care of by 2's complement arithmetic. + while (uwTick - start < Delay) { + // Enter sleep mode, waiting for (at least) the SysTick interrupt. + __WFI(); + } + } else { + // IRQs disabled, use mp_hal_delay_ms routine. + mp_hal_delay_ms(Delay); + } +} + +// Core delay function that does an efficient sleep and may switch thread context. +// If IRQs are enabled then we must have the GIL. +void mp_hal_delay_ms(mp_uint_t Delay) { + if (query_irq() == IRQ_STATE_ENABLED) { + // IRQs enabled, so can use systick counter to do the delay + uint32_t start = uwTick; + // Wraparound of tick is taken care of by 2's complement arithmetic. + while (uwTick - start < Delay) { + // This macro will execute the necessary idle behaviour. It may + // raise an exception, switch threads or enter sleep mode (waiting for + // (at least) the SysTick interrupt). + MICROPY_EVENT_POLL_HOOK + } + } else { + // IRQs disabled, so need to use a busy loop for the delay. + // To prevent possible overflow of the counter we use a double loop. + const uint32_t count_1ms = HAL_RCC_GetSysClockFreq() / 4000; + for (int i = 0; i < Delay; i++) { + for (uint32_t count = 0; ++count <= count_1ms;) { + } + } + } +} + +// delay for given number of microseconds +void mp_hal_delay_us(mp_uint_t usec) { + if (query_irq() == IRQ_STATE_ENABLED) { + // IRQs enabled, so can use systick counter to do the delay + uint32_t start = mp_hal_ticks_us(); + while (mp_hal_ticks_us() - start < usec) { + } + } else { + // IRQs disabled, so need to use a busy loop for the delay + // sys freq is always a multiple of 2MHz, so division here won't lose precision + const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 2000000 * usec / 2; + for (uint32_t count = 0; ++count <= ucount;) { + } + } +} + +mp_uint_t mp_hal_ticks_ms(void) { + return uwTick; +} + +mp_uint_t mp_hal_ticks_us(void) { + return uwTick * 1000; +} diff --git a/core/embed/trezorhal/dma.c b/core/embed/trezorhal/dma.c index 6126560200..46e10f31a1 100644 --- a/core/embed/trezorhal/dma.c +++ b/core/embed/trezorhal/dma.c @@ -29,7 +29,6 @@ #include #include -#include "py/obj.h" #include "dma.h" #include "irq.h" #include "systick.h" @@ -157,10 +156,10 @@ static void dma_tickle(dma_id_t dma_id) { static void dma_enable_clock(dma_id_t dma_id) { // We don't want dma_tick_handler() to turn off the clock right after we // enable it, so we need to mark the channel in use in an atomic fashion. - mp_uint_t irq_state = MICROPY_BEGIN_ATOMIC_SECTION(); + uint32_t irq_state = disable_irq(); uint32_t old_enable_mask = dma_enable_mask; dma_enable_mask |= (1 << dma_id); - MICROPY_END_ATOMIC_SECTION(irq_state); + enable_irq(irq_state); if (dma_id < NSTREAMS_PER_CONTROLLER) { if (((old_enable_mask & DMA1_ENABLE_MASK) == 0) && !DMA1_IS_CLK_ENABLED()) { diff --git a/core/embed/trezorhal/irq.h b/core/embed/trezorhal/irq.h index 52d90c09a0..1d06d4f958 100644 --- a/core/embed/trezorhal/irq.h +++ b/core/embed/trezorhal/irq.h @@ -28,6 +28,9 @@ #ifndef MICROPY_INCLUDED_STM32_IRQ_H #define MICROPY_INCLUDED_STM32_IRQ_H +#include STM32_HAL_H +#include + // Use this macro together with NVIC_SetPriority to indicate that an IRQn is non-negative, // which helps the compiler optimise the resulting inline function. #define IRQn_NONNEG(pri) ((pri) & 0x7f) @@ -54,6 +57,16 @@ static inline uint32_t query_irq(void) { return __get_PRIMASK(); } +static inline void enable_irq(uint32_t state) { + __set_PRIMASK(state); +} + +static inline uint32_t disable_irq(void) { + uint32_t state = __get_PRIMASK(); + __disable_irq(); + return state; +} + // enable_irq and disable_irq are defined inline in mpconfigport.h #if __CORTEX_M >= 0x03 diff --git a/core/embed/trezorhal/sdcard.c b/core/embed/trezorhal/sdcard.c index 249d616439..dd228fd688 100644 --- a/core/embed/trezorhal/sdcard.c +++ b/core/embed/trezorhal/sdcard.c @@ -46,7 +46,6 @@ #include STM32_HAL_H #include -#include "mpconfigport.h" #include "dma.h" #include "irq.h" diff --git a/core/embed/firmware/supervise.h b/core/embed/trezorhal/supervise.h similarity index 100% rename from core/embed/firmware/supervise.h rename to core/embed/trezorhal/supervise.h diff --git a/core/embed/trezorhal/systick.c b/core/embed/trezorhal/systick.c index 4d69cf9b6e..a4b08e5a53 100644 --- a/core/embed/trezorhal/systick.c +++ b/core/embed/trezorhal/systick.c @@ -45,8 +45,6 @@ * THE SOFTWARE. */ -#include "py/runtime.h" -#include "py/mphal.h" #include "irq.h" #include "systick.h" @@ -64,69 +62,3 @@ void SysTick_Handler(void) { f(uw_tick); } } - -// We provide our own version of HAL_Delay that calls __WFI while waiting, -// and works when interrupts are disabled. This function is intended to be -// used only by the ST HAL functions. -void HAL_Delay(uint32_t Delay) { - if (query_irq() == IRQ_STATE_ENABLED) { - // IRQs enabled, so can use systick counter to do the delay - uint32_t start = uwTick; - // Wraparound of tick is taken care of by 2's complement arithmetic. - while (uwTick - start < Delay) { - // Enter sleep mode, waiting for (at least) the SysTick interrupt. - __WFI(); - } - } else { - // IRQs disabled, use mp_hal_delay_ms routine. - mp_hal_delay_ms(Delay); - } -} - -// Core delay function that does an efficient sleep and may switch thread context. -// If IRQs are enabled then we must have the GIL. -void mp_hal_delay_ms(mp_uint_t Delay) { - if (query_irq() == IRQ_STATE_ENABLED) { - // IRQs enabled, so can use systick counter to do the delay - uint32_t start = uwTick; - // Wraparound of tick is taken care of by 2's complement arithmetic. - while (uwTick - start < Delay) { - // This macro will execute the necessary idle behaviour. It may - // raise an exception, switch threads or enter sleep mode (waiting for - // (at least) the SysTick interrupt). - MICROPY_EVENT_POLL_HOOK - } - } else { - // IRQs disabled, so need to use a busy loop for the delay. - // To prevent possible overflow of the counter we use a double loop. - const uint32_t count_1ms = HAL_RCC_GetSysClockFreq() / 4000; - for (int i = 0; i < Delay; i++) { - for (uint32_t count = 0; ++count <= count_1ms;) { - } - } - } -} - -// delay for given number of microseconds -void mp_hal_delay_us(mp_uint_t usec) { - if (query_irq() == IRQ_STATE_ENABLED) { - // IRQs enabled, so can use systick counter to do the delay - uint32_t start = mp_hal_ticks_us(); - while (mp_hal_ticks_us() - start < usec) { - } - } else { - // IRQs disabled, so need to use a busy loop for the delay - // sys freq is always a multiple of 2MHz, so division here won't lose precision - const uint32_t ucount = HAL_RCC_GetSysClockFreq() / 2000000 * usec / 2; - for (uint32_t count = 0; ++count <= ucount;) { - } - } -} - -mp_uint_t mp_hal_ticks_ms(void) { - return uwTick; -} - -mp_uint_t mp_hal_ticks_us(void) { - return uwTick * 1000; -}