diff --git a/components/modules/i2c_hw_master.c b/components/modules/i2c_hw_master.c index 74dc3312..8c81c365 100644 --- a/components/modules/i2c_hw_master.c +++ b/components/modules/i2c_hw_master.c @@ -102,13 +102,13 @@ static void i2c_transfer_task( task_param_t param, task_prio_t prio ) if (job->cb_ref != LUA_NOREF) { lua_rawgeti( L, LUA_REGISTRYINDEX, job->cb_ref ); - lua_pushinteger( L, job->err ); if (job->result) { // all fine, deliver read data lua_pushlstring( L, (char *)job->result->data, job->result->len ); } else { lua_pushnil( L ); } + lua_pushboolean( L, job->err == ESP_OK ); lua_call(L, 2, 0); } @@ -347,21 +347,32 @@ int li2c_hw_master_transfer( lua_State *L ) esp_err_t err = i2c_master_cmd_begin( job->port, job->cmd, job->to_ms > 0 ? job->to_ms / portTICK_RATE_MS : portMAX_DELAY ); - if (err == ESP_OK) { + switch (err) { + case ESP_OK: if (job->result) { // all fine, deliver read data lua_pushlstring( L, (char *)job->result->data, job->result->len ); } else { lua_pushnil( L ); } + lua_pushboolean( L, 1 ); // prepare the next transfer i2c_setup_ud_transfer( L, ud ); - return 1; - } + return 2; - i2c_setup_ud_transfer( L, ud ); - return i2c_lua_checkerr( L, err ); + case ESP_FAIL: + lua_pushnil( L ); + lua_pushboolean( L, 0 ); + + // prepare the next transfer + i2c_setup_ud_transfer( L, ud ); + return 2; + + default: + i2c_setup_ud_transfer( L, ud ); + return i2c_lua_checkerr( L, err ); + } } } diff --git a/docs/en/modules/i2c.md b/docs/en/modules/i2c.md index a29f999d..2cb4243d 100644 --- a/docs/en/modules/i2c.md +++ b/docs/en/modules/i2c.md @@ -129,18 +129,20 @@ Send (`SW`) or queue (`HWx`) an I²C stop condition. ## i2c.transfer() Starts a transfer for the specified hardware module. Providing a callback function allows the transfer to be started asynchronously in the background and `i2c.transfer()` finishes immediately. Without a callback function, the transfer is executed synchronously and `i2c.transfer()` comes back when the transfer completed. Data from a read operation is returned from `i2c.transfer()` in this case. -First argument to the callback is the error code (0 = no error), followed by a string with data obtained from a read operation during the transfer or `nil`. +First argument to the callback is a string with data obtained from a read operation during the transfer or `nil`, followed by the ack flag (true = ACK received). #### Syntax `i2c.transfer(id[, cb_fn][, to_ms])` #### Parameters - `id` interface id, `i2c.SW` not allowed -- `cb_fn(err, data)` function to be called when transfer finished +- `cb_fn(data, ack)` function to be called when transfer finished - `to_ms` timeout for the transfer in ms, defaults to 0=infinite #### Returns -- `string` of received data (or `nil` if no read) for synchronous operation +- synchronous operation: + - `data` string of received data (`nil` if no read or NACK) + - `ack` true if ACK received, false for NACK - `nil` for asynchronous operation ## i2c.write()