i2c.c 17.3 KB
Newer Older
1
2
3
#include <stdio.h>
#include <string.h>

4
#include "stm32f4xx_hal.h"
5
6
7
8
9
10
11

#include "nlr.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
12
13
#include "pin.h"
#include "genhdr/pins.h"
14
#include "bufhelper.h"
15
16
#include "i2c.h"

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Usage model:
//
// I2C objects are created attached to a specific bus.  They can be initialised
// when created, or initialised later on:
//
//     from pyb import I2C
//
//     i2c = I2C(1)                         # create on bus 1
//     i2c = I2C(1, I2C.MASTER)             # create and init as a master
//     i2c.deinit()                         # turn off the peripheral
//     i2c.init(I2C.MASTER, baudrate=20000) # init as a master
//     i2c.init(I2C.SLAVE, addr=0x42)       # init as a slave with given address
//
// Printing the i2c object gives you information about its configuration.
//
// Basic methods for slave are send and recv:
//
//     i2c.send('abc')      # send 3 bytes
//     i2c.send(0x42)       # send a single byte, given by the number
//     data = i2c.recv(3)   # receive 3 bytes
//
// To receive inplace, first create a bytearray:
//
//     data = bytearray(3)  # create a buffer
//     i2c.recv(data)       # receive 3 bytes, writing them into data
//
// You can specify a timeout (in ms):
//
//     i2c.send(b'123', timeout=2000)   # timout after 2 seconds
//
// A master must specify the recipient's address:
//
//     i2c.init(I2C.MASTER)
//     i2c.send('123', 0x42)        # send 3 bytes to slave with address 0x42
//     i2c.send(b'456', addr=0x42)  # keyword for address
//
// Master also has other methods:
//
//     i2c.is_ready(0x42)           # check if slave 0x42 is ready
//     i2c.scan()                   # scan for slaves on the bus, returning
//                                  #   a list of valid addresses
//     i2c.mem_read(3, 0x42, 2)     # read 3 bytes from memory of slave 0x42,
//                                  #   starting at address 2 in the slave
//     i2c.mem_write('abc', 0x42, 2, timeout=1000)

62
63
64
#define PYB_I2C_MASTER (0)
#define PYB_I2C_SLAVE  (1)

65
#if MICROPY_HW_ENABLE_I2C1
66
I2C_HandleTypeDef I2CHandle1 = {.Instance = NULL};
67
#endif
68
I2C_HandleTypeDef I2CHandle2 = {.Instance = NULL};
69

70
71
void i2c_init0(void) {
    // reset the I2C1 handles
72
#if MICROPY_HW_ENABLE_I2C1
73
74
    memset(&I2CHandle1, 0, sizeof(I2C_HandleTypeDef));
    I2CHandle1.Instance = I2C1;
75
#endif
76
77
    memset(&I2CHandle2, 0, sizeof(I2C_HandleTypeDef));
    I2CHandle2.Instance = I2C2;
78
79
}

80
void i2c_init(I2C_HandleTypeDef *i2c) {
81
    // init the GPIO lines
82
    GPIO_InitTypeDef GPIO_InitStructure;
83
84
85
86
    GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
    GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines

87
    const pin_obj_t *pins[2];
88
    if (0) {
89
#if MICROPY_HW_ENABLE_I2C1
90
    } else if (i2c == &I2CHandle1) {
91
        // X-skin: X9=PB6=SCL, X10=PB7=SDA
92
93
        pins[0] = &pin_B6;
        pins[1] = &pin_B7;
94
95
96
        GPIO_InitStructure.Alternate = GPIO_AF4_I2C1;
        // enable the I2C clock
        __I2C1_CLK_ENABLE();
97
#endif
98
    } else if (i2c == &I2CHandle2) {
99
        // Y-skin: Y9=PB10=SCL, Y10=PB11=SDA
100
101
        pins[0] = &pin_B10;
        pins[1] = &pin_B11;
102
103
104
        GPIO_InitStructure.Alternate = GPIO_AF4_I2C2;
        // enable the I2C clock
        __I2C2_CLK_ENABLE();
105
106
107
    } else {
        // I2C does not exist for this board (shouldn't get here, should be checked by caller)
        return;
108
109
    }

110
111
112
113
114
115
    // init the GPIO lines
    for (uint i = 0; i < 2; i++) {
        GPIO_InitStructure.Pin = pins[i]->pin_mask;
        HAL_GPIO_Init(pins[i]->gpio, &GPIO_InitStructure);
    }

116
    // init the I2C device
117
    if (HAL_I2C_Init(i2c) != HAL_OK) {
118
        // init error
119
120
        // TODO should raise an exception, but this function is not necessarily going to be
        // called via Python, so may not be properly wrapped in an NLR handler
121
        printf("HardwareError: HAL_I2C_Init failed\n");
122
123
124
125
        return;
    }
}

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
void i2c_deinit(I2C_HandleTypeDef *i2c) {
    HAL_I2C_DeInit(i2c);
    if (0) {
#if MICROPY_HW_ENABLE_I2C1
    } else if (i2c->Instance == I2C1) {
        __I2C1_FORCE_RESET();
        __I2C1_RELEASE_RESET();
        __I2C1_CLK_DISABLE();
#endif
    } else if (i2c->Instance == I2C2) {
        __I2C2_FORCE_RESET();
        __I2C2_RELEASE_RESET();
        __I2C2_CLK_DISABLE();
    }
}

