Skip to content

Commit 78f6c22

Browse files
committed
Allow empty reads and writes for busio.SPI
This is mostly for convenience, so that user code doesn't need to add additional checks. Also, bring the bitbangio into compatibility with busio wrt. empty buffers.
1 parent c066e4d commit 78f6c22

3 files changed

Lines changed: 23 additions & 6 deletions

File tree

shared-bindings/bitbangio/I2C.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock);
157157
//|
158158
//| Read into ``buffer`` from the slave specified by ``address``.
159159
//| The number of bytes read will be the length of ``buffer``.
160+
//| At least one byte must be read.
160161
//|
161162
//| If ``start`` or ``end`` is provided, then the buffer will be sliced
162163
//| 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
186187
int32_t start = args[ARG_start].u_int;
187188
uint32_t length = bufinfo.len;
188189
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
190+
if (length == 0) {
191+
mp_raise_ValueError("Buffer must be at least length 1");
192+
}
189193
uint8_t status = shared_module_bitbangio_i2c_read(self,
190194
args[ARG_address].u_int,
191195
((uint8_t*)bufinfo.buf) + start,
@@ -206,6 +210,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_rea
206210
//| as if ``buffer[start:end]``. This will not cause an allocation like
207211
//| ``buffer[start:end]`` will so it saves memory.
208212
//|
213+
//| Writing a buffer or slice of length zero is permitted, as it can be used
214+
//| to poll for the existence of a device.
215+
//|
209216
//| :param int address: 7-bit device address
210217
//| :param bytearray buffer: buffer containing the bytes to write
211218
//| :param int start: Index to start writing from

shared-bindings/bitbangio/SPI.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,17 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock);
191191
//| .. method:: SPI.write(buf)
192192
//|
193193
//| Write the data contained in ``buf``. Requires the SPI being locked.
194+
//| If the buffer is empty, nothing happens.
194195
//|
195196
// TODO(tannewt): Add support for start and end kwargs.
196197
STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
197198
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
198199
raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
199200
mp_buffer_info_t src;
200201
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
202+
if (src.len == 0) {
203+
return mp_const_none;
204+
}
201205
check_lock(self);
202206
bool ok = shared_module_bitbangio_spi_write(self, src.buf, src.len);
203207
if (!ok) {
@@ -210,14 +214,19 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write);
210214

211215
//| .. method:: SPI.readinto(buf)
212216
//|
213-
//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked.
217+
//| Read into the buffer specified by ``buf`` while writing zeroes.
218+
//| Requires the SPI being locked.
219+
//| If the number of bytes to read is 0, nothing happens.
214220
//|
215221
// TODO(tannewt): Add support for start and end kwargs.
216222
STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
217223
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
218224
raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
219225
mp_buffer_info_t bufinfo;
220226
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
227+
if (bufinfo.len == 0) {
228+
return mp_const_none;
229+
}
221230
check_lock(args[0]);
222231
bool ok = shared_module_bitbangio_spi_read(self, bufinfo.buf, bufinfo.len);
223232
if (!ok) {

shared-bindings/busio/SPI.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock);
207207
//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer))
208208
//|
209209
//| Write the data contained in ``buf``. Requires the SPI being locked.
210-
//| At least one byte must be written.
210+
//| If the buffer is empty, nothing happens.
211211
//|
212212
//| :param bytearray buffer: buffer containing the bytes to write
213213
//| :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_
233233
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
234234

235235
if (length == 0) {
236-
mp_raise_ValueError("Buffer must be at least length 1");
236+
return mp_const_none;
237237
}
238238

239239
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);
247247

248248
//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0)
249249
//|
250-
//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked.
251-
//| At least one byte must be read.
250+
//| Read into the buffer specified by ``buf`` while writing zeroes.
251+
//| Requires the SPI being locked.
252+
//| If the number of bytes to read is 0, nothing happens.
252253
//|
253254
//| :param bytearray buffer: buffer to write into
254255
//| :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
276277
normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
277278

278279
if (length == 0) {
279-
mp_raise_ValueError("Buffer must be at least length 1");
280+
return mp_const_none;
280281
}
281282

282283
bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, length, args[ARG_write_value].u_int);

0 commit comments

Comments
 (0)