aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/serial_to_settings.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/serial_to_settings.v')
-rw-r--r--fpga/usrp3/lib/control/serial_to_settings.v111
1 files changed, 111 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/serial_to_settings.v b/fpga/usrp3/lib/control/serial_to_settings.v
new file mode 100644
index 000000000..53e112a62
--- /dev/null
+++ b/fpga/usrp3/lib/control/serial_to_settings.v
@@ -0,0 +1,111 @@
+
+
+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
+ );
+
+ 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)
+
+
+
+endmodule // serial_to_settings