Test voltage on VREF before enabling target power (mon tpwr), to avoid potential power conflict.

This commit is contained in:
Thiadmer Riemersma 2021-09-21 12:37:01 +02:00 committed by UweBonnes
parent 356325f563
commit 64f756d627
4 changed files with 43 additions and 10 deletions

View File

@ -393,8 +393,15 @@ static bool cmd_target_power(target *t, int argc, const char **argv)
} else if (argc == 2) {
bool want_enable = false;
if (parse_enable_or_disable(argv[1], &want_enable)) {
platform_target_set_power(want_enable);
gdb_outf("%s target power\n", want_enable ? "Enabling" : "Disabling");
if (want_enable
&& !platform_target_get_power()
&& platform_target_voltage_sense() > POWER_CONFLICT_THRESHOLD) {
/* want to enable target power, but VREF > 0.5V sensed -> cancel */
gdb_outf("Target already powered (%s)\n", platform_target_voltage());
} else {
platform_target_set_power(want_enable);
gdb_outf("%s target power\n", want_enable ? "Enabling" : "Disabling");
}
}
} else {
gdb_outf("Unrecognized command format\n");

View File

@ -37,7 +37,9 @@ void platform_timeout_set(platform_timeout *t, uint32_t ms);
bool platform_timeout_is_expired(platform_timeout *t);
void platform_delay(uint32_t ms);
#define POWER_CONFLICT_THRESHOLD 5 /* in 0.1V, so 5 stands for 0.5V */
extern bool connect_assert_srst;
uint32_t platform_target_voltage_sense(void);
const char *platform_target_voltage(void);
int platform_hwversion(void);
void platform_srst_set_val(bool assert);

View File

@ -251,12 +251,16 @@ static void adc_init(void)
adc_calibrate(ADC1);
}
const char *platform_target_voltage(void)
uint32_t platform_target_voltage_sense(void)
{
/* returns the voltage in volt scaled by 10 (so 33 means 3.3V), except
* for hardware version 1
* this function is only needed for implementations that allow the
* target to be powered from the debug probe
*/
if (platform_hwversion() == 0)
return gpio_get(GPIOB, GPIO0) ? "OK" : "ABSENT!";
return 0;
static char ret[] = "0.0V";
const uint8_t channel = 8;
adc_set_regular_sequence(ADC1, 1, (uint8_t*)&channel);
@ -265,9 +269,19 @@ const char *platform_target_voltage(void)
/* Wait for end of conversion. */
while (!adc_eoc(ADC1));
uint32_t val = adc_read_regular(ADC1) * 99; /* 0-4095 */
ret[0] = '0' + val / 81910;
ret[2] = '0' + (val / 8191) % 10;
uint32_t val = adc_read_regular(ADC1); /* 0-4095 */
return (val * 99) / 8191;
}
const char *platform_target_voltage(void)
{
if (platform_hwversion() == 0)
return gpio_get(GPIOB, GPIO0) ? "OK" : "ABSENT!";
static char ret[] = "0.0V";
uint32_t val = platform_target_voltage_sense();
ret[0] = '0' + val / 10;
ret[2] = '0' + val % 10;
return ret;
}

View File

@ -296,8 +296,18 @@ static void remotePacketProcessGEN(unsigned i, char *packet)
case REMOTE_PWR_SET:
#ifdef PLATFORM_HAS_POWER_SWITCH
platform_target_set_power(packet[2]=='1');
_respond(REMOTE_RESP_OK,0);
if (packet[2]=='1'
&& !platform_target_get_power()
&& platform_target_voltage_sense() > POWER_CONFLICT_THRESHOLD)
{
/* want to enable target power, but voltage > 0.5V sensed
* on the pin -> cancel
*/
_respond(REMOTE_RESP_ERR,0);
} else {
platform_target_set_power(packet[2]=='1');
_respond(REMOTE_RESP_OK,0);
}
#else
_respond(REMOTE_RESP_NOTSUP,0);
#endif