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 
38 typedef mp_machine_soft_i2c_obj_t machine_i2c_obj_t;
39 
mp_hal_i2c_delay(machine_i2c_obj_t * self)40 STATIC 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 
mp_hal_i2c_scl_low(machine_i2c_obj_t * self)46 STATIC void mp_hal_i2c_scl_low(machine_i2c_obj_t *self) {
47     mp_hal_pin_od_low(self->scl);
48 }
49 
mp_hal_i2c_scl_release(machine_i2c_obj_t * self)50 STATIC 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 
mp_hal_i2c_sda_low(machine_i2c_obj_t * self)65 STATIC void mp_hal_i2c_sda_low(machine_i2c_obj_t *self) {
66     mp_hal_pin_od_low(self->sda);
67 }
68 
mp_hal_i2c_sda_release(machine_i2c_obj_t * self)69 STATIC void mp_hal_i2c_sda_release(machine_i2c_obj_t *self) {
70     mp_hal_pin_od_high(self->sda);
71 }
72 
mp_hal_i2c_sda_read(machine_i2c_obj_t * self)73 STATIC int mp_hal_i2c_sda_read(machine_i2c_obj_t *self) {
74     return mp_hal_pin_read(self->sda);
75 }
76 
mp_hal_i2c_start(machine_i2c_obj_t * self)77 STATIC 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 
mp_hal_i2c_stop(machine_i2c_obj_t * self)89 STATIC 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 
mp_hal_i2c_init(machine_i2c_obj_t * self,uint32_t freq)99 STATIC 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
mp_hal_i2c_write_byte(machine_i2c_obj_t * self,uint8_t val)113 STATIC 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
mp_hal_i2c_read_byte(machine_i2c_obj_t * self,uint8_t * val,int nack)149 STATIC 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
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)185 int 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
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)247 int 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 
mp_machine_i2c_readfrom(mp_obj_base_t * self,uint16_t addr,uint8_t * dest,size_t len,bool stop)288 STATIC 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 
mp_machine_i2c_writeto(mp_obj_base_t * self,uint16_t addr,const uint8_t * src,size_t len,bool stop)295 STATIC 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 
machine_i2c_init(size_t n_args,const mp_obj_t * args,mp_map_t * kw_args)305 STATIC 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 }
314 MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_init_obj, 1, machine_i2c_init);
315 
machine_i2c_deinit(size_t n_args,const mp_obj_t * args,mp_map_t * kw_args)316 STATIC mp_obj_t machine_i2c_deinit(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args)
317 {
318     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
319     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
320     if (i2c_p->deinit != NULL) {
321         i2c_p->deinit(self);
322     }
323     return mp_const_none;
324 }
325 MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_deinit_obj, 1, machine_i2c_deinit);
326 
machine_i2c_scan(mp_obj_t self_in)327 STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
328     mp_obj_base_t *self = MP_OBJ_TO_PTR(self_in);
329     mp_obj_t list = mp_obj_new_list(0, NULL);
330     // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
331     for (int addr = 0x08; addr < 0x78; ++addr) {
332         int ret = mp_machine_i2c_writeto(self, addr, NULL, 0, true);
333         if (ret == 0) {
334             mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
335         }
336     }
337     return list;
338 }
339 MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan);
340 
machine_i2c_start(mp_obj_t self_in)341 STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
342     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
343     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
344     if (i2c_p->start == NULL) {
345         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
346     }
347     int ret = i2c_p->start(self);
348     if (ret != 0) {
349         mp_raise_OSError(-ret);
350     }
351     return mp_const_none;
352 }
353 MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start);
354 
machine_i2c_stop(mp_obj_t self_in)355 STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
356     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
357     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
358     if (i2c_p->stop == NULL) {
359         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
360     }
361     int ret = i2c_p->stop(self);
362     if (ret != 0) {
363         mp_raise_OSError(-ret);
364     }
365     return mp_const_none;
366 }
367 MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop);
368 
machine_i2c_readinto(size_t n_args,const mp_obj_t * args)369 STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
370     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
371     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
372     if (i2c_p->read == NULL) {
373         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
374     }
375 
376     // get the buffer to read into
377     mp_buffer_info_t bufinfo;
378     mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
379 
380     // work out if we want to send a nack at the end
381     bool nack = (n_args == 2) ? true : mp_obj_is_true(args[2]);
382 
383     // do the read
384     int ret = i2c_p->read(self, bufinfo.buf, bufinfo.len, nack);
385     if (ret != 0) {
386         mp_raise_OSError(-ret);
387     }
388 
389     return mp_const_none;
390 }
391 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_readinto);
392 
machine_i2c_write(mp_obj_t self_in,mp_obj_t buf_in)393 STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
394     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
395     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
396     if (i2c_p->write == NULL) {
397         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
398     }
399 
400     // get the buffer to write from
401     mp_buffer_info_t bufinfo;
402     mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
403 
404     // do the write
405     int ret = i2c_p->write(self, bufinfo.buf, bufinfo.len);
406     if (ret < 0) {
407         mp_raise_OSError(-ret);
408     }
409 
410     // return number of acks received
411     return MP_OBJ_NEW_SMALL_INT(ret);
412 }
413 MP_DEFINE_CONST_FUN_OBJ_2(machine_i2c_write_obj, machine_i2c_write);
414 
machine_i2c_readfrom(size_t n_args,const mp_obj_t * args)415 STATIC mp_obj_t machine_i2c_readfrom(size_t n_args, const mp_obj_t *args) {
416     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
417     mp_int_t addr = mp_obj_get_int(args[1]);
418     vstr_t vstr;
419     vstr_init_len(&vstr, mp_obj_get_int(args[2]));
420     bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
421     int ret = mp_machine_i2c_readfrom(self, addr, (uint8_t *)vstr.buf, vstr.len, stop);
422     if (ret < 0) {
423         mp_raise_OSError(-ret);
424     }
425     return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
426 }
427 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_readfrom);
428 
machine_i2c_readfrom_into(size_t n_args,const mp_obj_t * args)429 STATIC mp_obj_t machine_i2c_readfrom_into(size_t n_args, const mp_obj_t *args) {
430     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
431     mp_int_t addr = mp_obj_get_int(args[1]);
432     mp_buffer_info_t bufinfo;
433     mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
434     bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
435     int ret = mp_machine_i2c_readfrom(self, addr, bufinfo.buf, bufinfo.len, stop);
436     if (ret < 0) {
437         mp_raise_OSError(-ret);
438     }
439     return mp_const_none;
440 }
441 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_into_obj, 3, 4, machine_i2c_readfrom_into);
442 
machine_i2c_writeto(size_t n_args,const mp_obj_t * args)443 STATIC mp_obj_t machine_i2c_writeto(size_t n_args, const mp_obj_t *args) {
444     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
445     mp_int_t addr = mp_obj_get_int(args[1]);
446     mp_buffer_info_t bufinfo;
447     mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
448     bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
449     int ret = mp_machine_i2c_writeto(self, addr, bufinfo.buf, bufinfo.len, stop);
450     if (ret < 0) {
451         mp_raise_OSError(-ret);
452     }
453     // return number of acks received
454     return MP_OBJ_NEW_SMALL_INT(ret);
455 }
456 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writeto_obj, 3, 4, machine_i2c_writeto);
457 
machine_i2c_writevto(size_t n_args,const mp_obj_t * args)458 STATIC mp_obj_t machine_i2c_writevto(size_t n_args, const mp_obj_t *args) {
459     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
460     mp_int_t addr = mp_obj_get_int(args[1]);
461 
462     // Get the list of data buffer(s) to write
463     size_t nitems;
464     const mp_obj_t *items;
465     mp_obj_get_array(args[2], &nitems, (mp_obj_t **)&items);
466 
467     // Get the stop argument
468     bool stop = (n_args == 3) ? true : mp_obj_is_true(args[3]);
469 
470     // Extract all buffer data, skipping zero-length buffers
471     size_t alloc = nitems == 0 ? 1 : nitems;
472     size_t nbufs = 0;
473     mp_machine_i2c_buf_t *bufs = mp_local_alloc(alloc * sizeof(mp_machine_i2c_buf_t));
474     for (; nitems--; ++items) {
475         mp_buffer_info_t bufinfo;
476         mp_get_buffer_raise(*items, &bufinfo, MP_BUFFER_READ);
477         if (bufinfo.len > 0) {
478             bufs[nbufs].len = bufinfo.len;
479             bufs[nbufs++].buf = bufinfo.buf;
480         }
481     }
482 
483     // Make sure there is at least one buffer, empty if needed
484     if (nbufs == 0) {
485         bufs[0].len = 0;
486         bufs[0].buf = NULL;
487         nbufs = 1;
488     }
489 
490     // Do the I2C transfer
491     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
492     int ret = i2c_p->transfer(self, addr, nbufs, bufs, stop ? MP_MACHINE_I2C_FLAG_STOP : 0);
493     mp_local_free(bufs);
494 
495     if (ret < 0) {
496         mp_raise_OSError(-ret);
497     }
498 
499     // Return number of acks received
500     return MP_OBJ_NEW_SMALL_INT(ret);
501 }
502 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writevto_obj, 3, 4, machine_i2c_writevto);
503 
fill_memaddr_buf(uint8_t * memaddr_buf,uint32_t memaddr,uint8_t addrsize)504 STATIC size_t fill_memaddr_buf(uint8_t *memaddr_buf, uint32_t memaddr, uint8_t addrsize) {
505     size_t memaddr_len = 0;
506     if ((addrsize & 7) != 0 || addrsize > 32) {
507         mp_raise_ValueError(MP_ERROR_TEXT("invalid addrsize"));
508     }
509     for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
510         memaddr_buf[memaddr_len++] = memaddr >> i;
511     }
512     return memaddr_len;
513 }
514 
read_mem(mp_obj_t self_in,uint16_t addr,uint32_t memaddr,uint8_t addrsize,uint8_t * buf,size_t len)515 STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, uint8_t *buf, size_t len) {
516     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
517 
518     // Create buffer with memory address
519     uint8_t memaddr_buf[4];
520     size_t memaddr_len = fill_memaddr_buf(&memaddr_buf[0], memaddr, addrsize);
521 
522     int ret = mp_machine_i2c_writeto(self, addr, memaddr_buf, memaddr_len, false);
523     if (ret != memaddr_len) {
524         // must generate STOP
525         mp_machine_i2c_writeto(self, addr, NULL, 0, true);
526         return ret;
527     }
528     return mp_machine_i2c_readfrom(self, addr, buf, len, true);
529 }
530 
write_mem(mp_obj_t self_in,uint16_t addr,uint32_t memaddr,uint8_t addrsize,const uint8_t * buf,size_t len)531 STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) {
532     mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
533 
534     // Create buffer with memory address
535     uint8_t memaddr_buf[4];
536     size_t memaddr_len = fill_memaddr_buf(&memaddr_buf[0], memaddr, addrsize);
537 
538     // Create partial write buffers
539     mp_machine_i2c_buf_t bufs[2] = {
540         {.len = memaddr_len, .buf = memaddr_buf},
541         {.len = len, .buf = (uint8_t *)buf},
542     };
543 
544     // Do I2C transfer
545     mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol;
546     return i2c_p->transfer(self, addr, 2, bufs, MP_MACHINE_I2C_FLAG_STOP);
547 }
548 
549 STATIC const mp_arg_t machine_i2c_mem_allowed_args[] = {
550     { MP_QSTR_addr,    MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
551     { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
552     { MP_QSTR_arg,     MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
553     { MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
554 };
555 
machine_i2c_readfrom_mem(size_t n_args,const mp_obj_t * pos_args,mp_map_t * kw_args)556 STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
557     enum { ARG_addr, ARG_memaddr, ARG_n, ARG_addrsize };
558     mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
559     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
560         MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
561 
562     // create the buffer to store data into
563     vstr_t vstr;
564     vstr_init_len(&vstr, mp_obj_get_int(args[ARG_n].u_obj));
565 
566     // do the transfer
567     int ret = read_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
568         args[ARG_addrsize].u_int, (uint8_t *)vstr.buf, vstr.len);
569     if (ret < 0) {
570         mp_raise_OSError(-ret);
571     }
572 
573     return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
574 }
575 MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem);
576 
577 
machine_i2c_readfrom_mem_into(size_t n_args,const mp_obj_t * pos_args,mp_map_t * kw_args)578 STATIC mp_obj_t machine_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
579     enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
580     mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
581     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
582         MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
583 
584     // get the buffer to store data into
585     mp_buffer_info_t bufinfo;
586     mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_WRITE);
587 
588     // do the transfer
589     int ret = read_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
590         args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
591     if (ret < 0) {
592         mp_raise_OSError(-ret);
593     }
594     return mp_const_none;
595 }
596 MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_into_obj, 1, machine_i2c_readfrom_mem_into);
597 
machine_i2c_writeto_mem(size_t n_args,const mp_obj_t * pos_args,mp_map_t * kw_args)598 STATIC mp_obj_t machine_i2c_writeto_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
599     enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
600     mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
601     mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
602         MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
603 
604     // get the buffer to write the data from
605     mp_buffer_info_t bufinfo;
606     mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ);
607 
608     // do the transfer
609     int ret = write_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
610         args[ARG_addrsize].u_int, bufinfo.buf, bufinfo.len);
611     if (ret < 0) {
612         mp_raise_OSError(-ret);
613     }
614 
615     return mp_const_none;
616 }
617 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_writeto_mem_obj, 1, machine_i2c_writeto_mem);
618 
619 STATIC const mp_rom_map_elem_t machine_i2c_locals_dict_table[] = {
620     { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2c_init_obj) },
621     { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2c_deinit_obj) },
622     { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&machine_i2c_scan_obj) },
623 
624     // primitive I2C operations
625     { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&machine_i2c_start_obj) },
626     { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_i2c_stop_obj) },
627     { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&machine_i2c_readinto_obj) },
628     { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&machine_i2c_write_obj) },
629 
630     // standard bus operations
631     { MP_ROM_QSTR(MP_QSTR_readfrom), MP_ROM_PTR(&machine_i2c_readfrom_obj) },
632     { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&machine_i2c_readfrom_into_obj) },
633     { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&machine_i2c_writeto_obj) },
634     { MP_ROM_QSTR(MP_QSTR_writevto), MP_ROM_PTR(&machine_i2c_writevto_obj) },
635 
636     // memory operations
637     { MP_ROM_QSTR(MP_QSTR_readfrom_mem), MP_ROM_PTR(&machine_i2c_readfrom_mem_obj) },
638     { MP_ROM_QSTR(MP_QSTR_readfrom_mem_into), MP_ROM_PTR(&machine_i2c_readfrom_mem_into_obj) },
639     { MP_ROM_QSTR(MP_QSTR_writeto_mem), MP_ROM_PTR(&machine_i2c_writeto_mem_obj) },
640 };
641 MP_DEFINE_CONST_DICT(mp_machine_i2c_locals_dict, machine_i2c_locals_dict_table);
642 
643 /******************************************************************************/
644 // Implementation of soft I2C
645 
mp_machine_soft_i2c_print(const mp_print_t * print,mp_obj_t self_in,mp_print_kind_t kind)646 STATIC void mp_machine_soft_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
647     mp_machine_soft_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
648     mp_printf(print, "SoftI2C(scl=" MP_HAL_PIN_FMT ", sda=" MP_HAL_PIN_FMT ", freq=%u)",
649         mp_hal_pin_name(self->scl), mp_hal_pin_name(self->sda), 500000 / self->us_delay);
650 }
651 
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)652 STATIC 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) {
653     enum { ARG_scl, ARG_sda, ARG_freq, ARG_timeout };
654     static const mp_arg_t allowed_args[] = {
655         { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
656         { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
657         { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
658         { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
659     };
660 
661     mp_machine_soft_i2c_obj_t *self = (mp_machine_soft_i2c_obj_t *)self_in;
662     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
663     mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
664 
665     self->scl = mp_hal_get_pin_obj(args[ARG_scl].u_obj);
666     self->sda = mp_hal_get_pin_obj(args[ARG_sda].u_obj);
667     self->us_timeout = args[ARG_timeout].u_int;
668     mp_hal_i2c_init(self, args[ARG_freq].u_int);
669 }
670 
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)671 STATIC 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) {
672     // create new soft I2C object
673     machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t);
674     self->base.type = &mp_machine_soft_i2c_type;
675     mp_map_t kw_args;
676     mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
677     mp_machine_soft_i2c_init(&self->base, n_args, args, &kw_args);
678     return MP_OBJ_FROM_PTR(self);
679 }
680 
mp_machine_soft_i2c_read(mp_obj_base_t * self_in,uint8_t * dest,size_t len,bool nack)681 int mp_machine_soft_i2c_read(mp_obj_base_t *self_in, uint8_t *dest, size_t len, bool nack) {
682     machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in;
683     while (len--) {
684         int ret = mp_hal_i2c_read_byte(self, dest++, nack && (len == 0));
685         if (ret != 0) {
686             return ret;
687         }
688     }
689     return 0; // success
690 }
691 
mp_machine_soft_i2c_write(mp_obj_base_t * self_in,const uint8_t * src,size_t len)692 int mp_machine_soft_i2c_write(mp_obj_base_t *self_in, const uint8_t *src, size_t len) {
693     machine_i2c_obj_t *self = (machine_i2c_obj_t *)self_in;
694     int num_acks = 0;
695     while (len--) {
696         int ret = mp_hal_i2c_write_byte(self, *src++);
697         if (ret < 0) {
698             return ret;
699         } else if (ret != 0) {
700             // nack received, stop sending
701             break;
702         }
703         ++num_acks;
704     }
705     return num_acks;
706 }
707 
708 STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = {
709     .init = mp_machine_soft_i2c_init,
710     .start = (int (*)(mp_obj_base_t *))mp_hal_i2c_start,
711     .stop = (int (*)(mp_obj_base_t *))mp_hal_i2c_stop,
712     .read = mp_machine_soft_i2c_read,
713     .write = mp_machine_soft_i2c_write,
714     .transfer = mp_machine_soft_i2c_transfer,
715 };
716 
717 const mp_obj_type_t mp_machine_soft_i2c_type = {
718     { &mp_type_type },
719     .name = MP_QSTR_SoftI2C,
720     .print = mp_machine_soft_i2c_print,
721     .make_new = mp_machine_soft_i2c_make_new,
722     .protocol = &mp_machine_soft_i2c_p,
723     .locals_dict = (mp_obj_dict_t *)&mp_machine_i2c_locals_dict,
724 };
725 
726 #endif // MICROPY_PY_MACHINE_I2C
727