142
143
144
145
146
/******************************************************************************/
/* Micro Python bindings                                                      */

typedef struct _pyb_i2c_obj_t {
    mp_obj_base_t base;
147
    I2C_HandleTypeDef *i2c;
148
149
} pyb_i2c_obj_t;

150
151
STATIC inline bool in_master_mode(pyb_i2c_obj_t *self) { return self->i2c->Init.OwnAddress1 == PYB_I2C_MASTER_ADDRESS; }

152
153
STATIC const pyb_i2c_obj_t pyb_i2c_obj[] = {
#if MICROPY_HW_ENABLE_I2C1
154
    {{&pyb_i2c_type}, &I2CHandle1},
155
156
157
#else
    {{&pyb_i2c_type}, NULL},
#endif
158
159
    {{&pyb_i2c_type}, &I2CHandle2}
};
160
#define PYB_NUM_I2C (sizeof(pyb_i2c_obj) / sizeof(pyb_i2c_obj[0]))
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
    pyb_i2c_obj_t *self = self_in;

    uint i2c_num;
    if (self->i2c->Instance == I2C1) { i2c_num = 1; }
    else { i2c_num = 2; }

    if (self->i2c->State == HAL_I2C_STATE_RESET) {
        print(env, "I2C(%u)", i2c_num);
    } else {
        if (in_master_mode(self)) {
            print(env, "I2C(%u, I2C.MASTER, baudrate=%u)", i2c_num, self->i2c->Init.ClockSpeed);
        } else {
            print(env, "I2C(%u, I2C.SLAVE, addr=0x%02x)", i2c_num, (self->i2c->Instance->OAR1 >> 1) & 0x7f);
        }
    }
}

STATIC const mp_arg_parse_t pyb_i2c_init_accepted_args[] = {
    { MP_QSTR_mode,     MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_INT, {.u_int = 0} },
    { MP_QSTR_addr,     MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = 0x12} },
    { MP_QSTR_baudrate, MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = 400000} },
    { MP_QSTR_gencall,  MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_BOOL, {.u_bool = false} },
};
#define PYB_I2C_INIT_NUM_ARGS (sizeof(pyb_i2c_init_accepted_args) / sizeof(pyb_i2c_init_accepted_args[0]))

STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    // parse args
    mp_arg_parse_val_t vals[PYB_I2C_INIT_NUM_ARGS];
    mp_arg_parse_all(n_args, args, kw_args, PYB_I2C_INIT_NUM_ARGS, pyb_i2c_init_accepted_args, vals);

    // set the I2C configuration values
    I2C_InitTypeDef *init = &self->i2c->Init;

    if (vals[0].u_int == PYB_I2C_MASTER) {
        // use a special address to indicate we are a master
        init->OwnAddress1 = PYB_I2C_MASTER_ADDRESS;
    } else {
        init->OwnAddress1 = (vals[1].u_int << 1) & 0xfe;
    }

    init->AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
    init->ClockSpeed      = MIN(vals[2].u_int, 400000);
    init->DualAddressMode = I2C_DUALADDRESS_DISABLED;
    init->DutyCycle       = I2C_DUTYCYCLE_16_9;
    init->GeneralCallMode = vals[3].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED;
    init->NoStretchMode   = I2C_NOSTRETCH_DISABLED;
    init->OwnAddress2     = 0xfe; // unused

    // init the I2C bus
    i2c_init(self->i2c);

    return mp_const_none;
}

217
218
STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    // check arguments
219
    mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
220
221
222
223
224

    // get i2c number
    machine_int_t i2c_id = mp_obj_get_int(args[0]) - 1;

    // check i2c number
225
    if (!(0 <= i2c_id && i2c_id < PYB_NUM_I2C && pyb_i2c_obj[i2c_id].i2c != NULL)) {
226
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "I2C bus %d does not exist", i2c_id + 1));
227
228
    }

229
    // get I2C object
230
    const pyb_i2c_obj_t *i2c_obj = &pyb_i2c_obj[i2c_id];
