diff --git a/.gitignore b/.gitignore index 2286167..21f2210 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ build +build_test +*.log _codeql_build_dir _codeql_detected_source_root \ No newline at end of file diff --git a/include/rpl4/peripheral/aux_spi.hpp b/include/rpl4/peripheral/aux_spi.hpp index e9fb7fb..8a74618 100644 --- a/include/rpl4/peripheral/aux_spi.hpp +++ b/include/rpl4/peripheral/aux_spi.hpp @@ -10,7 +10,15 @@ namespace rpl { -class AuxSpi : public SpiBase { +// Forward declaration for factory +class AuxSpi; + +// Helper struct to enable make_shared with private constructor +struct AuxSpiFactory { + static std::shared_ptr Create(AuxSpiRegisterMap* register_map); +}; + +class AuxSpi : public SpiBase, public std::enable_shared_from_this { public: enum class Port : size_t { kAuxSpi1 = 0, @@ -229,6 +237,9 @@ class AuxSpi : public SpiBase { void ConfigureDataShiftTx(); void ConfigureDataShiftRx(); + + // Allow factory struct to access private constructor + friend struct AuxSpiFactory; }; } // namespace rpl diff --git a/include/rpl4/peripheral/dma.hpp b/include/rpl4/peripheral/dma.hpp index b04d49c..adb5af8 100644 --- a/include/rpl4/peripheral/dma.hpp +++ b/include/rpl4/peripheral/dma.hpp @@ -9,7 +9,7 @@ namespace rpl { -class Dma { +class Dma : public std::enable_shared_from_this { public: enum class Channel : size_t { kChannel0 = 0, @@ -191,6 +191,14 @@ class Dma { DmaRegisterMap* register_map_; Channel channel_; + + // Allow factory struct to access private constructor + friend struct DmaFactory; +}; + +// Helper struct to enable make_shared with private constructor +struct DmaFactory { + static std::shared_ptr Create(DmaRegisterMap* register_map, Dma::Channel channel); }; } // namespace rpl diff --git a/include/rpl4/peripheral/gpio.hpp b/include/rpl4/peripheral/gpio.hpp index 19b86d7..4eb0b6a 100644 --- a/include/rpl4/peripheral/gpio.hpp +++ b/include/rpl4/peripheral/gpio.hpp @@ -7,7 +7,15 @@ namespace rpl { -class Gpio { +// Forward declaration for factory +class Gpio; + +// Helper struct to enable make_shared with private constructor +struct GpioFactory { + static std::shared_ptr Create(uint8_t pin); +}; + +class Gpio : public std::enable_shared_from_this { public: /** * @brief Resistor Select @@ -109,6 +117,9 @@ class Gpio { static std::array, kNumOfInstances> instances_; uint8_t pin_; + + // Allow factory struct to access private constructor + friend struct GpioFactory; }; } // namespace rpl diff --git a/include/rpl4/peripheral/pwm.hpp b/include/rpl4/peripheral/pwm.hpp index 09a21cc..2a2a9a1 100644 --- a/include/rpl4/peripheral/pwm.hpp +++ b/include/rpl4/peripheral/pwm.hpp @@ -9,7 +9,7 @@ namespace rpl { -class Pwm { +class Pwm : public std::enable_shared_from_this { public: enum class Port : size_t { kPwm0 = 0, @@ -216,6 +216,14 @@ class Pwm { Port port_; double clock_frequency_; static constexpr double kDefaultClockFrequency = 25000000.0; // 25 MHz + + // Allow factory struct to access private constructor + friend struct PwmFactory; +}; + +// Helper struct to enable make_shared with private constructor +struct PwmFactory { + static std::shared_ptr Create(PwmRegisterMap* register_map, Pwm::Port port); }; } // namespace rpl diff --git a/include/rpl4/peripheral/spi.hpp b/include/rpl4/peripheral/spi.hpp index 1e04565..ade23b5 100644 --- a/include/rpl4/peripheral/spi.hpp +++ b/include/rpl4/peripheral/spi.hpp @@ -9,7 +9,15 @@ namespace rpl { -class Spi : public SpiBase { +// Forward declaration for factory +class Spi; + +// Helper struct to enable make_shared with private constructor +struct SpiFactory { + static std::shared_ptr Create(SpiRegisterMap* register_map); +}; + +class Spi : public SpiBase, public std::enable_shared_from_this { public: enum class Port : size_t { kSpi0 = 0, @@ -221,6 +229,9 @@ class Spi : public SpiBase { static std::array, kNumOfInstances> instances_; SpiRegisterMap* register_map_; + + // Allow factory struct to access private constructor + friend struct SpiFactory; }; } // namespace rpl diff --git a/src/peripheral/aux_spi.cpp b/src/peripheral/aux_spi.cpp index 8074ca8..ba87051 100644 --- a/src/peripheral/aux_spi.cpp +++ b/src/peripheral/aux_spi.cpp @@ -8,6 +8,13 @@ namespace rpl { +std::shared_ptr AuxSpiFactory::Create(AuxSpiRegisterMap* register_map) { + struct EnableMakeShared : public AuxSpi { + explicit EnableMakeShared(AuxSpiRegisterMap* reg_map) : AuxSpi(reg_map) {} + }; + return std::make_shared(register_map); +} + std::array, AuxSpi::kNumOfInstances> AuxSpi::instances_ = {nullptr}; @@ -17,12 +24,10 @@ std::shared_ptr AuxSpi::GetInstance(Port port) { } else if (instances_[static_cast(port)] == nullptr) { switch (port) { case Port::kAuxSpi1: - instances_[static_cast(port)] = - std::shared_ptr(new AuxSpi(REG_SPI1)); + instances_[static_cast(port)] = AuxSpiFactory::Create(REG_SPI1); break; case Port::kAuxSpi2: - instances_[static_cast(port)] = - std::shared_ptr(new AuxSpi(REG_SPI2)); + instances_[static_cast(port)] = AuxSpiFactory::Create(REG_SPI2); break; default: Log(LogLevel::Fatal, diff --git a/src/peripheral/dma.cpp b/src/peripheral/dma.cpp index c7cba9d..d3ee303 100644 --- a/src/peripheral/dma.cpp +++ b/src/peripheral/dma.cpp @@ -8,6 +8,13 @@ namespace rpl { +std::shared_ptr DmaFactory::Create(DmaRegisterMap* register_map, Dma::Channel channel) { + struct EnableMakeShared : public Dma { + EnableMakeShared(DmaRegisterMap* reg_map, Dma::Channel ch) : Dma(reg_map, ch) {} + }; + return std::make_shared(register_map, channel); +} + std::array, Dma::kNumOfInstances> Dma::instances_ = { nullptr}; @@ -69,7 +76,7 @@ std::shared_ptr Dma::GetInstance(Channel channel) { reg_map = REG_DMA14; break; } - instances_[index] = std::shared_ptr(new Dma(reg_map, channel)); + instances_[index] = DmaFactory::Create(reg_map, channel); } return instances_[index]; } diff --git a/src/peripheral/gpio.cpp b/src/peripheral/gpio.cpp index 6a34606..83cd404 100644 --- a/src/peripheral/gpio.cpp +++ b/src/peripheral/gpio.cpp @@ -5,6 +5,13 @@ namespace rpl { +std::shared_ptr GpioFactory::Create(uint8_t pin) { + struct EnableMakeShared : public Gpio { + explicit EnableMakeShared(uint8_t p) : Gpio(p) {} + }; + return std::make_shared(pin); +} + std::array, Gpio::kNumOfInstances> Gpio::instances_ = { nullptr}; @@ -17,7 +24,7 @@ std::shared_ptr Gpio::GetInstance(uint8_t pin) { if (!IsInitialized()) { Log(LogLevel::Error, "[Gpio::GetInstance()] RPL is not initialized."); } else if (instances_[static_cast(pin)] == nullptr) { - instances_[static_cast(pin)] = std::shared_ptr(new Gpio(pin)); + instances_[static_cast(pin)] = GpioFactory::Create(pin); } return instances_[static_cast(pin)]; } diff --git a/src/peripheral/pwm.cpp b/src/peripheral/pwm.cpp index 7e3ba5d..030d022 100644 --- a/src/peripheral/pwm.cpp +++ b/src/peripheral/pwm.cpp @@ -6,6 +6,13 @@ namespace rpl { +std::shared_ptr PwmFactory::Create(PwmRegisterMap* register_map, Pwm::Port port) { + struct EnableMakeShared : public Pwm { + EnableMakeShared(PwmRegisterMap* reg_map, Pwm::Port p) : Pwm(reg_map, p) {} + }; + return std::make_shared(register_map, port); +} + std::array, Pwm::kNumOfInstances> Pwm::instances_ = { nullptr}; @@ -28,7 +35,7 @@ std::shared_ptr Pwm::GetInstance(Port port) { reg_map = REG_PWM1; break; } - instances_[index] = std::shared_ptr(new Pwm(reg_map, port)); + instances_[index] = PwmFactory::Create(reg_map, port); } return instances_[index]; } diff --git a/src/peripheral/spi.cpp b/src/peripheral/spi.cpp index 02f06e4..c041abf 100644 --- a/src/peripheral/spi.cpp +++ b/src/peripheral/spi.cpp @@ -8,6 +8,13 @@ namespace rpl { +std::shared_ptr SpiFactory::Create(SpiRegisterMap* register_map) { + struct EnableMakeShared : public Spi { + explicit EnableMakeShared(SpiRegisterMap* reg_map) : Spi(reg_map) {} + }; + return std::make_shared(register_map); +} + std::array, Spi::kNumOfInstances> Spi::instances_ = { nullptr}; @@ -17,24 +24,19 @@ std::shared_ptr Spi::GetInstance(Port port) { } else if (instances_[static_cast(port)] == nullptr) { switch (port) { case Port::kSpi0: - instances_[static_cast(port)] = - std::shared_ptr(new Spi(REG_SPI0)); + instances_[static_cast(port)] = SpiFactory::Create(REG_SPI0); break; case Port::kSpi3: - instances_[static_cast(port)] = - std::shared_ptr(new Spi(REG_SPI3)); + instances_[static_cast(port)] = SpiFactory::Create(REG_SPI3); break; case Port::kSpi4: - instances_[static_cast(port)] = - std::shared_ptr(new Spi(REG_SPI4)); + instances_[static_cast(port)] = SpiFactory::Create(REG_SPI4); break; case Port::kSpi5: - instances_[static_cast(port)] = - std::shared_ptr(new Spi(REG_SPI5)); + instances_[static_cast(port)] = SpiFactory::Create(REG_SPI5); break; case Port::kSpi6: - instances_[static_cast(port)] = - std::shared_ptr(new Spi(REG_SPI6)); + instances_[static_cast(port)] = SpiFactory::Create(REG_SPI6); break; default: Log(LogLevel::Fatal,