/*
*/
#include "efb.h"
#include "efb_i2c.h"
static int efb_write_bit(void *, int, const efb_i2c_functions_t *, int);
static int efb_read_bit(void *, int, const efb_i2c_functions_t *, int *);
int
{
int status;
/*
* A word of explanation. During data transfers in the I2C protocol,
* data never changes while the clock is high. The "start" and 'stop"
* conditions are marked by doing just that. The "stop" condition
* is signaled by raising the data line while the clock is high.
*
* This condition should be as simple to implement as simply calling
* set_sda(1). The problem here is that we can't count on the
* initial states of either clock or data.
*
* To make this work, we need to first make sure the data line is low
* so we can raise it. However, in order to make sure that lowering
* the data line doesn't generate a start condition, we must also make
* sure the clock is low too. Thus, the sequence is:
* lower clock
* lower data
* raise clock
* raise data <= this is the actual "stop"
*
* TODO: would it make sense to read the clock and data lines first
* so we can skip these steps?
*/
if (status != EFB_I2C_OK) {
return (status);
}
return (EFB_I2C_OK);
}
int
{
int status;
/*
* See above. A start condition is caused by data going low
* while clock is high.
*/
if (status != EFB_I2C_OK) {
return (status);
}
return (EFB_I2C_OK);
}
static int
{
int status;
/* Read a byte from client without sending either ack or nack */
return (status);
}
*rval =
(b7 << 7) |
(b6 << 6) |
(b5 << 5) |
(b4 << 4) |
(b3 << 3) |
(b2 << 2) |
(b1 << 1) |
(b0 << 0);
return (EFB_I2C_OK);
}
int
{
int status;
if (status != EFB_I2C_OK) {
return (status);
}
}
int
{
int status;
if (status != EFB_I2C_OK) {
return (status);
}
if (status != EFB_I2C_OK) {
return (status);
}
}
static int
{
int status;
if (status != EFB_I2C_OK) {
return (status);
}
return (EFB_I2C_OK);
}
int
{
int status;
int i;
int bit;
/* Read the bits high-to-low, write them out */
for (i = 0; i < 8; ++i) {
data <<= 1;
if (status != EFB_I2C_OK) {
return (status);
}
}
}
static int
{
int status;
/*
* One clock cycle is divided into four units of clock_interval.
* The timing diagram looks like:
*
* SDA _----____----___ (_=old data, -=new)
* SCL __--__--__--__--
* ^^^^
* one cycle
*
* (This diagram illustrates four transfer cycles, this
* function only executes one.)
*/
if (status != EFB_I2C_OK) {
return (status);
}
return (EFB_I2C_OK);
}
int
const efb_i2c_functions_t *fcns)
{
int status;
/*
* We've transfered eight bits to the slave. Cycle the clock
* one more time and let the slave acknowledge by pulling the
* data line to zero.
*/
if (status != EFB_I2C_OK) {
return (status);
}
}
void
{
}
int
{
int status = 0;
/*
* Slave devices can put a transfer on hold by holding the
* clock low. This function waits up to 10 ms for the
* clock to go high before returning error.
*/
while (--count >= 0) {
drv_usecwait(1);
break;
}
}
return (status);
}