231

232
233
234
235
236
237
    if (n_args > 1 || n_kw > 0) {
        // start the peripheral
        mp_map_t kw_args;
        mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
        pyb_i2c_init_helper(i2c_obj, n_args - 1, args + 1, &kw_args);
    }
238

239
    return (mp_obj_t)i2c_obj;
240
241
}

242
243
244
245
246
247
248
249
250
251
252
253
STATIC mp_obj_t pyb_i2c_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    return pyb_i2c_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init);

STATIC mp_obj_t pyb_i2c_deinit(mp_obj_t self_in) {
    pyb_i2c_obj_t *self = self_in;
    i2c_deinit(self->i2c);
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_deinit_obj, pyb_i2c_deinit);

254
// Check if an I2C device responds to the given address.
255
256
STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) {
    pyb_i2c_obj_t *self = self_in;
257
258
259
260
261

    if (!in_master_mode(self)) {
        nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
    }

262
263
264
    machine_uint_t i2c_addr = mp_obj_get_int(i2c_addr_o) << 1;

    for (int i = 0; i < 10; i++) {
265
        HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(self->i2c, i2c_addr, 10, 200);
266
267
268
269
270
271
272
273
274
        if (status == HAL_OK) {
            return mp_const_true;
        }
    }

    return mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_is_ready_obj, pyb_i2c_is_ready);

275
276
277
278
// Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
    pyb_i2c_obj_t *self = self_in;

279
280
281
282
    if (!in_master_mode(self)) {
        nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
    }

283
284
285
286
    mp_obj_t list = mp_obj_new_list(0, NULL);

    for (uint addr = 1; addr <= 127; addr++) {
        for (int i = 0; i < 10; i++) {
287
            HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(self->i2c, addr << 1, 10, 200);
288
289
290
291
292
293
294
295
296
297
298
            if (status == HAL_OK) {
                mp_obj_list_append(list, mp_obj_new_int(addr));
                break;
            }
        }
    }

    return list;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);

299
300
301
302
303
304
STATIC const mp_arg_parse_t pyb_i2c_send_accepted_args[] = {
    { MP_QSTR_send,    MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_OBJ, {.u_obj = MP_OBJ_NULL} },
    { MP_QSTR_addr,    MP_ARG_PARSE_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
    { MP_QSTR_timeout, MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = 5000} },
};
#define PYB_I2C_SEND_NUM_ARGS (sizeof(pyb_i2c_send_accepted_args) / sizeof(pyb_i2c_send_accepted_args[0]))
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
STATIC mp_obj_t pyb_i2c_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    pyb_i2c_obj_t *self = args[0];

    // parse args
    mp_arg_parse_val_t vals[PYB_I2C_SEND_NUM_ARGS];
    mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_SEND_NUM_ARGS, pyb_i2c_send_accepted_args, vals);

    // get the buffer to send from
    mp_buffer_info_t bufinfo;
    uint8_t data[1];
    pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);

    // send the data
    HAL_StatusTypeDef status;
    if (in_master_mode(self)) {
        if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required"));
        }
        machine_uint_t i2c_addr = vals[1].u_int << 1;
        status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, vals[2].u_int);
    } else {
        status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, vals[2].u_int);
    }
329
330
331

    if (status != HAL_OK) {
        // TODO really need a HardwareError object, or something
332
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_xxx_Transmit failed with code %d", status));
333
334
    }

335
    return mp_const_none;
336
}
337
338
339
340
341
342
343
344
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_send_obj, 1, pyb_i2c_send);

STATIC const mp_arg_parse_t pyb_i2c_recv_accepted_args[] = {
    { MP_QSTR_recv,    MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_OBJ, {.u_obj = MP_OBJ_NULL} },
    { MP_QSTR_addr,    MP_ARG_PARSE_INT, {.u_int = PYB_I2C_MASTER_ADDRESS} },
    { MP_QSTR_timeout, MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = 5000} },
};
#define PYB_I2C_RECV_NUM_ARGS (sizeof(pyb_i2c_recv_accepted_args) / sizeof(pyb_i2c_recv_accepted_args[0]))
345

346
347
STATIC mp_obj_t pyb_i2c_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    pyb_i2c_obj_t *self = args[0];
348

349
350
351
352
353
354
355
356
357
    // parse args
    mp_arg_parse_val_t vals[PYB_I2C_RECV_NUM_ARGS];
    mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_RECV_NUM_ARGS, pyb_i2c_recv_accepted_args, vals);

    // get the buffer to receive into
    mp_buffer_info_t bufinfo;
    mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo);

    // receive the data
358
    HAL_StatusTypeDef status;
