Skip to content

Commit a4a5c03

Browse files
committed
ARMmbed#62 Take ADC measurements for VIN and battery
1 parent 6a60f2b commit a4a5c03

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

source/board/microbitv2/microbitv2.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,11 @@ static void i2c_write_comms_callback(uint8_t* pData, uint8_t size) {
638638
memcpy(&i2cResponse.cmdData.readRspCmd.data, &power_source, sizeof(power_source));
639639
break;
640640
case gPowerConsumption_c: {
641-
uint32_t power_consumption = 1;
642-
i2cResponse.cmdData.readRspCmd.dataSize = sizeof(power_consumption);
643-
memcpy(&i2cResponse.cmdData.readRspCmd.data, &power_consumption, sizeof(power_consumption));
641+
uint32_t vin_voltage_uv = pwr_mon_get_vin_mv() * 1000;
642+
uint32_t vbat_voltage_uv = pwr_mon_get_vbat_mv() * 1000;
643+
i2cResponse.cmdData.readRspCmd.dataSize = sizeof(vin_voltage_uv) + sizeof(vbat_voltage_uv);
644+
memcpy(&i2cResponse.cmdData.readRspCmd.data[0], &vbat_voltage_uv, sizeof(vbat_voltage_uv));
645+
memcpy(&i2cResponse.cmdData.readRspCmd.data[sizeof(vbat_voltage_uv)], &vin_voltage_uv, sizeof(vin_voltage_uv));
644646
}
645647
break;
646648
case gUSBEnumerationState_c:

source/board/microbitv2/pwr_mon.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#define BATT_MIN_VOLTAGE 1500
2020

2121
void pwr_mon_bandgap_init(void);
22-
uint32_t pwr_mon_read_vbg(uint32_t channelGroup);
23-
uint32_t pwr_mon_adc_to_mv(uint32_t raw_adc);
22+
static uint32_t pwr_mon_read_vbg(uint32_t channelGroup);
23+
static uint32_t pwr_mon_adc_to_mv(uint32_t raw_adc);
2424

2525
void pwr_mon_init(void)
2626
{
@@ -40,21 +40,14 @@ void pwr_mon_init(void)
4040
power_source_t pwr_mon_get_power_source(void) {
4141
power_source_t power_source = PWR_SOURCE_NONE;
4242
uint32_t bat_voltage_mv = 0;
43-
// Detect if device is battery powered
44-
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 1);
45-
// Add a ~3ms delay to allow the 100nF capacitors to charge to about 3*RC.
46-
// 3 clock cycles per loop at -O2 ARMCC optimization
47-
for (uint32_t count = 48000; count > 0UL; count--);
48-
uint32_t bat_adc = adc_read_channel(0, PIN_VMON_BAT_ADC_CH, PIN_VMON_BAT_ADC_MUX);
49-
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 0);
50-
43+
44+
// Read WAKE_ON_EDGE pin for detecting if board is USB powered
5145
bool usb_on = (((PIN_WAKE_ON_EDGE_GPIO->PDIR) >> PIN_WAKE_ON_EDGE_BIT) & 0x01U) ? false : true;
5246

53-
// Compensate for voltage divider with ratio of 11
54-
bat_adc = bat_adc * 11;
55-
56-
bat_voltage_mv = pwr_mon_adc_to_mv(bat_adc);
47+
// Read battery voltage
48+
bat_voltage_mv = pwr_mon_get_vbat_mv();
5749

50+
// Get power source based on battery and USB
5851
if (usb_on == true && bat_voltage_mv < (BATT_MIN_VOLTAGE)) {
5952
power_source = PWR_USB_ONLY;
6053
} else if (usb_on == true && bat_voltage_mv >= (BATT_MIN_VOLTAGE)) {
@@ -68,23 +61,39 @@ power_source_t pwr_mon_get_power_source(void) {
6861
return power_source;
6962
}
7063

71-
uint32_t pwr_mon_vcc_mv(void) {
72-
// ADC read the Vref (same as Vcc) and the Vbg 1V internal reference
64+
uint32_t pwr_mon_get_vbat_mv(void) {
65+
// Enable voltage divider to take measurement
66+
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 1);
67+
// Add a ~3ms delay to allow the 100nF capacitors to charge to about 3*RC.
68+
// 3 clock cycles per loop at -O2 ARMCC optimization
69+
for (uint32_t count = 48000; count > 0UL; count--);
70+
uint32_t bat_adc = adc_read_channel(0, PIN_VMON_BAT_ADC_CH, PIN_VMON_BAT_ADC_MUX);
71+
// Disable voltage divider
72+
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 0);
73+
74+
// Compensate for voltage divider with ratio of 11
75+
bat_adc = bat_adc * 11;
76+
77+
return pwr_mon_adc_to_mv(bat_adc);
78+
}
79+
80+
uint32_t pwr_mon_get_vin_mv(void) {
81+
// ADC read the Vref (same as Vdda) and the Vbg 1V internal reference
7382
uint32_t vref_high = adc_read_channel(0, ADC_VREFH_CHANNEL, ADC_VREFH_MUX);
7483
uint32_t ref_volt = pwr_mon_read_vbg(0);
7584

7685
// Reference voltage is 1V, scale to millivolts
7786
return vref_high * 1000 / ref_volt;
7887
}
7988

80-
void pwr_mon_bandgap_init(void) {
89+
static void pwr_mon_bandgap_init(void) {
8190
pmc_bandgap_buffer_config_t pmcBandgapConfig;
8291
pmcBandgapConfig.enable = true;
8392
pmcBandgapConfig.enableInLowPowerMode = false;
8493
PMC_ConfigureBandgapBuffer(PMC, &pmcBandgapConfig);
8594
}
8695

87-
uint32_t pwr_mon_read_vbg(uint32_t channelGroup) {
96+
static uint32_t pwr_mon_read_vbg(uint32_t channelGroup) {
8897
// Ensure the Vbg is enabled from first use only
8998
static bool bandgap_enabled = false;
9099
if (!bandgap_enabled) {
@@ -94,7 +103,7 @@ uint32_t pwr_mon_read_vbg(uint32_t channelGroup) {
94103
return adc_read_channel(channelGroup, ADC_VBG_CHANNEL, ADC_VBG_MUX);
95104
}
96105

97-
uint32_t pwr_mon_adc_to_mv(uint32_t raw_adc)
106+
static uint32_t pwr_mon_adc_to_mv(uint32_t raw_adc)
98107
{
99108
// ADC read Vbg, a 1V internal reference
100109
uint32_t ref_volt_read = pwr_mon_read_vbg(0);

source/board/microbitv2/pwr_mon.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ typedef enum {
2121

2222
void pwr_mon_init(void);
2323
power_source_t pwr_mon_get_power_source(void);
24-
uint32_t pwr_mon_vcc_mv(void);
24+
uint32_t pwr_mon_get_vin_mv(void);
25+
uint32_t pwr_mon_get_vbat_mv(void);
2526

2627

2728
#ifdef __cplusplus

0 commit comments

Comments
 (0)