@@ -175,6 +175,23 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock);
175
175
//| :param int start: Index to start writing at
176
176
//| :param int end: Index to write up to but not include
177
177
//|
178
+ // Shared arg parsing for readfrom_into and writeto_then_readfrom.
179
+ STATIC void readfrom (bitbangio_i2c_obj_t * self , mp_int_t address , mp_obj_t buffer , int32_t start , mp_int_t end ) {
180
+ mp_buffer_info_t bufinfo ;
181
+ mp_get_buffer_raise (buffer , & bufinfo , MP_BUFFER_WRITE );
182
+
183
+ size_t length = bufinfo .len ;
184
+ normalize_buffer_bounds (& start , end , & length );
185
+ if (length == 0 ) {
186
+ mp_raise_ValueError (translate ("Buffer must be at least length 1" ));
187
+ }
188
+
189
+ uint8_t status = shared_module_bitbangio_i2c_read (self , address , ((uint8_t * )bufinfo .buf ) + start , length );
190
+ if (status != 0 ) {
191
+ mp_raise_OSError (status );
192
+ }
193
+ }
194
+
178
195
STATIC mp_obj_t bitbangio_i2c_readfrom_into (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
179
196
enum { ARG_address , ARG_buffer , ARG_start , ARG_end };
180
197
static const mp_arg_t allowed_args [] = {
@@ -185,33 +202,21 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a
185
202
};
186
203
bitbangio_i2c_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
187
204
check_for_deinit (self );
205
+ check_lock (self );
188
206
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
189
207
mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
190
- check_lock (self );
191
- mp_buffer_info_t bufinfo ;
192
- mp_get_buffer_raise (args [ARG_buffer ].u_obj , & bufinfo , MP_BUFFER_WRITE );
193
208
194
- int32_t start = args [ARG_start ].u_int ;
195
- uint32_t length = bufinfo .len ;
196
- normalize_buffer_bounds (& start , args [ARG_end ].u_int , & length );
197
- if (length == 0 ) {
198
- mp_raise_ValueError (translate ("Buffer must be at least length 1" ));
199
- }
200
- uint8_t status = shared_module_bitbangio_i2c_read (self ,
201
- args [ARG_address ].u_int ,
202
- ((uint8_t * )bufinfo .buf ) + start ,
203
- length );
204
- if (status != 0 ) {
205
- mp_raise_OSError (status );
206
- }
209
+ readfrom (self , args [ARG_address ].u_int , args [ARG_buffer ].u_obj , args [ARG_start ].u_int ,
210
+ args [ARG_end ].u_int );
207
211
return mp_const_none ;
208
212
}
209
213
MP_DEFINE_CONST_FUN_OBJ_KW (bitbangio_i2c_readfrom_into_obj , 3 , bitbangio_i2c_readfrom_into );
210
214
211
215
//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True)
212
216
//|
213
- //| Write the bytes from ``buffer`` to the slave specified by ``address``.
214
- //| Transmits a stop bit if ``stop`` is set.
217
+ //| Write the bytes from ``buffer`` to the slave specified by ``address`` and then transmits a
218
+ //| stop bit. Use `writeto_then_readfrom` when needing a write, no stop and repeated start
219
+ //| before a read.
215
220
//|
216
221
//| If ``start`` or ``end`` is provided, then the buffer will be sliced
217
222
//| as if ``buffer[start:end]``. This will not cause an allocation like
@@ -224,9 +229,27 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_rea
224
229
//| :param bytearray buffer: buffer containing the bytes to write
225
230
//| :param int start: Index to start writing from
226
231
//| :param int end: Index to read up to but not include
227
- //| :param bool stop: If true, output an I2C stop condition after the
228
- //| buffer is written
232
+ //| :param bool stop: If true, output an I2C stop condition after the buffer is written.
233
+ //| Deprecated. Will be removed in 6.x and act as stop=True.
229
234
//|
235
+ // Shared arg parsing for writeto and writeto_then_readfrom.
236
+ STATIC void writeto (bitbangio_i2c_obj_t * self , mp_int_t address , mp_obj_t buffer , int32_t start , mp_int_t end , bool stop ) {
237
+ // get the buffer to write the data from
238
+ mp_buffer_info_t bufinfo ;
239
+ mp_get_buffer_raise (buffer , & bufinfo , MP_BUFFER_READ );
240
+
241
+ size_t length = bufinfo .len ;
242
+ normalize_buffer_bounds (& start , end , & length );
243
+
244
+ // do the transfer
245
+ uint8_t status = shared_module_bitbangio_i2c_write (self , address ,
246
+ ((uint8_t * ) bufinfo .buf ) + start , length ,
247
+ stop );
248
+ if (status != 0 ) {
249
+ mp_raise_OSError (status );
250
+ }
251
+ }
252
+
230
253
STATIC mp_obj_t bitbangio_i2c_writeto (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
231
254
enum { ARG_address , ARG_buffer , ARG_start , ARG_end , ARG_stop };
232
255
static const mp_arg_t allowed_args [] = {
@@ -242,23 +265,56 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m
242
265
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
243
266
mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
244
267
245
- // get the buffer to write the data from
246
- mp_buffer_info_t bufinfo ;
247
- mp_get_buffer_raise (args [ARG_buffer ].u_obj , & bufinfo , MP_BUFFER_READ );
268
+ writeto (self , args [ARG_address ].u_int , args [ARG_buffer ].u_obj , args [ARG_start ].u_int ,
269
+ args [ARG_end ].u_int , args [ARG_stop ].u_bool );
270
+ return mp_const_none ;
271
+ }
272
+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (bitbangio_i2c_writeto_obj , 1 , bitbangio_i2c_writeto );
248
273
249
- int32_t start = args [ARG_start ].u_int ;
250
- uint32_t length = bufinfo .len ;
251
- normalize_buffer_bounds (& start , args [ARG_end ].u_int , & length );
252
274
253
- // do the transfer
254
- uint8_t status = shared_module_bitbangio_i2c_write (self , args [ARG_address ].u_int ,
255
- ((uint8_t * ) bufinfo .buf ) + start , length , args [ARG_stop ].u_bool );
256
- if (status != 0 ) {
257
- mp_raise_OSError (status );
258
- }
275
+ //| .. method:: writeto_then_readfrom(address, out_buffer, in_buffer, *, out_start=0, out_end=None, in_start=0, in_end=None)
276
+ //|
277
+ //| Write the bytes from ``out_buffer`` to the slave specified by ``address``, generate no stop
278
+ //| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and
279
+ //| ``in_buffer`` can be the same buffer because they are used sequentially.
280
+ //|
281
+ //| If ``start`` or ``end`` is provided, then the corresponding buffer will be sliced
282
+ //| as if ``buffer[start:end]``. This will not cause an allocation like ``buf[start:end]``
283
+ //| will so it saves memory.
284
+ //|
285
+ //| :param int address: 7-bit device address
286
+ //| :param bytearray out_buffer: buffer containing the bytes to write
287
+ //| :param bytearray in_buffer: buffer to write into
288
+ //| :param int out_start: Index to start writing from
289
+ //| :param int out_end: Index to read up to but not include. Defaults to ``len(buffer)``
290
+ //| :param int in_start: Index to start writing at
291
+ //| :param int in_end: Index to write up to but not include. Defaults to ``len(buffer)``
292
+ //|
293
+ STATIC mp_obj_t bitbangio_i2c_writeto_then_readfrom (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
294
+ enum { ARG_address , ARG_out_buffer , ARG_in_buffer , ARG_out_start , ARG_out_end , ARG_in_start , ARG_in_end };
295
+ static const mp_arg_t allowed_args [] = {
296
+ { MP_QSTR_address , MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 0 } },
297
+ { MP_QSTR_out_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
298
+ { MP_QSTR_in_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
299
+ { MP_QSTR_out_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
300
+ { MP_QSTR_out_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
301
+ { MP_QSTR_in_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
302
+ { MP_QSTR_in_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
303
+ };
304
+ bitbangio_i2c_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
305
+ check_for_deinit (self );
306
+ check_lock (self );
307
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
308
+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
309
+
310
+ writeto (self , args [ARG_address ].u_int , args [ARG_out_buffer ].u_obj , args [ARG_out_start ].u_int ,
311
+ args [ARG_out_end ].u_int , false);
312
+ readfrom (self , args [ARG_address ].u_int , args [ARG_in_buffer ].u_obj , args [ARG_in_start ].u_int ,
313
+ args [ARG_in_end ].u_int );
314
+
259
315
return mp_const_none ;
260
316
}
261
- STATIC MP_DEFINE_CONST_FUN_OBJ_KW (bitbangio_i2c_writeto_obj , 1 , bitbangio_i2c_writeto );
317
+ MP_DEFINE_CONST_FUN_OBJ_KW (bitbangio_i2c_writeto_then_readfrom_obj , 3 , bitbangio_i2c_writeto_then_readfrom );
262
318
263
319
STATIC const mp_rom_map_elem_t bitbangio_i2c_locals_dict_table [] = {
264
320
{ MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& bitbangio_i2c_deinit_obj ) },
@@ -271,6 +327,7 @@ STATIC const mp_rom_map_elem_t bitbangio_i2c_locals_dict_table[] = {
271
327
272
328
{ MP_ROM_QSTR (MP_QSTR_writeto ), MP_ROM_PTR (& bitbangio_i2c_writeto_obj ) },
273
329
{ MP_ROM_QSTR (MP_QSTR_readfrom_into ), MP_ROM_PTR (& bitbangio_i2c_readfrom_into_obj ) },
330
+ { MP_ROM_QSTR (MP_QSTR_writeto_then_readfrom ), MP_ROM_PTR (& bitbangio_i2c_writeto_then_readfrom_obj ) },
274
331
};
275
332
276
333
STATIC MP_DEFINE_CONST_DICT (bitbangio_i2c_locals_dict , bitbangio_i2c_locals_dict_table );
0 commit comments