+++ /dev/null
-import time
-
-class LcdApi:
-
- # Implements the API for talking with HD44780 compatible character LCDs.
- # This class only knows what commands to send to the LCD, and not how to get
- # them to the LCD.
- #
- # It is expected that a derived class will implement the hal_xxx functions.
- #
- # The following constant names were lifted from the avrlib lcd.h header file,
- # with bit numbers changed to bit masks.
-
- # HD44780 LCD controller command set
- LCD_CLR = 0x01 # DB0: clear display
- LCD_HOME = 0x02 # DB1: return to home position
-
- LCD_ENTRY_MODE = 0x04 # DB2: set entry mode
- LCD_ENTRY_INC = 0x02 # DB1: increment
- LCD_ENTRY_SHIFT = 0x01 # DB0: shift
-
- LCD_ON_CTRL = 0x08 # DB3: turn lcd/cursor on
- LCD_ON_DISPLAY = 0x04 # DB2: turn display on
- LCD_ON_CURSOR = 0x02 # DB1: turn cursor on
- LCD_ON_BLINK = 0x01 # DB0: blinking cursor
-
- LCD_MOVE = 0x10 # DB4: move cursor/display
- LCD_MOVE_DISP = 0x08 # DB3: move display (0-> move cursor)
- LCD_MOVE_RIGHT = 0x04 # DB2: move right (0-> left)
-
- LCD_FUNCTION = 0x20 # DB5: function set
- LCD_FUNCTION_8BIT = 0x10 # DB4: set 8BIT mode (0->4BIT mode)
- LCD_FUNCTION_2LINES = 0x08 # DB3: two lines (0->one line)
- LCD_FUNCTION_10DOTS = 0x04 # DB2: 5x10 font (0->5x7 font)
- LCD_FUNCTION_RESET = 0x30 # See "Initializing by Instruction" section
-
- LCD_CGRAM = 0x40 # DB6: set CG RAM address
- LCD_DDRAM = 0x80 # DB7: set DD RAM address
-
- LCD_RS_CMD = 0
- LCD_RS_DATA = 1
-
- LCD_RW_WRITE = 0
- LCD_RW_READ = 1
-
- def __init__(self, num_lines, num_columns):
- self.num_lines = num_lines
- if self.num_lines > 4:
- self.num_lines = 4
- self.num_columns = num_columns
- if self.num_columns > 40:
- self.num_columns = 40
- self.cursor_x = 0
- self.cursor_y = 0
- self.implied_newline = False
- self.backlight = True
- self.display_off()
- self.backlight_on()
- self.clear()
- self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC)
- self.hide_cursor()
- self.display_on()
-
- def clear(self):
- # Clears the LCD display and moves the cursor to the top left corner
- self.hal_write_command(self.LCD_CLR)
- self.hal_write_command(self.LCD_HOME)
- self.cursor_x = 0
- self.cursor_y = 0
-
- def show_cursor(self):
- # Causes the cursor to be made visible
- self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
- self.LCD_ON_CURSOR)
-
- def hide_cursor(self):
- # Causes the cursor to be hidden
- self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
-
- def blink_cursor_on(self):
- # Turns on the cursor, and makes it blink
- self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
- self.LCD_ON_CURSOR | self.LCD_ON_BLINK)
-
- def blink_cursor_off(self):
- # Turns on the cursor, and makes it no blink (i.e. be solid)
- self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
- self.LCD_ON_CURSOR)
-
- def display_on(self):
- # Turns on (i.e. unblanks) the LCD
- self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
-
- def display_off(self):
- # Turns off (i.e. blanks) the LCD
- self.hal_write_command(self.LCD_ON_CTRL)
-
- def backlight_on(self):
- # Turns the backlight on.
-
- # This isn't really an LCD command, but some modules have backlight
- # controls, so this allows the hal to pass through the command.
- self.backlight = True
- self.hal_backlight_on()
-
- def backlight_off(self):
- # Turns the backlight off.
-
- # This isn't really an LCD command, but some modules have backlight
- # controls, so this allows the hal to pass through the command.
- self.backlight = False
- self.hal_backlight_off()
-
- def move_to(self, cursor_x, cursor_y):
- # Moves the cursor position to the indicated position. The cursor
- # position is zero based (i.e. cursor_x == 0 indicates first column).
- self.cursor_x = cursor_x
- self.cursor_y = cursor_y
- addr = cursor_x & 0x3f
- if cursor_y & 1:
- addr += 0x40 # Lines 1 & 3 add 0x40
- if cursor_y & 2: # Lines 2 & 3 add number of columns
- addr += self.num_columns
- self.hal_write_command(self.LCD_DDRAM | addr)
-
- def putchar(self, char):
- # Writes the indicated character to the LCD at the current cursor
- # position, and advances the cursor by one position.
- if char == '\n':
- if self.implied_newline:
- # self.implied_newline means we advanced due to a wraparound,
- # so if we get a newline right after that we ignore it.
- pass
- else:
- self.cursor_x = self.num_columns
- else:
- self.hal_write_data(ord(char))
- self.cursor_x += 1
- if self.cursor_x >= self.num_columns:
- self.cursor_x = 0
- self.cursor_y += 1
- self.implied_newline = (char != '\n')
- if self.cursor_y >= self.num_lines:
- self.cursor_y = 0
- self.move_to(self.cursor_x, self.cursor_y)
-
- def putstr(self, string):
- # Write the indicated string to the LCD at the current cursor
- # position and advances the cursor position appropriately.
- for char in string:
- self.putchar(char)
-
- def custom_char(self, location, charmap):
- # Write a character to one of the 8 CGRAM locations, available
- # as chr(0) through chr(7).
- location &= 0x7
- self.hal_write_command(self.LCD_CGRAM | (location << 3))
- self.hal_sleep_us(40)
- for i in range(8):
- self.hal_write_data(charmap[i])
- self.hal_sleep_us(40)
- self.move_to(self.cursor_x, self.cursor_y)
-
- def hal_backlight_on(self):
- # Allows the hal layer to turn the backlight on.
- # If desired, a derived HAL class will implement this function.
- pass
-
- def hal_backlight_off(self):
- # Allows the hal layer to turn the backlight off.
- # If desired, a derived HAL class will implement this function.
- pass
-
- def hal_write_command(self, cmd):
- # Write a command to the LCD.
- # It is expected that a derived HAL class will implement this function.
- raise NotImplementedError
-
- def hal_write_data(self, data):
- # Write data to the LCD.
- # It is expected that a derived HAL class will implement this function.
- raise NotImplementedError
-
- def hal_sleep_us(self, usecs):
- # Sleep for some time (given in microseconds)
- time.sleep_us(usecs)