Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Mar 2021 12:58:50 +0300
From:      Daniel Braniss <danny@cs.huji.ac.il>
To:        "freebsd-arm@freebsd.org" <arm@freebsd.org>
Subject:   i2c/twsi/allwinner problems.
Message-ID:  <CB54E711-FC72-44E3-BB69-916E470C490E@cs.huji.ac.il>

next in thread | raw e-mail | index | archive | help
hi all,
after some time, I decided to try FreeBSD 13 on my all winner (nano neo) =
and got it working only with
debugging on, so I started cherry picking till I got it working, =
replacing printfs with DELAY
and this is is now working, of course not the correct solution, but if =
someone with better
i2c knowledge can propose a better solution I=E2=80=99m willing to test =
if with my program (it reads RFIDs using
a board with PN532),

this are the diffs:
diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c
index a606c2aef..8ede62073 100644
--- a/sys/dev/iicbus/twsi/twsi.c
+++ b/sys/dev/iicbus/twsi/twsi.c
@@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$");
#define	TWSI_DEBUG
#undef TWSI_DEBUG

+#define	debug_(dev, fmt, args...) device_printf(dev, "%s: " fmt, =
__func__, ##args)
+
#ifdef TWSI_DEBUG
#define	debugf(dev, fmt, args...) device_printf(dev, "%s: " fmt, =
__func__, ##args)
#else
@@ -103,6 +105,7 @@ TWSI_READ(struct twsi_softc *sc, bus_size_t off)
{
	uint32_t val;

+	DELAY(1000); // danny: needed=20
	val =3D bus_read_4(sc->res[0], off);
	debugf(sc->dev, "read %x from %lx\n", val, off);
	return (val);
@@ -165,15 +168,14 @@ twsi_clear_iflg(struct twsi_softc *sc)
static int
twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask)
{
-
	timeout /=3D 10;
-	debugf(sc->dev, "Waiting for ctrl reg to match mask %x\n", =
mask);
+	debug_(sc->dev, "Waiting for ctrl reg to match mask %x =
timeout=3D%d\n", mask, timeout);
	while (!(TWSI_READ(sc, sc->reg_control) & mask)) {
-		DELAY(10);
+		 // DELAY(10);
		if (--timeout < 0)
			return (timeout);
	}
-	debugf(sc->dev, "done\n");
+	debug_(sc->dev, "done\n");
	return (0);
}

@@ -212,7 +214,7 @@ twsi_locked_start(device_t dev, struct twsi_softc =
*sc, int32_t mask,
	DELAY(1000);

	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
-		debugf(dev, "timeout sending %sSTART condition\n",
+		debug_(dev, "timeout sending %sSTART condition\n",
		    mask =3D=3D TWSI_STATUS_START ? "" : "repeated ");
		return (IIC_ETIMEOUT);
	}
@@ -221,7 +223,7 @@ twsi_locked_start(device_t dev, struct twsi_softc =
*sc, int32_t mask,
	debugf(dev, "status=3D%x\n", status);

	if (status !=3D mask) {
-		debugf(dev, "wrong status (%02x) after sending %sSTART =
condition\n",
+		debug_(dev, "wrong status (%02x) after sending %sSTART =
condition\n",
		    status, mask =3D=3D TWSI_STATUS_START ? "" : =
"repeated ");
		return (IIC_ESTATUS);
	}
@@ -231,7 +233,7 @@ twsi_locked_start(device_t dev, struct twsi_softc =
*sc, int32_t mask,
	DELAY(1000);

	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
-		debugf(dev, "timeout sending slave address =
(timeout=3D%d)\n", timeout);
+		debug_(dev, "timeout sending slave address =
(timeout=3D%d)\n", timeout);
		return (IIC_ETIMEOUT);
	}

@@ -239,7 +241,7 @@ twsi_locked_start(device_t dev, struct twsi_softc =
*sc, int32_t mask,
	status =3D TWSI_READ(sc, sc->reg_status);
	if (status !=3D (read_access ?
	    TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
-		debugf(dev, "no ACK (status: %02x) after sending slave =
address\n",
+		debug_(dev, "no ACK (status: %02x) after sending slave =
address\n",
		    status);
		return (IIC_ENOACK);
	}
@@ -405,7 +407,8 @@ twsi_read(device_t dev, char *buf, int len, int =
*read, int last, int delay)
	int last_byte, rv;

	sc =3D device_get_softc(dev);
-
+	debug_(dev, "twsi_read: len=3D%d delay=3D%d", len, delay); // =
danny
+=09
	mtx_lock(&sc->mutex);
	*read =3D 0;
	while (*read < len) {
@@ -423,7 +426,7 @@ twsi_read(device_t dev, char *buf, int len, int =
*read, int last, int delay)
		DELAY(1000);

		if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
-			debugf(dev, "timeout reading data (delay=3D%d)\n",=
 delay);
+			debug_(dev, "timeout reading data (delay=3D%d)\n",=
 delay);
			rv =3D IIC_ETIMEOUT;
			goto out;
		}
@@ -431,7 +434,7 @@ twsi_read(device_t dev, char *buf, int len, int =
*read, int last, int delay)
		status =3D TWSI_READ(sc, sc->reg_status);
		if (status !=3D (last_byte ?
		    TWSI_STATUS_DATA_RD_NOACK : =
TWSI_STATUS_DATA_RD_ACK)) {
-			debugf(dev, "wrong status (%02x) while =
reading\n", status);
+			debug_(dev, "wrong status (%02x) while =
reading\n", status);
			rv =3D IIC_ESTATUS;
			goto out;
		}
@@ -462,14 +465,14 @@ twsi_write(device_t dev, const char *buf, int len, =
int *sent, int timeout)
		twsi_clear_iflg(sc);
		DELAY(1000);
		if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
-			debugf(dev, "timeout writing data =
(timeout=3D%d)\n", timeout);
+			debug_(dev, "timeout writing data =
(timeout=3D%d)\n", timeout);
			rv =3D IIC_ETIMEOUT;
			goto out;
		}

		status =3D TWSI_READ(sc, sc->reg_status);
		if (status !=3D TWSI_STATUS_DATA_WR_ACK) {
-			debugf(dev, "wrong status (%02x) while =
writing\n", status);
+			debug_(dev, "wrong status (%02x) while =
writing\n", status);
			rv =3D IIC_ESTATUS;
			goto out;
		}
@@ -496,8 +499,12 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, =
uint32_t nmsgs)
	sc->control_val =3D TWSI_CONTROL_TWSIEN |
		TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK;
	TWSI_WRITE(sc, sc->reg_control, sc->control_val);
-	debugf(dev, "transmitting %d messages\n", nmsgs);
-	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
+#if 0
+	debug_(dev, "transmitting %d messages\n", nmsgs);
+	debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
+#else
+	DELAY(8000);
+#endif
	sc->nmsgs =3D nmsgs;
	sc->msgs =3D msgs;
	sc->msg_idx =3D 0;
@@ -519,15 +526,24 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, =
uint32_t nmsgs)
	debugf(sc->dev, "pause finish\n");

	if (sc->error) {
-		debugf(sc->dev, "Error, aborting (%d)\n", sc->error);
+		debug_(sc->dev, "Error, aborting (%d)\n", sc->error);
		TWSI_WRITE(sc, sc->reg_control, 0);
	}

	/* Disable module and interrupts */
-	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
+#if 0
+	debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status)); =
//
	TWSI_WRITE(sc, sc->reg_control, 0);
-	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
-
+	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status)); =
//
+	debugf(sc->dev, "error=3D%d\n", sc->error); // danny
+#else
+	int status;
+	DELAY(8000); // danny: works!
+	status =3D TWSI_READ(sc, sc->reg_status);
+	TWSI_WRITE(sc, sc->reg_control, 0);
+	status =3D TWSI_READ(sc, sc->reg_status);
+	//debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, =
sc->reg_status));
+#endif
	return (sc->error);
}

@@ -581,7 +597,7 @@ twsi_intr(void *arg)

	case TWSI_STATUS_ADDR_W_NACK:
	case TWSI_STATUS_ADDR_R_NACK:
-		debugf(sc->dev, "No ack received after transmitting the =
address\n");
+		debug_(sc->dev, "No ack received after transmitting the =
address\n");
		sc->transfer =3D 0;
		sc->error =3D IIC_ENOACK;
		sc->control_val =3D 0;
@@ -662,7 +678,7 @@ twsi_intr(void *arg)
		break;

	default:
-		debugf(sc->dev, "status=3D%x hot handled\n", status);
+		debug_(sc->dev, "status=3D%x hot handled\n", status);
		sc->transfer =3D 0;
		sc->error =3D IIC_EBUSERR;
		sc->control_val =3D 0;




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CB54E711-FC72-44E3-BB69-916E470C490E>