2016-07-20 16:33:49 +00:00
|
|
|
#include STM32_HAL_H
|
|
|
|
|
|
|
|
#include "display.h"
|
|
|
|
|
|
|
|
// ### from main.c
|
|
|
|
|
|
|
|
void flash_error(int n) {
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
// blink(on)
|
|
|
|
HAL_Delay(250);
|
|
|
|
// blink(off)
|
|
|
|
HAL_Delay(250);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __attribute__((noreturn)) __fatal_error(const char *msg) {
|
|
|
|
for (volatile uint32_t delay = 0; delay < 10000000; delay++) {
|
|
|
|
}
|
|
|
|
// TODO: printf("FATAL ERROR: %s\n", msg);
|
|
|
|
for (;;) {
|
|
|
|
__WFI();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nlr_jump_fail(void *val) {
|
|
|
|
__fatal_error("FATAL: uncaught exception");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemClock_Config(void);
|
|
|
|
|
2016-09-29 12:38:31 +00:00
|
|
|
// ### from stm32_it.c
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles SysTick Handler.
|
|
|
|
* @param None
|
|
|
|
* @retval None
|
|
|
|
*/
|
|
|
|
void SysTick_Handler(void) {
|
|
|
|
// Instead of calling HAL_IncTick we do the increment here of the counter.
|
|
|
|
// This is purely for efficiency, since SysTick is called 1000 times per
|
|
|
|
// second at the highest interrupt priority.
|
|
|
|
// Note: we don't need uwTick to be declared volatile here because this is
|
|
|
|
// the only place where it can be modified, and the code is more efficient
|
|
|
|
// without the volatile specifier.
|
|
|
|
extern uint32_t uwTick;
|
|
|
|
uwTick += 1;
|
|
|
|
|
|
|
|
// Read the systick control regster. This has the side effect of clearing
|
|
|
|
// the COUNTFLAG bit, which makes the logic in sys_tick_get_microseconds
|
|
|
|
// work properly.
|
|
|
|
SysTick->CTRL;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Right now we have the storage and DMA controllers to process during
|
|
|
|
// this interrupt and we use custom dispatch handlers. If this needs to
|
|
|
|
// be generalised in the future then a dispatch table can be used as
|
|
|
|
// follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))();
|
|
|
|
|
|
|
|
if (STORAGE_IDLE_TICK(uwTick)) {
|
|
|
|
NVIC->STIR = FLASH_IRQn;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) {
|
|
|
|
dma_idle_handler(uwTick);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-07-20 16:33:49 +00:00
|
|
|
|
|
|
|
// ### from timer.c
|
|
|
|
|
|
|
|
uint32_t timer_get_source_freq(uint32_t tim_id) {
|
|
|
|
uint32_t source;
|
|
|
|
if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
|
|
|
|
// TIM{1,8,9,10,11} are on APB2
|
|
|
|
source = HAL_RCC_GetPCLK2Freq();
|
|
|
|
if ((uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3) != RCC_HCLK_DIV1) {
|
|
|
|
source *= 2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// TIM{2,3,4,5,6,7,12,13,14} are on APB1
|
|
|
|
source = HAL_RCC_GetPCLK1Freq();
|
|
|
|
if ((uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1) != RCC_HCLK_DIV1) {
|
|
|
|
source *= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ###
|
|
|
|
|
|
|
|
int main(void) {
|
|
|
|
|
|
|
|
HAL_Init();
|
|
|
|
|
|
|
|
SystemClock_Config();
|
|
|
|
|
|
|
|
__GPIOA_CLK_ENABLE();
|
|
|
|
__GPIOB_CLK_ENABLE();
|
|
|
|
__GPIOC_CLK_ENABLE();
|
|
|
|
__GPIOD_CLK_ENABLE();
|
|
|
|
|
|
|
|
display_init();
|
2016-09-28 16:15:06 +00:00
|
|
|
display_clear();
|
2016-09-29 12:38:31 +00:00
|
|
|
display_text(100, 120, "TREZOR", 6, FONT_MONO, 0xFFFF, 0x0000);
|
|
|
|
display_text(90, 140, "bootloader", 10, FONT_MONO, 0xFFFF, 0x0000);
|
|
|
|
display_backlight(255);
|
|
|
|
HAL_Delay(250);
|
|
|
|
display_backlight(0);
|
|
|
|
HAL_Delay(250);
|
|
|
|
display_backlight(100);
|
|
|
|
HAL_Delay(250);
|
|
|
|
display_backlight(0);
|
|
|
|
HAL_Delay(250);
|
2016-07-20 16:33:49 +00:00
|
|
|
display_backlight(255);
|
|
|
|
|
|
|
|
__fatal_error("end");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|