AXP192 low level I2C mutexing
This commit is contained in:
parent
58ed680a92
commit
c93b0867a9
@ -19,6 +19,8 @@ void power_event_IRQ(void);
|
|||||||
void AXP192_power(bool on);
|
void AXP192_power(bool on);
|
||||||
void AXP192_init(void);
|
void AXP192_init(void);
|
||||||
void AXP192_showstatus(void);
|
void AXP192_showstatus(void);
|
||||||
|
uint8_t i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len);
|
||||||
|
uint8_t i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len);
|
||||||
#endif // HAS_PMU
|
#endif // HAS_PMU
|
||||||
|
|
||||||
#endif
|
#endif
|
212
src/power.cpp
212
src/power.cpp
@ -11,48 +11,41 @@ AXP20X_Class pmu;
|
|||||||
|
|
||||||
void power_event_IRQ(void) {
|
void power_event_IRQ(void) {
|
||||||
|
|
||||||
if (!I2C_MUTEX_LOCK())
|
pmu.readIRQ();
|
||||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
|
||||||
else {
|
|
||||||
|
|
||||||
pmu.readIRQ();
|
if (pmu.isVbusOverVoltageIRQ())
|
||||||
// put your power event handler code here
|
ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000);
|
||||||
|
if (pmu.isVbusPlugInIRQ())
|
||||||
|
ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000,
|
||||||
|
pmu.getVbusCurrent());
|
||||||
|
if (pmu.isVbusRemoveIRQ())
|
||||||
|
ESP_LOGI(TAG, "USB unplugged.");
|
||||||
|
|
||||||
if (pmu.isVbusOverVoltageIRQ())
|
if (pmu.isBattPlugInIRQ())
|
||||||
ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000);
|
ESP_LOGI(TAG, "Battery is connected.");
|
||||||
if (pmu.isVbusPlugInIRQ())
|
if (pmu.isBattRemoveIRQ())
|
||||||
ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000,
|
ESP_LOGI(TAG, "Battery was removed.");
|
||||||
pmu.getVbusCurrent());
|
if (pmu.isChargingIRQ())
|
||||||
if (pmu.isVbusRemoveIRQ())
|
ESP_LOGI(TAG, "Battery charging.");
|
||||||
ESP_LOGI(TAG, "USB unplugged.");
|
if (pmu.isChargingDoneIRQ())
|
||||||
|
ESP_LOGI(TAG, "Battery charging done.");
|
||||||
|
if (pmu.isBattTempLowIRQ())
|
||||||
|
ESP_LOGI(TAG, "Battery high temperature.");
|
||||||
|
if (pmu.isBattTempHighIRQ())
|
||||||
|
ESP_LOGI(TAG, "Battery low temperature.");
|
||||||
|
|
||||||
if (pmu.isBattPlugInIRQ())
|
// display on/off
|
||||||
ESP_LOGI(TAG, "Battery is connected.");
|
if (pmu.isPEKShortPressIRQ()) {
|
||||||
if (pmu.isBattRemoveIRQ())
|
cfg.screenon = !cfg.screenon;
|
||||||
ESP_LOGI(TAG, "Battery was removed.");
|
}
|
||||||
if (pmu.isChargingIRQ())
|
|
||||||
ESP_LOGI(TAG, "Battery charging.");
|
|
||||||
if (pmu.isChargingDoneIRQ())
|
|
||||||
ESP_LOGI(TAG, "Battery charging done.");
|
|
||||||
if (pmu.isBattTempLowIRQ())
|
|
||||||
ESP_LOGI(TAG, "Battery high temperature.");
|
|
||||||
if (pmu.isBattTempHighIRQ())
|
|
||||||
ESP_LOGI(TAG, "Battery low temperature.");
|
|
||||||
|
|
||||||
// display on/off
|
// shutdown power
|
||||||
if (pmu.isPEKShortPressIRQ()) {
|
if (pmu.isPEKLongtPressIRQ()) {
|
||||||
cfg.screenon = !cfg.screenon;
|
AXP192_power(false); // switch off Lora, GPS, display
|
||||||
}
|
pmu.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
// shutdown power
|
pmu.clearIRQ();
|
||||||
if (pmu.isPEKLongtPressIRQ()) {
|
|
||||||
AXP192_power(false); // switch off Lora, GPS, display
|
|
||||||
pmu.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
pmu.clearIRQ();
|
|
||||||
I2C_MUTEX_UNLOCK();
|
|
||||||
} // mutex
|
|
||||||
|
|
||||||
// refresh stored voltage value
|
// refresh stored voltage value
|
||||||
read_voltage();
|
read_voltage();
|
||||||
@ -75,70 +68,103 @@ void AXP192_power(bool on) {
|
|||||||
|
|
||||||
void AXP192_showstatus(void) {
|
void AXP192_showstatus(void) {
|
||||||
|
|
||||||
if (!I2C_MUTEX_LOCK())
|
if (pmu.isBatteryConnect())
|
||||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
if (pmu.isChargeing())
|
||||||
else {
|
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
|
||||||
|
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent());
|
||||||
if (pmu.isBatteryConnect())
|
|
||||||
if (pmu.isChargeing())
|
|
||||||
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
|
|
||||||
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent());
|
|
||||||
else
|
|
||||||
ESP_LOGI(TAG, "Battery not charging");
|
|
||||||
else
|
else
|
||||||
ESP_LOGI(TAG, "No Battery");
|
ESP_LOGI(TAG, "Battery not charging");
|
||||||
|
else
|
||||||
|
ESP_LOGI(TAG, "No Battery");
|
||||||
|
|
||||||
if (pmu.isVBUSPlug())
|
if (pmu.isVBUSPlug())
|
||||||
ESP_LOGI(TAG, "USB powered, %.0fmW",
|
ESP_LOGI(TAG, "USB powered, %.0fmW",
|
||||||
pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent());
|
pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent());
|
||||||
else
|
else
|
||||||
ESP_LOGI(TAG, "USB not present");
|
ESP_LOGI(TAG, "USB not present");
|
||||||
|
|
||||||
I2C_MUTEX_UNLOCK();
|
|
||||||
} // mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AXP192_init(void) {
|
void AXP192_init(void) {
|
||||||
|
|
||||||
// block i2c bus access
|
if (pmu.begin(i2c_readBytes, i2c_writeBytes, AXP192_PRIMARY_ADDRESS) == AXP_FAIL)
|
||||||
if (I2C_MUTEX_LOCK()) {
|
ESP_LOGI(TAG, "AXP192 PMU initialization failed");
|
||||||
|
else {
|
||||||
|
|
||||||
if (pmu.begin(Wire, AXP192_PRIMARY_ADDRESS))
|
// configure AXP192
|
||||||
ESP_LOGI(TAG, "AXP192 PMU initialization failed");
|
pmu.setDCDC1Voltage(3300); // for external OLED display
|
||||||
else {
|
pmu.setTimeOutShutdown(false); // no automatic shutdown
|
||||||
|
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); // TS pin mode off to save power
|
||||||
|
|
||||||
// configure AXP192
|
// switch ADCs on
|
||||||
pmu.setDCDC1Voltage(3300); // for external OLED display
|
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true);
|
||||||
pmu.setTimeOutShutdown(false); // no automatic shutdown
|
pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true);
|
||||||
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); // TS pin mode off to save power
|
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true);
|
||||||
|
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true);
|
||||||
|
|
||||||
// switch ADCs on
|
// switch power rails on
|
||||||
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true);
|
AXP192_power(true);
|
||||||
pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true);
|
|
||||||
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true);
|
|
||||||
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true);
|
|
||||||
|
|
||||||
// switch power rails on
|
|
||||||
AXP192_power(true);
|
|
||||||
|
|
||||||
// I2C access of AXP202X library currently is not mutexable
|
|
||||||
// so we better should disable AXP interrupts... ?
|
|
||||||
#ifdef PMU_INT
|
#ifdef PMU_INT
|
||||||
pinMode(PMU_INT, INPUT_PULLUP);
|
pinMode(PMU_INT, INPUT_PULLUP);
|
||||||
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
|
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
|
||||||
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
|
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
|
||||||
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ |
|
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ |
|
||||||
AXP202_CHARGING_FINISHED_IRQ,
|
AXP202_CHARGING_FINISHED_IRQ,
|
||||||
1);
|
1);
|
||||||
pmu.clearIRQ();
|
pmu.clearIRQ();
|
||||||
#endif // PMU_INT
|
#endif // PMU_INT
|
||||||
|
|
||||||
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
||||||
}
|
}
|
||||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
|
||||||
} else
|
|
||||||
ESP_LOGE(TAG, "I2c bus busy - PMU initialization error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper functions for mutexing i2c access
|
||||||
|
uint8_t i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
|
||||||
|
if (I2C_MUTEX_LOCK()) {
|
||||||
|
|
||||||
|
uint8_t ret = 0;
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.endTransmission(false);
|
||||||
|
uint8_t cnt = Wire.requestFrom(addr, (uint8_t)len, (uint8_t)1);
|
||||||
|
if (!cnt) {
|
||||||
|
ret = 0xFF;
|
||||||
|
}
|
||||||
|
uint16_t index = 0;
|
||||||
|
while (Wire.available()) {
|
||||||
|
if (index > len)
|
||||||
|
return 0xFF;
|
||||||
|
data[index++] = Wire.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
|
||||||
|
if (I2C_MUTEX_LOCK()) {
|
||||||
|
|
||||||
|
uint8_t ret = 0;
|
||||||
|
Wire.beginTransmission(addr);
|
||||||
|
Wire.write(reg);
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
Wire.write(data[i]);
|
||||||
|
}
|
||||||
|
ret = Wire.endTransmission();
|
||||||
|
|
||||||
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||||
|
return ret ? 0xFF : ret;
|
||||||
|
//return ret ? ret : 0xFF;
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // HAS_PMU
|
#endif // HAS_PMU
|
||||||
|
|
||||||
#ifdef BAT_MEASURE_ADC
|
#ifdef BAT_MEASURE_ADC
|
||||||
@ -196,12 +222,12 @@ uint16_t read_voltage() {
|
|||||||
uint16_t voltage = 0;
|
uint16_t voltage = 0;
|
||||||
|
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
if (!I2C_MUTEX_LOCK())
|
// if (!I2C_MUTEX_LOCK())
|
||||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
// ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||||
else {
|
// else {
|
||||||
voltage = pmu.isVBUSPlug() ? 0xffff : pmu.getBattVoltage();
|
voltage = pmu.isVBUSPlug() ? 0xffff : pmu.getBattVoltage();
|
||||||
I2C_MUTEX_UNLOCK();
|
// I2C_MUTEX_UNLOCK();
|
||||||
}
|
// }
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef BAT_MEASURE_ADC
|
#ifdef BAT_MEASURE_ADC
|
||||||
|
Loading…
Reference in New Issue
Block a user