Fixed ADC functionality

This commit is contained in:
Ea-r-th
2025-10-19 18:33:18 -07:00
parent 2c5592c2d3
commit e41cf30c87
8 changed files with 74 additions and 37 deletions

View File

@@ -110,6 +110,8 @@ static inline void SHAL_set_register_value_16(volatile uint16_t* reg, uint16_t v
*reg = value; *reg = value;
} }
void SHAL_print_register(const volatile uint32_t* reg);
//--------------------------------------------------------- //---------------------------------------------------------

View File

@@ -32,9 +32,11 @@ enum class SHAL_ADC_Channel : uint32_t {
CH13, CH13,
CH14, CH14,
CH15, CH15,
CH16,
CHTemp, CHTemp,
CHRef, CHRef,
CHBat CHBat,
NO_ADC_MAPPING
}; };
enum class ADC_Key : uint8_t{ enum class ADC_Key : uint8_t{
@@ -116,10 +118,10 @@ static inline SHAL_ADC_Channel_Sampling_Time_Reg getADCChannelSamplingTimeRegist
auto channelNum = static_cast<uint8_t>(channel); auto channelNum = static_cast<uint8_t>(channel);
if (channelNum <= 9) { if (channelNum <= 9) {
SMPReg = &ADCReg->SQR1; SMPReg = &ADCReg->SMPR1;
pos = (channelNum * 3); pos = (channelNum * 3);
} else { } else {
SMPReg = &ADCReg->SQR2; SMPReg = &ADCReg->SMPR2;
pos = ((channelNum - 10) * 3); pos = ((channelNum - 10) * 3);
} }
@@ -144,11 +146,11 @@ static inline SHAL_ADC_Sequence_Reg getADCSequenceRegisters(ADC_Key key){
&adc_reg->SQR4, &adc_reg->SQR4,
nullptr, nullptr,
nullptr}, nullptr},
{1UL << 0, {0,
1UL << 6, 6,
1UL << 12, 12,
1UL << 18, 18,
1UL << 24} 24}
}; };
return res; return res;

View File

