80 lines
2.7 KiB
Verilog
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
|