Files
b210-k7-fpga/lib/control/serial_to_settings.v
T
Ben Hilburn fbbc991a7d Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
2014-02-14 12:05:07 -08:00

122 lines
2.3 KiB
Verilog

module serial_to_settings
(
input clk,
input reset,
// Serial signals (async)
input scl,
input sda,
// Settngs bus out
output reg set_stb,
output reg [7:0] set_addr,
output reg [31:0] set_data,
// Debug
output [31:0] debug
);
reg [2:0] state;
localparam SEARCH = 3'h0;
localparam ADDRESS = 3'h1;
localparam DATA = 3'h2;
localparam STOP1 = 3'h3;
localparam STOP2 = 3'h4;
reg scl_pre_reg, scl_reg, scl_reg2;
reg sda_pre_reg, sda_reg, sda_reg2;
reg [4:0] counter;
always @(posedge clk) begin
scl_reg2 <= scl_reg;
scl_reg <= scl_pre_reg;
scl_pre_reg <= scl;
sda_reg2 <= sda_reg;
sda_reg <= sda_pre_reg;
sda_pre_reg <= sda;
end
always @(posedge clk)
if (reset) begin
state <= SEARCH;
counter <= 0;
set_addr <= 0;
set_data <= 0;
set_stb <= 0;
end else begin
case(state)
//
// Search for I2C like start indication: SDA goes low whilst clock is high.
//
SEARCH: begin
set_stb <= 0;
// Look for START.
if (scl_reg && scl_reg2 && !sda_reg && sda_reg2) begin
state <= ADDRESS;
counter <= 0;
end
end
//
// Count 8 Address bits.
// Master changes SDA on falling edge of SCL, we sample on the rising edge.
//
ADDRESS: begin
if (scl_reg && !scl_reg2) begin
set_addr[7:0] <= {set_addr[6:0],sda_reg};
if (counter == 7) begin
state <= DATA;
counter <= 0;
end else
counter <= counter + 1;
end
end
//
// Count 32 data bits.
// Master changes SDA on falling edge of SCL, we sample on the rising edge.
//
DATA: begin
if (scl_reg && !scl_reg2) begin
set_data[31:0] <= {set_data[30:0],sda_reg};
if (counter == 31) begin
state <= STOP1;
counter <= 0;
end else
counter <= counter + 1;
end
end
//
// Looks for rising SCL edge before STOP bit.
//
STOP1: begin
if (scl_reg && !scl_reg2) begin
state <= STOP2;
end
end
//
// Looks for STOP bit
//
STOP2: begin
if (scl_reg && scl_reg2 && sda_reg && !sda_reg2) begin
state <= SEARCH;
counter <= 0;
set_stb <= 1;
end
end
endcase // case(state)
end // else: !if(reset)
assign debug =
{
counter[4:0],
state[2:0],
scl_reg,
sda_reg
};
endmodule // serial_to_settings