IIC bitbang changes - prepare to make the bit delay configurable; debug print changes.
* Right now the delay is hard coded at 10uS. This is a bit long when doing lots of periodic i2c transactions. So create a 'udelay' parameter and initialise it to 10. This can be tuned later. * Add a newline after a transaction finishes, so the debugging output isn't so horrible.
This commit is contained in:
parent
f90cdf352e
commit
943f0fd2d3
@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
struct iicbb_softc {
|
||||
device_t iicbus;
|
||||
int udelay; /* signal toggle delay in usec */
|
||||
};
|
||||
|
||||
static int iicbb_attach(device_t);
|
||||
@ -123,6 +124,7 @@ iicbb_attach(device_t dev)
|
||||
sc->iicbus = device_add_child(dev, "iicbus", -1);
|
||||
if (!sc->iicbus)
|
||||
return (ENXIO);
|
||||
sc->udelay = 10; /* 10 uS default */
|
||||
bus_generic_attach(dev);
|
||||
|
||||
return (0);
|
||||
@ -184,20 +186,18 @@ iicbb_print_child(device_t bus, device_t dev)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
#define IIC_DELAY 10
|
||||
|
||||
#define I2C_SETSDA(dev,val) do { \
|
||||
#define I2C_SETSDA(sc,dev,val) do { \
|
||||
IICBB_SETSDA(device_get_parent(dev), val); \
|
||||
DELAY(IIC_DELAY); \
|
||||
DELAY(sc->udelay); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_SETSCL(dev,val) do { \
|
||||
iicbb_setscl(dev, val, 100); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_SET(dev,ctrl,data) do { \
|
||||
#define I2C_SET(sc,dev,ctrl,data) do { \
|
||||
I2C_SETSCL(dev, ctrl); \
|
||||
I2C_SETSDA(dev, data); \
|
||||
I2C_SETSDA(sc, dev, data); \
|
||||
} while (0)
|
||||
|
||||
#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
|
||||
@ -216,34 +216,39 @@ static int i2c_debug = 0;
|
||||
static void
|
||||
iicbb_setscl(device_t dev, int val, int timeout)
|
||||
{
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
int k = 0;
|
||||
|
||||
IICBB_SETSCL(device_get_parent(dev), val);
|
||||
DELAY(IIC_DELAY);
|
||||
DELAY(sc->udelay);
|
||||
|
||||
while (val && !I2C_GETSCL(dev) && k++ < timeout) {
|
||||
IICBB_SETSCL(device_get_parent(dev), val);
|
||||
DELAY(IIC_DELAY);
|
||||
DELAY(sc->udelay);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
iicbb_one(device_t dev, int timeout)
|
||||
{
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(dev,1,1);
|
||||
I2C_SET(dev,0,1);
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
|
||||
I2C_SET(sc,dev,0,1);
|
||||
I2C_SET(sc,dev,1,1);
|
||||
I2C_SET(sc,dev,0,1);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
iicbb_zero(device_t dev, int timeout)
|
||||
{
|
||||
I2C_SET(dev,0,0);
|
||||
I2C_SET(dev,1,0);
|
||||
I2C_SET(dev,0,0);
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
|
||||
I2C_SET(sc,dev,0,0);
|
||||
I2C_SET(sc,dev,1,0);
|
||||
I2C_SET(sc,dev,0,0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -264,20 +269,21 @@ iicbb_zero(device_t dev, int timeout)
|
||||
static int
|
||||
iicbb_ack(device_t dev, int timeout)
|
||||
{
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
int noack;
|
||||
int k = 0;
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(dev,1,1);
|
||||
|
||||
I2C_SET(sc,dev,0,1);
|
||||
I2C_SET(sc,dev,1,1);
|
||||
do {
|
||||
noack = I2C_GETSDA(dev);
|
||||
if (!noack)
|
||||
break;
|
||||
DELAY(10);
|
||||
k += 10;
|
||||
DELAY(1);
|
||||
k++;
|
||||
} while (k < timeout);
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(sc,dev,0,1);
|
||||
I2C_DEBUG(printf("%c ",noack?'-':'+'));
|
||||
|
||||
return (noack);
|
||||
@ -302,16 +308,17 @@ iicbb_sendbyte(device_t dev, u_char data, int timeout)
|
||||
static u_char
|
||||
iicbb_readbyte(device_t dev, int last, int timeout)
|
||||
{
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
int i;
|
||||
unsigned char data=0;
|
||||
|
||||
I2C_SET(dev,0,1);
|
||||
|
||||
I2C_SET(sc,dev,0,1);
|
||||
for (i=7; i>=0; i--)
|
||||
{
|
||||
I2C_SET(dev,1,1);
|
||||
I2C_SET(sc,dev,1,1);
|
||||
if (I2C_GETSDA(dev))
|
||||
data |= (1<<i);
|
||||
I2C_SET(dev,0,1);
|
||||
I2C_SET(sc,dev,0,1);
|
||||
}
|
||||
if (last) {
|
||||
iicbb_one(dev, timeout);
|
||||
@ -337,13 +344,14 @@ iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
|
||||
static int
|
||||
iicbb_start(device_t dev, u_char slave, int timeout)
|
||||
{
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
int error;
|
||||
|
||||
I2C_DEBUG(printf("<"));
|
||||
|
||||
I2C_SET(dev,1,1);
|
||||
I2C_SET(dev,1,0);
|
||||
I2C_SET(dev,0,0);
|
||||
I2C_SET(sc,dev,1,1);
|
||||
I2C_SET(sc,dev,1,0);
|
||||
I2C_SET(sc,dev,0,0);
|
||||
|
||||
/* send address */
|
||||
iicbb_sendbyte(dev, slave, timeout);
|
||||
@ -364,10 +372,13 @@ iicbb_start(device_t dev, u_char slave, int timeout)
|
||||
static int
|
||||
iicbb_stop(device_t dev)
|
||||
{
|
||||
I2C_SET(dev,0,0);
|
||||
I2C_SET(dev,1,0);
|
||||
I2C_SET(dev,1,1);
|
||||
struct iicbb_softc *sc = device_get_softc(dev);
|
||||
|
||||
I2C_SET(sc,dev,0,0);
|
||||
I2C_SET(sc,dev,1,0);
|
||||
I2C_SET(sc,dev,1,1);
|
||||
I2C_DEBUG(printf(">"));
|
||||
I2C_DEBUG(printf("\n"));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user