summaryrefslogtreecommitdiff
path: root/src/drivers/adc.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-28 13:26:53 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-28 13:26:53 +1000
commit3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5 (patch)
tree0505db40de6fceaf5829548ef86f4cb53b739bcb /src/drivers/adc.cpp
parenta1327763ab70dbf4996e032dd227de368f78f4ad (diff)
downloadtangara-fw-3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5.tar.gz
Move battery measurement to its own class
Diffstat (limited to 'src/drivers/adc.cpp')
-rw-r--r--src/drivers/adc.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/drivers/adc.cpp b/src/drivers/adc.cpp
new file mode 100644
index 00000000..56d2cbb4
--- /dev/null
+++ b/src/drivers/adc.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "adc.hpp"
+#include <cstdint>
+
+#include "esp_adc/adc_cali.h"
+#include "esp_adc/adc_cali_scheme.h"
+#include "esp_adc/adc_oneshot.h"
+#include "hal/adc_types.h"
+
+namespace drivers {
+
+static const adc_bitwidth_t kAdcBitWidth = ADC_BITWIDTH_12;
+static const adc_unit_t kAdcUnit = ADC_UNIT_1;
+// Max battery voltage should be a little over 2V due to our divider, so we need
+// the max attenuation to properly handle the full range.
+static const adc_atten_t kAdcAttenuation = ADC_ATTEN_DB_11;
+// Corresponds to SENSOR_VP.
+static const adc_channel_t kAdcChannel = ADC_CHANNEL_0;
+
+AdcBattery::AdcBattery() {
+ adc_oneshot_unit_init_cfg_t unit_config = {
+ .unit_id = kAdcUnit,
+ };
+ ESP_ERROR_CHECK(adc_oneshot_new_unit(&unit_config, &adc_handle_));
+
+ adc_oneshot_chan_cfg_t channel_config = {
+ .atten = kAdcAttenuation,
+ .bitwidth = kAdcBitWidth,
+ };
+ ESP_ERROR_CHECK(
+ adc_oneshot_config_channel(adc_handle_, kAdcChannel, &channel_config));
+
+ // calibrate
+ // TODO: compile-time assert our scheme is available
+ adc_cali_line_fitting_config_t calibration_config = {
+ .unit_id = kAdcUnit,
+ .atten = kAdcAttenuation,
+ .bitwidth = kAdcBitWidth,
+ };
+ ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting(
+ &calibration_config, &adc_calibration_handle_));
+}
+
+AdcBattery::~AdcBattery() {
+ adc_cali_delete_scheme_line_fitting(adc_calibration_handle_);
+ ESP_ERROR_CHECK(adc_oneshot_del_unit(adc_handle_));
+}
+
+auto AdcBattery::Millivolts() -> uint32_t {
+ // GPIO 34
+ int raw = 0;
+ ESP_ERROR_CHECK(adc_oneshot_read(adc_handle_, kAdcChannel, &raw));
+
+ int voltage = 0;
+ ESP_ERROR_CHECK(
+ adc_cali_raw_to_voltage(adc_calibration_handle_, raw, &voltage));
+
+ // Voltage divider halves the battery voltage to get it into the ADC's range.
+ return voltage * 2;
+}
+
+} // namespace drivers