RISC-V/V003/math/stm32f051/CortexM0.h
2024-05-07 11:46:49 +02:00

139 lines
4.8 KiB
C++

#ifndef ARMCM0_HDEF
#define ARMCM0_HDEF
/** @brief SYSTICK for Cortex-M0
* Není to moc domyšlené, před tt. hlavičkou je nutné mít definován NVIC a IRQn,
* což je v STM generované hlavičce většinou uděláno. NVIC_EnableIRQ je zjednodušen
* jen pro CM0, jinak se tam čaruje s PRIO_BITS, tady to není potřeba.
*/
// tohle je jediné, co je potřeba z core_cm0.h
static inline void NVIC_EnableIRQ (IRQn irq) {
NVIC.ISER.R = ((1 << (static_cast<uint32_t>(irq) & 0x1F)));
}
static constexpr uint32_t SysTick_LOAD_RELOAD_Msk = (0xFFFFFFUL); /*!< SysTick LOAD: RELOAD Mask */
// ////////////////////+++ SysTick +-+//////////////////// //
struct SysTick_DEF { /*!< 24Bit System Tick Timer for use in RTOS */
union CSR_DEF { //!< [0000](04)[0x00000004] SysTick Control and Status Register
enum ENABLE_ENUM /*: uint32_t */ {
ENABLE_0 = 0, //!< disabled
ENABLE_1 = 1, //!< enabled
};
enum TICKINT_ENUM /*: uint32_t */ {
TICKINT_0 = 0, //!< Enable SysTick Exception
TICKINT_1 = 1, //!< Disable SysTick Exception
};
enum CLKSOURCE_ENUM /*: uint32_t */ {
CLKSOURCE_0 = 0, //!< External Clock
CLKSOURCE_1 = 1, //!< CPU Clock
};
struct {
__IO ENABLE_ENUM ENABLE : 1; //!<[00] Enable SysTick Timer
__IO TICKINT_ENUM TICKINT : 1; //!<[01] Generate Tick Interrupt
__IO CLKSOURCE_ENUM CLKSOURCE : 1; //!<[02] Source to count from
uint32_t UNUSED0 : 13; //!<[03]
__IO ONE_BIT COUNTFLAG : 1; //!<[16] SysTick counted to zero
} B;
__IO uint32_t R;
explicit CSR_DEF () noexcept { R = 0x00000004u; }
template<typename F> void setbit (F f) volatile {
CSR_DEF r;
R = f (r);
}
template<typename F> void modify (F f) volatile {
CSR_DEF r; r.R = R;
R = f (r);
}
};
__IO CSR_DEF CSR ; //!< register definition
union RVR_DEF { //!< [0004](04)[0x00000000] SysTick Reload Value Register
struct {
__IO uint32_t RELOAD : 24; //!<[00] Value to auto reload SysTick after reaching zero
} B;
__IO uint32_t R;
explicit RVR_DEF () noexcept { R = 0x00000000u; }
template<typename F> void setbit (F f) volatile {
RVR_DEF r;
R = f (r);
}
template<typename F> void modify (F f) volatile {
RVR_DEF r; r.R = R;
R = f (r);
}
};
__IO RVR_DEF RVR ; //!< register definition
union CVR_DEF { //!< [0008](04)[0x00000000] SysTick Current Value Register
struct {
__IO uint32_t CURRENT : 24; //!<[00] Current value
} B;
__IO uint32_t R;
explicit CVR_DEF () noexcept { R = 0x00000000u; }
template<typename F> void setbit (F f) volatile {
CVR_DEF r;
R = f (r);
}
template<typename F> void modify (F f) volatile {
CVR_DEF r; r.R = R;
R = f (r);
}
};
__IO CVR_DEF CVR ; //!< register definition
union CALIB_DEF { //!< [000c](04)[0x00000000] SysTick Calibration Value Register
enum SKEW_ENUM /*: uint32_t */ {
SKEW_0 = 0, //!< 10ms calibration value is exact
SKEW_1 = 1, //!< 10ms calibration value is inexact, because of the clock frequency
};
enum NOREF_ENUM /*: uint32_t */ {
NOREF_0 = 0, //!< Ref Clk available
NOREF_1 = 1, //!< Ref Clk not available
};
struct {
__I uint32_t TENMS : 24; //!<[00] Reload value to use for 10ms timing
uint32_t UNUSED0 : 6; //!<[24]
__I SKEW_ENUM SKEW : 1; //!<[30] Clock Skew
__I NOREF_ENUM NOREF : 1; //!<[31] No Ref
} B;
__IO uint32_t R;
explicit CALIB_DEF () noexcept { R = 0x00000000u; }
template<typename F> void setbit (F f) volatile {
CALIB_DEF r;
R = f (r);
}
template<typename F> void modify (F f) volatile {
CALIB_DEF r; r.R = R;
R = f (r);
}
};
__IO CALIB_DEF CALIB ; //!< register definition
// methods :
bool Config (const uint32_t ticks) {
if (ticks > SysTick_LOAD_RELOAD_Msk) return false; // Reload value impossible
RVR.B.RELOAD = ticks - 1u; // set reload register
NVIC_EnableIRQ (SysTick_IRQn); // Enable Interrupt
CVR.B.CURRENT = 0; // Load the SysTick Counter Value
CSR.modify([](CSR_DEF & r) -> auto { // Enable SysTick IRQ and SysTick Timer
r.B.CLKSOURCE = CSR_DEF::CLKSOURCE_ENUM::CLKSOURCE_1;
r.B.TICKINT = CSR_DEF::TICKINT_ENUM ::TICKINT_1;
r.B.ENABLE = CSR_DEF::ENABLE_ENUM ::ENABLE_1;
return r.R;
});
return true; // Function successful
}
}; /* total size = 0x0010, struct size = 0x0010 */
static SysTick_DEF & SysTick = * reinterpret_cast<SysTick_DEF *> (0xe000e010);
static_assert (sizeof(struct SysTick_DEF) == 16, "size error SysTick");
#endif