Skip to content

Commit df10543

Browse files
authored
Merge pull request #3768 from microDev1/i2c-S2
ESP32S2: Support for i2cperipheral
2 parents 620ef26 + 647e589 commit df10543

File tree

10 files changed

+319
-50
lines changed

10 files changed

+319
-50
lines changed

locale/circuitpython.pot

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,9 @@ msgstr ""
369369
msgid "All CAN peripherals are in use"
370370
msgstr ""
371371

372-
#: ports/espressif/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
372+
#: ports/espressif/common-hal/busio/I2C.c
373+
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
374+
#: ports/nrf/common-hal/busio/I2C.c
373375
msgid "All I2C peripherals are in use"
374376
msgstr ""
375377

@@ -1301,8 +1303,11 @@ msgstr ""
13011303
msgid "Invalid Pin"
13021304
msgstr ""
13031305

1304-
#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c
1305-
#: py/moduerrno.c shared-module/rgbmatrix/RGBMatrix.c
1306+
#: ports/espressif/bindings/espidf/__init__.c
1307+
#: ports/espressif/common-hal/busio/I2C.c
1308+
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
1309+
#: ports/espressif/esp_error.c py/moduerrno.c
1310+
#: shared-module/rgbmatrix/RGBMatrix.c
13061311
msgid "Invalid argument"
13071312
msgstr ""
13081313

@@ -1350,10 +1355,6 @@ msgstr ""
13501355
msgid "Invalid format chunk size"
13511356
msgstr ""
13521357

1353-
#: ports/espressif/common-hal/busio/I2C.c
1354-
msgid "Invalid frequency"
1355-
msgstr ""
1356-
13571358
#: supervisor/shared/safe_mode.c
13581359
msgid "Invalid memory access."
13591360
msgstr ""
@@ -1394,6 +1395,7 @@ msgstr ""
13941395
#: ports/espressif/common-hal/busio/SPI.c
13951396
#: ports/espressif/common-hal/busio/UART.c
13961397
#: ports/espressif/common-hal/canio/CAN.c
1398+
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
13971399
#: ports/mimxrt10xx/common-hal/busio/I2C.c
13981400
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/nrf/common-hal/busio/I2C.c
13991401
#: ports/raspberrypi/common-hal/busio/I2C.c
@@ -1771,6 +1773,10 @@ msgstr ""
17711773
msgid "Only one TouchAlarm can be set in deep sleep."
17721774
msgstr ""
17731775

1776+
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
1777+
msgid "Only one address is allowed"
1778+
msgstr ""
1779+
17741780
#: ports/espressif/common-hal/alarm/time/TimeAlarm.c
17751781
#: ports/nrf/common-hal/alarm/time/TimeAlarm.c
17761782
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c

ports/espressif/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ SRC_C += \
219219
boards/$(BOARD)/pins.c \
220220
modules/$(CIRCUITPY_MODULE).c \
221221
lib/netutils/netutils.c \
222+
peripherals/i2c.c \
222223
peripherals/rmt.c \
223224
peripherals/timer.c \
224225
peripherals/$(IDF_TARGET)/pins.c

ports/espressif/common-hal/busio/I2C.c

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,6 @@
3434
#include "shared-bindings/microcontroller/Pin.h"
3535
#include "supervisor/shared/translate.h"
3636

37-
typedef enum {
38-
STATUS_FREE = 0,
39-
STATUS_IN_USE,
40-
STATUS_NEVER_RESET
41-
} i2c_status_t;
42-
43-
static i2c_status_t i2c_status[I2C_NUM_MAX];
44-
45-
void never_reset_i2c(i2c_port_t num) {
46-
i2c_status[num] = STATUS_NEVER_RESET;
47-
}
48-
49-
void i2c_reset(void) {
50-
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
51-
if (i2c_status[num] == STATUS_IN_USE) {
52-
i2c_status[num] = STATUS_FREE;
53-
}
54-
}
55-
}
56-
5737
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
5838
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
5939
// Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to
@@ -99,21 +79,16 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
9979
}
10080
self->sda_pin = sda;
10181
self->scl_pin = scl;
102-
self->i2c_num = I2C_NUM_MAX;
103-
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
104-
if (i2c_status[num] == STATUS_FREE) {
105-
self->i2c_num = num;
106-
}
107-
}
82+
self->i2c_num = peripherals_i2c_get_free_num();
83+
10884
if (self->i2c_num == I2C_NUM_MAX) {
10985
mp_raise_ValueError(translate("All I2C peripherals are in use"));
11086
}
111-
i2c_status[self->i2c_num] = STATUS_IN_USE;
11287

11388
// Delete any previous driver.
11489
i2c_driver_delete(self->i2c_num);
11590

116-
i2c_config_t i2c_conf = {
91+
const i2c_config_t i2c_conf = {
11792
.mode = I2C_MODE_MASTER,
11893
.sda_io_num = self->sda_pin->number,
11994
.scl_io_num = self->scl_pin->number,
@@ -129,16 +104,15 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
129104
.clk_speed = frequency,
130105
}
131106
};
132-
if (i2c_param_config(self->i2c_num, &i2c_conf) != ESP_OK) {
133-
mp_raise_ValueError(translate("Invalid frequency"));
134-
}
135107

136-
if (i2c_driver_install(self->i2c_num,
137-
I2C_MODE_MASTER,
138-
0,
139-
0,
140-
0) != ESP_OK) {
141-
mp_raise_OSError(MP_EIO);
108+
// Initialize I2C.
109+
esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf);
110+
if (err != ESP_OK) {
111+
if (err == ESP_FAIL) {
112+
mp_raise_OSError(MP_EIO);
113+
} else {
114+
mp_raise_ValueError(translate("Invalid argument"));
115+
}
142116
}
143117

