245 lines
5.7 KiB
C++

/*
* Menu.cpp
*
* Created on: Jun 8, 2024
* Author: Carst
*/
#include <cstring>
#include <cstdio>
#include <cinttypes>
#include "Menu.hpp"
#include "Display.hpp"
#include "Button.hpp"
#include "Timer.hpp"
#include "ElektronischeLast.hpp"
#include "STM32G071KBT6.hpp"
namespace ElektronischeLast
{
static Timer timer = Timer();
static Button ok = Button();
static Button up = Button();
static Button down = Button();
static Display lcd = Display();
static const uint8_t degreeSymbol[] = { 0x0E, 0x0A, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const uint8_t arrowUp[] = { 0x04, 0x0E, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04 };
static const uint8_t arrowDown[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x0E, 0x04 };
void Menu::init()
{
timer.start(500U);
ok.init(GPIOA, LL_GPIO_PIN_7);
up.init(GPIOA, LL_GPIO_PIN_9);
down.init(GPIOA, LL_GPIO_PIN_8);
lcd.init();
while(lcd.ready_for_data() == false)
{
lcd.run();
}
lcd.lcd_set_user_chars(Display::FirstSign, arrowUp);
while(lcd.ready_for_data() == false)
{
lcd.run();
}
lcd.lcd_set_user_chars(Display::ThirdSign, arrowDown);
while(lcd.ready_for_data() == false)
{
lcd.run();
}
lcd.lcd_set_user_chars(Display::SecondSign, degreeSymbol);
while(lcd.ready_for_data() == false)
{
lcd.run();
}
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff);
lcd.print(Display::Line1, "Elektronische Last");
}
void Menu::set_measurements(uint32_t spannung, uint32_t strom, uint32_t temperatur, uint32_t geschwindigkeit)
{
this->spannung = spannung;
this->strom = strom;
this->temperatur = temperatur;
this->geschwindigkeit = geschwindigkeit;
}
void Menu::run()
{
ok.cyclic();
up.cyclic();
down.cyclic();
switch(menu_level)
{
case MenuLevel_Call:
menu_call();
break;
case MenuLevel_ICallInit:
menu_icall_init();
break;
case MenuLevel_ICall:
menu_icall();
break;
case MenuLevel_UCallInit:
menu_ucall_init();
break;
case MenuLevel_UCall:
menu_ucall();
break;
case MenuLevel_ISoll:
menu_isoll();
break;
case MenuLevel_Main:
default:
menu_main();
break;
}
lcd.run();
}
void Menu::menu_main(void)
{
if(timer.elapsed())
{
if(lcd.ready_for_data())
{
timer.start(500U);
char data[17U];
int32_t len = snprintf(data, sizeof(data) - 1, "%2" PRIu32 ".%02" PRIu32 "V",
spannung / 1000U, spannung % 1000U / 10U);
std::memset(&data[len], (int)' ', 16U - len);
snprintf(&data[12], sizeof(data) - 12, "%2" PRIu32 "%cC", temperatur, 0x1);
data[16] = '\0';
lcd.print(Display::Line1, data);
if(strom < 1000UL)
{
len = snprintf(data, sizeof(data) - 1, "%3" PRIu32 "mA", strom);
}
else
{
len = snprintf(data, sizeof(data) - 1, "%" PRIu32 ".%02" PRIu32 "A",
strom / 1000U, strom % 1000U / 10U);
}
std::memset(&data[len], (int)' ', 16U - len);
snprintf(&data[9], sizeof(data) - 9, "%4" PRIu32 "RPM", geschwindigkeit);
data[16] = '\0';
lcd.print(Display::Line2, data);
}
}
if(ok.isReleased())
{
this->menu_level = MenuLevel_ISoll;
this->configurations = 0UL;
}
}
void Menu::menu_call(void)
{
}
void Menu::menu_icall_init(void)
{
}
void Menu::menu_icall(void)
{
}
void Menu::menu_ucall_init(void)
{
}
void Menu::menu_ucall(void)
{
}
void Menu::menu_isoll(void)
{
const char *header = "Sollstrom: ";
char data[17U];
int32_t len;
bool changed = false;
if(lcd.ready_for_data())
{
switch(this->configurations)
{
case 0UL:
soll = get_current_sollstrom();
len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", soll);
std::memset(&data[len], (int)' ', 16U - len);
data[16] = '\0';
lcd.print(Display::Line1, header);
lcd.print(Display::Line2, data);
this->configurations++;
break;
case 1UL:
cursor = 0U;
lcd.set_cursor(Display::Line2, cursor);
this->configurations++;
break;
case 2UL:
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOn, Display::eCursorBlinkOn);
this->configurations++;
break;
default:
if(ok.isReleased())
{
cursor++;
if(cursor > 3U)
{
menu_level = MenuLevel_Main;
set_new_sollstrom(soll);
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff);
}
else
{
lcd.set_cursor(Display::Line2, cursor);
}
}
else if(up.isReleased())
{
uint32_t step = 10000UL;
uint32_t i = 0U;
while(i < cursor)
{
step /= 10UL;
i++;
}
this->soll = (this->soll + step) % 11000UL;
changed = true;
}
else if(down.isReleased())
{
uint32_t step = 10000UL;
uint32_t i = 0U;
while(i < cursor)
{
step /= 10UL;
i++;
}
this->soll = (this->soll - step) % 11000UL;
changed = true;
}
if(changed)
{
len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", this->soll);
std::memset(&data[len], (int)' ', 16U - len);
data[16] = '\0';
lcd.print(Display::Line2, data);
}
break;
}
}
}
}