1+ /*
2+ * This file is part of the MicroPython project, http://micropython.org/
3+ *
4+ * The MIT License (MIT)
5+ *
6+ * Copyright (c) 2016 Scott Shawcroft
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+ // This file contains all of the Python API definitions for the
28+ // busio.I2C class.
29+
30+ #include "shared-bindings/microcontroller/Pin.h"
31+ #include "shared-bindings/busdevice/I2CDevice.h"
32+ #include "shared-bindings/util.h"
33+ #include "shared-module/busdevice/I2CDevice.h"
34+
35+ #include "lib/utils/buffer_helper.h"
36+ #include "lib/utils/context_manager_helpers.h"
37+ #include "py/runtime.h"
38+ #include "supervisor/shared/translate.h"
39+
40+ //| class I2CDevice:
41+ //| """Two wire serial protocol"""
42+ //|
43+ //| def __init__(self, i2c, device_address, probe=True) -> None:
44+ //|
45+ //| ...
46+ //|
47+ STATIC mp_obj_t busdevice_i2cdevice_make_new (const mp_obj_type_t * type , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
48+ busdevice_i2cdevice_obj_t * self = m_new_obj (busdevice_i2cdevice_obj_t );
49+ self -> base .type = & busdevice_i2cdevice_type ;
50+ enum { ARG_i2c , ARG_device_address , ARG_probe };
51+ static const mp_arg_t allowed_args [] = {
52+ { MP_QSTR_i2c , MP_ARG_REQUIRED | MP_ARG_OBJ },
53+ { MP_QSTR_device_address , MP_ARG_REQUIRED | MP_ARG_INT },
54+ { MP_QSTR_probe , MP_ARG_BOOL , {.u_bool = true} },
55+ };
56+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
57+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
58+
59+ busio_i2c_obj_t * i2c = args [ARG_i2c ].u_obj ;
60+
61+ common_hal_busdevice_i2cdevice_construct (self , i2c , args [ARG_device_address ].u_int , args [ARG_probe ].u_bool );
62+ return (mp_obj_t )self ;
63+ }
64+
65+ //| def __enter__(self) -> None:
66+ //| """Automatically initializes the hardware on context exit. See FIX
67+ //| :ref:`lifetime-and-contextmanagers` for more info."""
68+ //| ...
69+ //|
70+ STATIC mp_obj_t busdevice_i2cdevice_obj___enter__ (mp_obj_t self_in ) {
71+ common_hal_busdevice_i2cdevice_lock (self_in );
72+ return self_in ;
73+ }
74+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (busdevice_i2cdevice___enter___obj , busdevice_i2cdevice_obj___enter__ );
75+
76+ //| def __exit__(self) -> None:
77+ //| """Automatically deinitializes the hardware on context exit. See
78+ //| :ref:`lifetime-and-contextmanagers` for more info."""
79+ //| ...
80+ //|
81+ STATIC mp_obj_t busdevice_i2cdevice_obj___exit__ (size_t n_args , const mp_obj_t * args ) {
82+ common_hal_busdevice_i2cdevice_unlock (args [0 ]);
83+ return mp_const_none ;
84+ }
85+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (busdevice_i2cdevice___exit___obj , 4 , 4 , busdevice_i2cdevice_obj___exit__ );
86+
87+ STATIC void readinto (busdevice_i2cdevice_obj_t * self , mp_obj_t buffer , int32_t start , mp_int_t end ) {
88+ mp_buffer_info_t bufinfo ;
89+ mp_get_buffer_raise (buffer , & bufinfo , MP_BUFFER_WRITE );
90+
91+ size_t length = bufinfo .len ;
92+ normalize_buffer_bounds (& start , end , & length );
93+ if (length == 0 ) {
94+ mp_raise_ValueError (translate ("Buffer must be at least length 1" ));
95+ }
96+
97+ uint8_t status = common_hal_busdevice_i2cdevice_readinto (self , ((uint8_t * )bufinfo .buf ) + start , length );
98+ if (status != 0 ) {
99+ mp_raise_OSError (status );
100+ }
101+ }
102+
103+ STATIC mp_obj_t busdevice_i2cdevice_readinto (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
104+ enum { ARG_buffer , ARG_start , ARG_end };
105+ static const mp_arg_t allowed_args [] = {
106+ { MP_QSTR_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
107+ { MP_QSTR_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
108+ { MP_QSTR_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
109+ };
110+
111+ busdevice_i2cdevice_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
112+
113+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
114+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
115+
116+ readinto (self , args [ARG_buffer ].u_obj , args [ARG_start ].u_int , args [ARG_end ].u_int );
117+ return mp_const_none ;
118+ }
119+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (busdevice_i2cdevice_readinto_obj , 2 , busdevice_i2cdevice_readinto );
120+
121+
122+ STATIC void write (busdevice_i2cdevice_obj_t * self , mp_obj_t buffer , int32_t start , mp_int_t end ) {
123+ mp_buffer_info_t bufinfo ;
124+ mp_get_buffer_raise (buffer , & bufinfo , MP_BUFFER_READ );
125+
126+ size_t length = bufinfo .len ;
127+ normalize_buffer_bounds (& start , end , & length );
128+ if (length == 0 ) {
129+ mp_raise_ValueError (translate ("Buffer must be at least length 1" ));
130+ }
131+
132+ uint8_t status = common_hal_busdevice_i2cdevice_write (self , ((uint8_t * )bufinfo .buf ) + start , length );
133+ if (status != 0 ) {
134+ mp_raise_OSError (status );
135+ }
136+ }
137+
138+ STATIC mp_obj_t busdevice_i2cdevice_write (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
139+ enum { ARG_buffer , ARG_start , ARG_end };
140+ static const mp_arg_t allowed_args [] = {
141+ { MP_QSTR_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
142+ { MP_QSTR_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
143+ { MP_QSTR_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
144+ };
145+ busdevice_i2cdevice_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
146+
147+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
148+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
149+
150+ write (self , args [ARG_buffer ].u_obj , args [ARG_start ].u_int , args [ARG_end ].u_int );
151+ return mp_const_none ;
152+ }
153+ MP_DEFINE_CONST_FUN_OBJ_KW (busdevice_i2cdevice_write_obj , 2 , busdevice_i2cdevice_write );
154+
155+
156+ /*STATIC void write_then_readinto(busdevice_i2cdevice_obj_t *self, mp_obj_t out_buffer, mp_obj_t in_buffer,
157+ int32_t out_start, mp_int_t out_end, int32_t in_start, mp_int_t in_end) {
158+ mp_buffer_info_t out_bufinfo;
159+ mp_get_buffer_raise(out_buffer, &out_bufinfo, MP_BUFFER_READ);
160+
161+ size_t out_length = out_bufinfo.len;
162+ normalize_buffer_bounds(&out_start, out_end, &out_length);
163+ if (out_length == 0) {
164+ mp_raise_ValueError(translate("Buffer must be at least length 1"));
165+ }
166+
167+ mp_buffer_info_t in_bufinfo;
168+ mp_get_buffer_raise(in_buffer, &in_bufinfo, MP_BUFFER_WRITE);
169+
170+ size_t in_length = in_bufinfo.len;
171+ normalize_buffer_bounds(&in_start, in_end, &in_length);
172+ if (in_length == 0) {
173+ mp_raise_ValueError(translate("Buffer must be at least length 1"));
174+ }
175+
176+ uint8_t status = common_hal_busdevice_i2cdevice_write_then_readinto(self, out_buffer, in_buffer, out_length, in_length);
177+ if (status != 0) {
178+ mp_raise_OSError(status);
179+ }
180+ }*/
181+
182+ STATIC mp_obj_t busdevice_i2cdevice_write_then_readinto (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
183+ enum { ARG_out_buffer , ARG_in_buffer , ARG_out_start , ARG_out_end , ARG_in_start , ARG_in_end };
184+ static const mp_arg_t allowed_args [] = {
185+ { MP_QSTR_out_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
186+ { MP_QSTR_in_buffer , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
187+ { MP_QSTR_out_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
188+ { MP_QSTR_out_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
189+ { MP_QSTR_in_start , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
190+ { MP_QSTR_in_end , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = INT_MAX } },
191+ };
192+ busdevice_i2cdevice_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
193+
194+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
195+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
196+
197+ write (self , args [ARG_out_buffer ].u_obj , args [ARG_out_start ].u_int , args [ARG_out_end ].u_int );
198+
199+ readinto (self , args [ARG_in_buffer ].u_obj , args [ARG_in_start ].u_int , args [ARG_in_end ].u_int );
200+
201+ return mp_const_none ;
202+ }
203+ MP_DEFINE_CONST_FUN_OBJ_KW (busdevice_i2cdevice_write_then_readinto_obj , 3 , busdevice_i2cdevice_write_then_readinto );
204+
205+
206+ STATIC mp_obj_t busdevice_i2cdevice___probe_for_device (mp_obj_t self_in ) {
207+ //busdevice_i2cdevice_obj_t *self = self_in;
208+
209+ //common_hal_busdevice_i2cdevice_lock(self_in);
210+
211+ /*
212+ uint8_t buffer;
213+ mp_buffer_info_t bufinfo;
214+ mp_get_buffer_raise(&buffer, &bufinfo, MP_BUFFER_WRITE);
215+
216+ uint8_t status = common_hal_busdevice_i2cdevice_readinto(self_in, (uint8_t*)bufinfo.buf, 1);
217+ if (status != 0) {
218+ common_hal_busdevice_i2cdevice_unlock(self_in);
219+ mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address);
220+ }
221+ */
222+ //common_hal_busdevice_i2cdevice_unlock(self_in);
223+
224+ return mp_const_none ;
225+ }
226+ MP_DEFINE_CONST_FUN_OBJ_1 (busdevice_i2cdevice___probe_for_device_obj , busdevice_i2cdevice___probe_for_device );
227+
228+
229+ STATIC const mp_rom_map_elem_t busdevice_i2cdevice_locals_dict_table [] = {
230+ { MP_ROM_QSTR (MP_QSTR___enter__ ), MP_ROM_PTR (& busdevice_i2cdevice___enter___obj ) },
231+ { MP_ROM_QSTR (MP_QSTR___exit__ ), MP_ROM_PTR (& busdevice_i2cdevice___exit___obj ) },
232+ { MP_ROM_QSTR (MP_QSTR_readinto ), MP_ROM_PTR (& busdevice_i2cdevice_readinto_obj ) },
233+ { MP_ROM_QSTR (MP_QSTR_write ), MP_ROM_PTR (& busdevice_i2cdevice_write_obj ) },
234+ { MP_ROM_QSTR (MP_QSTR_write_then_readinto ), MP_ROM_PTR (& busdevice_i2cdevice_write_then_readinto_obj ) },
235+ { MP_ROM_QSTR (MP_QSTR___probe_for_device ), MP_ROM_PTR (& busdevice_i2cdevice___probe_for_device_obj ) },
236+ };
237+
238+
239+ STATIC MP_DEFINE_CONST_DICT (busdevice_i2cdevice_locals_dict , busdevice_i2cdevice_locals_dict_table );
240+
241+ const mp_obj_type_t busdevice_i2cdevice_type = {
242+ { & mp_type_type },
243+ .name = MP_QSTR_I2CDevice ,
244+ .make_new = busdevice_i2cdevice_make_new ,
245+ .locals_dict = (mp_obj_dict_t * )& busdevice_i2cdevice_locals_dict ,
246+ };
0 commit comments