common-hal I2C combined write_read

This commit is contained in:
Dan Halbert 2022-01-31 22:03:30 -05:00
parent d5740c8ad9
commit cc410ad6a3
12 changed files with 134 additions and 30 deletions

View File

@ -1616,7 +1616,7 @@ msgstr ""
#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c
#, c-format
msgid "No I2C device at address: %x"
msgid "No I2C device at address: 0x%x"
msgstr ""
#: ports/espressif/common-hal/busio/SPI.c
@ -4069,7 +4069,10 @@ msgstr ""
#: ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h
#: ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h
msgid "pressing boot button at start up.\n"
msgstr ""

View File

@ -190,7 +190,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
self->has_lock = false;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
uint16_t attempts = ATTEMPTS;
@ -216,6 +216,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
return MP_EIO;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
@ -242,6 +247,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
return MP_EIO;
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
never_reset_sercom(self->i2c_desc.device.hw);

View File

@ -124,7 +124,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
}
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
uint8_t result = common_hal_busio_i2c_write(self, addr, NULL, 0, true);
uint8_t result = common_hal_busio_i2c_write(self, addr, NULL, 0);
return result == 0;
}
@ -147,7 +147,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
// Discussion of I2C implementation is here: https://github.com/raspberrypi/linux/issues/254
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
COMPLETE_MEMORY_READS;
self->peripheral->S_b.DONE = true;
@ -202,6 +202,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
return 0;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
COMPLETE_MEMORY_READS;
@ -247,6 +252,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
return 0;
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
never_reset_i2c[self->index] = true;

View File

@ -97,7 +97,7 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
return I2C_TRANSFER(self->i2c_dev, &msg, 1) < 0 ? false : true;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) {
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) {
struct i2c_msg_s msg;
msg.frequency = self->frequency;
@ -108,6 +108,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, cons
return -I2C_TRANSFER(self->i2c_dev, &msg, 1);
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) {
struct i2c_msg_s msg;
@ -119,6 +124,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8
return -I2C_TRANSFER(self->i2c_dev, &msg, 1);
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
never_reset_pin_number(self->scl_pin->number);
never_reset_pin_number(self->sda_pin->number);

View File

@ -182,19 +182,19 @@ static uint8_t convert_esp_err(esp_err_t result) {
}
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t addr, const uint8_t *data, size_t len) {
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) {
return convert_esp_err(len == 0
? i2c_zero_length_write(self, addr, 100)
: i2c_master_write_to_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */)
: i2c_master_write_to_device(self->i2c_num, (uint8_t)addr, data, len, 100 /* wait in ticks */)
);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len) {
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) {
return convert_esp_err(
i2c_master_read_from_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */));
i2c_master_read_from_device(self->i2c_num, (uint8_t)addr, data, len, 100 /* wait in ticks */));
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t addr,
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
return convert_esp_err(
i2c_master_write_read_device(self->i2c_num, (uint8_t)addr,

View File

@ -210,7 +210,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
self->has_lock = false;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
lpi2c_master_transfer_t xfer = { 0 };
@ -227,6 +227,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
return MP_EIO;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
@ -243,3 +248,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
return MP_EIO;
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}

View File

@ -238,7 +238,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
self->has_lock = false;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) {
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) {
if (len == 0) {
return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV;
}
@ -266,6 +266,10 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u
return twi_error_to_mp(err);
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) {
if (len == 0) {
return 0;
@ -292,3 +296,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t
return twi_error_to_mp(err);
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}

View File

@ -145,7 +145,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
}
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
return common_hal_busio_i2c_write(self, addr, NULL, 0, true) == 0;
return common_hal_busio_i2c_write(self, addr, NULL, 0) == 0;
}
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
@ -165,7 +165,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
self->has_lock = false;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
if (len == 0) {
// The RP2040 I2C peripheral will not perform 0 byte writes.
@ -203,6 +203,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
}
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
int result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US);
@ -219,6 +224,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
}
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
never_reset_i2c[i2c_hw_index(self->peripheral)] = true;

View File

