/* pcf8574_for_HD44780.v - takes in control sequences for an HD44780 display and outputs data that control a pcf8574 connected to a HD44780 in a standard manner over i2c This file is part of the 9086 project. Copyright (c) 2024 Efthymios Kritikos This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ module pcf8574_for_HD44780( input wire clock, input wire pcf_write_req, input wire pcf_command_data, input wire [3:0]pcf_data, output reg pcf_busy=0, /* verilator lint_off UNUSEDSIGNAL */ input new_backlight, /* verilator lint_on UNUSEDSIGNAL */ input backlight_update, input I2C_BUSY, output reg I2C_TRANSACT=0, output reg DIR=0, output reg [7:0]i2c_data_write ); reg backlight=1; reg backlight_latch=0; reg [3:0]pcf_state=0; always @(posedge clock) begin // [ D7 , D6 , D5 , D4 , BACKLIGHT , EN , WRITE , COMMAND/DATA ] if(backlight_update) backlight_latch<=1; case(pcf_state) 4'b0000: begin /*Idle*/ if(pcf_write_req&&I2C_BUSY==0)begin pcf_state<=4'b0001; I2C_TRANSACT<=0; pcf_busy<=1; end else if(backlight_latch&&I2C_BUSY==0)begin pcf_state<=4'b1111; I2C_TRANSACT<=0; pcf_busy<=1; end end 4'b0001: begin if(I2C_BUSY==0)begin i2c_data_write<={pcf_data[3:0],backlight,1'b0,1'b0,pcf_command_data}; I2C_TRANSACT<=1; backlight_latch<=0; pcf_state<=4'b0010; end end 4'b0010:begin if(I2C_BUSY==1)begin I2C_TRANSACT<=0; pcf_state<=4'b0011; end end 4'b0011: begin if(I2C_BUSY==0)begin i2c_data_write<={pcf_data[3:0],backlight,1'b1,1'b0,pcf_command_data}; I2C_TRANSACT<=1; backlight_latch<=0; pcf_state<=4'b0100; end end 4'b0100:begin if(I2C_BUSY==1)begin I2C_TRANSACT<=0; pcf_state<=4'b0101; end end 4'b0101: begin if(I2C_BUSY==0)begin i2c_data_write<={pcf_data[3:0],backlight,1'b0,1'b0,pcf_command_data}; I2C_TRANSACT<=1; pcf_state<=4'b0110; end end 4'b0110: begin if(I2C_BUSY==1)begin I2C_TRANSACT<=0; pcf_state<=4'b0111; end end 4'b0111:begin if(I2C_BUSY==0)begin pcf_state<=4'b0000; pcf_busy<=1'b0; end end 4'b1111:begin if(I2C_BUSY==1)begin pcf_state<=4'b0000; I2C_TRANSACT<=1'b0; pcf_busy<=1'b0; end else begin i2c_data_write<={4'b0,backlight,1'b0,1'b0,1'b0}; backlight_latch<=0; I2C_TRANSACT<=1'b1; pcf_busy<=1'b1; end end default:begin pcf_state<=0; end endcase end endmodule