From 189b037bdfed3a6a1693be2d5d4fe3eaf9aa1de0 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Sun, 12 Nov 2023 17:30:52 +0000 Subject: [PATCH] Added proper line wrapping for HD44780 LCDs and rewrote half the driver to make it more flexible --- system/peripherals/ascii_to_HD44780_driver.v | 167 +++++++++++++++---- 1 file changed, 137 insertions(+), 30 deletions(-) diff --git a/system/peripherals/ascii_to_HD44780_driver.v b/system/peripherals/ascii_to_HD44780_driver.v index fbf40d9..f1e6ea7 100644 --- a/system/peripherals/ascii_to_HD44780_driver.v +++ b/system/peripherals/ascii_to_HD44780_driver.v @@ -61,9 +61,13 @@ reg [3:0] init_cmd_data [15:0]; reg byte_n=0; -reg data_write_latch=0; reg [7:0]print_data; +reg [1:0]line=0; +reg [5:0]col=0; + +reg [7:0] driver_state =0; + always @(posedge clock,negedge rst_n) begin if(rst_n==0)begin in_data_ready<=0; @@ -72,40 +76,143 @@ always @(posedge clock,negedge rst_n) begin 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 + line<=0; + col<=0; + driver_state<=0; + end else begin + if (data_write_wait_counter!=6'd0 && done_writing) 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; + case(driver_state) + 8'd0:begin + if(done_writing)begin + if(init_seq!=5'd16&&data_write_wait_counter==6'd0)begin + /** Initialise display **/ + 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(col==6'd20)begin + /** Check if we run out of screen **/ + data<=4'hf; + write_req<=1'b1; + cmd_data<=1'b0; + data_write_wait_counter<=6'd50; + driver_state<=8'd2; + end else if(data_write_req==1)begin + cmd_data<=1'b1; + print_data<=in_ascii_data; + in_data_ready<=0; + driver_state<=8'd9; + end else begin + in_data_ready<=1; + end + end else begin + write_req<=1'b0; + in_data_ready<=0; + end + end + 8'd1:begin + if(done_writing==1) + driver_state<=8'd2; + end + 8'd2:begin + data<=4'hE; + cmd_data<=1'b0; + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd3; + write_req<=1'b0; + end else + write_req<=1'b1; + end + 8'd3:begin + if(done_writing==1) + driver_state<=8'd4; + end + 8'd4:begin + data<=4'h0; + cmd_data<=1'b0; + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd5; + write_req<=1'b0; + end else + write_req<=1'b1; + end + 8'd5:begin + if(done_writing==1) + driver_state<=8'd6; + end + 8'd6:begin + case(line) + 2'd0: data<=4'hC; + 2'd1: data<=4'h9; + 2'd2: data<=4'hD; + 2'd3: data<=4'hD; + endcase + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd7; + write_req<=1'b0; + end else + write_req<=1'b1; + end + 8'd7:begin + if(done_writing==1) + driver_state<=8'd8; + end + 8'd8:begin + case(line) + 2'd0: begin data<=4'h0; ; end + 2'd1: begin data<=4'h4; ; end + 2'd2: begin data<=4'h4; ; end + 2'd3: begin data<=4'h4; ; end + endcase + cmd_data<=1'b0; + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd0; + col<=0; + write_req<=1'b0; + case(line) + 2'd0: begin line<=1; end + 2'd1: begin line<=2; end + 2'd2: begin line<=3; end + 2'd3: begin line<=3; end + endcase + end else + write_req<=1'b1; + end + 8'd9:begin + data<=print_data[7:4]; + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd10; + write_req<=1'b0; + end else + write_req<=1'b1; + end + 8'd10:begin + if(done_writing==1) + driver_state<=8'd11; + end + 8'd11:begin + data<=print_data[3:0]; + data_write_wait_counter<=6'd50; + if(!done_writing)begin + driver_state<=8'd0; + write_req<=1'b0; + col<=col+1; + end else + write_req<=1'b1; + end + default: begin driver_state<=0; end + endcase end - end else begin - write_req<=1'b0; - in_data_ready<=0; end end