2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <vlib/vlib.h>
20 i2c_delay (i2c_bus_t * b, f64 timeout)
22 vlib_main_t *vm = vlib_get_main ();
23 vlib_time_wait (vm, timeout);
27 i2c_wait_for_scl (i2c_bus_t * b)
31 while (t < b->hold_time)
34 i2c_delay (b, b->rise_fall_time);
35 b->get_bits (b, &scl, &sda);
40 t += b->rise_fall_time;
46 i2c_start (i2c_bus_t * b)
50 b->put_bits (b, 1, 1);
53 if (vlib_i2c_bus_timed_out (b))
56 b->put_bits (b, 1, 0);
57 i2c_delay (b, b->hold_time);
58 b->put_bits (b, 0, 0);
59 i2c_delay (b, b->hold_time);
63 i2c_stop (i2c_bus_t * b)
65 b->put_bits (b, 0, 0);
66 i2c_delay (b, b->rise_fall_time);
68 b->put_bits (b, 1, 0);
69 i2c_delay (b, b->hold_time);
71 b->put_bits (b, 1, 1);
72 i2c_delay (b, b->hold_time);
76 i2c_write_bit (i2c_bus_t * b, int sda)
78 b->put_bits (b, 0, sda);
79 i2c_delay (b, b->rise_fall_time);
81 b->put_bits (b, 1, sda);
83 i2c_delay (b, b->hold_time);
85 b->put_bits (b, 0, sda);
86 i2c_delay (b, b->rise_fall_time);
90 i2c_read_bit (i2c_bus_t * b, int *sda)
94 b->put_bits (b, 1, 1);
96 i2c_delay (b, b->hold_time);
98 b->get_bits (b, &scl, sda);
100 b->put_bits (b, 0, 1);
101 i2c_delay (b, b->rise_fall_time);
105 i2c_write_byte (i2c_bus_t * b, u8 data)
109 for (i = 7; i >= 0; i--)
111 i2c_write_bit (b, (data >> i) & 1);
116 b->put_bits (b, 0, 1);
117 i2c_delay (b, b->rise_fall_time);
119 i2c_read_bit (b, &sda);
127 i2c_read_byte (i2c_bus_t * b, u8 * data, int ack)
133 b->put_bits (b, 0, 1);
134 i2c_delay (b, b->rise_fall_time);
136 for (i = 7; i >= 0; i--)
138 i2c_read_bit (b, &sda);
142 *data |= (sda != 0) << i;
145 i2c_write_bit (b, ack == 0);
150 vlib_i2c_init (i2c_bus_t * b)
156 tick = 1.0 / b->clock;
158 /* Spend 40% of time in low and high states */
160 b->hold_time = 0.4 * tick;
162 /* Spend 10% of time waiting for rise and fall */
163 if (!b->rise_fall_time)
164 b->rise_fall_time = 0.1 * tick;
168 vlib_i2c_xfer (i2c_bus_t * bus, i2c_msg_t * msgs)
173 vec_foreach (msg, msgs)
177 (msg->addr << 1) + (msg->flags == I2C_MSG_FLAG_READ));
179 if (msg->flags & I2C_MSG_FLAG_READ)
180 for (i = 0; i < msg->len; i++)
182 i2c_read_byte (bus, &msg->buffer[i], /* ack */ i + 1 != msg->len);
188 for (i = 0; i < msg->len; i++)
190 i2c_write_byte (bus, msg->buffer[i]);
201 vlib_i2c_read_eeprom (i2c_bus_t * bus, u8 i2c_addr, u16 start_addr,
202 u16 length, u8 * data)
207 vec_validate (msg, 1);
209 start_address[0] = start_addr;
210 msg[0].addr = i2c_addr;
211 msg[0].flags = I2C_MSG_FLAG_WRITE;
212 msg[0].buffer = (u8 *) & start_address;
215 msg[1].addr = i2c_addr;
216 msg[1].flags = I2C_MSG_FLAG_READ;
217 msg[1].buffer = data;
220 vlib_i2c_xfer (bus, msg);
226 * fd.io coding-style-patch-verification: ON
229 * eval: (c-set-style "gnu")