anchor.diff:    % Toggle Enable pin high
     ValueEnableSet = (Value bor ?ENABLE_SET),
     i2c:write(I2cRef, <<ValueEnableSet>>),
  -  % Toggle enable pin low, don't change the 4 data bits
  +  % Toggle enable pin low, don't change the 4 data bits, Backlight, RS, or R/~W lines
     ValueEnableClr = (Value band ?ENABLE_CLR),
     i2c:write(I2cRef, <<ValueEnableClr>>).
   
  
positive.code: -define(FONT_5X10, 16#04). % F: 5X8 dots = 0
  
  
  
  %
  % This code assumes the I2C Port Expander is wired to LCD Controller as follows:
  %
  %      Port  
  % Expander Output: db7  db6  db5  db4  db3  db2  db1  db0
  % ------------------|----|----|----|---------|----|----|            
  %     HD44780       V    V    V    V         V    V    V
  % LCD Controller   db7  db6  db5  db4       EN   R/W   RS 
  % 
  % EN (Enable) must be set high (1) and then low (0) to write a value to the LCD
  %   This requires 2 sequential writes of the same data.
  % R/W must be set low (0) to write values and high (1) to read values from the LCD
  % RS set low (0) for commands and high (1) for data (i.e. characters to display)
  %
  -define(ENABLE_SET, 16#04).
  -define(ENABLE_CLR, 16#FB).
  -define(RS_COMMAND, 16#00).
  -define(RS_DATA, 16#01).
  -define(RW_READ, 16#02).
  -define(RW_WRITE, 16#00).
  
  
  %%
  
negative.code:   end.
  
  
  %%
  %% Read control inputs and update the LCD control
  %%
  update_lcd_control(I2cRef, Inputs) ->
  
    case input_utils:get_boolean(Inputs, display) of
      {ok, true} -> Display = ?DISPLAY_ON;
              _  -> Display = ?DISPLAY_OFF
    end,
  
    case input_utils:get_boolean(Inputs, cursor) of
      {ok, true} -> Cursor = ?CURSOR_ON;
              _  -> Cursor = ?CURSOR_OFF
    end,
  
    case input_utils:get_boolean(Inputs, blink_cursor) of
      {ok, true} -> BlinkCursor = ?BLINK_CURSOR_ON;
              _  -> BlinkCursor = ?BLINK_CURSOR_OFF
    end,
   
    case input_utils:get_boolean(Inputs, backlight) of
      {ok, true} -> Backlight = ?BACKLIGHT_ON;
              _  -> Backlight = ?BACKLIGHT_OFF
    end,
  
    display_control(I2cRef, Backlight, ((Display bor Cursor) bor BlinkCursor)).
  
  
  
  clear(I2cRef, Backlight) ->
    write_command(I2cRef, Backlight, ?CLEAR_DISPLAY, ?NO_PARAMS).
  
  
  return_home(I2cRef, Backlight) ->
    write_command(I2cRef, Backlight, ?RETURN_HOME, ?NO_PARAMS).
  
  
  function_set(I2cRef, Backlight, Params) ->
    write_command(I2cRef, Backlight, ?FUNCTION_SET, Params).
  
  
  display_control(I2cRef, Backlight, Params) ->
    write_command(I2cRef, Backlight, ?DISPLAY_CONTROL, Params).
  
  
  entry_mode_set(I2cRef, Backlight, Params) ->
    write_command(I2cRef, Backlight, ?ENTRY_MODE_SET, Params).
  
  
  write_command(I2cRef, Backlight, Command, Params) ->
    CmdAndParams = (Command bor Params),
    % Always operate in 4 bit mode when using an I2C interface
    % Write high nibble (bits 7-4) first, then low nibble (bits 3-0)
    write_command_high(I2cRef, Backlight, CmdAndParams),
    write_command_low(I2cRef, Backlight, CmdAndParams).
  
  
  % write high half of command byte value, R/W = 0, RS = 0
  write_command_high(I2cRef, Backlight, Value) ->
    HighValue = ((Value band 16#F0) bor Backlight),
    write_value(I2cRef, HighValue).
  
  
  % write low half of command byte value, R/W = 0, RS = 0
  write_command_low(I2cRef, Backlight, Value) ->
    LowValue = ((Value bsl 4) bor Backlight),
    write_value(I2cRef, LowValue).
  
  
  write_data(I2cRef, Backlight, Data) ->
    % Always operate in 4 bit mode when using an I2C interface
    % Write high nibble (bits 7-4) first, then low nibble (bits 3-0)
    write_data_high(I2cRef, Backlight, Data),
    write_data_low(I2cRef, Backlight, Data).
  
  
  % write high half of data byte value, R/W = 0, RS = 1
  write_data_high(I2cRef, Backlight, Value) ->
    HighValue = (((Value band 16#F0) bor Backlight) bor ?RS_DATA),
    write_value(I2cRef, HighValue).
  
  
  % write low half of data byte value, R/W = 0, RS = 1
  write_data_low(I2cRef, Backlight, Value) ->
    LowValue = (((Value bsl 4) bor Backlight) bor ?RS_DATA),
    write_value(I2cRef, LowValue).
  
  
  