//! @file #ifndef _LCD_H #define _LCD_H #include #include #include "Timer.h" extern FILE _lcdout; #define lcdout (&_lcdout) extern void lcd_init(void); extern void lcd_refresh(void); extern void lcd_refresh_noclear(void); extern void lcd_clear(void); extern void lcd_home(void); /*extern void lcd_no_display(void); extern void lcd_display(void); extern void lcd_no_blink(void); extern void lcd_blink(void); extern void lcd_no_cursor(void); extern void lcd_cursor(void); extern void lcd_scrollDisplayLeft(void); extern void lcd_scrollDisplayRight(void); extern void lcd_leftToRight(void); extern void lcd_rightToLeft(void); extern void lcd_autoscroll(void); extern void lcd_no_autoscroll(void);*/ extern void lcd_set_cursor(uint8_t col, uint8_t row); extern void lcd_createChar_P(uint8_t, const uint8_t*); // char c is non-standard, however it saves 1B on stack extern int lcd_putc(char c); extern int lcd_putc_at(uint8_t c, uint8_t r, char ch); extern int lcd_puts_P(const char* str); extern int lcd_puts_at_P(uint8_t c, uint8_t r, const char* str); extern int lcd_printf_P(const char* format, ...); extern void lcd_space(uint8_t n); extern void lcd_printNumber(unsigned long n, uint8_t base); extern void lcd_printFloat(double number, uint8_t digits); extern void lcd_print(const char*); extern void lcd_print(char, int = 0); extern void lcd_print(unsigned char, int = 0); extern void lcd_print(int, int = 10); extern void lcd_print(unsigned int, int = 10); extern void lcd_print(long, int = 10); extern void lcd_print(unsigned long, int = 10); extern void lcd_print(double, int = 2); //! @brief Clear screen #define ESC_2J "\x1b[2J" //! @brief Show cursor #define ESC_25h "\x1b[?25h" //! @brief Hide cursor #define ESC_25l "\x1b[?25l" //! @brief Set cursor to //! @param c column //! @param r row #define ESC_H(c,r) "\x1b["#r";"#c"H" #define LCD_UPDATE_INTERVAL 100 #define LCD_TIMEOUT_TO_STATUS 30000ul //!< Generic timeout to status screen in ms, when no user action. #define LCD_TIMEOUT_TO_STATUS_BABYSTEP_Z 90000ul //!< Specific timeout for lcd_babystep_z screen in ms. typedef void (*lcd_longpress_func_t)(void); typedef void (*lcd_charsetup_func_t)(void); typedef void (*lcd_lcdupdate_func_t)(void); //Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) extern uint8_t lcd_draw_update; extern int32_t lcd_encoder; extern uint8_t lcd_encoder_bits; // lcd_encoder_diff is updated from interrupt context and added to lcd_encoder every LCD update extern int8_t lcd_encoder_diff; //the last checked lcd_buttons in a bit array. extern uint8_t lcd_buttons; extern uint8_t lcd_button_pressed; extern uint8_t lcd_update_enabled; extern LongTimer lcd_timeoutToStatus; extern uint32_t lcd_next_update_millis; extern uint8_t lcd_status_update_delay; extern lcd_longpress_func_t lcd_longpress_func; extern lcd_charsetup_func_t lcd_charsetup_func; extern lcd_lcdupdate_func_t lcd_lcdupdate_func; extern uint8_t lcd_clicked(void); extern void lcd_beeper_quick_feedback(void); //Cause an LCD refresh, and give the user visual or audible feedback that something has happened extern void lcd_quick_feedback(void); extern void lcd_update(uint8_t lcdDrawUpdateOverride); extern void lcd_update_enable(uint8_t enabled); extern void lcd_buttons_update(void); //! @brief Helper class to temporarily disable LCD updates //! //! When constructed (on stack), original state state of lcd_update_enabled is stored //! and LCD updates are disabled. //! When destroyed (gone out of scope), original state of LCD update is restored. //! It has zero overhead compared to storing bool saved = lcd_update_enabled //! and calling lcd_update_enable(false) and lcd_update_enable(saved). class LcdUpdateDisabler { public: LcdUpdateDisabler(): m_updateEnabled(lcd_update_enabled) { lcd_update_enable(false); } ~LcdUpdateDisabler() { lcd_update_enable(m_updateEnabled); } private: bool m_updateEnabled; }; //////////////////////////////////// // Setup button and encode mappings for each panel (into 'lcd_buttons' variable // // This is just to map common functions (across different panels) onto the same // macro name. The mapping is independent of whether the button is directly connected or // via a shift/i2c register. #define BLEN_B 1 #define BLEN_A 0 #define EN_B (1<