109 lines
4.0 KiB
C
109 lines
4.0 KiB
C
/**************************************************************************
|
|
* NAME: system_clock.c *
|
|
* PURPOSE: Enable and handle system clock functionality *
|
|
* INFORMATION: *
|
|
* *
|
|
* GLOBAL VARIABLES: *
|
|
* Variable Type Description *
|
|
* -------- ---- ----------- *
|
|
**************************************************************************/
|
|
|
|
#include "drivers/system_clock.h"
|
|
|
|
//the number of clock cycles per microsecond
|
|
static uint32_t usTicks = 0;
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Starts the system clock at 100MHz *
|
|
* INFORMATION: In the current version it works with ADC and DMA *
|
|
***********************************************************************/
|
|
void system_clock_config(void)
|
|
{
|
|
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
|
RCC_OscInitTypeDef RCC_OscInitStruct;
|
|
|
|
//Enable GPIO clocks
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
|
__HAL_RCC_GPIOC_CLK_ENABLE();
|
|
|
|
//Enable power clock
|
|
__HAL_RCC_PWR_CLK_ENABLE();
|
|
|
|
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
|
|
|
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
|
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
|
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
|
RCC_OscInitStruct.PLL.PLLM = 8;
|
|
RCC_OscInitStruct.PLL.PLLN = 288;
|
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
|
|
RCC_OscInitStruct.PLL.PLLQ = 6;
|
|
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
|
|
|
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
|
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
|
|
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
|
|
|
|
|
|
if (HAL_GetREVID() == 0x1001)
|
|
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
|
|
|
//Set the number of sycles per microsecond
|
|
usTicks = SystemCoreClock / 1000000;
|
|
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Get the time since the system started in microseconds
|
|
* INFORMATION: return the time in microseconds
|
|
***********************************************************************/
|
|
uint32_t clock_get_us()
|
|
{
|
|
register uint32_t ms, cycle_cnt;
|
|
|
|
//make sure that the system tick interrupt does not happen during the time we fetch microsecond from the register
|
|
do {
|
|
ms = clock_get_ms();
|
|
cycle_cnt = SysTick->VAL;
|
|
|
|
//If the SysTick timer expired during the previous instruction, we need to give it a little time for that
|
|
//interrupt to be delivered before we can recheck sysTickUptime:
|
|
asm volatile("\tnop\n");
|
|
} while (ms != clock_get_ms());
|
|
|
|
return (ms * 1000) + (usTicks * 1000 - cycle_cnt) / usTicks;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Get the time since the system started in milliseconds
|
|
* INFORMATION: return the time in milliseconds
|
|
***********************************************************************/
|
|
uint32_t clock_get_ms()
|
|
{
|
|
return HAL_GetTick();
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: stall the system for number of milliseconds
|
|
* INFORMATION:
|
|
***********************************************************************/
|
|
void clock_delay_ms(uint32_t ms)
|
|
{
|
|
HAL_Delay(ms);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Stall the system for a number of microseconds
|
|
* INFORMATION:
|
|
***********************************************************************/
|
|
void clock_delay_us(uint32_t us)
|
|
{
|
|
volatile uint32_t time = clock_get_us() + us;
|
|
while(clock_get_us() < time);
|
|
}
|