Add diagrams and pictures
[clump.git] / i2c.v
1 module i2c_write (
2 input clk,
3 output scl,
4 output sda,
5 input [7:0] tx_byte,
6 input transmit,
7 input [5:0] more_bytes, /* 0 or 1 or 16 are reasonable */
8 input [7:0] mb_in,
9 output [5:0] mb_addr,
10 output is_transmitting);
11
12 parameter CLOCK_DIVIDE = 1;
13
14 // States for the transmitting state machine.
15 // We transmit a START, then the address (constant 0xE1), then
16 // [tx_byte], then [more_bytes] bytes from [mb_in]
17 parameter TX_IDLE = 0;
18 parameter TX_START = 1;
19 parameter TX_ADDRESS = 2;
20 parameter TX_FIRST_BYTE = 3;
21 parameter TX_MORE_BYTES = 4;
22 parameter TX_STOP = 5;
23
24 reg [30:0] tx_clk_divider = CLOCK_DIVIDE;
25
26 reg data_out = 1'b1;
27 reg clk_out = 1'b1;
28
29 reg [3:0] tx_state = TX_IDLE;
30 reg [5:0] tx_countdown;
31 reg [3:0] tx_bits_remaining;
32 reg [7:0] tx_data;
33
34 reg [3:0] step = 0;
35 reg [5:0] more_bytes_idx = 0;
36
37 wire [7:0] address = {7'h70, 1'b0}; // address 0x70, write
38 wire [15:0] address_data = {address, tx_data};
39
40 assign sda = data_out;
41 assign scl = clk_out;
42 assign is_transmitting = tx_state != TX_IDLE;
43 assign mb_addr = more_bytes_idx;
44
45 always @(posedge clk) begin
46 if(tx_clk_divider) begin
47 tx_clk_divider <= tx_clk_divider - 1;
48 end else begin
49 tx_clk_divider <= CLOCK_DIVIDE - 1;
50 end
51
52 case (tx_state)
53 TX_IDLE: begin
54 if (transmit) begin
55 tx_data = tx_byte;
56 tx_bits_remaining = 8;
57 step = 0;
58 tx_state = TX_START;
59 tx_clk_divider <= CLOCK_DIVIDE - 1;
60 end
61 end // case: TX_IDLE
62
63 TX_START: begin
64 if(tx_clk_divider) begin end
65 else begin
66 data_out = 0;
67 tx_state = TX_ADDRESS;
68 end
69 end
70
71 TX_ADDRESS: begin
72 if(tx_clk_divider) begin end
73 else if(step == 0) begin
74 clk_out <= 0;
75 step <= 1;
76 end else if (tx_bits_remaining == 0) begin
77 if(step == 1) begin
78 data_out <= 0; // really should be z, not 0
79 step <= 2;
80 end else if(step == 2)begin
81 clk_out <= 1;
82 step <= 3;
83 end else begin
84 step <= 0;
85
86 tx_state <= TX_FIRST_BYTE;
87 tx_bits_remaining <= 8;
88 end
89 end else if(step == 1) begin
90 data_out <= address[tx_bits_remaining - 1];
91 step <= 2;
92 end else if(step == 2) begin
93 clk_out <= 1;
94 step <= 3;
95 end else begin // step == 3
96 tx_bits_remaining = tx_bits_remaining - 1;
97 step <= 0;
98 end
99 end // case: TX_ADDRESS
100
101 TX_FIRST_BYTE: begin
102 if(tx_clk_divider) begin end
103 else if(step == 0) begin
104 clk_out <= 0;
105 step <= 1;
106 end else if (tx_bits_remaining == 0) begin
107 if(step == 1) begin
108 data_out <= 0; // really should be z, not 0
109 step <= 2;
110 end else if(step == 2)begin
111 clk_out <= 1;
112 step <= 3;
113 end else begin
114 step <= 0;
115
116 if(more_bytes)
117 tx_state <= TX_MORE_BYTES;
118 else
119 tx_state <= TX_STOP;
120 tx_bits_remaining <= 8;
121 more_bytes_idx <= 0;
122 end
123 end else if(step == 1) begin
124 data_out <= tx_data[tx_bits_remaining - 1];
125 step <= 2;
126 end else if(step == 2) begin
127 clk_out <= 1;
128 step <= 3;
129 end else begin // step == 3
130 tx_bits_remaining = tx_bits_remaining - 1;
131 step <= 0;
132 end
133 end // case: TX_FIRST_BYTE
134
135 TX_MORE_BYTES: begin
136 if(tx_clk_divider) begin end
137 else if(step == 0) begin
138 clk_out <= 0;
139 step <= 1;
140 end else if (tx_bits_remaining == 0) begin
141 if(step == 1) begin
142 data_out <= 0; // really should be z, not 0
143 step <= 2;
144 end else if(step == 2)begin
145 clk_out <= 1;
146 step <= 3;
147 end else begin
148 step <= 0;
149 tx_bits_remaining <= 8;
150
151 if(more_bytes_idx == more_bytes)
152 tx_state <= TX_STOP;
153 more_bytes_idx <= more_bytes_idx + 1;
154 end
155 end else if(step == 1) begin
156 data_out <= mb_in[tx_bits_remaining - 1];
157 step <= 2;
158 end else if(step == 2) begin
159 clk_out <= 1;
160 step <= 3;
161 end else begin // step == 3
162 tx_bits_remaining = tx_bits_remaining - 1;
163 step <= 0;
164 end
165 end // case: TX_MORE_BYTES
166
167 TX_STOP: begin
168 if(tx_clk_divider) begin end
169 else if(step == 0) begin
170 clk_out <= 0;
171 step <= 1;
172 end else if(step == 1) begin
173 step <= 2;
174 end else if(step == 2) begin
175 clk_out <= 1;
176 step <= 3;
177 end else begin
178 data_out <= 1;
179 step <= 0;
180 tx_state <= TX_IDLE;
181 end
182 end
183 endcase
184 end
185 endmodule // i2c_write
This page took 0.025275 seconds and 4 git commands to generate.