Skip to content

Commit 7e9d9df

Browse files
committed
Use nicer atoms for I2C bus errors
These errors can happen when the I2C bus hangs or a zero-byte transfer is tried, but not supported. There are two kinds of timeouts: * `{:error, :timeout}` - Seen on Allwinner when the I2C bus is hung by a device pulling SDA low. If the device tree/Linux isn't configured to recover and the SDA line isn't released, then the error will continue. * `{:error, :retry}` - Seen on Beagleboards (TI AM335x) when the I2C bus is hung and there's an attempt to recover the bus.
1 parent 0207cdc commit 7e9d9df

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

c_src/i2c_nif.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ struct I2cNifPriv {
116116
static ERL_NIF_TERM atom_ok;
117117
static ERL_NIF_TERM atom_error;
118118
static ERL_NIF_TERM atom_nak;
119+
static ERL_NIF_TERM atom_timeout;
120+
static ERL_NIF_TERM atom_retry;
119121

120122
static void i2c_dtor(ErlNifEnv *env, void *obj)
121123
{
@@ -152,6 +154,8 @@ static int i2c_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM info)
152154
atom_ok = enif_make_atom(env, "ok");
153155
atom_error = enif_make_atom(env, "error");
154156
atom_nak = enif_make_atom(env, "i2c_nak");
157+
atom_timeout = enif_make_atom(env, "timeout");
158+
atom_retry = enif_make_atom(env, "retry");
155159

156160
*priv_data = priv;
157161
return 0;
@@ -173,10 +177,24 @@ static ERL_NIF_TERM enif_make_errno_error(ErlNifEnv *env)
173177
reason = atom_nak;
174178
break;
175179
#endif
180+
case ETIMEDOUT:
181+
// I2C bus hung. On some platforms, Linux can try to recover it.
182+
reason = atom_timeout;
183+
break;
184+
185+
case EAGAIN:
186+
// I2C bus hung and an attempt is being made to recover it.
187+
reason = atom_retry;
188+
break;
189+
176190
case ENOENT:
177191
reason = enif_make_atom(env, "bus_not_found");
178192
break;
179193

194+
case EOPNOTSUPP:
195+
reason = enif_make_atom(env, "not_supported");
196+
break;
197+
180198
default:
181199
// strerror isn't usually that helpful, so if these
182200
// errors happen, please report or update this code

0 commit comments

Comments
 (0)