9086/system/peripherals/pcf8574_for_HD44780.v

124 lines
2.8 KiB
Coq
Raw Normal View History

/* 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) 2023 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 <http://www.gnu.org/licenses/>. */
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,
input new_backlight,
input backlight_update,
input I2C_BUSY,
output reg I2C_SEND=0,
output reg [7:0]i2c_data
);
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_SEND<=0;
pcf_busy<=1;
end else if(backlight_latch&&I2C_BUSY==0)begin
pcf_state<=4'b1111;
I2C_SEND<=0;
pcf_busy<=1;
end
end
4'b0001: begin
if(I2C_BUSY==0)begin
i2c_data<={pcf_data[3:0],backlight,1'b0,1'b0,pcf_command_data};
I2C_SEND<=1;
backlight_latch<=0;
pcf_state<=4'b0010;
end
end
4'b0010:begin
if(I2C_BUSY==1)begin
I2C_SEND<=0;
pcf_state<=4'b0011;
end
end
4'b0011: begin
if(I2C_BUSY==0)begin
i2c_data<={pcf_data[3:0],backlight,1'b1,1'b0,pcf_command_data};
I2C_SEND<=1;
backlight_latch<=0;
pcf_state<=4'b0100;
end
end
4'b0100:begin
if(I2C_BUSY==1)begin
I2C_SEND<=0;
pcf_state<=4'b0101;
end
end
4'b0101: begin
if(I2C_BUSY==0)begin
i2c_data<={pcf_data[3:0],backlight,1'b0,1'b0,pcf_command_data};
I2C_SEND<=1;
pcf_state<=4'b0110;
end
end
4'b0110: begin
if(I2C_BUSY==1)begin
I2C_SEND<=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_SEND<=1'b0;
pcf_busy<=1'b0;
end else begin
i2c_data<={4'b0,backlight,1'b0,1'b0,1'b0};
backlight_latch<=0;
I2C_SEND<=1'b1;
pcf_busy<=1'b1;
end
end
default:begin
pcf_state<=0;
end
endcase
end
endmodule