#include "menu.h" #include #include #include #include "../../lib/ssd1306xled/font6x8.h" #include "state.h" #include "../buttons.h" #include "../power.h" #include "counter.h" #define MenuItemReset 0 #define MenuItemCancel 1 #define MenuCount MenuItemCancel + 1 uint8_t currentIndex = 0; uint8_t lastDrawnIndex = MenuCount; // Forward declarations void drawMenu(); void drawMenuItem(uint8_t itemIndex, char* caption); void selectMenuItem(); void closeMenu(); void ssd1306_string_inverted(char *s); void ssd1306_char_inverted(char ch); void handleMenuScreen() { if (button_is_pressed_or_repeated(&buttonUp)) { if (currentIndex >= MenuCount - 1) currentIndex = 0; else currentIndex++; } else if (button_is_pressed_or_repeated(&buttonDown)) { if (currentIndex <= 0) currentIndex = MenuCount - 1; else currentIndex--; } else if (button_is_released(&buttonOption)) { selectMenuItem(); return; } uint8_t invalidated = getScreenInvalidated(); if (currentIndex != lastDrawnIndex || invalidated) { if (invalidated) ssd1306_clear(); drawMenu(); lastDrawnIndex = currentIndex; } } void drawMenu() { // Since there are only two items at the moment, they're always going to be // involved in the change, so simply repaint them. drawMenuItem(MenuItemReset, "Reset "); drawMenuItem(MenuItemCancel, "Cancel "); // Can't use sprintf because that'll use up more than the // space we have left on the ATTiny. uint8_t intPart = vcc / 1000; if (intPart > 9) intPart = 9; uint8_t floatPart = (vcc % 1000) / 10; char statusText[22] = "Battery: 0-00- \0"; itoa(intPart, &statusText[9], 10); if (floatPart <= 9) itoa(floatPart, &statusText[12], 10); else itoa(floatPart, &statusText[11], 10); // itoa adds a \0 character statusText[10] = '.'; statusText[13] = 'v'; ssd1306_setpos(0, 7); ssd1306_string(statusText); } void drawMenuItem(uint8_t itemIndex, char* caption) { ssd1306_setpos(0, itemIndex); if (itemIndex == currentIndex) ssd1306_string_inverted(caption); else ssd1306_string(caption); } void selectMenuItem() { switch (currentIndex) { case MenuItemReset: resetCounter(); closeMenu(); break; case MenuItemCancel: closeMenu(); break; } } void closeMenu() { // Reset everything for the next time currentIndex = 0; lastDrawnIndex = MenuCount; setCurrentScreen(Counter); } void ssd1306_string_inverted(char *s) { while (*s) { ssd1306_char_inverted(*s++); } } void ssd1306_char_inverted(char ch) { uint8_t c = ch - 32; ssd1306_send_data_start(); for (uint8_t i = 0; i < 6; i++) { ssd1306_send_byte(~pgm_read_byte(&ssd1306xled_font6x8[c * 6 + i])); } ssd1306_send_data_stop(); }