i2cperipheral implementation for esp32s2

This commit is contained in:
microDev 2021-10-05 00:00:00 +05:30
parent e8f21f012c
commit d9eafffa6a
No known key found for this signature in database
GPG Key ID: 2C0867BE60967730
10 changed files with 318 additions and 50 deletions

View File

@ -369,7 +369,9 @@ msgstr ""
msgid "All CAN peripherals are in use"
msgstr ""
#: ports/espressif/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
#: ports/espressif/common-hal/busio/I2C.c
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
#: ports/nrf/common-hal/busio/I2C.c
msgid "All I2C peripherals are in use"
msgstr ""
@ -1301,8 +1303,11 @@ msgstr ""
msgid "Invalid Pin"
msgstr ""
#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c
#: py/moduerrno.c shared-module/rgbmatrix/RGBMatrix.c
#: ports/espressif/bindings/espidf/__init__.c
#: ports/espressif/common-hal/busio/I2C.c
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
#: ports/espressif/esp_error.c py/moduerrno.c
#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Invalid argument"
msgstr ""
@ -1350,10 +1355,6 @@ msgstr ""
msgid "Invalid format chunk size"
msgstr ""
#: ports/espressif/common-hal/busio/I2C.c
msgid "Invalid frequency"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Invalid memory access."
msgstr ""
@ -1394,6 +1395,7 @@ msgstr ""
#: ports/espressif/common-hal/busio/SPI.c
#: ports/espressif/common-hal/busio/UART.c
#: ports/espressif/common-hal/canio/CAN.c
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
#: ports/mimxrt10xx/common-hal/busio/I2C.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/nrf/common-hal/busio/I2C.c
#: ports/raspberrypi/common-hal/busio/I2C.c
@ -1771,6 +1773,10 @@ msgstr ""
msgid "Only one TouchAlarm can be set in deep sleep."
msgstr ""
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
msgid "Only one address is allowed"
msgstr ""
#: ports/espressif/common-hal/alarm/time/TimeAlarm.c
#: ports/nrf/common-hal/alarm/time/TimeAlarm.c
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c

View File

@ -219,6 +219,7 @@ SRC_C += \
boards/$(BOARD)/pins.c \
modules/$(CIRCUITPY_MODULE).c \
lib/netutils/netutils.c \
peripherals/i2c.c \
peripherals/rmt.c \
peripherals/timer.c \
peripherals/$(IDF_TARGET)/pins.c

View File

