124 lines
2.8 KiB
Coq
124 lines
2.8 KiB
Coq
|
/* 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
|