I2C/IIC working on RPI4 8GB?
Emmanuel Vadot
manu at bidouilliste.com
Mon Apr 26 14:06:21 UTC 2021
On Sun, 25 Apr 2021 18:41:31 +0300
Daniel Braniss <danny at cs.huji.ac.il> wrote:
>
>
> > On 25 Apr 2021, at 15:32, Mark Murray <markm at FreeBSD.org> wrote:
> >
> > Hi All,
> >
> > Does anyone here have IIC/I2C working on a CURRENT (I'm running latest) FreeBSD?
> >
> > I've never seen it work; Last time I had working IIC was on an RPI3.
> >
> > There is a /dev/iic0, and I have a known working RTC on it, but the scan just times out:
> >
> > [root at grasshopper ~]# i2c -s
> > Hardware may not support START/STOP scanning; trying less-reliable read method.
> > <TIMEOUT>
> > Scanning I2C devices on /dev/iic0: <none found>
> >
> >
> > I suspect something not-quite-right in DTS land, but I lack the knowledge to investigate. I've done some random stumbling around in the dark with overlays and the like, but I've either seen the above error, or a total lack of /dev/iic0.
> >
> > Thanks!
> >
> > M
> > --
> > Mark R V Murray
> >
>
> Q1: do you see /dev/iic?
> Q2: i2c -s shows anything?
>
> fianlly, you can try my patch, it works for me, but I understand it?s a five kilo hammer :-)
RPI doesn't uses twsi so that will not change a thing.
> 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;
> _______________________________________________
> freebsd-arm at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-arm
> To unsubscribe, send any mail to "freebsd-arm-unsubscribe at freebsd.org"
--
Emmanuel Vadot <manu at bidouilliste.com> <manu at FreeBSD.org>
More information about the freebsd-arm
mailing list