@ -34,26 +34,6 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "supervisor/shared/translate.h"
typedef enum {
STATUS_FREE = 0,
STATUS_IN_USE,
STATUS_NEVER_RESET
} i2c_status_t;
static i2c_status_t i2c_status[I2C_NUM_MAX];
void never_reset_i2c(i2c_port_t num) {
i2c_status[num] = STATUS_NEVER_RESET;
}
void i2c_reset(void) {
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
if (i2c_status[num] == STATUS_IN_USE) {
i2c_status[num] = STATUS_FREE;
}
}
}
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
// 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,
}
self->sda_pin = sda;
self->scl_pin = scl;
self->i2c_num = I2C_NUM_MAX;
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
if (i2c_status[num] == STATUS_FREE) {
self->i2c_num = num;
}
}
self->i2c_num = i2c_num_status();
if (self->i2c_num == I2C_NUM_MAX) {
mp_raise_ValueError(translate("All I2C peripherals are in use"));
}
i2c_status[self->i2c_num] = STATUS_IN_USE;
// Delete any previous driver.
i2c_driver_delete(self->i2c_num);
i2c_config_t i2c_conf = {
const i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = self->sda_pin->number,
.scl_io_num = self->scl_pin->number,
@ -129,16 +104,15 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
.clk_speed = frequency,
}
};
if (i2c_param_config(self->i2c_num, &i2c_conf) != ESP_OK) {
mp_raise_ValueError(translate("Invalid frequency"));
}
if (i2c_driver_install(self->i2c_num,
I2C_MODE_MASTER,
0,
0,
0) != ESP_OK) {
// Initialize I2C.
esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf);
if (err != ESP_OK) {
if (err == ESP_FAIL) {
mp_raise_OSError(MP_EIO);
} else {
mp_raise_ValueError(translate("Invalid argument"));
}
}
claim_pin(sda);
@ -154,14 +128,12 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
return;
}
i2c_driver_delete(self->i2c_num);
peripherals_i2c_deinit(self->i2c_num);
common_hal_reset_pin(self->sda_pin);
common_hal_reset_pin(self->scl_pin);
self->sda_pin = NULL;
self->scl_pin = NULL;
i2c_status[self->i2c_num] = STATUS_FREE;
}
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {

View File

@ -34,6 +34,8 @@
#include "freertos/semphr.h"
#include "py/obj.h"
#include "peripherals/i2c.h"
typedef struct {
mp_obj_base_t base;
const mcu_pin_obj_t *scl_pin;
@ -43,6 +45,4 @@ typedef struct {
bool has_lock;
} busio_i2c_obj_t;
void i2c_reset(void);
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_H

View File

@ -0,0 +1,125 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 microDev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/i2cperipheral/I2CPeripheral.h"
#include "py/mperrno.h"
#include "py/runtime.h"
#include "common-hal/i2cperipheral/I2CPeripheral.h"
void common_hal_i2cperipheral_i2c_peripheral_construct(i2cperipheral_i2c_peripheral_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
uint8_t *addresses, unsigned int num_addresses, bool smbus) {
// Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to
// be pulled-down so pulling them up for I2C is a bad idea. To make this hard, we don't
// support I2C on these pins.
// Also 46 is input-only so it'll never work.
if (scl->number == 45 || scl->number == 46 || sda->number == 45 || sda->number == 46) {
mp_raise_ValueError(translate("Invalid pins"));
}
if (num_addresses > 1) {
mp_raise_ValueError(translate("Only one address is allowed"));
}
self->addresses = addresses;
self->num_addresses = num_addresses;
self->sda_pin = sda;
self->scl_pin = scl;
self->i2c_num = i2c_num_status();
if (self->i2c_num == I2C_NUM_MAX) {
mp_raise_ValueError(translate("All I2C peripherals are in use"));
}
const i2c_config_t i2c_conf = {
.mode = I2C_MODE_SLAVE,
.sda_io_num = self->sda_pin->number,
.scl_io_num = self->scl_pin->number,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.slave.addr_10bit_en = 0,
.slave.slave_addr = self->addresses[0],
};
// Initialize I2C.
esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf);
if (err != ESP_OK) {
if (err == ESP_FAIL) {
mp_raise_OSError(MP_EIO);
} else {
mp_raise_ValueError(translate("Invalid argument"));
}
}
claim_pin(sda);
claim_pin(scl);
}
bool common_hal_i2cperipheral_i2c_peripheral_deinited(i2cperipheral_i2c_peripheral_obj_t *self) {
return self->sda_pin == NULL;
}
void common_hal_i2cperipheral_i2c_peripheral_deinit(i2cperipheral_i2c_peripheral_obj_t *self) {
if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) {
return;
}
peripherals_i2c_deinit(self->i2c_num);
common_hal_reset_pin(self->sda_pin);
common_hal_reset_pin(self->scl_pin);
self->sda_pin = NULL;
self->scl_pin = NULL;
}
int common_hal_i2cperipheral_i2c_peripheral_is_addressed(i2cperipheral_i2c_peripheral_obj_t *self,
uint8_t *address, bool *is_read, bool *is_restart) {
*address = self->addresses[0];
*is_read = true;
*is_restart = false;
return 1;
}
int common_hal_i2cperipheral_i2c_peripheral_read_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t *data) {
i2c_slave_read_buffer(self->i2c_num, data, 128, 0);
return 1;
}
int common_hal_i2cperipheral_i2c_peripheral_write_byte(i2cperipheral_i2c_peripheral_obj_t *self, uint8_t data) {
i2c_reset_tx_fifo(self->i2c_num);
i2c_slave_write_buffer(self->i2c_num, &data, 128, 0);
return 1;
}
void common_hal_i2cperipheral_i2c_peripheral_ack(i2cperipheral_i2c_peripheral_obj_t *self, bool ack) {
}
void common_hal_i2cperipheral_i2c_peripheral_close(i2cperipheral_i2c_peripheral_obj_t *self) {
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 microDev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H
#include "py/obj.h"
#include "peripherals/i2c.h"
#include "common-hal/microcontroller/Pin.h"
typedef struct {
mp_obj_base_t base;
i2c_port_t i2c_num;
uint8_t *addresses;
uint8_t num_addresses;
const mcu_pin_obj_t *scl_pin;
const mcu_pin_obj_t *sda_pin;
} i2cperipheral_i2c_peripheral_obj_t;
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_BUSIO_I2C_PERIPHERAL_H

View File

@ -0,0 +1 @@
// No i2cperipheral module functions.

View File

@ -25,7 +25,7 @@ CIRCUITPY_DUALBANK ?= 1
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_FREQUENCYIO ?= 1
CIRCUITPY_IMAGECAPTURE ?= 1
CIRCUITPY_I2CPERIPHERAL ?= 0
CIRCUITPY_I2CPERIPHERAL ?= 1
CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_ROTARYIO ?= 1
CIRCUITPY_NVM ?= 1

View File

@ -0,0 +1,82 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 microDev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "peripherals/i2c.h"
typedef enum {
STATUS_FREE = 0,
STATUS_IN_USE,
STATUS_NEVER_RESET
} i2c_status_t;
static i2c_status_t i2c_status[I2C_NUM_MAX];
void i2c_reset(void) {
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
if (i2c_status[num] == STATUS_IN_USE) {
i2c_driver_delete(num);
i2c_status[num] = STATUS_FREE;
}
}
}
void never_reset_i2c(i2c_port_t num) {
i2c_status[num] = STATUS_NEVER_RESET;
}
esp_err_t peripherals_i2c_init(i2c_port_t num, const i2c_config_t *i2c_conf) {
esp_err_t err = i2c_param_config(num, i2c_conf);
if (err != ESP_OK) {
return err;
}
size_t rx_buf_len = 0;
size_t tx_buf_len = 0;
if (i2c_conf->mode == I2C_MODE_SLAVE) {
rx_buf_len = 256;
tx_buf_len = 256;
}
return i2c_driver_install(num, i2c_conf->mode, rx_buf_len, tx_buf_len, 0);
}
void peripherals_i2c_deinit(i2c_port_t num) {
i2c_reset_rx_fifo(num);
i2c_reset_tx_fifo(num);
i2c_driver_delete(num);
i2c_status[num] = STATUS_FREE;
}
i2c_port_t i2c_num_status(void) {
i2c_port_t i2c_num = I2C_NUM_MAX;
for (i2c_port_t num = 0; num < I2C_NUM_MAX; num++) {
if (i2c_status[num] == STATUS_FREE) {
i2c_num = num;
}
}
if (i2c_num != I2C_NUM_MAX) {
i2c_status[i2c_num] = STATUS_IN_USE;
}
return i2c_num;
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 microDev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_ESPRESSIF_PERIPHERALS_I2C_HANDLER_H
#define MICROPY_INCLUDED_ESPRESSIF_PERIPHERALS_I2C_HANDLER_H
#include "driver/i2c.h"
extern void i2c_reset(void);
extern void never_reset_i2c(i2c_port_t num);
extern esp_err_t peripherals_i2c_init(i2c_port_t num, const i2c_config_t *i2c_conf);
extern void peripherals_i2c_deinit(i2c_port_t num);
extern i2c_port_t i2c_num_status(void);
#endif // MICROPY_INCLUDED_ESPRESSIF_PERIPHERALS_I2C_HANDLER_H