i2c/twsi/allwinner problems.

Daniel Braniss <[email protected]>
Newsgroups gmane.os.freebsd.devel.arm
Message-ID <[email protected]>
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’m 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 
	val = 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 /= 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=%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 == 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=%x\n", status);

	if (status != mask) {
-		debugf(dev, "wrong status (%02x) after sending %sSTART condition\n",
+		debug_(dev, "wrong status (%02x) after sending %sSTART condition\n",
		    status, mask == 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=%d)\n", timeout);
+		debug_(dev, "timeout sending slave address (timeout=%d)\n", timeout);
		return (IIC_ETIMEOUT);
	}

@@ -239,7 +241,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask,
	status = TWSI_READ(sc, sc->reg_status);
	if (status != (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 = device_get_softc(dev);
-
+	debug_(dev, "twsi_read: len=%d delay=%d", len, delay); // danny
+	
	mtx_lock(&sc->mutex);
	*read = 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=%d)\n", delay);
+			debug_(dev, "timeout reading data (delay=%d)\n", delay);
			rv = IIC_ETIMEOUT;
			goto out;
		}
@@ -431,7 +434,7 @@ twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
		status = TWSI_READ(sc, sc->reg_status);
		if (status != (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 = 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=%d)\n", timeout);
+			debug_(dev, "timeout writing data (timeout=%d)\n", timeout);
			rv = IIC_ETIMEOUT;
			goto out;
		}

		status = TWSI_READ(sc, sc->reg_status);
		if (status != TWSI_STATUS_DATA_WR_ACK) {
-			debugf(dev, "wrong status (%02x) while writing\n", status);
+			debug_(dev, "wrong status (%02x) while writing\n", status);
			rv = IIC_ESTATUS;
			goto out;
		}
@@ -496,8 +499,12 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
	sc->control_val = 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=%x\n", TWSI_READ(sc, sc->reg_status));
+#if 0
+	debug_(dev, "transmitting %d messages\n", nmsgs);
+	debug_(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
+#else
+	DELAY(8000);
+#endif
	sc->nmsgs = nmsgs;
	sc->msgs = msgs;
	sc->msg_idx = 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=%x\n", TWSI_READ(sc, sc->reg_status));
+#if 0
+	debug_(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); //
	TWSI_WRITE(sc, sc->reg_control, 0);
-	debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
-
+	debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); //
+	debugf(sc->dev, "error=%d\n", sc->error); // danny
+#else
+	int status;
+	DELAY(8000); // danny: works!
+	status = TWSI_READ(sc, sc->reg_status);
+	TWSI_WRITE(sc, sc->reg_control, 0);
+	status = TWSI_READ(sc, sc->reg_status);
+	//debug_(sc->dev, "status=%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 = 0;
		sc->error = IIC_ENOACK;
		sc->control_val = 0;
@@ -662,7 +678,7 @@ twsi_intr(void *arg)
		break;

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

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.