mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-08-18 15:42:03 -06:00
stm32: Rename clock.c to stm32f4.c
Rename the clock.c file to stm32f4.c to make it more clear that the code is specific to the stm32f4 chips. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
8b9cc62359
commit
fe065d72d0
2 changed files with 1 additions and 1 deletions
158
src/stm32/stm32f4.c
Normal file
158
src/stm32/stm32f4.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Code to setup clocks and gpio on stm32f4
|
||||
//
|
||||
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "autoconf.h" // CONFIG_CLOCK_REF_8M
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "internal.h" // enable_pclock
|
||||
|
||||
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 4)
|
||||
|
||||
// Enable a peripheral clock
|
||||
void
|
||||
enable_pclock(uint32_t periph_base)
|
||||
{
|
||||
if (periph_base < APB2PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
||||
RCC->APB1ENR |= (1<<pos);
|
||||
RCC->APB1ENR;
|
||||
} else if (periph_base < AHB1PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
||||
RCC->APB2ENR |= (1<<pos);
|
||||
RCC->APB2ENR;
|
||||
} else if (periph_base < AHB2PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - AHB1PERIPH_BASE) / 0x400;
|
||||
RCC->AHB1ENR |= (1<<pos);
|
||||
RCC->AHB1ENR;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a peripheral clock has been enabled
|
||||
int
|
||||
is_enabled_pclock(uint32_t periph_base)
|
||||
{
|
||||
if (periph_base < APB2PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - APB1PERIPH_BASE) / 0x400;
|
||||
return RCC->APB1ENR & (1<<pos);
|
||||
} else if (periph_base < AHB1PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - APB2PERIPH_BASE) / 0x400;
|
||||
return RCC->APB2ENR & (1<<pos);
|
||||
} else if (periph_base < AHB2PERIPH_BASE) {
|
||||
uint32_t pos = (periph_base - AHB1PERIPH_BASE) / 0x400;
|
||||
return RCC->AHB1ENR & (1<<pos);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the frequency of the given peripheral clock
|
||||
uint32_t
|
||||
get_pclock_frequency(uint32_t periph_base)
|
||||
{
|
||||
return FREQ_PERIPH;
|
||||
}
|
||||
|
||||
// Set the mode and extended function of a pin
|
||||
void
|
||||
gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
|
||||
{
|
||||
GPIO_TypeDef *regs = digital_regs[GPIO2PORT(gpio)];
|
||||
|
||||
// Enable GPIO clock
|
||||
uint32_t rcc_pos = ((uint32_t)regs - AHB1PERIPH_BASE) / 0x400;
|
||||
RCC->AHB1ENR |= (1<<rcc_pos);
|
||||
|
||||
// Configure GPIO
|
||||
uint32_t mode_bits = mode & 0x0f, func = mode >> 4;
|
||||
uint32_t pup = pullup ? (pullup > 0 ? 1 : 2) : 0;
|
||||
uint32_t pos = gpio % 16, af_reg = pos / 8;
|
||||
uint32_t af_shift = (pos % 8) * 4, af_msk = 0x0f << af_shift;
|
||||
uint32_t m_shift = pos * 2, m_msk = 0x03 << m_shift;
|
||||
|
||||
regs->AFR[af_reg] = (regs->AFR[af_reg] & ~af_msk) | (func << af_shift);
|
||||
regs->MODER = (regs->MODER & ~m_msk) | (mode_bits << m_shift);
|
||||
regs->PUPDR = (regs->PUPDR & ~m_msk) | (pup << m_shift);
|
||||
regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (0x02 << m_shift);
|
||||
}
|
||||
|
||||
#if CONFIG_CLOCK_REF_8M
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PH0,PH1");
|
||||
#endif
|
||||
|
||||
// Clock configuration
|
||||
static void
|
||||
enable_clock_stm32f40x(void)
|
||||
{
|
||||
#if CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407
|
||||
if (CONFIG_CLOCK_REF_8M) {
|
||||
// Configure 168Mhz PLL from external 8Mhz crystal (HSE)
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
RCC->PLLCFGR = (
|
||||
RCC_PLLCFGR_PLLSRC_HSE | (4 << RCC_PLLCFGR_PLLM_Pos)
|
||||
| (168 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos)
|
||||
| (7 << RCC_PLLCFGR_PLLQ_Pos));
|
||||
} else {
|
||||
// Configure 168Mhz PLL from internal 16Mhz oscillator (HSI)
|
||||
RCC->PLLCFGR = (
|
||||
RCC_PLLCFGR_PLLSRC_HSI | (8 << RCC_PLLCFGR_PLLM_Pos)
|
||||
| (168 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos)
|
||||
| (7 << RCC_PLLCFGR_PLLQ_Pos));
|
||||
}
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
enable_clock_stm32f446(void)
|
||||
{
|
||||
#if CONFIG_MACH_STM32F446
|
||||
if (CONFIG_CLOCK_REF_8M) {
|
||||
// Configure 180Mhz PLL from external 8Mhz crystal (HSE)
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
RCC->PLLCFGR = (
|
||||
RCC_PLLCFGR_PLLSRC_HSE | (4 << RCC_PLLCFGR_PLLM_Pos)
|
||||
| (180 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos)
|
||||
| (7 << RCC_PLLCFGR_PLLQ_Pos) | (6 << RCC_PLLCFGR_PLLR_Pos));
|
||||
} else {
|
||||
// Configure 180Mhz PLL from internal 16Mhz oscillator (HSI)
|
||||
RCC->PLLCFGR = (
|
||||
RCC_PLLCFGR_PLLSRC_HSI | (8 << RCC_PLLCFGR_PLLM_Pos)
|
||||
| (180 << RCC_PLLCFGR_PLLN_Pos) | (0 << RCC_PLLCFGR_PLLP_Pos)
|
||||
| (7 << RCC_PLLCFGR_PLLQ_Pos) | (6 << RCC_PLLCFGR_PLLR_Pos));
|
||||
}
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
|
||||
// Enable "over drive"
|
||||
enable_pclock(PWR_BASE);
|
||||
PWR->CR = (3 << PWR_CR_VOS_Pos) | PWR_CR_ODEN;
|
||||
while (!(PWR->CSR & PWR_CSR_ODRDY))
|
||||
;
|
||||
PWR->CR = (3 << PWR_CR_VOS_Pos) | PWR_CR_ODEN | PWR_CR_ODSWEN;
|
||||
while (!(PWR->CSR & PWR_CSR_ODSWRDY))
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Main clock setup called at chip startup
|
||||
void
|
||||
clock_setup(void)
|
||||
{
|
||||
if (CONFIG_MACH_STM32F405 || CONFIG_MACH_STM32F407)
|
||||
enable_clock_stm32f40x();
|
||||
else
|
||||
enable_clock_stm32f446();
|
||||
|
||||
// Set flash latency
|
||||
FLASH->ACR = (FLASH_ACR_LATENCY_5WS | FLASH_ACR_ICEN | FLASH_ACR_DCEN
|
||||
| FLASH_ACR_PRFTEN);
|
||||
|
||||
// Wait for PLL lock
|
||||
while (!(RCC->CR & RCC_CR_PLLRDY))
|
||||
;
|
||||
|
||||
// Switch system clock to PLL
|
||||
RCC->CFGR = RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV4 | RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
|
||||
;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue