#pragma once
#include "main.h"
#if !defined LCD_DELAY_CNT
#error need to define LCD delay counter ticking in microseconds
#endif
enum lcdType_t
{
LCD_8X1, ///< 8 chars, 1 column
LCD_10X1,
LCD_16X1,
LCD_20X1,
LCD_40X1,
LCD_8X2,
LCD_10X2,
LCD_16X2,
LCD_20X2,
LCD_40X2
};
class ioline_t
{
public:
ioline_t(GPIO_TypeDef *gpio, uint16_t pin) : gpio(gpio), pin(pin){};
ioline_t() : gpio(nullptr), pin(0){};
ioline_t &operator=(ioline_t const &data)
{
this->gpio = data.gpio;
this->pin = data.pin;
return *this;
};
GPIO_TypeDef *gpio; // GPIO pin port
uint16_t pin; // GPIO pin number
};
/// \brief Describe the bits of the databus for the LCD
struct lcdDataLines_t
{
lcdDataLines_t(ioline_t d0_, ioline_t d1_, ioline_t d2_, ioline_t d3_)
{
m_bits[0] = d0_;
m_bits[1] = d1_;
m_bits[2] = d2_;
m_bits[3] = d3_;
}
ioline_t &operator[](int i_) { return m_bits[i_]; };
private:
ioline_t m_bits[4];
};
class lcdInterface_t
{
public:
lcdInterface_t(lcdType_t type_, ///< LCD type code
ioline_t rsBit_, ///< LCD register select bit
ioline_t wrBit_, ///< LCD register write bit
ioline_t eBit_, ///< LCD enable bit
lcdDataLines_t dBits_ ///< LCD data bits
)
: m_lcdType(type_), m_rsBit(rsBit_), m_wrBit(wrBit_), m_eBit(eBit_), m_dBits(dBits_), m_timeouts(0){};
uint8_t displayXsize() const;
uint8_t displayYsize() const;
void writeData(uint8_t data_);
/// \brief write top 4 bits of the control register with the top 4 bits of data_
void writeCtrl4(uint8_t data_);
void writeCtrl(uint8_t data_);
/// \brief write a control value then wait for it to complete
void writeCtrlWait(uint8_t data_);
uint8_t readData();
uint8_t readCtrl();
lcdType_t lcdType() { return m_lcdType; };
/// \brief Set cursor position.
void gotoxy(uint8_t x_, uint8_t y_);
// \brief Start the polled timer for high speed signals.
void init();
// \brief maintaining data on the bus
void pulseE();
private:
/// \brief write low order 4 bits to data bus
void writeData4(uint8_t data_);
/// \brief read low order 4 bits from data bus
uint8_t readData4();
/// \brief write full 8 bits to data bus
void writeData8(uint8_t data_);
/// \brief read full 8 bits from data bus
uint8_t readData8();
/// \brief poll/wait while hardware reports busy
void pollBusy();
/// \brief Set the GPIO mode
void setLineMode(ioline_t line, unsigned mode);
/// \brief delay for microseconds
void polledDelay(unsigned microsec);
lcdType_t const m_lcdType;
ioline_t const m_rsBit;
ioline_t const m_wrBit;
ioline_t const m_eBit;
/// \brief gpio information
lcdDataLines_t m_dBits;
/// \brief a count of the number of failures
uint32_t m_timeouts;
};