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