144118
claim_pin(sda);
@@ -154,14 +128,12 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
154128
return;
155129
}
156130

157-
i2c_driver_delete(self->i2c_num);
131+
peripherals_i2c_deinit(self->i2c_num);
158132

159133
common_hal_reset_pin(self->sda_pin);
160134
common_hal_reset_pin(self->scl_pin);
161135
self->sda_pin = NULL;
162136
self->scl_pin = NULL;
163-
164-
i2c_status[self->i2c_num] = STATUS_FREE;
165137
}
166138

167139
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {

ports/espressif/common-hal/busio/I2C.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "freertos/semphr.h"
3535
#include "py/obj.h"
3636

37+
#include "peripherals/i2c.h"
38+
3739
typedef struct {
3840
mp_obj_base_t base;
3941
const mcu_pin_obj_t *scl_pin;
@@ -43,6 +45,4 @@ typedef struct {
4345
bool has_lock;
4446
} busio_i2c_obj_t;
4547

46-
void i2c_reset(void);
47-
4848
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_H
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020 microDev
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 "shared-bindings/i2cperipheral/I2CPeripheral.h"
28+
29+
#include "py/mperrno.h"
30+
#include "py/runtime.h"
31+
32+
#include "common-hal/i2cperipheral/I2CPeripheral.h"
33+
34+
void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self,
35+
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
36+
uint8_t *addresses, unsigned int num_addresses, bool smbus) {
37+
// Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to
38+
// be pulled-down so pulling them up for I2C is a bad idea. To make this hard, we don't
39+
// support I2C on these pins.
40+
// Also 46 is input-only so it'll never work.
41+
if (scl->number == 45 || scl->number == 46 || sda->number == 45 || sda->number == 46) {
42+
mp_raise_ValueError(translate("Invalid pins"));
43+
}
44+
45+
if (num_addresses > 1) {
46+
mp_raise_ValueError(translate("Only one address is allowed"));
47+
}
48+
self->addresses = addresses;
49+
self->num_addresses = num_addresses;
50+
51+
self->sda_pin = sda;
52+
self->scl_pin = scl;
53+
self->i2c_num = peripherals_i2c_get_free_num();
54+
55+
if (self->i2c_num == I2C_NUM_MAX) {
56+
mp_raise_ValueError(translate("All I2C peripherals are in use"));
57+
}
58+
59+
const i2c_config_t i2c_conf = {
60+
.mode = I2C_MODE_SLAVE,
61+
.sda_io_num = self->sda_pin->number,
62+
.scl_io_num = self->scl_pin->number,
63+
.sda_pullup_en = GPIO_PULLUP_ENABLE,
64+
.scl_pullup_en = GPIO_PULLUP_ENABLE,
65+
.slave.addr_10bit_en = 0,
66+
.slave.slave_addr = self->addresses[0],
67+
};
68+
69+
// Initialize I2C.
70+
esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf);
71+
if (err != ESP_OK) {
72+
if (err == ESP_FAIL) {
73+
mp_raise_OSError(MP_EIO);
74+
} else {
75+
mp_raise_ValueError(translate("Invalid argument"));
76+
}
77+
}
78+
79+
claim_pin(sda);
80+
claim_pin(scl);
81+
}
82+
83+
bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self) {
84+
return self->sda_pin == NULL;
85+
}
86+
87+
void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self) {
88+
if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) {
89+
return;
90+
}
91+
92+
peripherals_i2c_deinit(self->i2c_num);
93+
94+
common_hal_reset_pin(self->sda_pin);
95+
common_hal_reset_pin(self->scl_pin);
96+
self->sda_pin = NULL;
97+
self->scl_pin = NULL;
98+
}
99+
100+
int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self,
101+
uint8_t *address, bool *is_read, bool *is_restart) {
102+
*address = self->addresses[0];
103+
*is_read = true;
104+
*is_restart = false;
105+
return 1;
106+
}
107+
108+
int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data) {
109+
i2c_slave_read_buffer(self->i2c_num, data, 128, 0);
110+
return 1;
111+
}
112+
113+
int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data) {
114+
i2c_reset_tx_fifo(self->i2c_num);
115+
i2c_slave_write_buffer(self->i2c_num, &data, 128, 0);
116+
return 1;
117+
}
118+
119+
void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack) {
120+
121+
}
122+
123+
void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self) {
124+
125+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020 microDev
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+
#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H
28+
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H
29+
30+
#include "py/obj.h"
31+
#include "peripherals/i2c.h"
32+
#include "common-hal/microcontroller/Pin.h"
33+
34+
typedef struct {
35+
mp_obj_base_t base;
36+
i2c_port_t i2c_num;
37+
uint8_t *addresses;
38+
uint8_t num_addresses;
39+
const mcu_pin_obj_t *scl_pin;
40+
const mcu_pin_obj_t *sda_pin;
41+
} i2cperipheral_i2c_peripheral_obj_t;
42+
43+
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// No i2cperipheral module functions.

ports/espressif/mpconfigport.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ CIRCUITPY_DUALBANK ?= 1
2525
CIRCUITPY_FRAMEBUFFERIO ?= 1
2626
CIRCUITPY_FREQUENCYIO ?= 1
2727
CIRCUITPY_IMAGECAPTURE ?= 1
28-
CIRCUITPY_I2CPERIPHERAL ?= 0
28+
CIRCUITPY_I2CPERIPHERAL ?= 1
2929
CIRCUITPY_RGBMATRIX ?= 1
3030
CIRCUITPY_ROTARYIO ?= 1
3131
CIRCUITPY_NVM ?= 1

0 commit comments

Comments
 (0)