359
360
361
362
363
364
    if (in_master_mode(self)) {
        if (vals[1].u_int == PYB_I2C_MASTER_ADDRESS) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "addr argument required"));
        }
        machine_uint_t i2c_addr = vals[1].u_int << 1;
        status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, vals[2].u_int);
365
    } else {
366
        status = HAL_I2C_Slave_Receive(self->i2c, bufinfo.buf, bufinfo.len, vals[2].u_int);
367
368
369
370
    }

    if (status != HAL_OK) {
        // TODO really need a HardwareError object, or something
371
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_xxx_Receive failed with code %d", status));
372
373
    }

374
375
376
377
378
379
    // return the received data
    if (o_ret == MP_OBJ_NULL) {
        return vals[0].u_obj;
    } else {
        return mp_obj_str_builder_end(o_ret);
    }
380
}
381
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv);
382

383
384
385
386
387
388
389
STATIC const mp_arg_parse_t pyb_i2c_mem_read_accepted_args[] = {
    { MP_QSTR_data,    MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_OBJ, {.u_obj = MP_OBJ_NULL} },
    { MP_QSTR_addr,    MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_INT, {.u_int = 0} },
    { MP_QSTR_memaddr, MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_INT, {.u_int = 0} },
    { MP_QSTR_timeout, MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = 5000} },
};
#define PYB_I2C_MEM_READ_NUM_ARGS (sizeof(pyb_i2c_mem_read_accepted_args) / sizeof(pyb_i2c_mem_read_accepted_args[0]))
390

391
STATIC mp_obj_t pyb_i2c_mem_read(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
392
393
    pyb_i2c_obj_t *self = args[0];

394
395
396
397
398
399
400
401
402
403
404
    if (!in_master_mode(self)) {
        nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
    }

    // parse args
    mp_arg_parse_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
    mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_accepted_args, vals);

    // get the buffer to read into
    mp_buffer_info_t bufinfo;
    mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo);
405

406
407
408
409
410
    // get the addresses
    machine_uint_t i2c_addr = vals[1].u_int << 1;
    machine_uint_t mem_addr = vals[2].u_int;

    HAL_StatusTypeDef status = HAL_I2C_Mem_Read(self->i2c, i2c_addr, mem_addr, I2C_MEMADD_SIZE_8BIT, bufinfo.buf, bufinfo.len, vals[3].u_int);
411
412
413

    if (status != HAL_OK) {
        // TODO really need a HardwareError object, or something
414
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_Mem_Read failed with code %d", status));
415
416
    }

417
418
419
420
421
422
    // return the read data
    if (o_ret == MP_OBJ_NULL) {
        return vals[0].u_obj;
    } else {
        return mp_obj_str_builder_end(o_ret);
    }
423
}
424
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_read_obj, 1, pyb_i2c_mem_read);
425

426
STATIC mp_obj_t pyb_i2c_mem_write(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
427
    pyb_i2c_obj_t *self = args[0];
428
429
430

    if (!in_master_mode(self)) {
        nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "I2C must be a master"));
431
432
    }

433
434
435
436
437
438
439
440
441
442
443
444
445
446
    // parse args (same as mem_read)
    mp_arg_parse_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
    mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_accepted_args, vals);

    // get the buffer to write from
    mp_buffer_info_t bufinfo;
    uint8_t data[1];
    pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);

    // get the addresses
    machine_uint_t i2c_addr = vals[1].u_int << 1;
    machine_uint_t mem_addr = vals[2].u_int;

    HAL_StatusTypeDef status = HAL_I2C_Mem_Write(self->i2c, i2c_addr, mem_addr, I2C_MEMADD_SIZE_8BIT, bufinfo.buf, bufinfo.len, vals[3].u_int);
447
448
449

    if (status != HAL_OK) {
        // TODO really need a HardwareError object, or something
450
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_I2C_Mem_Write failed with code %d", status));
451
452
453
454
    }

    return mp_const_none;
}
455
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_write_obj, 1, pyb_i2c_mem_write);
456

457
STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
458
459
460
    // instance methods
    { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_i2c_init_obj },
    { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_i2c_deinit_obj },
461
    { MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj },
462
    { MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj },
463
464
    { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_i2c_send_obj },
    { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj },
465
466
    { MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj },
    { MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj },
467
468
469
470

    // class constants
    { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER),       MP_OBJ_NEW_SMALL_INT(PYB_I2C_MASTER) },
    { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE),        MP_OBJ_NEW_SMALL_INT(PYB_I2C_SLAVE) },
471
472
};

473
474
STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table);

475
476
477
const mp_obj_type_t pyb_i2c_type = {
    { &mp_type_type },
    .name = MP_QSTR_I2C,
478
    .print = pyb_i2c_print,
479
    .make_new = pyb_i2c_make_new,
480
    .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict,
481
};