mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Merge "[ion] Update the battery sensing after schematics change"
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user