@ -246,7 +246,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
self->has_lock = false;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len, bool transmit_stop_bit) {
HAL_StatusTypeDef result;
if (!transmit_stop_bit) {
@ -271,6 +271,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
return result == HAL_OK ? 0 : MP_EIO;
}
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr,
const uint8_t *data, size_t len) {
return _common_hal_busio_i2c_write(self, addr, data, len, true);
}
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *data, size_t len) {
if (!self->frame_in_prog) {
@ -288,6 +293,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
}
}
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false);
if (result != 0) {
return result;
}
return common_hal_busio_i2c_read(self, addr, in_data, in_len);
}
STATIC void i2c_clock_enable(uint8_t mask) {
// Note: hard reset required due to soft reboot issue.
#ifdef I2C1

View File

@ -60,16 +60,16 @@ extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self);
extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr);
// Write to the device and return 0 on success or an appropriate error code from mperrno.h
extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t address,
extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address,
const uint8_t *data, size_t len);
// Reads memory of the i2c device picking up where it left off and return 0 on
// success or an appropriate error code from mperrno.h
extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t address,
extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address,
uint8_t *data, size_t len);
// Do a write and then a read in the same I2C transaction.
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t address,
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address,
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len);
// This is used by the supervisor to claim I2C devices indefinitely.

View File

@ -79,7 +79,7 @@ void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_devi
common_hal_adafruit_bus_device_i2cdevice_unlock(self);
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address);
mp_raise_ValueError_varg(translate("No I2C device at address: 0x%x"), self->device_address);
} else {
/* In case we receive an unrelated exception pass it up */
nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));

View File

@ -106,9 +106,8 @@ void common_hal_is31fl3741_IS31FL3741_reconstruct(is31fl3741_IS31FL3741_obj_t *s
common_hal_displayio_is31fl3741_begin_transaction(self);
uint8_t command = 0xFC; // device ID
common_hal_busio_i2c_write(self->i2c, self->device_address, &command, 1, false);
uint8_t data = 0;
common_hal_busio_i2c_read(self->i2c, self->device_address, &data, 1);
common_hal_busio_i2c_write_read(self->i2c, self->device_address, &command, 1, &data, 1);
is31fl3741_send_reset(self->i2c, self->device_address);
is31fl3741_send_enable(self->i2c, self->device_address);
@ -275,7 +274,7 @@ uint8_t cur_page = 99; // set to invalid page to start
void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) {
uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command
common_hal_busio_i2c_write(i2c, addr, unlock, 2, true);
common_hal_busio_i2c_write(i2c, addr, unlock, 2);
}
void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) {
@ -288,35 +287,33 @@ void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) {
uint8_t page[2] = { 0xFD, 0x00 }; // page command
page[1] = p;
common_hal_busio_i2c_write(i2c, addr, page, 2, true);
common_hal_busio_i2c_write(i2c, addr, page, 2);
}
void is31fl3741_send_enable(busio_i2c_obj_t *i2c, uint8_t addr) {
is31fl3741_set_page(i2c, addr, 4);
uint8_t enable[2] = { 0x00, 0x01 }; // enable command
common_hal_busio_i2c_write(i2c, addr, enable, 2, true);
common_hal_busio_i2c_write(i2c, addr, enable, 2);
}
void is31fl3741_send_reset(busio_i2c_obj_t *i2c, uint8_t addr) {
is31fl3741_set_page(i2c, addr, 4);
uint8_t rst[2] = { 0x3F, 0xAE }; // reset command
common_hal_busio_i2c_write(i2c, addr, rst, 2, true);
common_hal_busio_i2c_write(i2c, addr, rst, 2);
}
void is31fl3741_set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current) {
is31fl3741_set_page(i2c, addr, 4);
uint8_t gcur[2] = { 0x01, 0x00 }; // global current command
gcur[1] = current;
common_hal_busio_i2c_write(i2c, addr, gcur, 2, true);
common_hal_busio_i2c_write(i2c, addr, gcur, 2);
}
uint8_t is31fl3741_get_current(busio_i2c_obj_t *i2c, uint8_t addr) {
is31fl3741_set_page(i2c, addr, 4);
uint8_t gcur = 0x01; // global current command
common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true);
uint8_t data = 0;
common_hal_busio_i2c_read(i2c, addr, &data, 1);
common_hal_busio_i2c_write_read(i2c, addr, &gcur, 1, &data, 1);
return data;
}
@ -333,7 +330,7 @@ void is31fl3741_set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_
cmd[1] = level;
common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
common_hal_busio_i2c_write(i2c, addr, cmd, 2);
}
void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color, uint16_t *mapping) {