Files
bagdewitch/src/menu.c
2026-02-07 22:54:19 +00:00

132 lines
3.5 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include "CH58x_common.h"
#include "CH58x_sys.h"
#include "CH58xBLE_LIB.h"
#include "usb/core.h"
#include "led.h"
#include "ble.h"
#include "input.h"
#include "wang.h"
#include "screen.h"
#include "img/menu.xbm"
static void boop()
{
WWDG_ResetCfg(DISABLE);
PFIC_DisableIRQ(TMR0_IRQn);
PFIC_DisableIRQ(TMR3_IRQn);
// Stop wasting energy
GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_Floating);
GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_Floating);
GPIOA_ModeCfg(GPIO_Pin_1, GPIO_ModeIN_PD);
while (GPIOA_ReadPortPin(GPIO_Pin_1)) DelayMs(1);
DelayMs(100);
// 0 to 1 (pulldown, so implies being _pressed_)
// however, this doesn't work?
GPIOA_ITModeCfg(GPIO_Pin_1, GPIO_ITMode_HighLevel);
PFIC_EnableIRQ(GPIO_A_IRQn);
// Wait for shit to settle
while (GPIOA_ReadPortPin(GPIO_Pin_1)) DelayMs(1);
PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
/* Good bye */
LowPower_Shutdown(0);
}
static void render_xbm(uint8_t *bits, struct row_buf *b) {
uint16_t fb[45] = {0};
int index = 0;
for (int j = 0; j < 11; j++) {
index = j * 48;
for (int i = 0; i < 44; i++) {
int bit = bits[index / 8] & (1 << (index % 8));
if (!bit) fb[i] |= (1 << j);
index++;
}
}
display_make_buf_all(fb, b);
}
static int menu_index = 0;
static int menu_ticks = 0;
static void menu_event(struct screen_event event) {
if (event.type == SE_TICK) {
if (menu_ticks++ > 125) {
screen_dirty = 1;
}
} else if (event.type == SE_BUTTON_PRESS) {
if (event.data == 0) {
menu_index = (menu_index + 1) % 3;
if (!flash_header_valid && !menu_index) menu_index = 1;
screen_dirty = 1;
} else if (event.data == 1) {
if (menu_index == 0) {
screen_pop();
return;
} else if (menu_index == 1) {
ble_toggle();
screen_dirty = 1;
} else if (menu_index == 2) {
boop();
}
}
}
}
static void menu_draw(struct row_buf *rb) {
uint8_t buffer[(48 * 11) / 8];
memcpy(buffer, menu_bits, sizeof(buffer));
int invert_index = 1 + menu_index * 13;
for (int i = invert_index; i < (invert_index + 9); i++) {
for (int j = 1; j < 10; j++)
buffer[(i / 8) + (j * 48 / 8)] ^= (1 << (i % 8));
}
int batt_percent = ((get_battery_percentage() + 7) * 10) / 100;
int charge = is_charging() || is_plugged();
for (int i = 39; i < 43; i++) {
for (int j = 0; j < 10; j++) {
int index = 10 - j;
if (j <= batt_percent) {
buffer[(i / 8) + (index * 48 / 8)] &= ~(1 << (i % 8));
} else if (charge && (j - 2) <= batt_percent) {
if (i % 2 == j % 2)
buffer[(i / 8) + (index * 48 / 8)] &= ~(1 << (i % 8));
}
}
}
if (!ble_on) {
#define PIX(x, y) buffer[((x) / 8) + ((y) * 48 / 8)] |= (1 << ((x) % 8))
for (int i = 0; i < 11; i += 2) {
PIX(13 + i, 0);
PIX(13 + i, 10);
PIX(13, i);
PIX(23, i);
}
}
if (!flash_header_valid) {
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
PIX(i, j);
}
}
}
render_xbm(buffer, rb);
menu_ticks = 0;
}
struct screen menu_screen = {
menu_draw,
menu_event,
};