refine ack handling for i2c hw master

This commit is contained in:
devsaurus 2017-03-08 16:38:43 +01:00
parent d4b6180cd2
commit 2b98037fa9
2 changed files with 22 additions and 9 deletions

View File

@ -102,13 +102,13 @@ static void i2c_transfer_task( task_param_t param, task_prio_t prio )
if (job->cb_ref != LUA_NOREF) { if (job->cb_ref != LUA_NOREF) {
lua_rawgeti( L, LUA_REGISTRYINDEX, job->cb_ref ); lua_rawgeti( L, LUA_REGISTRYINDEX, job->cb_ref );
lua_pushinteger( L, job->err );
if (job->result) { if (job->result) {
// all fine, deliver read data // all fine, deliver read data
lua_pushlstring( L, (char *)job->result->data, job->result->len ); lua_pushlstring( L, (char *)job->result->data, job->result->len );
} else { } else {
lua_pushnil( L ); lua_pushnil( L );
} }
lua_pushboolean( L, job->err == ESP_OK );
lua_call(L, 2, 0); 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, esp_err_t err = i2c_master_cmd_begin( job->port, job->cmd,
job->to_ms > 0 ? job->to_ms / portTICK_RATE_MS : portMAX_DELAY ); job->to_ms > 0 ? job->to_ms / portTICK_RATE_MS : portMAX_DELAY );
if (err == ESP_OK) { switch (err) {
case ESP_OK:
if (job->result) { if (job->result) {
// all fine, deliver read data // all fine, deliver read data
lua_pushlstring( L, (char *)job->result->data, job->result->len ); lua_pushlstring( L, (char *)job->result->data, job->result->len );
} else { } else {
lua_pushnil( L ); lua_pushnil( L );
} }
lua_pushboolean( L, 1 );
// prepare the next transfer // prepare the next transfer
i2c_setup_ud_transfer( L, ud ); i2c_setup_ud_transfer( L, ud );
return 1; return 2;
}
i2c_setup_ud_transfer( L, ud ); case ESP_FAIL:
return i2c_lua_checkerr( L, err ); 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 );
}
} }
} }

View File

@ -129,18 +129,20 @@ Send (`SW`) or queue (`HWx`) an I²C stop condition.
## i2c.transfer() ## 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. 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 #### Syntax
`i2c.transfer(id[, cb_fn][, to_ms])` `i2c.transfer(id[, cb_fn][, to_ms])`
#### Parameters #### Parameters
- `id` interface id, `i2c.SW` not allowed - `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 - `to_ms` timeout for the transfer in ms, defaults to 0=infinite
#### Returns #### 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 - `nil` for asynchronous operation
## i2c.write() ## i2c.write()