Skip to content

Commit

Permalink
RP2040: Monitor board supply voltage and warn if voltage drops too low.
Browse files Browse the repository at this point in the history
This helps detect issues with inadequate power supply.
  • Loading branch information
PetteriAimonen authored and erichelgeson committed May 6, 2023
1 parent 2cef5a3 commit 6dd37e3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
48 changes: 48 additions & 0 deletions lib/BlueSCSI_platform_RP2040/BlueSCSI_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <hardware/gpio.h>
#include <hardware/uart.h>
#include <hardware/spi.h>
#include <hardware/adc.h>
#include <hardware/flash.h>
#include <hardware/structs/xip_ctrl.h>
#include <hardware/structs/usb.h>
Expand Down Expand Up @@ -352,6 +353,51 @@ static void usb_log_poll()
}
}

// Use ADC to implement supply voltage monitoring for the +3.0V rail.
// This works by sampling the temperature sensor channel, which has
// a voltage of 0.7 V, allowing to calculate the VDD voltage.
static void adc_poll()
{
#if PLATFORM_VDD_WARNING_LIMIT_mV > 0
static bool initialized = false;
static int lowest_vdd_seen = PLATFORM_VDD_WARNING_LIMIT_mV;

if (!initialized)
{
adc_init();
adc_set_temp_sensor_enabled(true);
adc_set_clkdiv(65535); // Lowest samplerate, about 2 kHz
adc_select_input(4);
adc_fifo_setup(true, false, 0, false, false);
adc_run(true);
initialized = true;
}

int adc_value_max = 0;
while (!adc_fifo_is_empty())
{
int adc_value = adc_fifo_get();
if (adc_value > adc_value_max) adc_value_max = adc_value;
}

// adc_value = 700mV * 4096 / Vdd
// => Vdd = 700mV * 4096 / adc_value
// To avoid wasting time on division, compare against
// limit directly.
const int limit = (700 * 4096) / PLATFORM_VDD_WARNING_LIMIT_mV;
if (adc_value_max > limit)
{
// Warn once, and then again if we detect even a lower drop.
int vdd_mV = (700 * 4096) / adc_value_max;
if (vdd_mV < lowest_vdd_seen)
{
log("WARNING: Detected supply voltage drop to ", vdd_mV, "mV. Verify power supply is adequate.");
lowest_vdd_seen = vdd_mV - 50; // Small hysteresis to avoid excessive warnings
}
}
#endif
}

// This function is called for every log message.
void platform_log(const char *s)
{
Expand Down Expand Up @@ -444,6 +490,8 @@ void platform_reset_watchdog()
}

usb_log_poll();

adc_poll();
}

/*****************************************/
Expand Down
4 changes: 4 additions & 0 deletions lib/BlueSCSI_platform_RP2040/BlueSCSI_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ extern const char *g_platform_name;
#define SD_USE_SDIO 1
#define PLATFORM_HAS_INITIATOR_MODE 1

#ifndef PLATFORM_VDD_WARNING_LIMIT_mV
#define PLATFORM_VDD_WARNING_LIMIT_mV 2800
#endif

// NOTE: The driver supports synchronous speeds higher than 10MB/s, but this
// has not been tested due to lack of fast enough SCSI adapter.
// #define PLATFORM_MAX_SCSI_SPEED S2S_CFG_SPEED_TURBO
Expand Down

0 comments on commit 6dd37e3

Please sign in to comment.