Refactored timer for F0
This commit is contained in:
@@ -8,6 +8,30 @@
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_ADC_TYPES.h"
|
||||
|
||||
enum class SHAL_ADC_Channel : uint32_t { //TODO remove unused or non existing channels?
|
||||
CH0 = 0,
|
||||
CH1,
|
||||
CH2,
|
||||
CH3,
|
||||
CH4,
|
||||
CH5,
|
||||
CH6,
|
||||
CH7,
|
||||
CH8,
|
||||
CH9,
|
||||
CH10,
|
||||
CH11,
|
||||
CH12,
|
||||
CH13,
|
||||
CH14,
|
||||
CH15,
|
||||
CH16,
|
||||
CHTemp,
|
||||
CHRef,
|
||||
CHBat,
|
||||
NO_ADC_MAPPING
|
||||
};
|
||||
|
||||
#define SHAL_ADC1 SHAL_ADC(1)
|
||||
|
||||
enum class ADC_Key : uint8_t{
|
||||
|
||||
@@ -57,7 +57,7 @@ static volatile ADC_TypeDef* ADC_TABLE[1] = { //Lookup table for ADCs
|
||||
};
|
||||
|
||||
static inline SHAL_ADC_Common_Control_Reg getADCCommonControl() {
|
||||
return {&ADC1_COMMON->CCR ,ADC_CCR_VREFEN,ADC_CCR_TSEN,ADC_CCR_VBATEN};
|
||||
return {&ADC1_COMMON->CCR,ADC_CCR_VREFEN,ADC_CCR_TSEN,ADC_CCR_VBATEN};
|
||||
}
|
||||
|
||||
static inline SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(ADC_Key key){
|
||||
|
||||
@@ -29,66 +29,29 @@ enum class GPIO_Key : uint8_t {
|
||||
INVALID
|
||||
};
|
||||
|
||||
static volatile GPIO_TypeDef * GPIO_TABLE[3] = { //Lookup table for ADCs
|
||||
GPIOA,
|
||||
GPIOB,
|
||||
GPIOC,
|
||||
};
|
||||
|
||||
|
||||
constexpr SHAL_GPIO_Peripheral getGPIORegister(const GPIO_Key g){
|
||||
switch(g) {
|
||||
case GPIO_Key::A0: return {GPIOA,0};
|
||||
case GPIO_Key::A1: return {GPIOA,1};
|
||||
case GPIO_Key::A2: return {GPIOA,2};
|
||||
case GPIO_Key::A3: return {GPIOA,3};
|
||||
case GPIO_Key::A4: return {GPIOA,4};
|
||||
case GPIO_Key::A5: return {GPIOA,5};
|
||||
case GPIO_Key::A6: return {GPIOA,6};
|
||||
case GPIO_Key::A7: return {GPIOA,7};
|
||||
case GPIO_Key::A8: return {GPIOA,8};
|
||||
case GPIO_Key::A9: return {GPIOA,9};
|
||||
case GPIO_Key::A10: return {GPIOA,10};
|
||||
case GPIO_Key::A11: return {GPIOA,11};
|
||||
case GPIO_Key::A12: return {GPIOA,12};
|
||||
case GPIO_Key::A13: return {GPIOA,13};
|
||||
case GPIO_Key::A14: return {GPIOA,14};
|
||||
case GPIO_Key::A15: return {GPIOA,15};
|
||||
case GPIO_Key::B0: return {GPIOB,0};
|
||||
case GPIO_Key::B1: return {GPIOB,1};
|
||||
case GPIO_Key::B2: return {GPIOB,2};
|
||||
case GPIO_Key::B3: return {GPIOB,3};
|
||||
case GPIO_Key::B4: return {GPIOB,4};
|
||||
case GPIO_Key::B5: return {GPIOB,5};
|
||||
case GPIO_Key::B6: return {GPIOB,6};
|
||||
case GPIO_Key::B7: return {GPIOB,7};
|
||||
case GPIO_Key::B8: return {GPIOB,8};
|
||||
case GPIO_Key::B9: return {GPIOB,9};
|
||||
case GPIO_Key::B10: return {GPIOB,10};
|
||||
case GPIO_Key::B11: return {GPIOB,11};
|
||||
case GPIO_Key::B12: return {GPIOB,12};
|
||||
case GPIO_Key::B13: return {GPIOB,13};
|
||||
case GPIO_Key::B14: return {GPIOB,14};
|
||||
case GPIO_Key::B15: return {GPIOB,15};
|
||||
case GPIO_Key::C0: return {GPIOC,0};
|
||||
case GPIO_Key::C1: return {GPIOC,1};
|
||||
case GPIO_Key::C2: return {GPIOC,2};
|
||||
case GPIO_Key::C3: return {GPIOC,3};
|
||||
case GPIO_Key::C4: return {GPIOC,4};
|
||||
case GPIO_Key::C5: return {GPIOC,5};
|
||||
case GPIO_Key::C6: return {GPIOC,6};
|
||||
case GPIO_Key::C7: return {GPIOC,7};
|
||||
case GPIO_Key::C8: return {GPIOC,8};
|
||||
case GPIO_Key::C9: return {GPIOC,9};
|
||||
case GPIO_Key::C10: return {GPIOC,10};
|
||||
case GPIO_Key::C11: return {GPIOC,11};
|
||||
case GPIO_Key::C12: return {GPIOC,12};
|
||||
case GPIO_Key::C13: return {GPIOC,13};
|
||||
case GPIO_Key::C14: return {GPIOC,14};
|
||||
case GPIO_Key::C15: return {GPIOC,15};
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_GPIO_Peripheral(nullptr,0); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
constexpr uint8_t getGPIOPinNumber(GPIO_Key key){
|
||||
return static_cast<uint8_t>(key) % 16;
|
||||
}
|
||||
|
||||
static inline uint32_t getGPIOPortNumber(const GPIO_Key g){
|
||||
return (static_cast<uint8_t>(g) / 16);
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
||||
volatile uint32_t* reg = &RCC->AHBENR; //register
|
||||
uint32_t mask;
|
||||
mask = RCC_AHBENR_GPIOAEN << getGPIOPortNumber(g); //Should shift to get each port number
|
||||
|
||||
return {reg,mask};
|
||||
}
|
||||
|
||||
|
||||
constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
switch(g) {
|
||||
case GPIO_Key::A0: return {&SYSCFG->EXTICR[0],SYSCFG_EXTICR1_EXTI0_PA,EXTI0_1_IRQn};
|
||||
@@ -148,128 +111,55 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
constexpr SHAL_Peripheral_Register getGPIORCCEnable(const GPIO_Key g){
|
||||
switch(g) {
|
||||
case GPIO_Key::A0:
|
||||
case GPIO_Key::A1:
|
||||
case GPIO_Key::A2:
|
||||
case GPIO_Key::A3:
|
||||
case GPIO_Key::A4:
|
||||
case GPIO_Key::A5:
|
||||
case GPIO_Key::A6:
|
||||
case GPIO_Key::A7:
|
||||
case GPIO_Key::A8:
|
||||
case GPIO_Key::A9:
|
||||
case GPIO_Key::A10:
|
||||
case GPIO_Key::A11:
|
||||
case GPIO_Key::A12:
|
||||
case GPIO_Key::A13:
|
||||
case GPIO_Key::A14:
|
||||
case GPIO_Key::A15:
|
||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOAEN_Pos};
|
||||
case GPIO_Key::B0:
|
||||
case GPIO_Key::B1:
|
||||
case GPIO_Key::B2:
|
||||
case GPIO_Key::B3:
|
||||
case GPIO_Key::B4:
|
||||
case GPIO_Key::B5:
|
||||
case GPIO_Key::B6:
|
||||
case GPIO_Key::B7:
|
||||
case GPIO_Key::B8:
|
||||
case GPIO_Key::B9:
|
||||
case GPIO_Key::B10:
|
||||
case GPIO_Key::B11:
|
||||
case GPIO_Key::B12:
|
||||
case GPIO_Key::B13:
|
||||
case GPIO_Key::B14:
|
||||
case GPIO_Key::B15:
|
||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOBEN_Pos};
|
||||
case GPIO_Key::C0:
|
||||
case GPIO_Key::C1:
|
||||
case GPIO_Key::C2:
|
||||
case GPIO_Key::C3:
|
||||
case GPIO_Key::C4:
|
||||
case GPIO_Key::C5:
|
||||
case GPIO_Key::C6:
|
||||
case GPIO_Key::C7:
|
||||
case GPIO_Key::C8:
|
||||
case GPIO_Key::C9:
|
||||
case GPIO_Key::C10:
|
||||
case GPIO_Key::C11:
|
||||
case GPIO_Key::C12:
|
||||
case GPIO_Key::C13:
|
||||
case GPIO_Key::C14:
|
||||
case GPIO_Key::C15:
|
||||
return {&RCC->AHBENR, RCC_AHBENR_GPIOCEN_Pos};
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return SHAL_Peripheral_Register(nullptr,0); //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
|
||||
|
||||
static inline SHAL_GPIO_Mode_Register getGPIOModeRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->MODER;
|
||||
uint32_t offset = 2 * (static_cast<uint8_t>(key) % 16);
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){
|
||||
switch(g) {
|
||||
case GPIO_Key::A0:
|
||||
case GPIO_Key::A1:
|
||||
case GPIO_Key::A2:
|
||||
case GPIO_Key::A3:
|
||||
case GPIO_Key::A4:
|
||||
case GPIO_Key::A5:
|
||||
case GPIO_Key::A6:
|
||||
case GPIO_Key::A7:
|
||||
case GPIO_Key::A8:
|
||||
case GPIO_Key::A9:
|
||||
case GPIO_Key::A10:
|
||||
case GPIO_Key::A11:
|
||||
case GPIO_Key::A12:
|
||||
case GPIO_Key::A13:
|
||||
case GPIO_Key::A14:
|
||||
case GPIO_Key::A15:
|
||||
return 0;
|
||||
case GPIO_Key::B0:
|
||||
case GPIO_Key::B1:
|
||||
case GPIO_Key::B2:
|
||||
case GPIO_Key::B3:
|
||||
case GPIO_Key::B4:
|
||||
case GPIO_Key::B5:
|
||||
case GPIO_Key::B6:
|
||||
case GPIO_Key::B7:
|
||||
case GPIO_Key::B8:
|
||||
case GPIO_Key::B9:
|
||||
case GPIO_Key::B10:
|
||||
case GPIO_Key::B11:
|
||||
case GPIO_Key::B12:
|
||||
case GPIO_Key::B13:
|
||||
case GPIO_Key::B14:
|
||||
case GPIO_Key::B15:
|
||||
return 1;
|
||||
case GPIO_Key::C0:
|
||||
case GPIO_Key::C1:
|
||||
case GPIO_Key::C2:
|
||||
case GPIO_Key::C3:
|
||||
case GPIO_Key::C4:
|
||||
case GPIO_Key::C5:
|
||||
case GPIO_Key::C6:
|
||||
case GPIO_Key::C7:
|
||||
case GPIO_Key::C8:
|
||||
case GPIO_Key::C9:
|
||||
case GPIO_Key::C10:
|
||||
case GPIO_Key::C11:
|
||||
case GPIO_Key::C12:
|
||||
case GPIO_Key::C13:
|
||||
case GPIO_Key::C14:
|
||||
case GPIO_Key::C15:
|
||||
return 2;
|
||||
case GPIO_Key::INVALID:
|
||||
case GPIO_Key::NUM_GPIO:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
__builtin_unreachable();
|
||||
static inline SHAL_GPIO_Pullup_Pulldown_Register getGPIOPUPDRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->PUPDR;
|
||||
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Alternate_Function_Register getGPIOAlternateFunctionRegister(const GPIO_Key key){
|
||||
|
||||
uint32_t pinNumber = static_cast<uint8_t>(key) % 16; //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2)
|
||||
uint32_t afrIndex = pinNumber < 8 ? 0 : 1;
|
||||
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->AFR[afrIndex];
|
||||
uint32_t offset = (pinNumber % 8) * 4; //Increment in groups of four
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Speed_Register getGPIOOutputSpeedRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OSPEEDR;
|
||||
uint32_t offset = 2 * static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Type_Register getGPIOOutputTypeRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->OTYPER;
|
||||
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Output_Data_Register getGPIOOutputDataRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->ODR;
|
||||
uint32_t offset = (static_cast<uint8_t>(key) % 16);
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
static inline SHAL_GPIO_Input_Data_Register getGPIOInputDataRegister(const GPIO_Key key){
|
||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->IDR;
|
||||
uint32_t offset = static_cast<uint8_t>(key) % 16;
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
/* TODO reimplement
|
||||
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
||||
switch(key){
|
||||
case GPIO_Key::A0:
|
||||
@@ -343,6 +233,6 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||
|
||||
@@ -113,7 +113,8 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){
|
||||
static inline SHAL_GPIO_RCC_Enable_Register getGPIORCCEnable(const GPIO_Key g){
|
||||
volatile uint32_t* reg = &RCC->AHB2ENR; //register
|
||||
uint32_t offset;
|
||||
offset = (static_cast<uint8_t>(g) / 16) == 0 ? RCC_AHB2ENR_GPIOAEN_Pos : RCC_AHB2ENR_GPIOBEN_Pos;
|
||||
|
||||
offset = RCC_AHB2ENR_GPIOAEN << getGPIOPortNUmber(g); //Should shift to get each port number
|
||||
|
||||
return {reg,offset};
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "SHAL_EXTI_CALLBACK.h"
|
||||
#include "SHAL_ADC.h"
|
||||
//#include "SHAL_EXTI_CALLBACK.h"
|
||||
//#include "SHAL_ADC.h"
|
||||
|
||||
|
||||
//Abstraction of SHAL_GPIO registers
|
||||
@@ -27,12 +27,12 @@ public:
|
||||
/// Uses the ADC to read an analog voltage value
|
||||
/// \param sampleTime The amount of clock cycles to use for the ADC
|
||||
/// \return ADC result
|
||||
uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8);
|
||||
//uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8); TODO Reimplement
|
||||
|
||||
uint16_t digitalRead();
|
||||
|
||||
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
||||
void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile;
|
||||
//void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile; //TODO reimplement?
|
||||
|
||||
void setOutputType(PinType type) volatile;
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
void setInternalResistor(InternalResistorType type) volatile;
|
||||
|
||||
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
|
||||
//void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback); TODO reimplement
|
||||
|
||||
SHAL_Result setPinMode(PinMode mode) volatile;
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
|
||||
#define GET_GPIO(key) GPIOManager::get(key)
|
||||
|
||||
#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x)
|
||||
//#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x) TODO reimplement
|
||||
|
||||
|
||||
//Manages instances of SHAL_GPIO objects
|
||||
@@ -75,9 +75,9 @@ public:
|
||||
|
||||
static SHAL_GPIO& get(GPIO_Key);
|
||||
|
||||
static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;}
|
||||
//static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;} TODO Reimplement
|
||||
|
||||
static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;}
|
||||
//static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;} TODO Reimplement
|
||||
|
||||
GPIOManager() = delete;
|
||||
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
|
||||
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
||||
|
||||
inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1);
|
||||
//inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1); TODO Reimplement
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define SHAL_GPIO_TYPES_H
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_ADC.h"
|
||||
#include "SHAL_ADC_TYPES.h"
|
||||
//#include "SHAL_ADC.h"
|
||||
//#include "SHAL_ADC_TYPES.h"
|
||||
|
||||
struct SHAL_GPIO_EXTI_Register{
|
||||
volatile uint32_t* EXT_ICR; //4 32 bit registers which say which GPIO a line is connected to
|
||||
@@ -17,7 +17,7 @@ struct SHAL_GPIO_EXTI_Register{
|
||||
|
||||
struct SHAL_GPIO_RCC_Enable_Register{
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
struct SHAL_GPIO_Mode_Register {
|
||||
@@ -55,11 +55,12 @@ struct SHAL_GPIO_Input_Data_Register {
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
/* TODO reimplement and uncomment ADC references (Here and on GPIO.h)
|
||||
struct SHAL_GPIO_Port_Info{
|
||||
uint8_t number;
|
||||
SHAL_ADC_Channel ADCChannel;
|
||||
};
|
||||
|
||||
*/
|
||||
enum class PinMode : uint8_t{
|
||||
INPUT_MODE = 0x00,
|
||||
OUTPUT_MODE = 0x01,
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "SHAL_TIM_TYPES.h"
|
||||
|
||||
enum class Timer_Key : uint8_t { //For STM32F072
|
||||
S_TIM1,
|
||||
S_TIM2,
|
||||
S_TIM3,
|
||||
S_TIM1 = 0,
|
||||
S_TIM2 = 1,
|
||||
S_TIM3 = 2,
|
||||
S_TIM6,
|
||||
S_TIM7,
|
||||
S_TIM14,
|
||||
@@ -39,20 +39,40 @@ enum class Timer_Key : uint8_t { //For STM32F072
|
||||
#define SHAL_TIM16 TimerManager::get(Timer_Key::S_TIM16)
|
||||
#define SHAL_TIM17 TimerManager::get(Timer_Key::S_TIM17)
|
||||
|
||||
static SHAL_TIM_Info TIM_INFO_TABLE[9] = {
|
||||
{TIM1,TIM1_BRK_UP_TRG_COM_IRQn,4},
|
||||
{TIM2,TIM2_IRQn,4},
|
||||
{TIM3,TIM3_IRQn,4},
|
||||
{TIM6,TIM6_DAC_IRQn,0},
|
||||
{TIM7,TIM7_IRQn,0},
|
||||
{TIM14,TIM14_IRQn,1},
|
||||
{TIM15,TIM15_IRQn,2},
|
||||
{TIM16,TIM16_IRQn,1},
|
||||
{TIM17,TIM17_IRQn,1},
|
||||
};
|
||||
|
||||
//Get actual register value based on enum
|
||||
static volatile TIM_TypeDef* getTimerRegister(Timer_Key t) {
|
||||
return TIM_INFO_TABLE[static_cast<uint8_t>(t)].timer;
|
||||
}
|
||||
|
||||
static IRQn_Type getIRQn(Timer_Key t) {
|
||||
return TIM_INFO_TABLE[static_cast<uint8_t>(t)].IRQn;
|
||||
}
|
||||
|
||||
|
||||
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
||||
constexpr TIM_RCC_Enable getTimerRCC(Timer_Key t) {
|
||||
static SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
|
||||
switch(t) {
|
||||
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos};
|
||||
case Timer_Key::S_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN_Pos};
|
||||
case Timer_Key::S_TIM3: return {&RCC->APB1ENR, RCC_APB1ENR_TIM3EN_Pos};
|
||||
case Timer_Key::S_TIM6: return {&RCC->APB1ENR, RCC_APB1ENR_TIM6EN_Pos};
|
||||
case Timer_Key::S_TIM7: return {&RCC->APB1ENR, RCC_APB1ENR_TIM7EN_Pos};
|
||||
case Timer_Key::S_TIM14: return {&RCC->APB1ENR, RCC_APB1ENR_TIM14EN_Pos};
|
||||
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN_Pos};
|
||||
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN_Pos};
|
||||
case Timer_Key::S_TIM17: return {&RCC->APB2ENR, RCC_APB2ENR_TIM17EN_Pos};
|
||||
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN};
|
||||
case Timer_Key::S_TIM2: return {&RCC->APB1ENR, RCC_APB1ENR_TIM2EN};
|
||||
case Timer_Key::S_TIM3: return {&RCC->APB1ENR, RCC_APB1ENR_TIM3EN};
|
||||
case Timer_Key::S_TIM6: return {&RCC->APB1ENR, RCC_APB1ENR_TIM6EN};
|
||||
case Timer_Key::S_TIM7: return {&RCC->APB1ENR, RCC_APB1ENR_TIM7EN};
|
||||
case Timer_Key::S_TIM14: return {&RCC->APB1ENR, RCC_APB1ENR_TIM14EN};
|
||||
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN};
|
||||
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN};
|
||||
case Timer_Key::S_TIM17: return {&RCC->APB2ENR, RCC_APB2ENR_TIM17EN};
|
||||
case Timer_Key::NUM_TIMERS:
|
||||
case Timer_Key::S_TIM_INVALID:
|
||||
assert(false);
|
||||
@@ -62,43 +82,161 @@ constexpr TIM_RCC_Enable getTimerRCC(Timer_Key t) {
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
//Get actual register value based on enum
|
||||
constexpr volatile TIM_TypeDef* getTimerRegister(Timer_Key t) {
|
||||
switch(t) {
|
||||
case Timer_Key::S_TIM1: return TIM1;
|
||||
case Timer_Key::S_TIM2: return TIM2;
|
||||
case Timer_Key::S_TIM3: return TIM3;
|
||||
case Timer_Key::S_TIM6: return TIM6;
|
||||
case Timer_Key::S_TIM7: return TIM7;
|
||||
case Timer_Key::S_TIM14: return TIM14;
|
||||
case Timer_Key::S_TIM15: return TIM15;
|
||||
case Timer_Key::S_TIM16: return TIM16;
|
||||
case Timer_Key::S_TIM17: return TIM17;
|
||||
case Timer_Key::NUM_TIMERS:
|
||||
case Timer_Key::S_TIM_INVALID:
|
||||
assert(false);
|
||||
return nullptr; //Unreachable
|
||||
}
|
||||
__builtin_unreachable();
|
||||
|
||||
static inline SHAL_TIM_Status_Register getTimerStatusRegister(Timer_Key key){
|
||||
|
||||
SHAL_TIM_Status_Register res = {nullptr, TIM_SR_UIF};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->SR;
|
||||
return res;
|
||||
}
|
||||
|
||||
constexpr IRQn_Type getIRQn(Timer_Key t) {
|
||||
switch(t) {
|
||||
case Timer_Key::S_TIM1: return TIM1_BRK_UP_TRG_COM_IRQn;
|
||||
case Timer_Key::S_TIM2: return TIM2_IRQn;
|
||||
case Timer_Key::S_TIM3: return TIM3_IRQn;
|
||||
case Timer_Key::S_TIM6: return TIM6_DAC_IRQn;
|
||||
case Timer_Key::S_TIM7: return TIM7_IRQn;
|
||||
case Timer_Key::S_TIM14: return TIM14_IRQn;
|
||||
case Timer_Key::S_TIM15: return TIM15_IRQn;
|
||||
case Timer_Key::S_TIM16: return TIM16_IRQn;
|
||||
case Timer_Key::S_TIM17: return TIM17_IRQn;
|
||||
case Timer_Key::NUM_TIMERS:
|
||||
case Timer_Key::S_TIM_INVALID:
|
||||
assert(false);
|
||||
return TIM1_BRK_UP_TRG_COM_IRQn; //Unreachable
|
||||
static inline SHAL_TIM_Control_Register_1 getTimerControlRegister1(Timer_Key key){
|
||||
|
||||
SHAL_TIM_Control_Register_1 res = {nullptr, TIM_CR1_CEN_Msk,
|
||||
TIM_CR1_UDIS,
|
||||
TIM_CR1_OPM,
|
||||
TIM_CR1_CMS_Pos,
|
||||
TIM_CR1_ARPE};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->CR1;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_DMA_Interrupt_Enable_Register getTimerDMAInterruptEnableRegister(Timer_Key key){
|
||||
|
||||
SHAL_TIM_DMA_Interrupt_Enable_Register res = {nullptr, TIM_DIER_UIE};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->DIER;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Event_Generation_Register getTimerEventGenerationRegister(Timer_Key key){
|
||||
|
||||
SHAL_TIM_Event_Generation_Register res = {nullptr, TIM_EGR_UG};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->EGR;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Break_Dead_Time_Register getTimerBreakDeadTimeRegister(Timer_Key key) {
|
||||
|
||||
SHAL_TIM_Break_Dead_Time_Register res = {nullptr,
|
||||
TIM_BDTR_DTG_Pos,
|
||||
TIM_BDTR_LOCK_Pos,
|
||||
TIM_BDTR_OSSI,
|
||||
TIM_BDTR_OSSR,
|
||||
TIM_BDTR_BKE,
|
||||
TIM_BDTR_BKP,
|
||||
TIM_BDTR_AOE,
|
||||
TIM_BDTR_MOE};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->BDTR;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Prescaler_Register getTimerPrescalerRegister(Timer_Key key){
|
||||
|
||||
SHAL_TIM_Prescaler_Register res = {nullptr, 1UL << 15};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->PSC;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Auto_Reload_Register getTimerAutoReloadRegister(Timer_Key key){
|
||||
|
||||
SHAL_TIM_Auto_Reload_Register res = {nullptr, 1UL << 15};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->ARR;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Capture_Compare_Register getTimerCaptureCompareRegister(Timer_Key key, SHAL_Timer_Channel channel){
|
||||
auto channel_num = static_cast<uint8_t>(channel);
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
assert(channel_num <= TIM_INFO_TABLE[static_cast<uint8_t>(key)].numChannels);
|
||||
|
||||
switch(channel){
|
||||
case SHAL_Timer_Channel::CH1: return {&tim->CCR1,0};
|
||||
case SHAL_Timer_Channel::CH2: return {&tim->CCR2,0};
|
||||
case SHAL_Timer_Channel::CH3: return {&tim->CCR3,0};
|
||||
case SHAL_Timer_Channel::CH4: return {&tim->CCR4,0};
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Capture_Compare_Enable_Register getTimerCaptureCompareEnableRegister(Timer_Key key, SHAL_Timer_Channel channel){
|
||||
|
||||
uint8_t channel_stride = 3;
|
||||
auto channel_num = static_cast<uint8_t>(channel);
|
||||
|
||||
auto output_enable = TIM_CCER_CC1E << (channel_stride * (channel_num - 1));
|
||||
auto output_polarity = TIM_CCER_CC1P << (channel_stride * channel_num);
|
||||
auto output_complimentary_enable = TIM_CCER_CC1NE << (channel_stride * channel_num);
|
||||
auto output_complimentary_polarity = TIM_CCER_CC1NP << (channel_stride * channel_num);
|
||||
|
||||
SHAL_TIM_Capture_Compare_Enable_Register res = {nullptr,
|
||||
output_enable,
|
||||
output_polarity,
|
||||
output_complimentary_enable,
|
||||
output_complimentary_polarity,
|
||||
};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
|
||||
res.reg = &tim->CCER;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline SHAL_TIM_Output_Capture_Compare_Mode_Register getTimerOutputCaptureCompareModeRegister(Timer_Key key, SHAL_Timer_Channel channel) {
|
||||
SHAL_TIM_Output_Capture_Compare_Mode_Register res = {
|
||||
nullptr,
|
||||
TIM_CCMR1_CC1S_Pos, //Channel 1 Capture/Compare selection
|
||||
TIM_CCMR1_OC1FE, //Channel 1 Fast enable
|
||||
TIM_CCMR1_OC1PE, //Channel 1 Preload enable
|
||||
TIM_CCMR1_OC1M_Pos, //Channel 1 Mode (OC1M)
|
||||
TIM_CCMR1_OC1CE, //Channel 1 Clear enable
|
||||
TIM_CCMR1_CC2S_Pos, //Channel 2 Capture/Compare selection
|
||||
TIM_CCMR1_OC2FE, //Channel 2 Fast enable
|
||||
TIM_CCMR1_OC2PE, //Channel 2 Preload enable
|
||||
TIM_CCMR1_OC2M_Pos, //Channel 2 Mode (OC2M)
|
||||
TIM_CCMR1_OC2CE //Channel 2 Clear enable
|
||||
};
|
||||
|
||||
volatile TIM_TypeDef* tim = TIM_INFO_TABLE[static_cast<uint8_t>(key)].timer;
|
||||
uint8_t num_tim_channels = TIM_INFO_TABLE[static_cast<uint8_t>(key)].numChannels;
|
||||
|
||||
volatile uint32_t* reg = nullptr;
|
||||
|
||||
uint8_t channelNum = static_cast<uint32_t>(channel);
|
||||
|
||||
assert(num_tim_channels >= channelNum); //Assert that we don't access undefined memory trying to initialize a non-existent channel
|
||||
|
||||
if(channelNum >= 3){
|
||||
reg = &tim->CCMR2;
|
||||
}
|
||||
else{
|
||||
reg = &tim->CCMR1;
|
||||
}
|
||||
|
||||
res.reg = reg;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ public:
|
||||
//Enable interrupts
|
||||
void enableInterrupt();
|
||||
|
||||
void setPWMMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
||||
//Capture Compare Functions
|
||||
void setCaptureCompareValue(SHAL_Timer_Channel channel, uint16_t value);
|
||||
void enableChannel(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
||||
void setOutputCompareMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode);
|
||||
|
||||
/// Set the duty cycle for PWM
|
||||
/// \param dutyCycle 10 * percentage (e.g. 500 = 50%)
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
|
||||
struct SHAL_TIM_Info{
|
||||
volatile TIM_TypeDef* timer;
|
||||
IRQn_Type IRQn;
|
||||
uint8_t numChannels;
|
||||
};
|
||||
|
||||
struct SHAL_TIM_RCC_Register{
|
||||
volatile uint32_t* reg;
|
||||
uint32_t enable_mask;
|
||||
@@ -47,7 +53,7 @@ struct SHAL_TIM_Auto_Reload_Register {
|
||||
};
|
||||
|
||||
struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
||||
volatile uint32_t* regs[2];
|
||||
volatile uint32_t* regs;
|
||||
uint32_t input_capture_1_filter_offset;
|
||||
uint32_t input_capture_1_prescaler_offset;
|
||||
uint32_t capture_compare_1_selection_offset;
|
||||
@@ -56,8 +62,8 @@ struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
||||
uint32_t capture_compare_2_selection_offset;
|
||||
};
|
||||
|
||||
struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
||||
volatile uint32_t* regs[2];
|
||||
struct SHAL_TIM_Output_Capture_Compare_Mode_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t capture_compare_1_selection_offset;
|
||||
uint32_t output_compare_1_fast_enable_mask;
|
||||
uint32_t output_compare_1_preload_enable_mask;
|
||||
@@ -72,15 +78,27 @@ struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
||||
|
||||
struct SHAL_TIM_Break_Dead_Time_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t main_output_enable_mask;
|
||||
uint32_t dead_time_offset; // [7:0] DTG - Dead-time generator setup
|
||||
uint32_t lock_configuration_offset; // [9:8] LOCK - Lock configuration
|
||||
uint32_t off_state_selection_idle_mask; // [10] OSSI - Off-state selection for idle mode
|
||||
uint32_t off_state_selection_run_mask; // [11] OSSR - Off-state selection for run mode
|
||||
uint32_t break_enable_mask; // [12] BKE - Break enable
|
||||
uint32_t break_polarity_mask; // [13] BKP - Break polarity
|
||||
uint32_t automatic_output_enable_mask; // [14] AOE - Automatic output enable
|
||||
uint32_t main_output_enable_mask; // [15] MOE - Main output enable
|
||||
};
|
||||
|
||||
struct SHAL_TIM_Capture_Compare_Enable_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t cc_output_enable_offset;
|
||||
uint32_t cc_output_polarity_offset;
|
||||
uint32_t cc_complimentary_output_enable_offset;
|
||||
uint32_t cc_complimentary_output_polarity_offset;
|
||||
};
|
||||
|
||||
struct SHAL_TIM_Capture_Compare_Register {
|
||||
volatile uint32_t* reg;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
|
||||
@@ -102,12 +120,10 @@ enum class SHAL_TIM_Output_Compare_Preload : uint8_t {
|
||||
};
|
||||
|
||||
enum class SHAL_Timer_Channel : uint8_t { //TODO change if other timers have fewer than 6 channels
|
||||
CH1 = 0,
|
||||
CH2 = 1,
|
||||
CH3 = 2,
|
||||
CH4 = 3,
|
||||
CH5 = 4,
|
||||
CH6 = 5,
|
||||
CH1 = 1,
|
||||
CH2 = 2,
|
||||
CH3 = 3,
|
||||
CH4 = 4,
|
||||
};
|
||||
|
||||
enum class SHAL_Timer_Channel_Main_Output_Mode : uint8_t {
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_GPIO_REG.h"
|
||||
|
||||
|
||||
|
||||
//Represents a pair of pins usable for USART Tx + Rx in combination, and their alternate function mapping
|
||||
struct SHAL_UART_Pair{
|
||||
USART_TypeDef* USARTReg;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
#include "SHAL_TIM.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
#include "SHAL_UART.h"
|
||||
#include "SHAL_ADC.h"
|
||||
//#include "SHAL_UART.h"
|
||||
//#include "SHAL_ADC.h"
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user