80 lines
2.7 KiB
Verilog

/*
* LCD communicates with ILI9341V LCD controller over 4 wire SPI.
*
* When load=1 and in[8]=0 transmission of byte in[7:0] is initiated.
* CSX is goes low (and stays low even when transmission is completed).
* DCX is set to in[9]. The byte in[7:0] is send to SDO bitwise together
* with 8 clock signals on SCK. During transmission out[15] is 1.
* After 16 clock cycles transmission is completed and out[15] is set to 0.
*
* When load=1 and in[8]=1 CSX goes high and DCX=in[9] without transmission
* of any bit.
*
* When load16=1 transmission of word in[15:0] is initiated. CSX is goes low
* (and stays low even when transmission is completed). DCX is set to 1 (data).
* After 32 clock cycles transmission is completed and out[15] is set to 0.
*/
`default_nettype none
module LCD (
input wire clk, // 25 MHz clock
input wire load, // Start sending 8-bit command/data
input wire load16, // Start sending 16-bit data
input wire [15:0] in, // Data to be sent
output reg [15:0] out, // Status output
output reg DCX, // Data/Command select (1 = data, 0 = command)
output reg CSX, // Chip select (active low)
output reg SDO, // Serial data out (MOSI)
output reg SCK // Serial clock
);
reg [15:0] shift_reg = 16'b0;
reg [3:0] bit_counter = 0;
reg transmitting = 0;
reg is_16bit = 0;
initial begin
CSX <= 1;
DCX <= 0;
SCK <= 0;
SDO <= 0;
end
always @(posedge clk) begin
// Default signal values
SCK <= 0;
SDO <= transmitting ? SDO : 0;
out <= (transmitting || load || load16) ? 16'h8000 : 16'h0000;
//CSX <= ~transmitting;
// Handle new transmission start
if ((load || load16) && ~transmitting) begin
transmitting <= 1;
bit_counter <= (load16) ? 15 : 7;
shift_reg <= (load16) ? in : {8'b0, in[7:0]};
is_16bit <= load16;
DCX <= (load16) ? 1 : in[9]; // data if load16 or in[9] for load
CSX <= 0;
SDO <= (load16) ? in[15] : in[7]; // First bit to send
end
// Continue shifting out bits
else if (transmitting) begin
SCK <= ~SCK;
if (SCK == 1) begin
// Set next bit on falling edge
SDO <= shift_reg[bit_counter - 1];
bit_counter <= bit_counter - 1;
end
else begin
// Shift on rising edge
if (bit_counter == 0 && SCK == 0) begin
transmitting <= 0;
end
end
end
end
endmodule