Skip to content
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ target_sources(${PROJECT_NAME} PRIVATE
src/core/io/ADC.cpp
src/core/io/CAN.cpp
src/core/io/CANopen.cpp
src/core/io/DAC.cpp
src/core/io/GPIO.cpp
src/core/io/I2C.cpp
src/core/io/PWM.cpp
Expand All @@ -54,6 +55,7 @@ if(COMPDEFS MATCHES "(.*)STM32F3xx(.*)")
src/core/platform/f3xx/stm32f302x8.cpp
src/core/io/platform/f3xx/ADCf3xx.cpp
src/core/io/platform/f3xx/CANf3xx.cpp
src/core/io/platform/f3xx/DACf3xx.cpp
src/core/io/platform/f3xx/GPIOf3xx.cpp
src/core/io/platform/f3xx/I2Cf3xx.cpp
src/core/io/platform/f3xx/PWMf3xx.cpp
Expand All @@ -67,6 +69,7 @@ elseif(COMPDEFS MATCHES "(.*)STM32F4xx(.*)")
src/core/platform/f4xx/stm32f446xx.cpp
src/core/io/platform/f4xx/ADCf4xx.cpp
src/core/io/platform/f4xx/CANf4xx.cpp
src/core/io/platform/f4xx/DACf4xx.cpp
src/core/io/platform/f4xx/GPIOf4xx.cpp
src/core/io/platform/f4xx/I2Cf4xx.cpp
src/core/io/platform/f4xx/PWMf4xx.cpp
Expand Down
63 changes: 63 additions & 0 deletions include/core/io/DAC.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef _EVT_DAC_
#define _EVT_DAC_

#include <stdint.h>

namespace core::io {

// Forward declarations:
// The different pins are hardware specific. Forward declarations to allow
// at compilation time the decision of which pins should be used.
enum class Pin;
enum class DACPeriph;

class DACBase {

public:
/**
* Setup the given pin for DAC (digital to analog) usage
*
* @param[in] pin The pin to setup for DAC
* @param[in] dacPeriph The DAC peripheral being used
*/
DACBase(Pin pin, DACPeriph dacPeriph);

/**
* Set the DAC output value
* @param value The digital value to convert (0-4095 for 12-bit DAC)
*/
virtual void setValue(uint32_t value) = 0;

/**
* Get the current DAC output value
* @return The current digital value being output
*/
virtual uint32_t getValue() const = 0;

/**
* Set the DAC output voltage directly
* @param voltage The desired output voltage in volts
*/
virtual void setVoltage(float voltage) = 0;

/**
* Get the current DAC output voltage
* @return The current output voltage in volts
*/
virtual float getVoltage() const = 0;

protected:
/// The pin the DAC is attached to
Pin pin;
/// The internal DAC being used
DACPeriph dacPeriph;
};

} // namespace core::io

// Convenience typedef - use different name to avoid macro conflict
namespace core::io {
using DigitalToAnalogConverter = DACBase;
}

#endif // _EVT_DAC_
66 changes: 66 additions & 0 deletions include/core/io/platform/f3xx/DACf3xx.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef _EVT_DACF3XX_H
#define _EVT_DACF3XX_H

#include <HALf3/stm32f3xx.h>
#include <HALf3/stm32f3xx_hal.h>

#include <core/io/DAC.hpp>

namespace core::io {

enum class DACPeriph {
ONE
};

class DACf3xx : public DACBase {
public:
/**
* Setup the given pin for DAC usage
*
* @param[in] pin The pin to setup for DAC
* @param[in] dacPeriph The DAC peripheral being used
*/
DACf3xx(Pin pin, DACPeriph dacPeriph);

void setValue(uint32_t value) override;
uint32_t getValue() const override;
void setVoltage(float voltage) override;
float getVoltage() const override;

DAC_HandleTypeDef* getHalDac() {
return &halDac;
}

private:
static constexpr uint32_t MAX_RAW = 4095;
static constexpr float VREF_POS = 3.3;
uint32_t currentValue = 0;
DAC_HandleTypeDef halDac;

/**
* Bit packed struct to contain the channel along with the DAC peripherals the channel supports
*
* dac1: 1 bit. Support for DAC1 peripheral. 1 for supported, 0 for not supported.
* channel: 5 bits. The STM32 DAC channel value with said supported DAC peripherals
*/
struct Channel_Support {
uint8_t dac1 : 1;
uint8_t channel : 5;
};

/**
* Check if the channel that is being initialized supports the DAC peripheral that it is being initialized on.
*
* @param periph the DAC peripheral being used
* @param channelStruct the struct of the channel with supports to test
* @return true if channel is supported by the DAC peripheral, false otherwise
*/
static bool checkSupport(DACPeriph periph, Channel_Support channelStruct);

void initDAC();
void initGPIO();
};

} // namespace core::io

#endif // _EVT_DACF3XX_H
66 changes: 66 additions & 0 deletions include/core/io/platform/f4xx/DACf4xx.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef _EVT_DACF4XX_H
#define _EVT_DACF4XX_H

#include <HALf4/stm32f4xx.h>
#include <HALf4/stm32f4xx_hal.h>

#include <core/io/DAC.hpp>

namespace core::io {

enum class DACPeriph {
ONE
};

class DACf4xx : public DACBase {
public:
/**
* Setup the given pin for DAC usage
*
* @param[in] pin The pin to setup for DAC
* @param[in] dacPeriph The DAC peripheral being used
*/
DACf4xx(Pin pin, DACPeriph dacPeriph);

void setValue(uint32_t value) override;
uint32_t getValue() const override;
void setVoltage(float voltage) override;
float getVoltage() const override;

DAC_HandleTypeDef* getHalDac() {
return &halDac;
}

private:
static constexpr uint32_t MAX_RAW = 4095;
static constexpr float VREF_POS = 3.3;
uint32_t currentValue = 0;
DAC_HandleTypeDef halDac;

/**
* Bit packed struct to contain the channel along with the DAC peripherals the channel supports
*
* dac1: 1 bit. Support for DAC1 peripheral. 1 for supported, 0 for not supported.
* channel: 5 bits. The STM32 DAC channel value with said supported DAC peripherals
*/
struct Channel_Support {
uint8_t dac1 : 1;
uint8_t channel : 5;
};

/**
* Check if the channel that is being initialized supports the DAC peripheral that it is being initialized on.
*
* @param periph the DAC peripheral being used
* @param channelStruct the struct of the channel with supports to test
* @return true if channel is supported by the DAC peripheral, false otherwise
*/
static bool checkSupport(DACPeriph periph, Channel_Support channelStruct);

void initDAC();
void initGPIO();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add descriptions for these methods

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chat these methods are like not worth documenting

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am with Diego on this, add at least a little description.

};

} // namespace core::io

#endif // _EVT_DACF4XX_H
1 change: 1 addition & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_subdirectory(button)
add_subdirectory(button_debounce)
add_subdirectory(can)
add_subdirectory(canopen)
add_subdirectory(dac)
add_subdirectory(echo)
add_subdirectory(eeprom)
add_subdirectory(encoder)
Expand Down
3 changes: 3 additions & 0 deletions samples/dac/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/evt-core_build.cmake)

make_exe(dac main.cpp)
Loading