Skip to content

Commit 4869599

Browse files
authored
Merge pull request adafruit#404 from pewpew-game/fix-spi-empty-read-write
Allow empty reads and writes for busio.SPI
2 parents c066e4d + 78f6c22 commit 4869599

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

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)