#include "cppmain.h" #include "usbd_cdc_if.h" #include "usb_device.h" #include "cmsis_os.h" DAC_HandleTypeDef hdac1; DMA_HandleTypeDef hdma_dac1; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim6; TIM_HandleTypeDef htim7; RNG_HandleTypeDef hrng; void sysclk_init(void) { // Enable ALL the clocks __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); // ALL GPIO Ports __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); // ALL Timers __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_TIM4_CLK_ENABLE(); __HAL_RCC_TIM5_CLK_ENABLE(); __HAL_RCC_TIM6_CLK_ENABLE(); __HAL_RCC_TIM7_CLK_ENABLE(); __HAL_RCC_TIM8_CLK_ENABLE(); __HAL_RCC_TIM9_CLK_ENABLE(); __HAL_RCC_TIM10_CLK_ENABLE(); __HAL_RCC_TIM11_CLK_ENABLE(); __HAL_RCC_TIM12_CLK_ENABLE(); __HAL_RCC_TIM13_CLK_ENABLE(); __HAL_RCC_TIM14_CLK_ENABLE(); // ALL DMA Controllers __HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_DMA2_CLK_ENABLE(); // The DAC __HAL_RCC_DAC_CLK_ENABLE(); // The RNG __HAL_RCC_RNG_CLK_ENABLE(); // Configure the main internal regulator output voltage __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); { // Initializes the RCC Oscillators according to the specified parameters // in the RCC_OscInitTypeDef structure. RCC_OscInitTypeDef conf = { .OscillatorType = RCC_OSCILLATORTYPE_HSE, .HSEState = RCC_HSE_ON, .PLL.PLLState = RCC_PLL_ON, .PLL.PLLSource = RCC_PLLSOURCE_HSE, .PLL.PLLM = 4, .PLL.PLLN = 168, .PLL.PLLP = RCC_PLLP_DIV2, .PLL.PLLQ = 7, }; if (HAL_RCC_OscConfig(&conf) != HAL_OK) { Error_Handler(); } } { // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitTypeDef conf = { .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2, .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK, .AHBCLKDivider = RCC_SYSCLK_DIV1, .APB1CLKDivider = RCC_HCLK_DIV4, .APB2CLKDivider = RCC_HCLK_DIV2, }; if (HAL_RCC_ClockConfig(&conf, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } } void gpio_init(void) { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); { // Button Blue GPIO_InitTypeDef conf = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_IT_RISING, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_LOW, }; HAL_GPIO_Init(GPIOA, &conf); } { // LED Green GPIO_InitTypeDef conf = { .Pin = GPIO_PIN_12, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, }; HAL_GPIO_Init(GPIOD, &conf); } { // DAC1 GPIO_InitTypeDef conf = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_ANALOG, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, }; HAL_GPIO_Init(GPIOA, &conf); } } void dac_init(void) { hdac1.Instance = DAC1; if (HAL_DAC_Init(&hdac1) != HAL_OK) { Error_Handler(); } DAC_ChannelConfTypeDef conf = { .DAC_Trigger = DAC_TRIGGER_T6_TRGO, .DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE, }; if (HAL_DAC_ConfigChannel(&hdac1, &conf, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(); } } void dma_init(void) { hdma_dac1.Instance = DMA1_Stream5; hdma_dac1.Init.Channel = DMA_CHANNEL_7; hdma_dac1.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_dac1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_dac1.Init.MemInc = DMA_MINC_ENABLE; hdma_dac1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_dac1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_dac1.Init.Mode = DMA_NORMAL; hdma_dac1.Init.Priority = DMA_PRIORITY_LOW; hdma_dac1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_dac1) != HAL_OK) { Error_Handler(); } // Originally that was: // __HAL_LINKDMA(&hdac1, DMA_Handle1, hdma_dac1); // Exapanded to: // hdma_dac1.Parent = &hdac1; // hdac1.DMA_Handle1 = &hdma_dac1; // But this seems to be enough: hdac1.DMA_Handle1 = &hdma_dac1; } // -------------------------------------------------------------------------------------------------- // Timers // -------------------------------------------------------------------------------------------------- void timer_init(void) { { htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 42949000; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } { TIM_ClockConfigTypeDef conf = { .ClockSource = TIM_CLOCKSOURCE_INTERNAL, }; if (HAL_TIM_ConfigClockSource(&htim2, &conf) != HAL_OK) { Error_Handler(); } } { TIM_MasterConfigTypeDef conf = { .MasterOutputTrigger = TIM_TRGO_RESET, .MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE, }; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &conf) != HAL_OK) { Error_Handler(); } } } { htim6.Instance = TIM6; htim6.Init.Prescaler = 0; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 1904; htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { Error_Handler(); } { TIM_MasterConfigTypeDef conf = { .MasterOutputTrigger = TIM_TRGO_UPDATE, .MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE, }; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &conf) != HAL_OK) { Error_Handler(); } } } { htim7.Instance = TIM7; htim7.Init.Prescaler = 10000; htim7.Init.CounterMode = TIM_COUNTERMODE_UP; htim7.Init.Period = 429490000; htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim7) != HAL_OK) { Error_Handler(); } { TIM_MasterConfigTypeDef conf = { .MasterOutputTrigger = TIM_TRGO_RESET, .MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE, }; if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &conf) != HAL_OK) { Error_Handler(); } } } } void irq_init() { // This is for RTOS i guess // HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 0); HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0); HAL_NVIC_EnableIRQ(TIM2_IRQn); HAL_NVIC_SetPriority(TIM7_IRQn, 5, 0); HAL_NVIC_EnableIRQ(TIM7_IRQn); HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); } void rng_init(void) { hrng.Instance = RNG; if (HAL_RNG_Init(&hrng) != HAL_OK) { Error_Handler(); } } void heck_init() { HAL_Init(); sysclk_init(); MX_USB_DEVICE_Init(); // USB first, for logging over serial port gpio_init(); dac_init(); timer_init(); rng_init(); irq_init(); dma_init(); }