diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 80718090ab..f8f60210e6 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -157,6 +157,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| //| Read into ``buffer`` from the slave specified by ``address``. //| The number of bytes read will be the length of ``buffer``. +//| At least one byte must be read. //| //| If ``start`` or ``end`` is provided, then the buffer will be sliced //| as if ``buffer[start:end]``. This will not cause an allocation like @@ -186,6 +187,9 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a int32_t start = args[ARG_start].u_int; uint32_t length = bufinfo.len; normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + if (length == 0) { + mp_raise_ValueError("Buffer must be at least length 1"); + } uint8_t status = shared_module_bitbangio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, @@ -206,6 +210,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_rea //| as if ``buffer[start:end]``. This will not cause an allocation like //| ``buffer[start:end]`` will so it saves memory. //| +//| Writing a buffer or slice of length zero is permitted, as it can be used +//| to poll for the existence of a device. +//| //| :param int address: 7-bit device address //| :param bytearray buffer: buffer containing the bytes to write //| :param int start: Index to start writing from diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 6c7bac3e51..5442b9ea26 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -191,6 +191,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); //| .. method:: SPI.write(buf) //| //| Write the data contained in ``buf``. Requires the SPI being locked. +//| If the buffer is empty, nothing happens. //| // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { @@ -198,6 +199,9 @@ STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); mp_buffer_info_t src; mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ); + if (src.len == 0) { + return mp_const_none; + } check_lock(self); bool ok = shared_module_bitbangio_spi_write(self, src.buf, src.len); if (!ok) { @@ -210,7 +214,9 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write); //| .. method:: SPI.readinto(buf) //| -//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked. +//| Read into the buffer specified by ``buf`` while writing zeroes. +//| Requires the SPI being locked. +//| If the number of bytes to read is 0, nothing happens. //| // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { @@ -218,6 +224,9 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); + if (bufinfo.len == 0) { + return mp_const_none; + } check_lock(args[0]); bool ok = shared_module_bitbangio_spi_read(self, bufinfo.buf, bufinfo.len); if (!ok) { diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index add541aa70..72787af30b 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -207,7 +207,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); //| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer)) //| //| Write the data contained in ``buf``. Requires the SPI being locked. -//| At least one byte must be written. +//| If the buffer is empty, nothing happens. //| //| :param bytearray buffer: buffer containing the bytes to write //| :param int start: Index to start writing from @@ -233,7 +233,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); if (length == 0) { - mp_raise_ValueError("Buffer must be at least length 1"); + return mp_const_none; } bool ok = common_hal_busio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, length); @@ -247,8 +247,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write); //| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0) //| -//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked. -//| At least one byte must be read. +//| Read into the buffer specified by ``buf`` while writing zeroes. +//| Requires the SPI being locked. +//| If the number of bytes to read is 0, nothing happens. //| //| :param bytearray buffer: buffer to write into //| :param int start: Index to start writing at @@ -276,7 +277,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); if (length == 0) { - mp_raise_ValueError("Buffer must be at least length 1"); + return mp_const_none; } bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, length, args[ARG_write_value].u_int);