/* * Display.cpp * * Created on: Aug 12, 2023 * Author: Carst */ #include #include "STM32G071KBT6.hpp" #include "Display.hpp" #define pulse_delay() for(uint32_t i = 0UL; i < 1UL; i++); #define PIN_RS LL_GPIO_PIN_4 #define PIN_RW LL_GPIO_PIN_5 #define PIN_E LL_GPIO_PIN_6 #define PIN_BL LL_GPIO_PIN_7 namespace ElektronischeLast { void Display::init(void) { LL_GPIO_InitTypeDef init = { .Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 | LL_GPIO_PIN_2 | LL_GPIO_PIN_3 | PIN_RS | PIN_RW | PIN_E | PIN_BL, .Mode = LL_GPIO_MODE_OUTPUT, .Speed = LL_GPIO_SPEED_FREQ_LOW, .OutputType = LL_GPIO_OUTPUT_PUSHPULL, .Pull = LL_GPIO_PULL_NO, }; LL_GPIO_Init(GPIOB, &init); this->set_backlight(true); this->current_state = StateDelay; this->next_state = StateInit01; this->start_timer(15UL); // 15ms Startup Delay } void Display::run(void) { switch (this->current_state) { case StateIdle: // do nothing; break; case StateDelay: if(this->timer_elapsed()) { this->current_state = this->next_state; this->run(); } break; case StateWaitWhileBusy: break; case StateInit01: write_command_8bit_4pin(0x30u); this->start_timer(5UL); // 5ms Delay this->next_state = StateInit02; break; case StateInit02: write_command_8bit_4pin(0x30u); this->start_timer(1UL); // 1ms Delay this->next_state = StateInit03; break; case StateInit03: write_command_8bit_4pin(0x30u); this->start_timer(1UL); // 1ms Delay this->next_state = StateInit04; break; case StateInit04: // 4-bit mode write_command_8bit_4pin(0x20u); this->start_timer(1UL); this->next_state = StateInit05; break; case StateInit05: // 4-bit mode, 2 lines write_command_4bit(0x28u); this->start_timer(1UL); this->next_state = StateInit06; break; case StateInit06: // Display off write_command_4bit(0x08u); this->start_timer(1UL); this->next_state = StateInit07; break; case StateInit07: // Clear Display write_command_4bit(0x01u); this->start_timer(1UL); this->next_state = StateInit08; break; case StateInit08: // increment DDRAM write_command_4bit(0x06u); this->start_timer(1UL); this->next_state = StateInit09; break; case StateInit09: // return cursor home write_command_4bit(0x02u); this->start_timer(1UL); this->next_state = StateInit10; break; case StateInit10: // Display on, Cursor on, Blink on write_command_4bit(0x0Fu); this->start_timer(1UL); this->next_state = StateIdle; break; default: break; } } void Display::set_backlight(bool on) { if(on) { LL_GPIO_SetOutputPin(GPIOB, PIN_BL); } else { LL_GPIO_ResetOutputPin(GPIOB, PIN_BL); } } void Display::set_cursor(Line_t line, std::uint32_t position) { } void Display::print(const char* const string) { } bool Display::timer_elapsed(void) { return (this->timer < systick); } void Display::start_timer(std::uint32_t timeout) { this->timer = systick + 1U + timeout; // +1 damit auch mindestens 1ms vorbei geht. this->current_state = StateDelay; } void Display::write_command_8bit_4pin(std::uint32_t data) { // RS=low, RW=low LL_GPIO_ResetOutputPin(GPIOB, PIN_RS | PIN_RW | PIN_E); std::uint32_t tmp = data >> 4U; tmp |= ((~(data >> 4U) & 0xFU) << GPIO_BSRR_BR0_Pos); LL_GPIO_SetOutputPin(GPIOB, tmp); __NOP(); LL_GPIO_SetOutputPin(GPIOB, PIN_E); pulse_delay(); LL_GPIO_ResetOutputPin(GPIOB, PIN_E); } void Display::write_command_4bit(std::uint32_t command) { // RS=low, RW=low LL_GPIO_ResetOutputPin(GPIOB, PIN_RS | PIN_RW | PIN_E); std::uint32_t tmp = command >> 4U; tmp |= ((~(command >> 4U) & 0xFU) << GPIO_BSRR_BR0_Pos); __NOP(); LL_GPIO_SetOutputPin(GPIOB, PIN_E); pulse_delay(); LL_GPIO_ResetOutputPin(GPIOB, PIN_E); tmp = command; tmp |= ((~command & 0xFU) << GPIO_BSRR_BR0_Pos); __NOP(); LL_GPIO_SetOutputPin(GPIOB, PIN_E); pulse_delay(); LL_GPIO_ResetOutputPin(GPIOB, PIN_E); } }