-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#45 Continued restructure of peripheral code for arms
- Loading branch information
Robert
committed
Dec 19, 2022
1 parent
2ca325f
commit 724c51c
Showing
35 changed files
with
1,104 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...ripherals/clock/clock-ll-stm32f/src/main/c++/clock-ll-stm32f/specific/ClockManagercpp.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Zcode Library - Command System for Microcontrollers) | ||
* Copyright (c) 2022 Zcode team (Susan Witts, Alicia Witts) | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#ifndef SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKMANAGERCPP_HPP_ | ||
#define SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKMANAGERCPP_HPP_ | ||
|
||
#include <clock-ll/ClockManager.hpp> | ||
#include "Clock.hpp" | ||
#include "SystemClocks.hpp" | ||
|
||
template<class LL> | ||
Clock<LL> ClockManager<LL>::clocks[NONE] = { | ||
Clock<LL>(8000, SysClock, HSI), | ||
Clock<LL>(8000, HSI, NONE), | ||
Clock<LL>(0, HSI14, NONE), | ||
Clock<LL>(0, LSI, NONE), | ||
Clock<LL>(0, HSE, NONE), | ||
Clock<LL>(0, LSE, NONE), | ||
Clock<LL>(0, PLL, HSI), | ||
Clock<LL>(8000, HCLK, SysClock), | ||
Clock<LL>(8000, PCLK, HCLK), | ||
}; | ||
|
||
template<class LL> | ||
void ClockManager<LL>::fastSetup() { | ||
ClockManager<LL>::getClock(HSI)->set(8000, NONE); | ||
ClockManager<LL>::getClock(PLL)->set(40000, HSI); | ||
ClockManager<LL>::getClock(SysClock)->set(40000, PLL); | ||
ClockManager<LL>::getClock(HCLK)->set(40000, SysClock); | ||
ClockManager<LL>::getClock(PCLK)->set(20000, HCLK); | ||
} | ||
template<class LL> | ||
void ClockManager<LL>::basicSetup() { | ||
ClockManager<LL>::getClock(HSI)->set(8000, NONE); | ||
ClockManager<LL>::getClock(SysClock)->set(8000, HSI); | ||
ClockManager<LL>::getClock(HCLK)->set(8000, SysClock); | ||
ClockManager<LL>::getClock(PCLK)->set(8000, HCLK); | ||
} | ||
template<class LL> | ||
void ClockManager<LL>::slowSetup() { | ||
ClockManager<LL>::getClock(LSI)->set(32, NONE); | ||
ClockManager<LL>::getClock(SysClock)->set(32, LSI); | ||
ClockManager<LL>::getClock(HCLK)->set(32, SysClock); | ||
ClockManager<LL>::getClock(PCLK)->set(32, HCLK); | ||
} | ||
#endif /* SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKMANAGERCPP_HPP_ */ |
237 changes: 237 additions & 0 deletions
237
.../arm/peripherals/clock/clock-ll-stm32f/src/main/c++/clock-ll-stm32f/specific/Clockcpp.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
/* | ||
* Zcode Library - Command System for Microcontrollers) | ||
* Copyright (c) 2022 Zcode team (Susan Witts, Alicia Witts) | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#ifndef SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKCPP_HPP_ | ||
#define SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKCPP_HPP_ | ||
|
||
#include "Clock.hpp" | ||
#include <clock-ll/ClockManager.hpp> | ||
|
||
template<class LL> | ||
void clocksInternal_DO_NOT_USE_activateHSI14() { | ||
const uint32_t enableHSI14 = 0x1; | ||
const uint32_t HSI14Ready = 0x2; | ||
|
||
RCC->CR2 |= enableHSI14; | ||
while (!(RCC->CR2 & HSI14Ready)) | ||
; | ||
return; | ||
} | ||
|
||
template<class LL> | ||
void clocksInternal_DO_NOT_USE_activateHSI() { | ||
const uint32_t enableHSI8 = 0x1; | ||
const uint32_t HSI8Ready = 0x2; | ||
|
||
RCC->CR |= enableHSI8; | ||
while (!(RCC->CR & HSI8Ready)) | ||
; | ||
return; | ||
} | ||
|
||
template<class LL> | ||
void clocksInternal_DO_NOT_USE_activateLSI() { | ||
const uint32_t enableLSI = 0x1; | ||
const uint32_t LSIReady = 0x2; | ||
|
||
RCC->CSR |= enableLSI; | ||
while (!(RCC->CSR & LSIReady)) | ||
; | ||
return; | ||
} | ||
|
||
template<class LL> | ||
int Clock<LL>::set(uint32_t targetFreqKhz, SystemClock source) { | ||
if (clock == SysClock) { | ||
const uint32_t sysClkSwitchMask = 0x03; | ||
const uint32_t sysClkSwitchHSI16 = 0x00; | ||
const uint32_t sysClkSwitchHSE = 0x01; | ||
const uint32_t sysClkSwitchPLL = 0x02; | ||
|
||
uint32_t cfgr = RCC->CFGR; | ||
if (source == PLL && (ClockManager<LL>::getClock(source)->freq != 0 || ClockManager<LL>::getClock(source)->set(targetFreqKhz, NONE) == 0)) { | ||
freq = ClockManager<LL>::getClock(source)->freq; | ||
this->source = (uint8_t) source; | ||
cfgr &= ~sysClkSwitchMask; | ||
cfgr |= sysClkSwitchPLL; | ||
RCC->CFGR = cfgr; | ||
return 0; | ||
} else if (source == HSI && (ClockManager<LL>::getClock(source)->freq != 0 || ClockManager<LL>::getClock(source)->set(targetFreqKhz, NONE) == 0)) { | ||
freq = ClockManager<LL>::getClock(source)->freq; | ||
this->source = (uint8_t) source; | ||
cfgr &= ~sysClkSwitchMask; | ||
cfgr |= sysClkSwitchHSI16; | ||
RCC->CFGR = cfgr; | ||
return 0; | ||
} else if (source == HSE && (ClockManager<LL>::getClock(source)->freq != 0 || ClockManager<LL>::getClock(source)->set(targetFreqKhz, NONE) == 0)) { | ||
freq = ClockManager<LL>::getClock(source)->freq; | ||
this->source = (uint8_t) source; | ||
cfgr &= ~sysClkSwitchMask; | ||
cfgr |= sysClkSwitchHSE; | ||
RCC->CFGR = cfgr; | ||
return 0; | ||
} else { | ||
return -1; | ||
} | ||
} else if (clock == HSI) { | ||
clocksInternal_DO_NOT_USE_activateHSI<LL>(); | ||
freq = 8000; | ||
return 0; | ||
} else if (clock == HSI14) { | ||
clocksInternal_DO_NOT_USE_activateHSI14<LL>(); | ||
freq = 14000; | ||
return 0; | ||
} else if (clock == LSI) { | ||
clocksInternal_DO_NOT_USE_activateLSI<LL>(); | ||
freq = 40; | ||
return 0; | ||
} else if (clock == HSE) { | ||
return -1; | ||
} else if (clock == LSE) { | ||
return -1; | ||
} else if (clock == PLL) { | ||
const uint32_t pllEnable = 0x01000000; | ||
const uint32_t pllReady = 0x02000000; | ||
|
||
const uint32_t pllDivMask = 0xF; | ||
const uint32_t pllMultMask = 0x003c0000; | ||
|
||
const uint32_t pllHSISource = 0x00010000; | ||
|
||
uint8_t mult = 2; | ||
uint8_t div = 1; | ||
if (targetFreqKhz >= 48000) { | ||
return -1; | ||
} else if (targetFreqKhz < 4000) { | ||
return -1; | ||
} | ||
uint32_t bestDiff = 0xFFFFFFFF; | ||
for (uint8_t i = 2; i <= 16; i++) { | ||
if (source == HSI) { | ||
uint32_t freq = ClockManager<LL>::getClock(HSI)->freq * i / 2; | ||
if (freq < 48000) { | ||
if (freq >= targetFreqKhz && freq - targetFreqKhz < bestDiff) { | ||
mult = i; | ||
bestDiff = freq - targetFreqKhz; | ||
} else if (freq < targetFreqKhz && targetFreqKhz - freq < bestDiff) { | ||
mult = i; | ||
bestDiff = targetFreqKhz - freq; | ||
} | ||
} | ||
} else { | ||
for (uint8_t j = 1; j <= 16; j++) { | ||
uint32_t freq = ClockManager<LL>::getClock(HSE)->freq * i / j; | ||
if (freq < 48000) { | ||
if (freq >= targetFreqKhz && freq - targetFreqKhz < bestDiff) { | ||
mult = i; | ||
div = j; | ||
bestDiff = freq - targetFreqKhz; | ||
} else if (freq < targetFreqKhz && targetFreqKhz - freq < bestDiff) { | ||
mult = i; | ||
div = j; | ||
bestDiff = targetFreqKhz - freq; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
RCC->CR &= ~pllEnable; // Disable PLL (needed to change things) | ||
|
||
uint32_t cfg = RCC->CFGR; | ||
cfg &= ~(pllMultMask | pllHSISource); | ||
cfg |= (mult - 2) << 18; | ||
if (source == HSE) { | ||
cfg |= pllHSISource; | ||
} | ||
RCC->CFGR = cfg; | ||
if (source == HSE) { | ||
uint32_t cfg2 = RCC->CFGR2; | ||
cfg2 &= ~pllDivMask; | ||
cfg2 |= div - 1; | ||
RCC->CFGR = cfg2; | ||
freq = ClockManager<LL>::getClock(HSE)->freq * mult / div; | ||
} else { | ||
freq = ClockManager<LL>::getClock(HSI)->freq * mult / 2; | ||
} | ||
RCC->CR |= pllEnable; // Enable PLL | ||
while (!(RCC->CR & pllReady)) | ||
; | ||
this->source = (uint8_t) source; | ||
return 0; | ||
} else if (clock == HCLK) { | ||
const uint32_t hclkPrescalerMask = 0xF0; | ||
|
||
uint32_t sourceFreq = ClockManager<LL>::getClock(SysClock)->freq; | ||
uint32_t bestDiff = 0xFFFFFFFF; | ||
uint8_t presc = 0; | ||
for (uint8_t i = 0; i <= 8; ++i) { | ||
uint8_t j = i; | ||
if (j > 4) { | ||
j++; | ||
} | ||
uint32_t resultFreq = sourceFreq / (1 << j); | ||
if (resultFreq > targetFreqKhz) { | ||
if (resultFreq - targetFreqKhz < bestDiff) { | ||
bestDiff = resultFreq - targetFreqKhz; | ||
presc = i; | ||
} | ||
} else { | ||
if (targetFreqKhz - resultFreq < bestDiff) { | ||
bestDiff = targetFreqKhz - resultFreq; | ||
presc = i; | ||
} | ||
} | ||
} | ||
uint8_t j = presc; | ||
if (j > 4) { | ||
j++; | ||
} | ||
freq = sourceFreq / (1 << j); | ||
if (presc != 0) { | ||
presc += 7; | ||
} | ||
uint32_t cfgr = RCC->CFGR; | ||
cfgr &= ~hclkPrescalerMask; | ||
cfgr |= presc << 4; | ||
RCC->CFGR = cfgr; | ||
return 0; | ||
} else if (clock == PCLK) { | ||
const uint32_t pclkPrescalerMask = 0x700; | ||
|
||
uint32_t sourceFreq = ClockManager<LL>::getClock(HCLK)->freq; | ||
uint32_t bestDiff = 0xFFFFFFFF; | ||
uint8_t presc = 0; | ||
for (uint8_t i = 0; i <= 4; ++i) { | ||
uint32_t resultFreq = sourceFreq / (1 << i); | ||
if (resultFreq > targetFreqKhz) { | ||
if (resultFreq - targetFreqKhz < bestDiff) { | ||
bestDiff = resultFreq - targetFreqKhz; | ||
presc = i; | ||
} | ||
} else { | ||
if (targetFreqKhz - resultFreq < bestDiff) { | ||
bestDiff = targetFreqKhz - resultFreq; | ||
presc = i; | ||
} | ||
} | ||
} | ||
freq = sourceFreq / (1 << presc); | ||
if (presc != 0) { | ||
presc += 3; | ||
} | ||
uint32_t cfgr = RCC->CFGR; | ||
cfgr &= ~pclkPrescalerMask; | ||
cfgr |= presc << 8; | ||
RCC->CFGR = cfgr; | ||
return 0; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
|
||
#endif /* SRC_MAIN_CPP_ARM_NO_OS_STM32G4_SYSTEM_CLOCK_SPECIFIC_CLOCKCPP_HPP_ */ |
15 changes: 15 additions & 0 deletions
15
.../peripherals/clock/clock-ll-stm32f/src/main/c++/clock-ll-stm32f/specific/SystemClocks.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Zcode Library - Command System for Microcontrollers) | ||
* Copyright (c) 2022 Zcode team (Susan Witts, Alicia Witts) | ||
* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#ifndef SRC_MAIN_CPP_ARM_NO_OS_STM32F0_SYSTEM_CLOCK_SPECIFIC_SYSTEMCLOCKS_HPP_ | ||
#define SRC_MAIN_CPP_ARM_NO_OS_STM32F0_SYSTEM_CLOCK_SPECIFIC_SYSTEMCLOCKS_HPP_ | ||
|
||
enum SystemClock { | ||
SysClock, HSI, HSI14, LSI, HSE, LSE, PLL, HCLK, PCLK, NONE | ||
}; | ||
|
||
#endif /* SRC_MAIN_CPP_ARM_NO_OS_STM32F0_SYSTEM_CLOCK_SPECIFIC_SYSTEMCLOCKS_HPP_ */ |
39 changes: 39 additions & 0 deletions
39
...erals/clock/clock-ll-stm32f/src/main/c++/clock-ll-stm32f/specific/SystemMilliClockcpp.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* SystemMilliClockcpp.hpp | ||
* | ||
* Created on: 16 Dec 2022 | ||
* Author: alicia | ||
*/ | ||
|
||
#ifndef PERIPHERALS_CLOCK_CLOCK_LL_STM32F_SRC_MAIN_C___CLOCK_LL_SPECIFIC_SYSTEMMILLICLOCKCPP_HPP_ | ||
#define PERIPHERALS_CLOCK_CLOCK_LL_STM32F_SRC_MAIN_C___CLOCK_LL_SPECIFIC_SYSTEMMILLICLOCKCPP_HPP_ | ||
|
||
#include <clock-ll/SystemMilliClock.hpp> | ||
|
||
template<class LL> | ||
static void SystemMilliClock<LL>::init() { | ||
const uint32_t enableSysTickEnable = 0x1; | ||
const uint32_t enableSysTickEnableInt = 0x2; | ||
const uint32_t enableSysTickSetAsClock = 0x4; | ||
SysTick->LOAD = ClockManager<LL>::getClock(SysClock)->getFreqKhz(); | ||
SysTick->CTRL = enableSysTickEnable | enableSysTickEnableInt | enableSysTickSetAsClock; | ||
|
||
InterruptManager::setInterrupt(&SystemMilliClock::resetHappened, SysTickInt); | ||
InterruptManager::enableInterrupt(SysTickInt, 0, 5); | ||
timeBroad = 0; | ||
} | ||
|
||
template<class LL> | ||
static void SystemMilliClock<LL>::blockDelayMillis(uint32_t delay) { | ||
uint32_t end = getTimeMillis() + delay; | ||
while (end > getTimeMillis()) | ||
; | ||
return; | ||
} | ||
|
||
template<class LL> | ||
static uint32_t SystemMilliClock<LL>::getTimeMillis() { | ||
return timeBroad; | ||
} | ||
|
||
#endif /* PERIPHERALS_CLOCK_CLOCK_LL_STM32F_SRC_MAIN_C___CLOCK_LL_SPECIFIC_SYSTEMMILLICLOCKCPP_HPP_ */ |
Oops, something went wrong.