feat(pa01): add long-press power-on and improve charging indication (#6885)

This commit is contained in:
sneone
2025-12-20 13:17:02 +10:00
committed by GitHub
parent c795b76bfd
commit 2ec48d23f9
5 changed files with 160 additions and 89 deletions
+71 -60
View File
@@ -412,13 +412,57 @@ void rgbPowerOn(uint8_t color) {
power_on_step++;
}
#define BRIGHTNESS_MAX 255
void rgbBatteryDis(uint8_t color, uint8_t power_level ) {
switch (power_level)
{
case POWER_LEVEL_CRITICAL:
setLedGroupColor(0, color, 0);
setLedGroupColor(1, color, 0);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
break;
case POWER_LEVEL_LOW:
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, 0);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
break;
case POWER_LEVEL_MEDIUM:
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, 0);
setLedGroupColor(3, color, 0);
break;
case POWER_LEVEL_HIGH:
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, BRIGHTNESS_MAX);
setLedGroupColor(3, color, 0);
break;
case POWER_LEVEL_NEAR_FULL:
case POWER_LEVEL_FULL:
setLedGroupColor(0, color, BRIGHTNESS_MAX);
setLedGroupColor(1, color, BRIGHTNESS_MAX);
setLedGroupColor(2, color, BRIGHTNESS_MAX);
setLedGroupColor(3, color, BRIGHTNESS_MAX);
break;
default:
break;
}
setLedGroupColor(4, color, BRIGHTNESS_MAX);
setLedGroupColor(5, color, BRIGHTNESS_MAX);
setLedGroupColor(6, color, BRIGHTNESS_MAX);
}
void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
uint8_t color = 0;
uint8_t breath_index = 0;
switch (power_level)
{
case POWER_LEVEL_CRITICAL:
color = RGB_COLOR_NONE;
color = RGB_COLOR_RED;
if (rgb_state == RGB_STATE_CHARGE) {
color = RGB_COLOR_RED;
breath_index |= RGB_GROUP_MASK_FUNC_1;
@@ -429,7 +473,7 @@ void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
break;
case POWER_LEVEL_LOW:
color = RGB_COLOR_RED;
color = RGB_COLOR_PURPLE;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_1;
setLedGroupColor(1, color, 0);
@@ -439,7 +483,7 @@ void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
break;
case POWER_LEVEL_MEDIUM:
color = RGB_COLOR_PURPLE;
color = RGB_COLOR_YELLOW;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_2;
setLedGroupColor(0, color, CHARGING_BRIGHT);
@@ -449,7 +493,7 @@ void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
break;
case POWER_LEVEL_HIGH:
color = RGB_COLOR_YELLOW;
color = RGB_COLOR_GREEN;
if (rgb_state == RGB_STATE_CHARGE) {
breath_index |= RGB_GROUP_MASK_FUNC_3;
setLedGroupColor(0, color, CHARGING_BRIGHT);
@@ -477,7 +521,6 @@ void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
setLedGroupColor(3, color, CHARGING_BRIGHT);
}
break;
default:
break;
}
@@ -496,7 +539,8 @@ void rgbBatteryLevelInfo(uint8_t power_level, uint8_t rgb_state) {
case RGB_STATE_POWER_ON:
rgbPowerOn(color);
break;
case RGB_STATE_BAT_DIS:
rgbBatteryDis(color, power_level);
default:
break;
}
@@ -594,7 +638,7 @@ void ledLoop(void) {
led_info.led_state = RGB_STATE_NONE;
rgbLedClearAll();
return;
} else if (led_info.led_state == RGB_STATE_POWER_ON) {
} else if ( led_info.led_state == RGB_STATE_POWER_ON || led_info.led_state == RGB_STATE_BAT_DIS ) {
rgbLedColorApply();
return;
} else if (led_info.led_state == RGB_STATE_NONE) {
@@ -610,67 +654,34 @@ void rgbChargeInit(void) {
rgbLedClearAll();
}
constexpr uint16_t vbatLedTable[] = {660, 720, 760, 800, 823};
constexpr uint16_t HYSTERESIS = 5;
constexpr uint16_t vbatLedTable[] = {650, 720, 760, 800, 823 };
void updateBatteryState(uint8_t rgb_state) {
uint16_t bat_v = getBatteryVoltage();
uint16_t bat_v = getBatteryVoltage()*BAT_VOL_FACTOR;
uint8_t power_level = POWER_LEVEL_NONE;
static uint8_t last_power_level = POWER_LEVEL_NONE;
uint16_t current_level_min = 0;
uint16_t current_level_max = 0;
bool need_update = true;
if (last_power_level != POWER_LEVEL_NONE) {
switch (last_power_level) {
case POWER_LEVEL_CRITICAL:
current_level_min = 0;
current_level_max = vbatLedTable[0] + HYSTERESIS;
break;
case POWER_LEVEL_LOW:
current_level_min = vbatLedTable[0] - HYSTERESIS;
current_level_max = vbatLedTable[1] + HYSTERESIS;
break;
case POWER_LEVEL_MEDIUM:
current_level_min = vbatLedTable[1] - HYSTERESIS;
current_level_max = vbatLedTable[2] + HYSTERESIS;
break;
case POWER_LEVEL_HIGH:
current_level_min = vbatLedTable[2] - HYSTERESIS;
current_level_max = vbatLedTable[3] + HYSTERESIS;
break;
case POWER_LEVEL_NEAR_FULL:
current_level_min = vbatLedTable[3] - HYSTERESIS;
current_level_max = vbatLedTable[4] + HYSTERESIS;
break;
case POWER_LEVEL_FULL:
current_level_min = vbatLedTable[4] - HYSTERESIS;
current_level_max = UINT16_MAX;
break;
default:
need_update = true;
}
if (bat_v < vbatLedTable[0]) {
power_level = POWER_LEVEL_CRITICAL;
} else if (bat_v < vbatLedTable[1]) {
power_level = POWER_LEVEL_LOW;
} else if (bat_v < vbatLedTable[2]) {
power_level = POWER_LEVEL_MEDIUM;
} else if (bat_v < vbatLedTable[3]) {
power_level = POWER_LEVEL_HIGH;
}else if (bat_v < vbatLedTable[4]) {
power_level = POWER_LEVEL_NEAR_FULL;
} else {
power_level = POWER_LEVEL_FULL;
}
if (bat_v >= current_level_min && bat_v <= current_level_max) {
need_update = false;
power_level = last_power_level;
if( last_power_level != POWER_LEVEL_NONE )
{
if(power_level<last_power_level)
{
power_level=last_power_level;
}
}
if (need_update) {
if (bat_v < vbatLedTable[0]) {
power_level = POWER_LEVEL_CRITICAL;
} else if (bat_v < vbatLedTable[1]) {
power_level = POWER_LEVEL_LOW;
} else if (bat_v < vbatLedTable[2]) {
power_level = POWER_LEVEL_MEDIUM;
} else if (bat_v < vbatLedTable[3]) {
power_level = POWER_LEVEL_HIGH;
} else if (bat_v < vbatLedTable[4]){
power_level = POWER_LEVEL_NEAR_FULL;
} else {
power_level = POWER_LEVEL_FULL;
}
}
rgbBatteryLevelInfo(power_level, rgb_state);
ledLoop();
last_power_level = power_level;
+2
View File
@@ -45,6 +45,8 @@ enum PowerLevel {
POWER_LEVEL_FULL,
};
#define BAT_VOL_FACTOR (1.038)
extern void battery_charge_init();
extern void handle_battery_charge(uint32_t last_press_time);
extern uint16_t get_battery_charge_state();
+85 -28
View File
@@ -276,44 +276,101 @@ void boardInit()
}
#else
uint32_t press_start = 0;
uint32_t press_end = 0;
rotenc_t lastEncoderValue = 0;
if (UNEXPECTED_SHUTDOWN()) {
pwrOn();
} else if (isChargerActive()) {
while (true) {
pwrOn();
uint32_t now = timersGetMsTick();
if (pwrPressed()) {
press_end = now;
if (press_start == 0) press_start = now;
if ((now - press_start) > POWER_ON_DELAY) {
} else {
pwrOn();
hapticInit();
// Init debounce
pwrPressedDebounced();
pwrPressedDebounced();
uint32_t adc_sample_time = 0; // Hardware ADC sample tick
uint32_t led_start_time = 0;
uint32_t led_start_time1 = 0;
uint32_t start_time = timersGetMsTick();
uint32_t pwrPressed_start_time = 0;
uint32_t now = 0;
uint8_t is_charging = 0;
uint8_t is_pwrPressed = 0;
while(1)
{
now = timersGetMsTick();
if (now - adc_sample_time > 10)
{
adc_sample_time = now;
getADC();
is_charging &= 0xFE;
is_charging |= isChargerActive();
is_pwrPressed &= 0xFE;
is_pwrPressed |= pwrPressedDebounced();
if( 0x03 == (is_pwrPressed & 0x03) )
{
led_start_time = now;
led_start_time1 = now;
}
switch( is_charging & 0x03 )
{
case 0x02:
rgbLedClearAll();
led_start_time1 = now;
case 0x00:
{
start_time = now;
led_start_time = 0;
if(now-led_start_time1<6000)
{
updateBatteryState(RGB_STATE_BAT_DIS);
}
else
{
if( 0==(is_pwrPressed & 0x03))
{
rgbLedClearAll();
boardOff();
}
}
}
break;
case 0x01: led_start_time = now;
case 0x03:
{
if( (led_start_time && now-led_start_time<6000) || (!led_start_time && now-start_time<6000) )
{
updateBatteryState(RGB_STATE_CHARGE);
}
else
{
rgbLedClearAll();
}
}
break;
default: break;
}
} else if (!isChargerActive()) {
boardOff();
} else {
uint32_t press_end_touch = press_end;
extern void rotaryEncoderCheck();
rotaryEncoderCheck();
rotenc_t value = rotaryEncoderGetValue();
if (value != lastEncoderValue) {
lastEncoderValue = value;
press_end_touch = timersGetMsTick();
if( !pwrPressed_start_time && 0x03 == (is_pwrPressed & 0x03) )
{
pwrPressed_start_time = now;
}
press_start = 0;
handle_battery_charge(press_end_touch);
delay_ms(10);
press_end = 0;
else if( 0x00 == (is_pwrPressed & 0x03) )
{
pwrPressed_start_time = 0;
}
if(pwrPressed_start_time && now-pwrPressed_start_time>1500 )
{
rgbLedClearAll();
break; //power on
}
is_pwrPressed <<= 1;
is_charging <<= 1;
}
}
battery_charge_end();
}
#endif
#endif
rgbLedInit();
rgbLedClearAll();
keysInit();
+1
View File
@@ -253,6 +253,7 @@ enum rgb_state_e {
RGB_STATE_OFF,
RGB_STATE_POWER_ON,
RGB_STATE_POWER_OFF,
RGB_STATE_BAT_DIS,
};
enum rgb_color_e {
+1 -1
View File
@@ -209,7 +209,7 @@
// Power
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOE, 6) // PE.06
#define PWR_ON_GPIO GPIO_PIN(GPIOE, 3) // PE.03
#define SHORT_LONG_PRESS
// #define SHORT_LONG_PRESS
// USB Chargers
#define UCHARGER_GPIO GPIO_PIN(GPIOB, 0) // PB.00