diff --git a/bootloader/main.c b/bootloader/main.c index c672c35..6907149 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -1,12 +1,78 @@ #include "led.h" #include "uart_log.h" +#include "ltimer.h" #include "stdio.h" void system_init(void) { + /* Enable I-Cache */ + SCB_EnableICache(); + /* Enable D-Cache */ + SCB_EnableDCache(); + + /* STM32H7xx HAL library initialization: + - Configure the Systick to generate an interrupt each 1 msec + - Set NVIC Group Priority to 4 + - Low Level Initialization + */ + HAL_Init(); + + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + HAL_StatusTypeDef ret = HAL_OK; + + /*!< Supply configuration update enable */ + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* PWR set to LDO for the STM32H750B-DISCO board */ + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 160; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; + + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); + if(ret != HAL_OK) { + while(1); + } + + /* Select PLL as system clock source and configure bus clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; + ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + if(ret != HAL_OK) { + while(1); + } + led_init(LED_PIN); uart_log_init(); + ltimer_init(); } void led_blink(void) @@ -15,19 +81,20 @@ void led_blink(void) led_off(LED_PIN); } -extern UART_HandleTypeDef UartHandle; - int main(void) { system_init(); - // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); - // __enable_irq(); printf("Run start ...\r\n"); + printf("SystemCoreClock = %ld\r\n", SystemCoreClock); + printf("SystemD2Clock = %ld\r\n", SystemD2Clock); + while (1) { - static uint32_t count = 0; - printf("Hello World, count = %ld\r\n", count++); + uint64_t ms; + ms = ltimer_get_ms(); + printf("Hello World, ms = %llu\r\n", ms); led_blink(); - } + ltimer_delay_ms(1000); + } return 0; } diff --git a/driver/board/ltimer.c b/driver/board/ltimer.c new file mode 100644 index 0000000..cbce558 --- /dev/null +++ b/driver/board/ltimer.c @@ -0,0 +1,79 @@ +#include "ltimer.h" + +TIM_HandleTypeDef htim2; +TIM_HandleTypeDef htim4; + +void ltimer_init(void) +{ + __HAL_RCC_TIM2_CLK_ENABLE(); + htim2.Instance = TIM2; + htim2.Init.Prescaler = (SystemD2Clock / 1000000) - 1; // 1us + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + htim2.Init.Period = 0xFFFFFFFF; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_Base_Init(&htim2); + + __HAL_RCC_TIM4_CLK_ENABLE(); + htim4.Instance = TIM4; + htim4.Init.Prescaler = 0; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.Period = 0xFFFFFFFF; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + HAL_TIM_Base_Init(&htim4); + + TIM_MasterConfigTypeDef sMasterConfig = {0}; + sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; + HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); + + TIM_SlaveConfigTypeDef sSlaveConfig = {0}; + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; + sSlaveConfig.InputTrigger = TIM_TS_ITR1; + HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig); + + HAL_TIM_Base_Start(&htim2); + HAL_TIM_Base_Start(&htim4); +} + +uint64_t ltimer_get_us(void) +{ + uint32_t tim2_count; + uint32_t tim4_count_0, tim4_count_1; + uint64_t us; + + do { + tim4_count_0 = __HAL_TIM_GET_COUNTER(&htim4); + tim2_count = __HAL_TIM_GET_COUNTER(&htim2); + tim4_count_1 = __HAL_TIM_GET_COUNTER(&htim4); + } while (tim4_count_0 != tim4_count_1); + + us = (uint64_t)tim2_count | ((uint64_t)tim4_count_1 << 32); + + return us; +} + +uint64_t ltimer_get_ms(void) +{ + return (ltimer_get_us() + 500) / 1000; +} + +void ltimer_delay_us(uint32_t us) +{ + uint64_t start; + + start = ltimer_get_us(); + while (ltimer_get_us() - start < us) { + + } +} + +void ltimer_delay_ms(uint32_t ms) +{ + uint64_t start; + + start = ltimer_get_us(); + while (ltimer_get_us() - start < ms * 1000) { + + } +} diff --git a/driver/board/ltimer.h b/driver/board/ltimer.h new file mode 100644 index 0000000..3ac44d5 --- /dev/null +++ b/driver/board/ltimer.h @@ -0,0 +1,20 @@ +#ifndef __LTIMER_H__ +#define __LTIMER_H__ + +#include "stm32h7xx_hal.h" + +#ifdef __cplusplus + extern "C" { +#endif + +void ltimer_init(void); +uint64_t ltimer_get_us(void); +uint64_t ltimer_get_ms(void); +void ltimer_delay_us(uint32_t us); +void ltimer_delay_ms(uint32_t ms); + +#ifdef __cplusplus +} +#endif + +#endif /* __LTIMER_H__ */