PERFORCE change 111931 for review
Warner Losh
imp at FreeBSD.org
Mon Dec 18 23:57:19 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=111931
Change 111931 by imp at imp_lighthouse on 2006/12/19 07:57:09
Fix two major bugs, and a bunch of nits:
o Eliminate an extra, redundant reading off the sr.
o If we don't read enough bytes, don't pretend that we did. Instead,
return an error. Maybe we should give an indication of how many
bytes were read in this case, but for now we just return the error.
o When we encounter an error, use the big hammer of software reset
to fix. This may not be entirely necessary but seems to help
solve problems we see when reading after there's been an error.
o Return ENXIO for NACK. Lame error message, but follows existing
practice.
o Use #defines for clock speeds rather than hard coding numbers.
# this makes it possible to read from existent and then non-existent
# devices in a tight loop w/o occasional data corruption of many
# flavors.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 (text+ko) ====
@@ -45,6 +45,10 @@
#include <dev/iicbus/iicbus.h>
#include "iicbus_if.h"
+#define TWI_SLOW_CLOCK 1500
+#define TWI_FAST_CLOCK 45000
+#define TWI_FASTEST_CLOCK 90000
+
struct at91_twi_softc
{
device_t dev; /* Myself */
@@ -123,7 +127,7 @@
AT91_TWI_LOCK_DESTROY(sc);
goto out;
}
- sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / 90000) |
+ sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / TWI_FASTEST_CLOCK) |
TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) |
TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK));
WR4(sc, TWI_CR, TWI_CR_SWRST);
@@ -232,7 +236,7 @@
if (counter <= 0)
err = EBUSY;
else if (sr & TWI_SR_NACK)
- err = EADDRNOTAVAIL;
+ err = ENXIO; // iic nack convention
return (err);
}
@@ -252,17 +256,17 @@
*/
switch (speed) {
case IIC_SLOW:
- clk = 1500;
+ clk = TWI_SLOW_CLOCK;
break;
case IIC_FAST:
- clk = 45000;
+ clk = TWI_FAST_CLOCK;
break;
case IIC_UNKNOWN:
case IIC_FASTEST:
default:
- clk = 90000;
+ clk = TWI_FASTEST_CLOCK;
break;
}
sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) |
@@ -332,7 +336,6 @@
if (msgs[i].flags & IIC_M_RD) {
sr = RD4(sc, TWI_SR);
while (!(sr & TWI_SR_TXCOMP)) {
- sr = RD4(sc, TWI_SR);
if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) {
len--;
*buf++ = RD4(sc, TWI_RHR) & 0xff;
@@ -340,8 +343,8 @@
WR4(sc, TWI_CR, TWI_CR_STOP);
}
}
- if (sr & TWI_SR_NACK) {
- err = EADDRNOTAVAIL;
+ if (len > 0 || (sr & TWI_SR_NACK)) {
+ err = ENXIO; // iic nack convention
goto out;
}
} else {
@@ -357,8 +360,11 @@
break;
}
out:;
- if (err)
- WR4(sc, TWI_CR, TWI_CR_STOP);
+ if (err) {
+ WR4(sc, TWI_CR, TWI_CR_SWRST);
+ WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
+ WR4(sc, TWI_CWGR, sc->cwgr);
+ }
AT91_TWI_UNLOCK(sc);
return (err);
}
More information about the p4-projects
mailing list