// // Created by Luca on 10/8/2025. // #ifndef SHMINGO_HAL_SHAL_ADC_REG_H753ZI_H #define SHMINGO_HAL_SHAL_ADC_REG_H753ZI_H #include "SHAL_CORE.h" #include "SHAL_ADC_TYPES.h" #include "stm32h753xx.h" #define SHAL_ADC1 SHAL_ADC(1) #define SHAL_ADC2 SHAL_ADC(2) #define SHAL_ADC3 SHAL_ADC(3) #define NUM_ADCS 3 #define NUM_ADC_CHANNELS 16 enum class SHAL_ADC_Channel : uint32_t { CH0 = 0, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8, CH9, CH10, CH11, CH12, CH13, CH14, CH15, CH16, CH17, CH18, CHTemp, CHRef, CHBat, NO_ADC_MAPPING }; enum class ADC_Key : uint8_t{ S_ADC1 = 0, S_ADC2 = 1, S_ADC3 = 2, NUM_ADC = 3, INVALID = 255 }; enum class SHAL_ADC_Resolution : uint8_t { //TODO figure out what to do with this difference B16 = 0x00, B14 = 0x01, B12 = 0x02, B10 = 0x03, B8 = 0x04, B6 = 0x05, }; enum class SHAL_ADC_Clock_Mode { ASYNC = 0x00, SYNC_BY_1 = 0x01, SYNC_BY_2 = 0x02, SYNC_BY_4 = 0x03, }; static volatile ADC_TypeDef* ADC_TABLE[3] = { //Lookup table for ADCs ADC1, ADC2, ADC3, }; static volatile ADC_Common_TypeDef* ADC_CCR_TABLE[3] = { //Common registers ADC12_COMMON, //1 and 2 share a common register ADC12_COMMON, ADC3_COMMON, }; enum class ADC_Clock_Source : uint32_t { SHAL_NO_CLOCK = 0x00, SHAL_PLLSAI1 = 0x01, SHAL_PLLSYS = 0x02, SHAL_SYSCLK = 0x03, }; static SHAL_ADC_Common_Control_Reg getADCCommonControl(ADC_Key key) { SHAL_ADC_Common_Control_Reg res = { .reg = nullptr, .VoltageRefEnable = ADC_CCR_VREFEN, .TempSensorEnable = ADC_CCR_TSEN, .VBatteryEnable = ADC_CCR_VBATEN, .clock_mode_position = ADC_CCR_CKMODE_Pos }; res.reg = &ADC_CCR_TABLE[static_cast(key)]->CCR; return res; } static inline SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(const ADC_Key key){ switch (key) { case ADC_Key::S_ADC1: case ADC_Key::S_ADC2: return {&RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN}; case ADC_Key::S_ADC3: return {&RCC->AHB4ENR, RCC_AHB4ENR_ADC3EN}; default: __builtin_unreachable(); } } static inline SHAL_ADC_Control_Reg getADCControlReg(ADC_Key key) { SHAL_ADC_Control_Reg res = {nullptr, ADC_CR_ADEN, ADC_CR_ADSTP, ADC_CR_ADDIS, ADC_CR_ADCAL, ADC_CR_ADSTART, ADC_CR_DEEPPWD, ADC_CR_ADVREGEN, ADC_CR_ADCALDIF}; res.reg = &(ADC_TABLE[static_cast(key)]->CR); return res; } static inline SHAL_ADC_Config_Reg getADCConfigReg(ADC_Key key) { //NOTE offset of 33 means the function is deprecated SHAL_ADC_Config_Reg res = {nullptr, ADC_CFGR_CONT, ADC_CFGR_RES_Pos, 0, //TODO 0 is broken, shouldnt have alignment ADC_CFGR_CONT_Msk }; res.reg = &(ADC_TABLE[static_cast(key)]->CFGR); return res; } static inline SHAL_ADC_ISR_Reg getADCISRReg(ADC_Key key){ SHAL_ADC_ISR_Reg res = {nullptr, ADC_ISR_EOC, ADC_ISR_EOS, ADC_ISR_ADRDY, ADC_ISR_OVR, ADC_ISR_LDORDY}; res.reg = &(ADC_TABLE[static_cast(key)]->ISR); return res; } static inline SHAL_ADC_Data_Reg getADCDataReg(ADC_Key key){ SHAL_ADC_Data_Reg res = {nullptr, 0xFFFF}; res.reg = &(ADC_TABLE[static_cast(key)]->DR); return res; } static inline SHAL_ADC_Channel_Sampling_Time_Reg getADCChannelSamplingTimeRegister(ADC_Key key, SHAL_ADC_Channel channel){ volatile ADC_TypeDef* ADCReg = ADC_TABLE[static_cast(key)]; volatile uint32_t* SMPReg = nullptr; uint32_t pos; auto channelNum = static_cast(channel); if (channelNum <= 9) { SMPReg = &ADCReg->SMPR1; pos = (channelNum * 3); } else { SMPReg = &ADCReg->SMPR2; pos = ((channelNum - 10) * 3); } return {SMPReg, pos}; } static inline SHAL_ADC_Sequence_Amount_Reg getADCSequenceAmountRegister(ADC_Key key){ SHAL_ADC_Sequence_Amount_Reg res = {nullptr, ADC_SQR1_L_Pos}; res.reg = &(ADC_TABLE[static_cast(key)]->SQR1); return res; } static SHAL_ADC_Sequence_Reg getADCSequenceRegister(ADC_Key key, uint32_t conversionNum){ volatile ADC_TypeDef* adc_reg = ADC_TABLE[static_cast(key)]; volatile uint32_t* sqr[4] = {&adc_reg->SQR1, &adc_reg->SQR2, &adc_reg->SQR3, &adc_reg->SQR4, }; const uint8_t sqrIndex = conversionNum / 5; //CONVERSION NUM STARTS AT 1! AS PER DATASHEET REFERENCING IT AS SQ1 const uint32_t offset = (((conversionNum) % 5) * 6); return {sqr[sqrIndex], offset}; } static SHAL_ADC_Preselect_Reg getADCPreselectRegister(ADC_Key key, SHAL_ADC_Channel channel) { SHAL_ADC_Preselect_Reg res = {nullptr, static_cast(channel)}; res.reg = &(ADC_TABLE[static_cast(key)]->PCSEL); return res; } #endif //SHMINGO_HAL_SHAL_ADC_REG_H753ZI_H