[ion] Update the battery sensing after schematics change

Change-Id: I2ecc4c3dc9a42afe0c602ef987918ac9722ccb31
This commit is contained in:
Romain Goyet
2017-01-09 11:31:00 +01:00
parent 6e01c55f1a
commit 3fb14a44ae
3 changed files with 35 additions and 11 deletions

View File

@@ -2,6 +2,14 @@
#include "battery.h"
#include "regs/regs.h"
/* To measure the battery voltage, we're using the internal ADC. The ADC works
* by comparing the input voltage to a reference voltage. The only fixed voltage
* we have around is 2.8V, so that's the one we're using as a refrence. However,
* and ADC can only measure voltage that is lower than the reference voltage. So
* we need to use a voltage divider before sampling Vbat.
* To avoid draining the battery, we're using an high-impedence voltage divider,
* so we need to be careful when sampling the ADC. See AN2834 for more info. */
namespace Ion {
namespace Battery {
@@ -19,7 +27,6 @@ float voltage() {
return Device::ADCDividerBridgeRatio*(Device::ADCReferenceVoltage * value)/0xFFF;
}
}
}
@@ -43,6 +50,10 @@ void initGPIO() {
/* The BAT_SNS pin is connected to Vbat through a divider bridge. It therefore
* has a voltage of Vbat/2. We'll measure this using ADC channel 0. */
ADCGPIO.MODER()->setMode(ADCPin, GPIO::MODER::Mode::Analog);
ADC.SMPR()->setSamplingTime(ADCChannel, ADC::SMPR::SamplingTime::Cycles480);
// ADC.SQR1()->setL(0); // Default
ADC.SQR3()->setSQ1(ADCChannel);
}
void initADC() {

View File

@@ -9,19 +9,20 @@ namespace Device {
/* Pin | Role | Mode | Function
* -----+-------------------+-----------------------+----------
* PA0 | BAT_SNS | Analog | ADC1_0
* PC2 | BAT_CHRG | Input, pulled up |
* PA0 | BAT_CHRG | Input, pulled up | Low = charging, high = full
* PA1 | VBAT_SNS | Analog | ADC1_1
*/
void init();
void initGPIO();
void initADC();
constexpr GPIO ChargingGPIO = GPIOC;
constexpr uint8_t ChargingPin = 2;
constexpr GPIO ChargingGPIO = GPIOA;
constexpr uint8_t ChargingPin = 0;
constexpr GPIO ADCGPIO = GPIOA;
constexpr uint8_t ADCPin = 0;
constexpr uint8_t ADCPin = 1;
constexpr uint8_t ADCChannel = 1;
constexpr float ADCReferenceVoltage = 2.8f;
constexpr float ADCDividerBridgeRatio = 2.0f;

View File

@@ -19,7 +19,7 @@ public:
REGS_BOOL_FIELD(ADON, 0);
REGS_BOOL_FIELD(SWSTART, 30);
};
#if 0
class SMPR : Register64 {
/* The SMPR register doesn't exist per-se in the documentation. It is the
* consolidation of SMPR1 and SMPR2 which are two 32-bit registers. */
@@ -34,14 +34,23 @@ public:
Cycles144 = 6,
Cycles480 = 7
};
SamplingTime setSamplingTime(int channel) {
return (SamplingTime)getBitRange(3*index+2, 3*index);
SamplingTime getSamplingTime(int channel) {
return (SamplingTime)getBitRange(3*channel+2, 3*channel);
}
void setSamplingTime(int channel, SamplingTime t) volatile {
setBitRange(3*index+2, 3*index, (uint64_t)t);
setBitRange(3*channel+2, 3*channel, (uint64_t)t);
}
};
#endif
class SQR1 : Register32 {
public:
REGS_FIELD(L, uint8_t, 23, 20);
};
class SQR3 : Register32 {
public:
REGS_FIELD(SQ1, uint8_t, 4, 0);
};
class DR : public Register16 {
};
@@ -49,6 +58,9 @@ public:
constexpr ADC() {};
REGS_REGISTER_AT(SR, 0x0);
REGS_REGISTER_AT(CR2, 0x08);
REGS_REGISTER_AT(SMPR, 0x0C);
REGS_REGISTER_AT(SQR1, 0x2C);
REGS_REGISTER_AT(SQR3, 0x34);
REGS_REGISTER_AT(DR, 0x4C);
private:
constexpr uint32_t Base() const {