@@ -169,47 +169,54 @@ constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
switch(key){ switch(key){
case GPIO_Key::A0: case GPIO_Key::A0:
return {0, SHAL_ADC_Channel::CH5};
case GPIO_Key::B0: case GPIO_Key::B0:
return {0, SHAL_ADC_Channel::CH0}; return {0, SHAL_ADC_Channel::CH15};
case GPIO_Key::A1: case GPIO_Key::A1:
return {1, SHAL_ADC_Channel::CH6};
case GPIO_Key::B1: case GPIO_Key::B1:
return {1, SHAL_ADC_Channel::CH1}; return {1, SHAL_ADC_Channel::CH16};
case GPIO_Key::A2: case GPIO_Key::A2:
return {2, SHAL_ADC_Channel::CH2}; return {2, SHAL_ADC_Channel::CH7};
case GPIO_Key::A3: case GPIO_Key::A3:
return {3, SHAL_ADC_Channel::CH8};
case GPIO_Key::B3: case GPIO_Key::B3:
return {3, SHAL_ADC_Channel::CH3}; return {3, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A4: case GPIO_Key::A4:
return {4, SHAL_ADC_Channel::CH9};
case GPIO_Key::B4: case GPIO_Key::B4:
return {4, SHAL_ADC_Channel::CH4}; return {4, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A5: case GPIO_Key::A5:
return {5, SHAL_ADC_Channel::CH10};
case GPIO_Key::B5: case GPIO_Key::B5:
return {5, SHAL_ADC_Channel::CH5}; return {5, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A6: case GPIO_Key::A6:
return {6, SHAL_ADC_Channel::CH11};
case GPIO_Key::B6: case GPIO_Key::B6:
return {6, SHAL_ADC_Channel::CH6}; return {6, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A7: case GPIO_Key::A7:
return {7, SHAL_ADC_Channel::CH12};
case GPIO_Key::B7: case GPIO_Key::B7:
return {7, SHAL_ADC_Channel::CH7}; return {7, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A8: case GPIO_Key::A8:
return {8, SHAL_ADC_Channel::CH8}; return {8, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A9: case GPIO_Key::A9:
return {9, SHAL_ADC_Channel::CH9}; return {9, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A10: case GPIO_Key::A10:
return {10, SHAL_ADC_Channel::CH10}; return {10, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A11: case GPIO_Key::A11:
return {11, SHAL_ADC_Channel::CH11}; return {11, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A12: case GPIO_Key::A12:
return {12, SHAL_ADC_Channel::CH12}; return {12, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A13: case GPIO_Key::A13:
return {13, SHAL_ADC_Channel::CH13}; return {13, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A14: case GPIO_Key::A14:
return {14, SHAL_ADC_Channel::CH14}; return {14, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::A15: case GPIO_Key::A15:
return {15, SHAL_ADC_Channel::CH15}; return {15, SHAL_ADC_Channel::NO_ADC_MAPPING};
case GPIO_Key::NUM_GPIO: case GPIO_Key::NUM_GPIO:
case GPIO_Key::INVALID: case GPIO_Key::INVALID:
return {0, SHAL_ADC_Channel::CH0}; return {0, SHAL_ADC_Channel::NO_ADC_MAPPING};
} }
__builtin_unreachable(); __builtin_unreachable();
} }

View File

@@ -29,7 +29,6 @@ public:
/// \return ADC result /// \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);
void setPinMode(PinMode mode) volatile;
void setAlternateFunction(GPIO_Alternate_Function AF) volatile; void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
@@ -42,7 +41,7 @@ public:
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback); void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
SHAL_Result setPinMode(PinMode mode) volatile;
private: private:
@@ -67,6 +66,7 @@ private:
#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x) #define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x)
//Manages instances of SHAL_GPIO objects //Manages instances of SHAL_GPIO objects
class GPIOManager{ class GPIOManager{

View File

@@ -2,9 +2,12 @@
// Created by Luca on 9/15/2025. // Created by Luca on 9/15/2025.
// //
#include <cstdio>
#include "SHAL_CORE.h" #include "SHAL_CORE.h"
#include "SHAL_GPIO.h" #include "SHAL_GPIO.h"
#include "SHAL_ADC.h" #include "SHAL_ADC.h"
#include "SHAL_UART.h"
void SHAL_init(){ void SHAL_init(){
systick_init(); systick_init();
@@ -51,3 +54,9 @@ void SHAL_delay_ms(uint32_t ms){
SHAL_delay_us(1000); SHAL_delay_us(1000);
} }
} }
void SHAL_print_register(const volatile uint32_t* reg){
char buff[32];
sprintf(buff, "0x%08lX\r\n", (unsigned long)(*reg));
SHAL_UART2.sendString(buff);
}

View File

@@ -85,7 +85,7 @@ uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, SHAL_ADC_Sample
SHAL_set_bits(sampleTimeReg.reg,3,static_cast<uint8_t>(time),sampleTimeReg.channel_offset); //Set sample time register TODO un-hardcode bit width? SHAL_set_bits(sampleTimeReg.reg,3,static_cast<uint8_t>(time),sampleTimeReg.channel_offset); //Set sample time register TODO un-hardcode bit width?
addADCChannelToSequence(channel,0); //Use index 0 to convert channel addADCChannelToSequence(channel,0); //Use index 0 to convert channel
setADCSequenceAmount(1); //Since we're using single convert, convert 1 channel if(setADCSequenceAmount(1) == SHAL_Result::ERROR){return 0;} //Since we're using single convert, convert 1 channel
if(enable() != SHAL_Result::OKAY){ if(enable() != SHAL_Result::OKAY){
return 0; return 0;
@@ -95,7 +95,7 @@ uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, SHAL_ADC_Sample
auto ISR_reg = getADCISRReg(m_ADCKey); auto ISR_reg = getADCISRReg(m_ADCKey);
if(!SHAL_WAIT_FOR_CONDITION_US(((*ISR_reg.reg & ISR_reg.end_of_conversion_mask) != 0),500)){ //Wait for conversion if(!SHAL_WAIT_FOR_CONDITION_US(((*ISR_reg.reg & ISR_reg.end_of_sequence_mask) != 0),500)){ //Wait for conversion
return 0; //Failed return 0; //Failed
} }
@@ -268,6 +268,7 @@ SHAL_Result SHAL_ADC::setADCSequenceAmount(uint32_t amount) {
} }
SHAL_Result SHAL_ADC::addADCChannelToSequence(SHAL_ADC_Channel channel, uint32_t index) { SHAL_Result SHAL_ADC::addADCChannelToSequence(SHAL_ADC_Channel channel, uint32_t index) {
if(!isValid()){return SHAL_Result::ERROR;} if(!isValid()){return SHAL_Result::ERROR;}
auto sequenceRegisters = getADCSequenceRegisters(m_ADCKey); auto sequenceRegisters = getADCSequenceRegisters(m_ADCKey);
@@ -280,6 +281,13 @@ SHAL_Result SHAL_ADC::addADCChannelToSequence(SHAL_ADC_Channel channel, uint32_t
volatile uint32_t* sequenceReg = sequenceRegisters.regs[sequenceRegNumber]; volatile uint32_t* sequenceReg = sequenceRegisters.regs[sequenceRegNumber];
uint32_t bitSectionOffset = sequenceRegisters.offsets[bitSection]; uint32_t bitSectionOffset = sequenceRegisters.offsets[bitSection];
if(sequenceRegNumber != 0){
*sequenceReg = 0; //Clear previous conversions
}
else{
*sequenceReg &= 0x0000000F;
}
SHAL_set_bits(sequenceReg,5,channelNum,bitSectionOffset); SHAL_set_bits(sequenceReg,5,channelNum,bitSectionOffset);
return SHAL_Result::OKAY; return SHAL_Result::OKAY;

View File

@@ -5,7 +5,7 @@
#include "SHAL_GPIO.h" #include "SHAL_GPIO.h"
#include "SHAL_EXTI_CALLBACK.h" #include "SHAL_EXTI_CALLBACK.h"
#include "SHAL_UART.h"
SHAL_GPIO::SHAL_GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){ SHAL_GPIO::SHAL_GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){
//Do not initialize anything //Do not initialize anything
@@ -34,7 +34,19 @@ void SHAL_GPIO::toggle() volatile {
gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset); gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset);
} }
SHAL_Result SHAL_GPIO::setPinMode(PinMode mode) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->MODER &= ~(0x03 << (2 * gpioPeripheral.global_offset));
gpioPeripheral.reg->MODER |= (static_cast<uint8_t>(mode) << (2 * gpioPeripheral.global_offset));
if(mode == PinMode::ANALOG_MODE && getGPIOPortInfo(m_GPIO_KEY).ADCChannel != SHAL_ADC_Channel::NO_ADC_MAPPING){
SHAL_UART2.sendString("Error: GPIO pin has no valid ADC mapping\r\n");
return SHAL_Result::ERROR;
}
return SHAL_Result::OKAY;
}
void SHAL_GPIO::setPinType(PinType type) volatile { void SHAL_GPIO::setPinType(PinType type) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY); SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
@@ -62,11 +74,7 @@ void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function AF) volatile {
gpioPeripheral.reg->AFR[afrIndex] |= (static_cast<int>(AF) << (gpioPeripheral.global_offset * 4)); gpioPeripheral.reg->AFR[afrIndex] |= (static_cast<int>(AF) << (gpioPeripheral.global_offset * 4));
} }
void SHAL_GPIO::setPinMode(PinMode mode) volatile {
SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY);
gpioPeripheral.reg->MODER &= ~(0x03 << (2 * gpioPeripheral.global_offset)); //Clear any previous mode
gpioPeripheral.reg->MODER |= (static_cast<uint8_t>(mode) << (2 * gpioPeripheral.global_offset)); //Set mode based on pinmode bit structure
}
void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) { void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) {

View File

@@ -10,7 +10,7 @@ void togglePin() {
} }
void timer2callback(){ void timer2callback(){
auto val = PIN(B7).analogRead(); auto val = PIN(A5).analogRead();
char buf [6]; char buf [6];
sprintf (buf, "%d\r\n", val); sprintf (buf, "%d\r\n", val);
@@ -22,12 +22,13 @@ int main() {
SHAL_init(); SHAL_init();
PIN(B4).setPinMode(PinMode::OUTPUT_MODE); PIN(B4).setPinMode(PinMode::OUTPUT_MODE);
PIN(B4).setLow(); PIN(B4).setLow();
PIN(B3).setPinMode(PinMode::OUTPUT_MODE); PIN(B3).setPinMode(PinMode::OUTPUT_MODE);
PIN(A5).setPinMode(PinMode::ANALOG_MODE);
SHAL_UART2.init(UART_Pair_Key::Tx2A2_Rx2A3); SHAL_UART2.init(UART_Pair_Key::Tx2A2_Rx2A3);
SHAL_UART2.begin(115200); SHAL_UART2.begin(115200);