Added an I2C driver, a PCF8574 driver and an HD44780 display driver. Unfortunately this shows that even fibonacci doesn't run correctly. Nonetheless, I made colored_led.asm output text to the display!
This commit is contained in:
parent
e0dc7bae07
commit
a88c420ca5
@ -69,10 +69,12 @@ endif
|
||||
ECP5_TARGETS=synth_ecp5.json synth_ecp5_out.config synth_ecp5.bit synth_ecp5.dfu
|
||||
ECP5_TARGETS+=abc.history # created from yosys
|
||||
|
||||
EXTRA_SYNTHESIS_SOURCES=peripherals/I2C_driver.v peripherals/ascii_to_HD44780_driver.v peripherals/pcf8574_for_HD44780.v
|
||||
|
||||
#TODO: we are relying on yosys to trim the input program txt file and hope its enough for the whole program...
|
||||
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${INCLUDES} ../boot_code/colored_led.txt
|
||||
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${INCLUDES} ../boot_code/colored_led.txt
|
||||
${QUIET_YOSYS}
|
||||
${Q} yosys -q -D BUILTIN_RAM=512 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ; synth_ecp5 -json $@"
|
||||
${Q} yosys -q -D BUILTIN_RAM=512 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ; synth_ecp5 -json $@ -top fpga_top"
|
||||
|
||||
synth_ecp5_out.config:synth_ecp5.json
|
||||
${QUIET_NEXTPNR}
|
||||
|
@ -28,6 +28,9 @@ module fpga_top(
|
||||
output rgb_led0_r,
|
||||
output rgb_led0_g,
|
||||
output rgb_led0_b,
|
||||
|
||||
inout gpio_0,/*sda*/
|
||||
output gpio_1 /*scl*/
|
||||
);
|
||||
|
||||
wire HALT;
|
||||
@ -35,6 +38,7 @@ wire [`ERROR_BITS-1:0]ERROR;
|
||||
wire [19:0] address_bus;
|
||||
wire [15:0] data_bus_read,data_bus_write;
|
||||
wire rd,wr,BHE,IOMEM;
|
||||
|
||||
system system(
|
||||
/* MISC */ clk48,reset
|
||||
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
||||
@ -45,15 +49,6 @@ assign rgb_led0_r=rgb_led_color[0];
|
||||
assign rgb_led0_g=rgb_led_color[1];
|
||||
assign rgb_led0_b=rgb_led_color[2];
|
||||
|
||||
always @(negedge wr) begin
|
||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
||||
if(data_bus_write[0:0]==1)
|
||||
rgb_led_color=3'b000;
|
||||
else
|
||||
rgb_led_color=3'b111;
|
||||
end
|
||||
end
|
||||
|
||||
// A bit useless since if the cpu ERORRS out or HALTS it will continue executing anyway
|
||||
//always @(HALT or ERROR or user_button) begin
|
||||
// if (HALT==1) begin
|
||||
@ -68,15 +63,16 @@ end
|
||||
// end
|
||||
//end
|
||||
|
||||
// Create a 27 bit register
|
||||
reg [26:0] counter = 0;
|
||||
|
||||
/*** RESET CIRCUIT ***/
|
||||
|
||||
reg [3:0] counter = 0;
|
||||
|
||||
// Every positive edge increment register by 1
|
||||
always @(posedge clk48) begin
|
||||
counter <= counter + 1;
|
||||
end
|
||||
|
||||
/*** RESET CIRCUIT ***/
|
||||
|
||||
reg reset=0;
|
||||
reg [1:0] state=0;
|
||||
|
||||
@ -97,4 +93,113 @@ always @(posedge counter[3]) begin
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
always @(negedge wr) begin
|
||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )begin
|
||||
//disp_write_cache[disp_cache_end]<=data_bus_write[7:0];
|
||||
disp_write_cache[disp_cache_end]<=data_bus_write[15:8];
|
||||
disp_cache_end<=disp_cache_end+5'd1;
|
||||
end else if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
||||
if(data_bus_write[0:0]==1)
|
||||
rgb_led_color=3'b000;
|
||||
else
|
||||
rgb_led_color=3'b111;
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------//
|
||||
// Cache to allow the slow display to have a
|
||||
// chance to keep up with the relentless CPU
|
||||
|
||||
reg [4:0] disp_cache_start=0;
|
||||
reg [4:0] disp_cache_end=0;
|
||||
reg [7:0] disp_write_cache [31:0];
|
||||
reg ascii_state=0;
|
||||
always @(posedge clk48)begin
|
||||
case (ascii_state)
|
||||
1'b0:begin
|
||||
if(ascii_data_ready&disp_cache_start!=disp_cache_end)begin
|
||||
ascii_data<=disp_write_cache[disp_cache_start];
|
||||
disp_cache_start<=disp_cache_start+5'd1;
|
||||
ascii_data_write_req<=1;
|
||||
ascii_state<=1'b1;
|
||||
end
|
||||
end
|
||||
1'b1:begin
|
||||
if(!ascii_data_ready)begin
|
||||
ascii_data_write_req<=0;
|
||||
ascii_state<=1'b0;
|
||||
end
|
||||
end
|
||||
default: begin end
|
||||
endcase
|
||||
end
|
||||
|
||||
wire I2C_SPEED=counter[7];
|
||||
|
||||
// Display driver
|
||||
|
||||
wire ascii_data_ready;
|
||||
reg ascii_data_write_req=0;
|
||||
reg [7:0] ascii_data;
|
||||
ascii_to_HD44780_driver LCD_DRIVER(
|
||||
/* system */
|
||||
I2C_SPEED,
|
||||
1'b1,
|
||||
|
||||
/* Data Input */
|
||||
ascii_data_ready,
|
||||
ascii_data_write_req,
|
||||
ascii_data,
|
||||
|
||||
/* write circuitry */
|
||||
!pcf_busy,
|
||||
pcf_write_req,
|
||||
pcf_data,
|
||||
pcf_command_data
|
||||
);
|
||||
|
||||
// Port expander driver
|
||||
|
||||
wire pcf_write_req,pcf_command_data,pcf_busy;
|
||||
wire [3:0]pcf_data;
|
||||
wire [7:0]i2c_data;
|
||||
|
||||
pcf8574_for_HD44780 PCF8574_driver(
|
||||
.clock(I2C_SPEED),
|
||||
|
||||
.pcf_write_req(pcf_write_req),
|
||||
.pcf_command_data(pcf_command_data),
|
||||
.pcf_data(pcf_data),
|
||||
|
||||
.pcf_busy(pcf_busy),
|
||||
.new_backlight(1'b0),
|
||||
.backlight_update(1'b0),
|
||||
|
||||
.I2C_BUSY(I2C_BUSY),
|
||||
.I2C_SEND(I2C_SEND),
|
||||
|
||||
.i2c_data(i2c_data)
|
||||
);
|
||||
|
||||
// I2C driver
|
||||
|
||||
wire SCL,SDA,I2C_BUSY,I2C_SEND;
|
||||
assign gpio_1=SCL;
|
||||
assign gpio_0=SDA;
|
||||
reg [7:0]i2c_data;
|
||||
I2C_driver i2c_driver(
|
||||
.clock(I2C_SPEED),
|
||||
|
||||
.SDA_(SDA),
|
||||
.SCL(SCL),
|
||||
|
||||
.address(7'h27),
|
||||
.I2C_BUSY(I2C_BUSY),
|
||||
.I2C_SEND(I2C_SEND),
|
||||
.i2c_data(i2c_data),
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
258
system/peripherals/I2C_driver.v
Normal file
258
system/peripherals/I2C_driver.v
Normal file
@ -0,0 +1,258 @@
|
||||
/* I2C_driver.v - Implements an I2C interface
|
||||
|
||||
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 I2C_driver (
|
||||
input wire clock,
|
||||
inout wire SDA_,
|
||||
output reg SCL,
|
||||
|
||||
input wire [6:0] address,
|
||||
output reg I2C_BUSY=0,
|
||||
input wire I2C_SEND,
|
||||
input wire [7:0] i2c_data
|
||||
);
|
||||
|
||||
reg SDA;
|
||||
|
||||
assign SDA_=(i2c_bus_dir==0)?SDA:1'bz;
|
||||
|
||||
reg i2c_bus_dir=0;
|
||||
reg [5:0] i2c_state = 6'b100100;
|
||||
|
||||
reg [3:0] data_bit_counter;
|
||||
reg [7:0] data_internal;
|
||||
reg [6:0]address_internal;
|
||||
|
||||
always @(posedge clock) begin
|
||||
case (i2c_state)
|
||||
/***** start sequence ******/
|
||||
6'b000000:begin
|
||||
i2c_bus_dir<=0;
|
||||
SDA<=1;
|
||||
SCL<=1;
|
||||
i2c_state<=6'b000001;
|
||||
end
|
||||
6'b000001:begin
|
||||
SDA<=0;
|
||||
SCL<=1;
|
||||
i2c_state<=6'b000010;
|
||||
end
|
||||
6'b000010:begin
|
||||
SDA<=0;
|
||||
SCL<=0;
|
||||
i2c_state<=6'b000011;
|
||||
data_bit_counter<=0;
|
||||
end
|
||||
/****** Set address ********/
|
||||
6'b000011:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b000100;
|
||||
end
|
||||
6'b000100:begin
|
||||
SCL<=0;
|
||||
SDA<=address_internal[6:6];
|
||||
address_internal[6:0]<={address_internal[5:0],1'b0};
|
||||
data_bit_counter<=data_bit_counter+1;
|
||||
i2c_state<=6'b000101;
|
||||
end
|
||||
6'b000101:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b000110;
|
||||
end
|
||||
6'b000110:begin
|
||||
SCL<=1;
|
||||
if(data_bit_counter==4'd7)
|
||||
i2c_state<=6'b000111;
|
||||
else
|
||||
i2c_state<=6'b000011;
|
||||
end
|
||||
/****** Read/Write *********/
|
||||
6'b000111:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b001000;
|
||||
end
|
||||
6'b001000:begin
|
||||
SCL<=0;
|
||||
SDA<=0;/*Write=0 Read=1*/
|
||||
i2c_state<=6'b001001;
|
||||
end
|
||||
6'b001001:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b001010;
|
||||
end
|
||||
6'b001010:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b001011;
|
||||
end
|
||||
/****** Acknowledge ********/
|
||||
6'b001011:begin
|
||||
SCL<=0;
|
||||
i2c_bus_dir<=1;
|
||||
i2c_state<=6'b001100;
|
||||
end
|
||||
6'b001100:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b001101;
|
||||
end
|
||||
6'b001101:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b001110;
|
||||
end
|
||||
6'b001110:begin
|
||||
SCL<=1;
|
||||
// if (SDA==1)begin
|
||||
// led<=1;
|
||||
// i2c_state<=6'b011111;
|
||||
// end else begin
|
||||
i2c_state<=6'b001111;
|
||||
data_bit_counter<=0;
|
||||
// end
|
||||
end
|
||||
/****** separator ********/
|
||||
6'b001111:begin
|
||||
SCL<=0;
|
||||
SDA<=0;
|
||||
i2c_state<=6'b010000;
|
||||
end
|
||||
6'b010000:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b010001;
|
||||
end
|
||||
6'b010001:begin
|
||||
SCL<=0;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b010010;
|
||||
end
|
||||
6'b010010:begin
|
||||
SCL<=0;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b010011;
|
||||
end
|
||||
6'b010011:begin
|
||||
SCL<=0;
|
||||
SDA<=0;
|
||||
i2c_state<=6'b010100;
|
||||
end
|
||||
/****** Send data ********/
|
||||
6'b010100:begin
|
||||
SCL<=0;
|
||||
i2c_bus_dir<=0;
|
||||
i2c_state<=6'b010101;
|
||||
end
|
||||
6'b010101:begin
|
||||
SCL<=0;
|
||||
SDA<=data_internal[7:7];
|
||||
data_internal[7:0]<={data_internal[6:0],1'b0};
|
||||
data_bit_counter<=data_bit_counter+1;
|
||||
i2c_state<=6'b010110;
|
||||
end
|
||||
6'b010110:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b010111;
|
||||
end
|
||||
6'b010111:begin
|
||||
SCL<=1;
|
||||
if(data_bit_counter==4'd8)begin
|
||||
i2c_state<=6'b011000;
|
||||
end else
|
||||
i2c_state<=6'b010100;
|
||||
end
|
||||
/****** Acknowledge ********/
|
||||
6'b011000:begin
|
||||
i2c_bus_dir<=1;
|
||||
SCL<=0;
|
||||
i2c_state<=6'b011001;
|
||||
end
|
||||
6'b011001:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b011010;
|
||||
end
|
||||
6'b011010:begin
|
||||
SCL<=1;
|
||||
i2c_state<=6'b011011;
|
||||
end
|
||||
6'b011011:begin
|
||||
SCL<=1;
|
||||
// if (SDA==1)begin
|
||||
// led<=1;
|
||||
// i2c_state<=6'b011111;
|
||||
// end else begin
|
||||
i2c_state<=6'b011100;
|
||||
i2c_bus_dir<=0;
|
||||
// end
|
||||
end
|
||||
/****** separator ********/
|
||||
6'b011100:begin
|
||||
SCL<=0;
|
||||
SDA<=0;
|
||||
i2c_state<=6'b011101;
|
||||
end
|
||||
6'b011101:begin
|
||||
SCL<=0;
|
||||
i2c_state<=6'b011110;
|
||||
end
|
||||
6'b011110:begin
|
||||
SCL<=0;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b011111;
|
||||
end
|
||||
6'b011111:begin
|
||||
SCL<=0;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b100000;
|
||||
end
|
||||
6'b100000:begin
|
||||
SCL<=0;
|
||||
SDA<=0;
|
||||
i2c_state<=6'b100001;
|
||||
end
|
||||
/****** stop bit *******/
|
||||
6'b100001:begin
|
||||
SCL<=1;
|
||||
SDA<=0;
|
||||
i2c_state<=6'b100010;
|
||||
end
|
||||
6'b100010:begin
|
||||
SCL<=1;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b100011;
|
||||
end
|
||||
6'b100011:begin
|
||||
SCL<=1;
|
||||
SDA<=1;
|
||||
i2c_state<=6'b100100;
|
||||
I2C_BUSY<=0;
|
||||
end
|
||||
6'b100100:begin
|
||||
if(I2C_SEND==1)begin
|
||||
I2C_BUSY<=1;
|
||||
i2c_state<=0;
|
||||
data_internal<=i2c_data;
|
||||
address_internal<=address;
|
||||
end
|
||||
end
|
||||
default:begin
|
||||
SCL<=0;
|
||||
SDA<=0;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
114
system/peripherals/ascii_to_HD44780_driver.v
Normal file
114
system/peripherals/ascii_to_HD44780_driver.v
Normal file
@ -0,0 +1,114 @@
|
||||
/* ascii_to_HD44780_driver.v - driver that takes in ascii and outputs control
|
||||
sequences for an HD44780 display
|
||||
|
||||
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 ascii_to_HD44780_driver (
|
||||
/* system */
|
||||
input wire clock,
|
||||
input wire rst_n,
|
||||
|
||||
/* Data Input */
|
||||
output reg in_data_ready=0,
|
||||
input data_write_req,
|
||||
input [7:0] in_ascii_data,
|
||||
|
||||
/* write circuitry */
|
||||
input wire done_writing,
|
||||
output reg write_req=0,
|
||||
output reg [3:0] data,
|
||||
output reg cmd_data=0
|
||||
);
|
||||
|
||||
initial begin
|
||||
init_cmd_data[ 0] = 4'h3;
|
||||
init_cmd_data[ 1] = 4'h3;
|
||||
init_cmd_data[ 2] = 4'h3;
|
||||
init_cmd_data[ 3] = 4'h2;
|
||||
init_cmd_data[ 4] = 4'h2; //0x28
|
||||
init_cmd_data[ 5] = 4'h8;
|
||||
init_cmd_data[ 6] = 4'h0; //0x07
|
||||
init_cmd_data[ 7] = 4'h7;
|
||||
init_cmd_data[ 8] = 4'h0; //0x0C
|
||||
init_cmd_data[ 9] = 4'hC;
|
||||
init_cmd_data[10] = 4'h0; //0x01
|
||||
init_cmd_data[11] = 4'h1;
|
||||
init_cmd_data[12] = 4'h0; //0x06
|
||||
init_cmd_data[13] = 4'h6;
|
||||
init_cmd_data[14] = 4'h0; // 0x02
|
||||
init_cmd_data[15] = 4'h2;
|
||||
end
|
||||
|
||||
reg [4:0] init_seq=0;
|
||||
reg [5:0] data_write_wait_counter = 0;
|
||||
|
||||
reg [3:0] init_cmd_data [15:0];
|
||||
|
||||
reg byte_n=0;
|
||||
|
||||
reg data_write_latch=0;
|
||||
reg [7:0]print_data;
|
||||
|
||||
always @(posedge clock,negedge rst_n) begin
|
||||
if(rst_n==0)begin
|
||||
in_data_ready<=0;
|
||||
write_req<=1'b0;
|
||||
init_seq<=5'd0;
|
||||
data_write_wait_counter<=6'd0;
|
||||
byte_n<=1'b0;
|
||||
cmd_data<=1'b0;
|
||||
end else if(done_writing)begin
|
||||
if(init_seq!=5'd16&&data_write_wait_counter==6'd0)begin
|
||||
data<=init_cmd_data[init_seq[3:0]];
|
||||
init_seq<=init_seq+5'd1;
|
||||
write_req<=1'b1;
|
||||
data_write_wait_counter<=6'd50;
|
||||
in_data_ready<=0;
|
||||
end else if (data_write_wait_counter!=6'd0) begin
|
||||
data_write_wait_counter<=data_write_wait_counter-6'd1;
|
||||
write_req<=1'b0;
|
||||
in_data_ready<=0;
|
||||
end else if(data_write_req==1&&data_write_latch==0)begin
|
||||
data_write_latch<=1;
|
||||
print_data<=in_ascii_data;
|
||||
in_data_ready<=0;
|
||||
byte_n<=0;
|
||||
end else if(data_write_latch&byte_n==0)begin
|
||||
data<=print_data[7:4];
|
||||
write_req<=1'b1;
|
||||
data_write_wait_counter<=6'd50;
|
||||
byte_n<=1;
|
||||
end else if(data_write_latch&byte_n==1)begin
|
||||
data<=print_data[3:0];
|
||||
write_req<=1'b1;
|
||||
data_write_wait_counter<=6'd50;
|
||||
byte_n<=0;
|
||||
data_write_latch<=0;
|
||||
end else begin
|
||||
cmd_data<=1;
|
||||
in_data_ready<=1;
|
||||
end
|
||||
end else begin
|
||||
write_req<=1'b0;
|
||||
in_data_ready<=0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
123
system/peripherals/pcf8574_for_HD44780.v
Normal file
123
system/peripherals/pcf8574_for_HD44780.v
Normal file
@ -0,0 +1,123 @@
|
||||
/* 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
|
Loading…
Reference in New Issue
Block a user