1/*
2 * This file is part of the MicroPython project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2016 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27#include <stdio.h>
28#include <stdint.h>
29#include <string.h>
30
31#include "py/mperrno.h"
32#include "py/mphal.h"
33#include "py/runtime.h"
34#include "extmod/machine_i2c.h"
35
36#if MICROPY_PY_MACHINE_I2C
37
38typedef mp_machine_soft_i2c_obj_t machine_i2c_obj_t;
39
40STATIC void mp_hal_i2c_delay(machine_i2c_obj_t *self) {
41 // We need to use an accurate delay to get acceptable I2C
42 // speeds (eg 1us should be not much more than 1us).
43 mp_hal_delay_us_fast(self->us_delay);
44}
45
46STATIC void mp_hal_i2c_scl_low(machine_i2c_obj_t *self) {
47 mp_hal_pin_od_low(self->scl);
48}
49
50STATIC int mp_hal_i2c_scl_release(machine_i2c_obj_t *self) {
51 uint32_t count = self->us_timeout;
52
53 mp_hal_pin_od_high(self->scl);
54 mp_hal_i2c_delay(self);
55 // For clock stretching, wait for the SCL pin to be released, with timeout.
56 for (; mp_hal_pin_read(self->scl) == 0 && count; --count) {
57 mp_hal_delay_us_fast(1);
58 }
59 if (count == 0) {
60 return -MP_ETIMEDOUT;
61 }
62 return 0; // success
63}
64
65STATIC void mp_hal_i2c_sda_low(machine_i2c_obj_t *self) {
66 mp_hal_pin_od_low(self->sda);
67}
68
69STATIC void mp_hal_i2c_sda_release(machine_i2c_obj_t *self) {
70 mp_hal_pin_od_high(self->sda);
71}
72
73STATIC int mp_hal_i2c_sda_read(machine_i2c_obj_t *self) {
74 return mp_hal_pin_read(self->sda);
75}
76
77STATIC int mp_hal_i2c_start(machine_i2c_obj_t *self) {
78 mp_hal_i2c_sda_release(self);
79 mp_hal_i2c_delay(self);
80 int ret = mp_hal_i2c_scl_release(self);
81 if (ret != 0) {
82 return ret;
83 }
84 mp_hal_i2c_sda_low(self);
85 mp_hal_i2c_delay(self);
86 return 0; // success
87}
88
89STATIC int mp_hal_i2c_stop(machine_i2c_obj_t *self) {
90 mp_hal_i2c_delay(self);
91 mp_hal_i2c_sda_low(self);
92 mp_hal_i2c_delay(self);
93 int ret = mp_hal_i2c_scl_release(self);
94 mp_hal_i2c_sda_release(self);
95 mp_hal_i2c_delay(self);
96 return ret;
97}
98
99STATIC void mp_hal_i2c_init(machine_i2c_obj_t *self, uint32_t freq) {
100 self->us_delay = 500000 / freq;
101 if (self->us_delay == 0) {
102 self->us_delay = 1;
103 }
104 mp_hal_pin_open_drain(self->scl);
105 mp_hal_pin_open_drain(self->sda);
106 mp_hal_i2c_stop(self); // ignore error
107}
108
109// return value:
110// 0 - byte written and ack received
111// 1 - byte written and nack received
112// <0 - error, with errno being the negative of the return value
113STATIC int mp_hal_i2c_write_byte(machine_i2c_obj_t *self, uint8_t val) {
114 mp_hal_i2c_delay(self);
115 mp_hal_i2c_scl_low(self);
116
117 for (int i = 7; i >= 0; i--) {
118 if ((val >> i) & 1) {
119 mp_hal_i2c_sda_release(self);
120 } else {
121 mp_hal_i2c_sda_low(self);
122 }
123 mp_hal_i2c_delay(self);
124 int ret = mp_hal_i2c_scl_release(self);
125 if (ret != 0) {
126 mp_hal_i2c_sda_release(self);
127 return ret;
128 }
129 mp_hal_i2c_scl_low(self);
130 }
131
132 mp_hal_i2c_sda_release(self);
133 mp_hal_i2c_delay(self);
134 int ret = mp_hal_i2c_scl_release(self);
135 if (ret != 0) {
136 return ret;
137 }
138
139 int ack = mp_hal_i2c_sda_read(self);
140 mp_hal_i2c_delay(self);
141 mp_hal_i2c_scl_low(self);
142
143 return ack;
144}
145
146// return value:
147// 0 - success
148// <0 - error, with errno being the negative of the return value
149STATIC int mp_hal_i2c_read_byte(machine_i2c_obj_t *self, uint8_t *val, int nack) {
150 mp_hal_i2c_delay(self);
151 mp_hal_i2c_scl_low(self);
152 mp_hal_i2c_delay(self);
153
154 uint8_t data = 0;
155 for (int i = 7; i >= 0; i--) {
156 int ret = mp_hal_i2c_scl_release(self);
157 if (ret != 0) {
158 return ret;
159 }
160 data = (data << 1) | mp_hal_i2c_sda_read(self);
161 mp_hal_i2c_scl_low(self);
162 mp_hal_i2c_delay(self);
163 }
164 *val = data;
165
166 // send ack/nack bit
167 if (!nack) {
168 mp_hal_i2c_sda_low(self);
169 }
170 mp_hal_i2c_delay(self);
171 int ret = mp_hal_i2c_scl_release(self);
172 if (ret != 0) {
173 mp_hal_i2c_sda_release(self);
174 return ret;
175 }
176 mp_hal_i2c_scl_low(self);
177 mp_hal_i2c_sda_release(self);
178
179 return 0; // success
180}
181
182// return value:
183// >=0 - success; for read it's 0, for write it's number of acks received
184// <0 - error, with errno being the negative of the return value
185int mp_machine_soft_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t n, mp_machine_i2c_buf_t *bufs, unsigned int flags) {
186 machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in;
187
188 // start the I2C transaction
189 int ret = mp_hal_i2c_start(self);
190 if (ret != 0) {
191 return ret;
192 }
193
194 // write the slave address
195 ret = mp_hal_i2c_write_byte(self, (addr << 1) | (flags & MP_MACHINE_I2C_FLAG_READ));
196 if (ret < 0) {
197 return ret;
198 } else if (ret != 0) {
199 // nack received, release the bus cleanly
200 mp_hal_i2c_stop(self);
201 return -MP_ENODEV;
202 }
203
204 int transfer_ret = 0;
205 for (; n--; ++bufs) {
206 size_t len = bufs->len;
207 uint8_t *buf = bufs->buf;
208 if (flags & MP_MACHINE_I2C_FLAG_READ) {
209 // read bytes from the slave into the given buffer(s)
210 while (len--) {
211 ret = mp_hal_i2c_read_byte(self, buf++, (n | len) == 0);
212 if (ret != 0) {
213 return ret;
214 }
215 }
216 } else {
217 // write bytes from the given buffer(s) to the slave
218 while (len--) {
219 ret = mp_hal_i2c_write_byte(self, *buf++);
220 if (ret < 0) {
221 return ret;
222 } else if (ret != 0) {
223 // nack received, stop sending
224 n = 0;
225 break;
226 }
227 ++transfer_ret; // count the number of acks
228 }
229 }
230 }
231
232 // finish the I2C transaction
233 if (flags & MP_MACHINE_I2C_FLAG_STOP) {
234 ret = mp_hal_i2c_stop(self);
235 if (ret != 0) {
236 return ret;
237 }
238 }
239
240 return transfer_ret;
241}
242
243/******************************************************************************/
244// Generic helper functions
245
246// For use by ports that require a single buffer of data for a read/write transfer
247int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n, mp_machine_i2c_buf_t *bufs, unsigned int flags) {
248 size_t len;
249 uint8_t *buf;
250 if (n == 1) {
251 // Use given single buffer
252 len = bufs[0].len;
253 buf = bufs[0].buf;
254 } else {
255 // Combine buffers into a single one
256 len = 0;
257 for (size_t i = 0; i < n; ++i) {
258 len += bufs[i].len;
259 }
260 buf = m_new(uint8_t, len);
261 if (!(flags & MP_MACHINE_I2C_FLAG_READ)) {
262 len = 0;
263 for (size_t i = 0; i < n; ++i) {
264 memcpy(buf + len, bufs[i].buf, bufs[i].len);
265 len += bufs[i].len;
266 }
267 }
268 }
269
270 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
271 int ret = i2c_p->transfer_single(self, addr, len, buf, flags);
272
273 if (n > 1) {
274 if (flags & MP_MACHINE_I2C_FLAG_READ) {
275 // Copy data from single buffer to individual ones
276 len = 0;
277 for (size_t i = 0; i < n; ++i) {
278 memcpy(bufs[i].buf, buf + len, bufs[i].len);
279 len += bufs[i].len;
280 }
281 }
282 m_del(uint8_t, buf, len);
283 }
284
285 return ret;
286}
287
288STATIC int mp_machine_i2c_readfrom(mp_obj_base_t *self, uint16_t addr, uint8_t *dest, size_t len, bool stop) {
289 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
290 mp_machine_i2c_buf_t buf = {.len = len, .buf = dest};
291 unsigned int flags = MP_MACHINE_I2C_FLAG_READ | (stop ? MP_MACHINE_I2C_FLAG_STOP : 0);
292 return i2c_p->transfer(self, addr, 1, &buf, flags);
293}
294
295STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint8_t *src, size_t len, bool stop) {
296 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
297 mp_machine_i2c_buf_t buf = {.len = len, .buf = (uint8_t *)src};
298 unsigned int flags = stop ? MP_MACHINE_I2C_FLAG_STOP : 0;
299 return i2c_p->transfer(self, addr, 1, &buf, flags);
300}
301
302/******************************************************************************/
303// MicroPython bindings for generic machine.I2C
304
305STATIC mp_obj_t machine_i2c_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
306 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
307 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
308 if (i2c_p->init == NULL) {
309 mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
310 }
311 i2c_p->init(self, n_args - 1, args + 1, kw_args);
312 return mp_const_none;
313}
314MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_init_obj, 1, machine_i2c_init);
315
316STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
317 mp_obj_base_t *self = MP_OBJ_TO_PTR(self_in);
318 mp_obj_t list = mp_obj_new_list(0, NULL);
319 // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
320 for (int addr = 0x08; addr < 0x78; ++addr) {
321 int ret = mp_machine_i2c_writeto(self, addr, NULL, 0, true);
322 if (ret == 0) {
323 mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
324 }
325 }
326 return list;
327}
328MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan);
329
330STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
331 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
332 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
333 if (i2c_p->start == NULL) {
334 mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
335 }
336 int ret = i2c_p->start(self);
337 if (ret != 0) {
338 mp_raise_OSError(-ret);
339 }
340 return mp_const_none;
341}
342MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start);
343
344STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
345 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
346 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
347 if (i2c_p->stop == NULL) {
348 mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
349 }
350 int ret = i2c_p->stop(self);
351 if (ret != 0) {
352 mp_raise_OSError(-ret);
353 }
354 return mp_const_none;
355}
356MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop);
357
358STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
359 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
360 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
361 if (i2c_p->read == NULL) {
362 mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
363 }
364
365 // get the buffer to read into
366 mp_buffer_info_t bufinfo;
367 mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
368
369 // work out if we want to send a nack at the end
370 bool nack = (n_args == 2) ? true : mp_obj_is_true(args[2]);
371
372 // do the read
373 int ret = i2c_p->read(self, bufinfo.buf, bufinfo.len, nack);
374 if (ret != 0) {
375 mp_raise_OSError(-ret);
376 }
377
378 return mp_const_none;
379}
380MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_readinto);
381
382STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
383 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
384 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
385 if (i2c_p->write == NULL) {
386 mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
387 }
388
389 // get the buffer to write from
390 mp_buffer_info_t bufinfo;
391 mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
392
393 // do the write
394 int ret = i2c_p->write(self, bufinfo.buf, bufinfo.len);
395 if (ret < 0) {
396 mp_raise_OSError(-ret);
397 }
398
399 // return number of acks received
400 return MP_OBJ_NEW_SMALL_INT(ret);
401}
402MP_DEFINE_CONST_FUN_OBJ_2(machine_i2c_write_obj, machine_i2c_write);
403
404STATIC mp_obj_t machine_i2c_readfrom(size_t n_args, const mp_obj_t *args) {
405 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
406 mp_int_t addr = mp_obj_get_int(args[1]);
407 vstr_t vstr;
408 vstr_init_len(&vstr, mp_obj_get_int(args[2]));
409 bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
410 int ret = mp_machine_i2c_readfrom(self, addr, (uint8_t *)vstr.buf, vstr.len, stop);
411 if (ret < 0) {
412 mp_raise_OSError(-ret);
413 }
414 return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
415}
416MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_readfrom);
417
418STATIC mp_obj_t machine_i2c_readfrom_into(size_t n_args, const mp_obj_t *args) {
419 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
420 mp_int_t addr = mp_obj_get_int(args[1]);
421 mp_buffer_info_t bufinfo;
422 mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
423 bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
424 int ret = mp_machine_i2c_readfrom(self, addr, bufinfo.buf, bufinfo.len, stop);
425 if (ret < 0) {
426 mp_raise_OSError(-ret);
427 }
428 return mp_const_none;
429}
430MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_into_obj, 3, 4, machine_i2c_readfrom_into);
431
432STATIC mp_obj_t machine_i2c_writeto(size_t n_args, const mp_obj_t *args) {
433 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
434 mp_int_t addr = mp_obj_get_int(args[1]);
435 mp_buffer_info_t bufinfo;
436 mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
437 bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
438 int ret = mp_machine_i2c_writeto(self, addr, bufinfo.buf, bufinfo.len, stop);
439 if (ret < 0) {
440 mp_raise_OSError(-ret);
441 }
442 // return number of acks received
443 return MP_OBJ_NEW_SMALL_INT(ret);
444}
445STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writeto_obj, 3, 4, machine_i2c_writeto);
446
447STATIC mp_obj_t machine_i2c_writevto(size_t n_args, const mp_obj_t *args) {
448 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
449 mp_int_t addr = mp_obj_get_int(args[1]);
450
451 // Get the list of data buffer(s) to write
452 size_t nitems;
453 const mp_obj_t *items;
454 mp_obj_get_array(args[2], &nitems, (mp_obj_t **)&items);
455
456 // Get the stop argument
457 bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
458
459 // Extract all buffer data, skipping zero-length buffers
460 size_t alloc = nitems == 0 ? 1 : nitems;
461 size_t nbufs = 0;
462 mp_machine_i2c_buf_t *bufs = mp_local_alloc(alloc * sizeof(mp_machine_i2c_buf_t));
463 for (; nitems--; ++items) {
464 mp_buffer_info_t bufinfo;
465 mp_get_buffer_raise(*items, &bufinfo, MP_BUFFER_READ);
466 if (bufinfo.len > 0) {
467 bufs[nbufs].len = bufinfo.len;
468 bufs[nbufs++].buf = bufinfo.buf;
469 }
470 }
471
472 // Make sure there is at least one buffer, empty if needed
473 if (nbufs == 0) {
474 bufs[0].len = 0;
475 bufs[0].buf = NULL;
476 nbufs = 1;
477 }
478
479 // Do the I2C transfer
480 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
481 int ret = i2c_p->transfer(self, addr, nbufs, bufs, stop ? MP_MACHINE_I2C_FLAG_STOP : 0);
482 mp_local_free(bufs);
483
484 if (ret < 0) {
485 mp_raise_OSError(-ret);
486 }
487
488 // Return number of acks received
489 return MP_OBJ_NEW_SMALL_INT(ret);
490}
491STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writevto_obj, 3, 4, machine_i2c_writevto);
492
493STATIC size_t fill_memaddr_buf(uint8_t *memaddr_buf, uint32_t memaddr, uint8_t addrsize) {
494 size_t memaddr_len = 0;
495 if ((addrsize & 7) != 0 || addrsize > 32) {
496 mp_raise_ValueError(MP_ERROR_TEXT("invalid addrsize"));
497 }
498 for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
499 memaddr_buf[memaddr_len++] = memaddr >> i;
500 }
501 return memaddr_len;
502}
503
504STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, uint8_t *buf, size_t len) {
505 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
506
507 // Create buffer with memory address
508 uint8_t memaddr_buf[4];
509 size_t memaddr_len = fill_memaddr_buf(&memaddr_buf[0], memaddr, addrsize);
510
511 int ret = mp_machine_i2c_writeto(self, addr, memaddr_buf, memaddr_len, false);
512 if (ret != memaddr_len) {
513 // must generate STOP
514 mp_machine_i2c_writeto(self, addr, NULL, 0, true);
515 return ret;
516 }
517 return mp_machine_i2c_readfrom(self, addr, buf, len, true);
518}
519
520STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) {
521 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
522
523 // Create buffer with memory address
524 uint8_t memaddr_buf[4];
525 size_t memaddr_len = fill_memaddr_buf(&memaddr_buf[0], memaddr, addrsize);
526
527 // Create partial write buffers
528 mp_machine_i2c_buf_t bufs[2] = {
529 {.len = memaddr_len, .buf = memaddr_buf},
530 {.len = len, .buf = (uint8_t *)buf},
531 };
532
533 // Do I2C transfer
534 mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
535 return i2c_p->transfer(self, addr, 2, bufs, MP_MACHINE_I2C_FLAG_STOP);
536}
537
538STATIC const mp_arg_t machine_i2c_mem_allowed_args[] = {
539 { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
540 { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
541 { MP_QSTR_arg, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
542 { MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
543};
544
545STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
546 enum { ARG_addr, ARG_memaddr, ARG_n, ARG_addrsize };
547 mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
548 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
549 MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
550
551 // create the buffer to store data into
552 vstr_t vstr;
553 vstr_init_len(&vstr, mp_obj_get_int(args[ARG_n].u_obj));
554
555 // do the transfer
556 int ret = read_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
557 args[ARG_addrsize].u_int, (uint8_t *)vstr.buf, vstr.len);
558 if (ret < 0) {
559 mp_raise_OSError(-ret);
560 }
561
562 return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
563}
564MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem);
565
566
567STATIC mp_obj_t machine_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
568 enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
569 mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
570 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
571 MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
572
573 // get the buffer to store data into
574 mp_buffer_info_t bufinfo;
575 mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_WRITE);
576
577 // do the transfer
578 int ret = read_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
579 args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
580 if (ret < 0) {
581 mp_raise_OSError(-ret);
582 }
583 return mp_const_none;
584}
585MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_into_obj, 1, machine_i2c_readfrom_mem_into);
586
587STATIC mp_obj_t machine_i2c_writeto_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
588 enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
589 mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
590 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
591 MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
592
593 // get the buffer to write the data from
594 mp_buffer_info_t bufinfo;
595 mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ);
596
597 // do the transfer
598 int ret = write_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
599 args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
600 if (ret < 0) {
601 mp_raise_OSError(-ret);
602 }
603
604 return mp_const_none;
605}
606STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_writeto_mem_obj, 1, machine_i2c_writeto_mem);
607
608STATIC const mp_rom_map_elem_t machine_i2c_locals_dict_table[] = {
609 { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2c_init_obj) },
610 { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&machine_i2c_scan_obj) },
611
612 // primitive I2C operations
613 { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&machine_i2c_start_obj) },
614 { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_i2c_stop_obj) },
615 { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&machine_i2c_readinto_obj) },
616 { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&machine_i2c_write_obj) },
617
618 // standard bus operations
619 { MP_ROM_QSTR(MP_QSTR_readfrom), MP_ROM_PTR(&machine_i2c_readfrom_obj) },
620 { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&machine_i2c_readfrom_into_obj) },
621 { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&machine_i2c_writeto_obj) },
622 { MP_ROM_QSTR(MP_QSTR_writevto), MP_ROM_PTR(&machine_i2c_writevto_obj) },
623
624 // memory operations
625 { MP_ROM_QSTR(MP_QSTR_readfrom_mem), MP_ROM_PTR(&machine_i2c_readfrom_mem_obj) },
626 { MP_ROM_QSTR(MP_QSTR_readfrom_mem_into), MP_ROM_PTR(&machine_i2c_readfrom_mem_into_obj) },
627 { MP_ROM_QSTR(MP_QSTR_writeto_mem), MP_ROM_PTR(&machine_i2c_writeto_mem_obj) },
628};
629MP_DEFINE_CONST_DICT(mp_machine_i2c_locals_dict, machine_i2c_locals_dict_table);
630
631/******************************************************************************/
632// Implementation of soft I2C
633
634STATIC void mp_machine_soft_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
635 mp_machine_soft_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
636 mp_printf(print, "SoftI2C(scl=" MP_HAL_PIN_FMT ", sda=" MP_HAL_PIN_FMT ", freq=%u)",
637 mp_hal_pin_name(self->scl), mp_hal_pin_name(self->sda), 500000 / self->us_delay);
638}
639
640STATIC void mp_machine_soft_i2c_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
641 enum { ARG_scl, ARG_sda, ARG_freq, ARG_timeout };
642 static const mp_arg_t allowed_args[] = {
643 { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
644 { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
645 { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
646 { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
647 };
648
649 mp_machine_soft_i2c_obj_t *self = (mp_machine_soft_i2c_obj_t *)self_in;
650 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
651 mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
652
653 self->scl = mp_hal_get_pin_obj(args[ARG_scl].u_obj);
654 self->sda = mp_hal_get_pin_obj(args[ARG_sda].u_obj);
655 self->us_timeout = args[ARG_timeout].u_int;
656 mp_hal_i2c_init(self, args[ARG_freq].u_int);
657}
658
659STATIC mp_obj_t mp_machine_soft_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
660 // create new soft I2C object
661 machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t);
662 self->base.type = &mp_machine_soft_i2c_type;
663 mp_map_t kw_args;
664 mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
665 mp_machine_soft_i2c_init(&self->base, n_args, args, &kw_args);
666 return MP_OBJ_FROM_PTR(self);
667}
668
669int mp_machine_soft_i2c_read(mp_obj_base_t *self_in, uint8_t *dest, size_t len, bool nack) {
670 machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in;
671 while (len--) {
672 int ret = mp_hal_i2c_read_byte(self, dest++, nack && (len == 0));
673 if (ret != 0) {
674 return ret;
675 }
676 }
677 return 0; // success
678}
679
680int mp_machine_soft_i2c_write(mp_obj_base_t *self_in, const uint8_t *src, size_t len) {
681 machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in;
682 int num_acks = 0;
683 while (len--) {
684 int ret = mp_hal_i2c_write_byte(self, *src++);
685 if (ret < 0) {
686 return ret;
687 } else if (ret != 0) {
688 // nack received, stop sending
689 break;
690 }
691 ++num_acks;
692 }
693 return num_acks;
694}
695
696STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = {
697 .init = mp_machine_soft_i2c_init,
698 .start = (int (*)(mp_obj_base_t *))mp_hal_i2c_start,
699 .stop = (int (*)(mp_obj_base_t *))mp_hal_i2c_stop,
700 .read = mp_machine_soft_i2c_read,
701 .write = mp_machine_soft_i2c_write,
702 .transfer = mp_machine_soft_i2c_transfer,
703};
704
705const mp_obj_type_t mp_machine_soft_i2c_type = {
706 { &mp_type_type },
707 .name = MP_QSTR_SoftI2C,
708 .print = mp_machine_soft_i2c_print,
709 .make_new = mp_machine_soft_i2c_make_new,
710 .protocol = &mp_machine_soft_i2c_p,
711 .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict,
712};
713
714#endif // MICROPY_PY_MACHINE_I2C
715