New compile file

This commit is contained in:
Carl Vargklint 2026-07-18 14:09:06 +02:00
parent 5727751ea0
commit 4fe1405411
6 changed files with 3225 additions and 2969 deletions

BIN
tama.bin

Binary file not shown.

50
tama.c
View File

@ -89,21 +89,31 @@ static uint8_t evo_anim; // frames remaining for an evolution banner
// settings // settings
static uint8_t sound_on = 1; static uint8_t sound_on = 1;
static uint8_t timeout_idx = 1; // index into screen_timeout_opts (default 10 s) static uint8_t timeout_idx = 1; // index into screen_timeout_opts (default 10 s)
static uint8_t bright_idx = 1; // index into brightness_opts (default Med)
static uint8_t set_sel = 0; // highlighted row on the settings screen static uint8_t set_sel = 0; // highlighted row on the settings screen
static uint8_t sel_species = 0; // highlighted species on the welcome screen static uint8_t sel_species = 0; // highlighted species on the welcome screen
// OLED contrast (brightness) levels written to SSD1306_SETCONTRAST (0x81).
// Lower also means less charge-pump current, which is gentler on the coin cell.
static const uint8_t brightness_opts[] = { 0x01, 0x30, 0x80, 0xCF };
static const char *const brightness_names[] = { "Low", "Med", "High", "Max" };
#define BRIGHT_OPT_COUNT 4
// screen-off-on-inactivity options, in frames (0 = never sleep the display). // screen-off-on-inactivity options, in frames (0 = never sleep the display).
// Shorter timeouts blank the OLED sooner, which is the single biggest power // Shorter timeouts blank the OLED sooner, which is the single biggest power
// win on a CR2032 — the panel draws far more than the dozing MCU. // win on a CR2032 — the panel draws far more than the dozing MCU.
static const uint16_t screen_timeout_opts[] = { 83, 167, 250, 500, 1000, 0 }; static const uint16_t screen_timeout_opts[] = { 83, 167, 250, 500, 1000, 0 };
static const char *const screen_timeout_names[] = { "5s", "10s", "15s", "30s", "60s", "Off" }; static const char *const screen_timeout_names[] = { "5s", "10s", "15s", "30s", "60s", "Off" };
#define TIMEOUT_OPT_COUNT 6 #define TIMEOUT_OPT_COUNT 6
#define SETTINGS_ROWS 3 // screen-off, sound, back #define SETTINGS_ROWS 4 // screen-off, brightness, sound, back
// display power state // display power state
static uint8_t disp_on = 1; static uint8_t disp_on = 1;
static uint32_t idle_frames = 0; // frames since the last button activity static uint32_t idle_frames = 0; // frames since the last button activity
// reset cause latched at boot (helps tell a brown-out from a software reset)
static uint32_t reset_cause = 0;
// menu icon order must match sprites.h menu_icons[] / menu_labels[] // menu icon order must match sprites.h menu_icons[] / menu_labels[]
enum { ACT_FEED, ACT_PLAY, ACT_SLEEP, ACT_CLEAN, ACT_HEAL, ACT_STATS, ACT_SETTINGS }; enum { ACT_FEED, ACT_PLAY, ACT_SLEEP, ACT_CLEAN, ACT_HEAL, ACT_STATS, ACT_SETTINGS };
@ -146,6 +156,13 @@ static void led_blink(void)
funDigitalWrite(LED_PIN, FUN_LOW); funDigitalWrite(LED_PIN, FUN_LOW);
} }
// push the currently selected brightness to the panel's contrast register
static void apply_brightness(void)
{
ssd1306_cmd(SSD1306_SETCONTRAST);
ssd1306_cmd(brightness_opts[bright_idx]);
}
static void pet_reset(void) static void pet_reset(void)
{ {
pet.satiety = 80; pet.satiety = 80;
@ -547,11 +564,12 @@ static void draw_settings(void)
char rows[SETTINGS_ROWS][17]; char rows[SETTINGS_ROWS][17];
*s_cat(s_cat(rows[0], "Screen off:"), screen_timeout_names[timeout_idx]) = 0; *s_cat(s_cat(rows[0], "Screen off:"), screen_timeout_names[timeout_idx]) = 0;
*s_cat(s_cat(rows[1], "Sound: "), sound_on ? "On" : "Off") = 0; *s_cat(s_cat(rows[1], "Bright: "), brightness_names[bright_idx]) = 0;
*s_cat(rows[2], "Back") = 0; *s_cat(s_cat(rows[2], "Sound: "), sound_on ? "On" : "Off") = 0;
*s_cat(rows[3], "Back") = 0;
for (uint8_t r = 0; r < SETTINGS_ROWS; r++) { for (uint8_t r = 0; r < SETTINGS_ROWS; r++) {
int y = 18 + r * 12; int y = 12 + r * 11;
if (r == set_sel) ssd1306_fillRect(0, y - 1, SSD1306_W, 10, 1); if (r == set_sel) ssd1306_fillRect(0, y - 1, SSD1306_W, 10, 1);
// selected row drawn inverted (color 0 on the lit bar) // selected row drawn inverted (color 0 on the lit bar)
ssd1306_drawstr(4, y, rows[r], r == set_sel ? 0 : 1); ssd1306_drawstr(4, y, rows[r], r == set_sel ? 0 : 1);
@ -693,6 +711,21 @@ static void splash(void)
beep(1200 + i * 120, 25); beep(1200 + i * 120, 25);
Delay_Ms(220); Delay_Ms(220);
} }
// show what woke the chip: POR == power dip / brown-out (e.g. OLED inrush
// sagging the coin cell), PIN == reset pin, SFT == software, none == we got
// here without a real hardware reset.
char rc[20], *rp = rc;
rp = s_cat(rp, "rst:");
if (reset_cause & RCC_LPWRRSTF) rp = s_cat(rp, "LPW ");
if (reset_cause & RCC_WWDGRSTF) rp = s_cat(rp, "WWD ");
if (reset_cause & RCC_IWDGRSTF) rp = s_cat(rp, "WDG ");
if (reset_cause & RCC_SFTRSTF) rp = s_cat(rp, "SFT ");
if (reset_cause & RCC_PORRSTF) rp = s_cat(rp, "POR ");
if (reset_cause & RCC_PINRSTF) rp = s_cat(rp, "PIN ");
if (rp == rc + 4) rp = s_cat(rp, "none");
*rp = 0;
ssd1306_drawstr(0, 44, rc, 1);
draw_center_str(54, "press any key"); draw_center_str(54, "press any key");
ssd1306_refresh(); ssd1306_refresh();
beep(988, 120); beep(988, 120);
@ -709,6 +742,8 @@ static void splash(void)
int main(void) int main(void)
{ {
SystemInit(); SystemInit();
reset_cause = RCC->RSTSCKR & 0xFC000000; // latch reset flags...
RCC->RSTSCKR |= RCC_RMVF; // ...then clear for next boot
gpio_setup(); gpio_setup();
lowpower_setup(); // button-wake EXTI + periodic-check timer lowpower_setup(); // button-wake EXTI + periodic-check timer
@ -718,6 +753,7 @@ int main(void)
while (1) { led_blink(); Delay_Ms(700); } while (1) { led_blink(); Delay_Ms(700); }
} }
ssd1306_init(); ssd1306_init();
apply_brightness(); // start at the configured (dimmer) brightness
splash(); splash();
screen = SCR_SELECT; // pick a species before a pet is born screen = SCR_SELECT; // pick a species before a pet is born
@ -793,7 +829,11 @@ int main(void)
if (set_sel == 0) { // cycle screen-off timeout if (set_sel == 0) { // cycle screen-off timeout
timeout_idx = (timeout_idx + 1) % TIMEOUT_OPT_COUNT; timeout_idx = (timeout_idx + 1) % TIMEOUT_OPT_COUNT;
beep(880, 40); beep(880, 40);
} else if (set_sel == 1) { // toggle sound } else if (set_sel == 1) { // cycle brightness
bright_idx = (bright_idx + 1) % BRIGHT_OPT_COUNT;
apply_brightness(); // takes effect immediately
beep(880, 40);
} else if (set_sel == 2) { // toggle sound
sound_on = !sound_on; sound_on = !sound_on;
beep(988, 60); // only audible if just enabled beep(988, 60); // only audible if just enabled
} else { // Back } else { // Back

BIN
tama.elf

Binary file not shown.

1238
tama.hex

File diff suppressed because it is too large Load Diff

4094
tama.lst

File diff suppressed because it is too large Load Diff

812
tama.map

File diff suppressed because it is too large Load Diff