From 23a997898090d54da7c34dbe87823c316431f777 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 6 Mar 2023 08:58:05 +0100 Subject: [PATCH] VCC undervoltage check module --- src/config/config.h | 8 ++++++++ src/logic/error_codes.h | 2 ++ src/main.cpp | 2 ++ src/modules/CMakeLists.txt | 1 + src/modules/undervoltage_check.cpp | 26 ++++++++++++++++++++++++++ src/modules/undervoltage_check.h | 25 +++++++++++++++++++++++++ 6 files changed, 64 insertions(+) create mode 100644 src/modules/undervoltage_check.cpp create mode 100644 src/modules/undervoltage_check.h diff --git a/src/config/config.h b/src/config/config.h index cd2c499..eb28cd9 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -42,6 +42,14 @@ static constexpr const uint16_t buttonADCLimits[buttonCount][2] = { { 0, 50 }, { static constexpr const uint16_t buttonADCMaxValue = 1023; ///< used in unit tests static constexpr const uint8_t buttonsADCIndex = 5; ///< ADC index of buttons input +// VCC measurement setup +static constexpr const uint8_t VCCADCIndex = 30; ///< ADC index of scaled VCC input +static constexpr const uint16_t VCCADCThreshold = 274; ///< ADC value for triggering the UV_VCC error +/// We are measuring the bandgap voltage, Vb=1.1V. +/// To compute the threshold value: `VAL = 1125.3 / AVCC` +/// So for AVCC=4.1V, you get VAL=274.46 +static constexpr const uint8_t VCCADCReadCnt = 10; ///< Number of ADC reads to perform, only the last one being used + // Motion and planning /// Do not plan moves equal or shorter than the requested steps diff --git a/src/logic/error_codes.h b/src/logic/error_codes.h index 130e3be..8c7490f 100644 --- a/src/logic/error_codes.h +++ b/src/logic/error_codes.h @@ -118,4 +118,6 @@ enum class ErrorCode : uint_fast16_t { /// Unfixable possible cause: bad or cracked solder joints on the PCB, failed shift register, failed driver. MMU_SOLDERING_NEEDS_ATTENTION = 0xC200, + /// MCU VCC rail undervoltage. + MCU_UNDERVOLTAGE_VCC = 0xC400, }; diff --git a/src/main.cpp b/src/main.cpp index f6b407e..cc2cf57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,7 @@ #include "modules/timebase.h" #include "modules/motion.h" #include "modules/usb_cdc.h" +#include "modules/undervoltage_check.h" #include "application.h" @@ -167,6 +168,7 @@ void loop() { } hal::cpu::Step(); mu::cdc.Step(); + muv::uv_vcc.Step(); application.Step(); diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index c3ca5e7..8fd33fc 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources( serial.cpp speed_table.cpp timebase.cpp + undervoltage_check.cpp usb_cdc.cpp user_input.cpp ) diff --git a/src/modules/undervoltage_check.cpp b/src/modules/undervoltage_check.cpp new file mode 100644 index 0000000..db063b2 --- /dev/null +++ b/src/modules/undervoltage_check.cpp @@ -0,0 +1,26 @@ +/// @file undervoltage_check.cpp +#include "undervoltage_check.h" +#include "../hal/adc.h" +#include "../logic/error_codes.h" +#include "../panic.h" + +namespace modules { +namespace undervoltage_check { + +Undervoltage_check uv_vcc; + +void Undervoltage_check::Step() { + uint16_t vcc_val; + + // dummy reads are so that the final measurement is valid + for (uint8_t i = 0; i < config::VCCADCReadCnt; i++) { + vcc_val = hal::adc::ReadADC(config::VCCADCIndex); + } + + if (vcc_val > config::VCCADCThreshold) { + Panic(ErrorCode::MCU_UNDERVOLTAGE_VCC); + } +} + +} // namespace undervoltage_check +} // namespace modules diff --git a/src/modules/undervoltage_check.h b/src/modules/undervoltage_check.h new file mode 100644 index 0000000..cc9f7f6 --- /dev/null +++ b/src/modules/undervoltage_check.h @@ -0,0 +1,25 @@ +/// @file undervoltage_check.h +#pragma once + +#include +#include "../config/config.h" + +/// The modules namespace contains models of MMU's components +namespace modules { +namespace undervoltage_check { + +class Undervoltage_check { +public: + inline constexpr Undervoltage_check() = default; + + /// Reads the ADC, checks the value + void Step(); +}; + +/// The one and only instance of Undervoltage_check in the FW +extern Undervoltage_check uv_vcc; + +} // namespace undervoltage_check +} // namespace modules + +namespace muv = modules::undervoltage_check;