Switch to IDF 5.2 I2C API
Make busio.I2C use finalizers for reset instead of bulk reset. This makes it easier to track and free the memory that the IDF allocates internally for its "handle".
This commit is contained in:
parent
13d659a883
commit
e9f8ed41dc
31 changed files with 169 additions and 292 deletions
|
|
@ -108,21 +108,29 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
|||
mp_arg_error_invalid(MP_QSTR_frequency);
|
||||
}
|
||||
|
||||
self->sda_pin = sda->number;
|
||||
self->scl_pin = scl->number;
|
||||
claim_pin(sda);
|
||||
claim_pin(scl);
|
||||
|
||||
if (i2c_m_sync_enable(&self->i2c_desc) != ERR_NONE) {
|
||||
common_hal_busio_i2c_deinit(self);
|
||||
mp_raise_OSError(MP_EIO);
|
||||
}
|
||||
|
||||
self->sda_pin = sda->number;
|
||||
self->scl_pin = scl->number;
|
||||
claim_pin(sda);
|
||||
claim_pin(scl);
|
||||
|
||||
// Prevent bulk sercom reset from resetting us. The finalizer will instead.
|
||||
never_reset_sercom(self->i2c_desc.device.hw);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
return self->sda_pin == NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda_pin = NO_PIN;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
|
|
@ -135,6 +143,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
reset_pin_number(self->scl_pin);
|
||||
self->sda_pin = NO_PIN;
|
||||
self->scl_pin = NO_PIN;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
|
|
@ -236,8 +245,6 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
|
|||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset_sercom(self->i2c_desc.device.hw);
|
||||
|
||||
never_reset_pin_number(self->scl_pin);
|
||||
never_reset_pin_number(self->sda_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,28 +23,8 @@ static BSC0_Type *i2c[NUM_I2C] = {BSC0, BSC1, NULL, BSC3, BSC4, BSC5, BSC6, NULL
|
|||
static BSC0_Type *i2c[NUM_I2C] = {BSC0, BSC1, NULL};
|
||||
#endif
|
||||
|
||||
static bool never_reset_i2c[NUM_I2C];
|
||||
static bool i2c_in_use[NUM_I2C];
|
||||
|
||||
void reset_i2c(void) {
|
||||
// BSC2 is dedicated to the first HDMI output.
|
||||
never_reset_i2c[2] = true;
|
||||
i2c_in_use[2] = true;
|
||||
#if BCM_VERSION == 2711
|
||||
// BSC7 is dedicated to the second HDMI output.
|
||||
never_reset_i2c[7] = true;
|
||||
i2c_in_use[7] = true;
|
||||
#endif
|
||||
for (size_t i = 0; i < NUM_I2C; i++) {
|
||||
if (never_reset_i2c[i]) {
|
||||
continue;
|
||||
}
|
||||
i2c_in_use[i] = false;
|
||||
i2c[i]->C_b.I2CEN = false;
|
||||
COMPLETE_MEMORY_READS;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
size_t instance_index = NUM_I2C;
|
||||
|
|
@ -90,17 +70,21 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
|||
return self->sda_pin == NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda_pin = NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
never_reset_i2c[self->index] = false;
|
||||
i2c_in_use[self->index] = false;
|
||||
|
||||
common_hal_reset_pin(self->sda_pin);
|
||||
common_hal_reset_pin(self->scl_pin);
|
||||
self->sda_pin = NULL;
|
||||
self->scl_pin = NULL;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
|
|
@ -246,8 +230,6 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
|
|||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset_i2c[self->index] = true;
|
||||
|
||||
common_hal_never_reset_pin(self->scl_pin);
|
||||
common_hal_never_reset_pin(self->sda_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,3 @@ typedef struct {
|
|||
bool finish_write;
|
||||
uint8_t last_write_data;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void reset_i2c(void);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "genhdr/mpversion.h"
|
||||
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "common-hal/busio/UART.h"
|
||||
|
||||
|
|
@ -66,7 +65,6 @@ safe_mode_t port_init(void) {
|
|||
|
||||
void reset_port(void) {
|
||||
#if CIRCUITPY_BUSIO
|
||||
reset_i2c();
|
||||
reset_spi();
|
||||
reset_uart();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,12 +44,18 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
|
||||
reset_pin_number(self->scl_pin->number);
|
||||
reset_pin_number(self->sda_pin->number);
|
||||
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
return self->i2c_dev == NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->i2c_dev = NULL;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -392,7 +392,6 @@ SRC_C += \
|
|||
boards/$(BOARD)/board.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
shared/netutils/netutils.c \
|
||||
peripherals/i2c.c \
|
||||
peripherals/$(IDF_TARGET)/pins.c
|
||||
|
||||
ifeq ($(CIRCUITPY_SSL),1)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@
|
|||
|
||||
#include "components/driver/i2c/include/driver/i2c.h"
|
||||
|
||||
#include "bindings/espidf/__init__.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
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) {
|
||||
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout_us) {
|
||||
// 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.
|
||||
|
|
@ -60,44 +61,42 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
i2c_master_bus_config_t config = {
|
||||
.i2c_port = -1, // auto
|
||||
.sda_io_num = sda->number,
|
||||
.scl_io_num = scl->number,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.glitch_ignore_cnt = 7,
|
||||
.flags = {
|
||||
#if CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP
|
||||
.enable_internal_pullup = true, /*!< Internal GPIO pull mode for I2C sda signal*/
|
||||
#else
|
||||
.enable_internal_pullup = false, /*!< Internal GPIO pull mode for I2C sda signal*/
|
||||
#endif
|
||||
}
|
||||
};
|
||||
esp_err_t result = i2c_new_master_bus(&config, &self->handle);
|
||||
|
||||
if (result == ESP_ERR_NOT_FOUND) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use"));
|
||||
}
|
||||
CHECK_ESP_RESULT(result);
|
||||
|
||||
self->xSemaphore = xSemaphoreCreateMutex();
|
||||
if (self->xSemaphore == NULL) {
|
||||
i2c_del_master_bus(self->handle);
|
||||
self->handle = NULL;
|
||||
mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to create lock"));
|
||||
}
|
||||
self->sda_pin = sda;
|
||||
self->scl_pin = scl;
|
||||
self->i2c_num = peripherals_i2c_get_free_num();
|
||||
self->has_lock = 0;
|
||||
|
||||
if (self->i2c_num == I2C_NUM_MAX) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use"));
|
||||
}
|
||||
|
||||
const i2c_config_t i2c_conf = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = self->sda_pin->number,
|
||||
.scl_io_num = self->scl_pin->number,
|
||||
#if CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE, /*!< Internal GPIO pull mode for I2C sda signal*/
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE, /*!< Internal GPIO pull mode for I2C scl signal*/
|
||||
#else
|
||||
.sda_pullup_en = GPIO_PULLUP_DISABLE, /*!< Internal GPIO pull mode for I2C sda signal*/
|
||||
.scl_pullup_en = GPIO_PULLUP_DISABLE, /*!< Internal GPIO pull mode for I2C scl signal*/
|
||||
#endif
|
||||
|
||||
.master = {
|
||||
.clk_speed = frequency,
|
||||
}
|
||||
};
|
||||
|
||||
// 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_RuntimeError(MP_ERROR_TEXT("init I2C"));
|
||||
}
|
||||
self->has_lock = false;
|
||||
self->frequency = frequency;
|
||||
self->timeout_ms = timeout_us / 1000;
|
||||
// Round up timeout to nearest ms.
|
||||
if (timeout_us % 1000 != 0) {
|
||||
self->timeout_ms += 1;
|
||||
}
|
||||
|
||||
claim_pin(sda);
|
||||
|
|
@ -108,32 +107,27 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
|||
return self->sda_pin == NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda_pin = NULL;
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
peripherals_i2c_deinit(self->i2c_num);
|
||||
i2c_del_master_bus(self->handle);
|
||||
self->handle = NULL;
|
||||
|
||||
common_hal_reset_pin(self->sda_pin);
|
||||
common_hal_reset_pin(self->scl_pin);
|
||||
self->sda_pin = NULL;
|
||||
self->scl_pin = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t i2c_zero_length_write(busio_i2c_obj_t *self, uint8_t addr, TickType_t timeout) {
|
||||
// i2c_master_write_to_device() won't do zero-length writes, so we do it by hand.
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, addr << 1, true);
|
||||
i2c_master_stop(cmd);
|
||||
esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, timeout);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return result;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
esp_err_t result = i2c_zero_length_write(self, addr, pdMS_TO_TICKS(10));
|
||||
esp_err_t result = i2c_master_probe(self->handle, addr, 1);
|
||||
return result == ESP_OK;
|
||||
}
|
||||
|
||||
|
|
@ -170,28 +164,54 @@ static uint8_t convert_esp_err(esp_err_t result) {
|
|||
}
|
||||
}
|
||||
|
||||
static size_t _transaction_duration(size_t frequency, size_t len) {
|
||||
size_t khz = frequency / 1000;
|
||||
size_t bytes_per_ms = khz / 8;
|
||||
// + 1 for the address byte
|
||||
return (len + 1) / bytes_per_ms;
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) {
|
||||
return convert_esp_err(len == 0
|
||||
? i2c_zero_length_write(self, addr, pdMS_TO_TICKS(1000))
|
||||
: i2c_master_write_to_device(self->i2c_num, (uint8_t)addr, data, len, pdMS_TO_TICKS(1000))
|
||||
);
|
||||
i2c_device_config_t dev_config = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = addr,
|
||||
.scl_speed_hz = self->frequency
|
||||
};
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle));
|
||||
esp_err_t result = i2c_master_transmit(dev_handle, data, len, _transaction_duration(self->frequency, len) + self->timeout_ms);
|
||||
CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle));
|
||||
return convert_esp_err(result);
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) {
|
||||
return convert_esp_err(
|
||||
i2c_master_read_from_device(self->i2c_num, (uint8_t)addr, data, len, pdMS_TO_TICKS(1000)));
|
||||
i2c_device_config_t dev_config = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = addr,
|
||||
.scl_speed_hz = self->frequency
|
||||
};
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle));
|
||||
esp_err_t result = i2c_master_receive(dev_handle, data, len, _transaction_duration(self->frequency, len) + self->timeout_ms);
|
||||
CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle));
|
||||
return convert_esp_err(result);
|
||||
}
|
||||
|
||||
uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
|
||||
uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) {
|
||||
return convert_esp_err(
|
||||
i2c_master_write_read_device(self->i2c_num, (uint8_t)addr,
|
||||
out_data, out_len, in_data, in_len, pdMS_TO_TICKS(1000)));
|
||||
i2c_device_config_t dev_config = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = addr,
|
||||
.scl_speed_hz = self->frequency
|
||||
};
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle));
|
||||
esp_err_t result = i2c_master_transmit_receive(dev_handle, out_data, out_len, in_data, in_len, _transaction_duration(self->frequency, out_len) + _transaction_duration(self->frequency, in_len) + self->timeout_ms);
|
||||
CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle));
|
||||
return convert_esp_err(result);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset_i2c(self->i2c_num);
|
||||
|
||||
common_hal_never_reset_pin(self->scl_pin);
|
||||
common_hal_never_reset_pin(self->sda_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,15 @@
|
|||
#include "freertos/semphr.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "peripherals/i2c.h"
|
||||
#include "driver/i2c_master.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t *scl_pin;
|
||||
const mcu_pin_obj_t *sda_pin;
|
||||
i2c_port_t i2c_num;
|
||||
size_t timeout_ms;
|
||||
size_t frequency;
|
||||
i2c_master_bus_handle_t handle;
|
||||
SemaphoreHandle_t xSemaphore;
|
||||
bool has_lock;
|
||||
} busio_i2c_obj_t;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,19 @@
|
|||
#include "shared-bindings/util.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
// These two includes are needed to peek into the i2c handle to get the i2c port
|
||||
// number.
|
||||
#include "sdkconfig.h"
|
||||
// Define these two macros if not defined so that we don't get the -Wundef
|
||||
// warning from i2c_private.h
|
||||
#ifndef CONFIG_I2C_ISR_IRAM_SAFE
|
||||
#define CONFIG_I2C_ISR_IRAM_SAFE 0
|
||||
#endif
|
||||
#ifndef CONFIG_PM_ENABLE
|
||||
#define CONFIG_PM_ENABLE 0
|
||||
#endif
|
||||
#include "esp-idf/components/driver/i2c/i2c_private.h"
|
||||
|
||||
#include "esp-camera/driver/private_include/cam_hal.h"
|
||||
|
||||
#if !CONFIG_SPIRAM
|
||||
|
|
@ -106,7 +119,7 @@ void common_hal_espcamera_camera_construct(
|
|||
self->camera_config.fb_count = framebuffer_count;
|
||||
self->camera_config.grab_mode = grab_mode;
|
||||
|
||||
self->camera_config.sccb_i2c_port = i2c->i2c_num;
|
||||
self->camera_config.sccb_i2c_port = self->i2c->handle->base->port_num;
|
||||
|
||||
i2c_lock(self);
|
||||
esp_err_t result = esp_camera_init(&self->camera_config);
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2020 microDev
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#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_port_t)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;
|
||||
#ifdef SOC_I2C_SUPPORT_SLAVE
|
||||
if (i2c_conf->mode == I2C_MODE_SLAVE) {
|
||||
rx_buf_len = 256;
|
||||
tx_buf_len = 256;
|
||||
}
|
||||
#endif
|
||||
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 peripherals_i2c_get_free_num(void) {
|
||||
i2c_port_t i2c_num = I2C_NUM_MAX;
|
||||
for (i2c_port_t num = 0; num < (int)I2C_NUM_MAX; num++) {
|
||||
if (i2c_status[num] == STATUS_FREE) {
|
||||
i2c_num = num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i2c_num != I2C_NUM_MAX) {
|
||||
i2c_status[i2c_num] = STATUS_IN_USE;
|
||||
}
|
||||
return i2c_num;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||
//
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2020 microDev
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#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 peripherals_i2c_get_free_num(void);
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
#include "bindings/espulp/__init__.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/analogio/AnalogOut.h"
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "common-hal/busio/UART.h"
|
||||
#include "common-hal/dualbank/__init__.h"
|
||||
|
|
@ -343,7 +342,6 @@ void reset_port(void) {
|
|||
#endif
|
||||
|
||||
#if CIRCUITPY_BUSIO
|
||||
i2c_reset();
|
||||
spi_reset();
|
||||
uart_reset();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,16 +27,6 @@
|
|||
|
||||
// arrays use 0 based numbering: I2C1 is stored at index 0
|
||||
static bool reserved_i2c[MP_ARRAY_SIZE(mcu_i2c_banks)];
|
||||
static bool never_reset_i2c[MP_ARRAY_SIZE(mcu_i2c_banks)];
|
||||
|
||||
void i2c_reset(void) {
|
||||
for (uint i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
|
||||
if (!never_reset_i2c[i]) {
|
||||
reserved_i2c[i] = false;
|
||||
LPI2C_MasterDeinit(mcu_i2c_banks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void config_periph_pin(const mcu_periph_obj_t *periph) {
|
||||
IOMUXC_SetPinMux(
|
||||
|
|
@ -153,8 +143,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
|||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset_i2c[self->sda->bank_idx - 1] = true;
|
||||
|
||||
common_hal_never_reset_pin(self->sda->pin);
|
||||
common_hal_never_reset_pin(self->scl->pin);
|
||||
}
|
||||
|
|
@ -168,7 +156,6 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
return;
|
||||
}
|
||||
reserved_i2c[self->sda->bank_idx - 1] = false;
|
||||
never_reset_i2c[self->sda->bank_idx - 1] = false;
|
||||
|
||||
LPI2C_MasterDeinit(self->i2c);
|
||||
|
||||
|
|
@ -177,6 +164,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
|
||||
self->sda = NULL;
|
||||
self->scl = NULL;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda = NULL;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
|
|
@ -187,9 +179,6 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
|||
}
|
||||
|
||||
bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
|
||||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return false;
|
||||
}
|
||||
bool grabbed_lock = false;
|
||||
// CRITICAL_SECTION_ENTER()
|
||||
if (!self->has_lock) {
|
||||
|
|
|
|||
|
|
@ -19,5 +19,3 @@ typedef struct {
|
|||
const mcu_periph_obj_t *scl;
|
||||
const mcu_periph_obj_t *sda;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void i2c_reset(void);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
|
|
@ -427,7 +426,6 @@ safe_mode_t port_init(void) {
|
|||
|
||||
void reset_port(void) {
|
||||
#if CIRCUITPY_BUSIO
|
||||
i2c_reset();
|
||||
spi_reset();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
#define I2C_MAX_XFER_LEN MIN(((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1), 1024)
|
||||
#define I2C_TIMEOUT 1000 // 1 second timeout
|
||||
|
||||
static twim_peripheral_t twim_peripherals[] = {
|
||||
static
|
||||
twim_peripheral_t twim_peripherals[] = {
|
||||
#if NRFX_CHECK(NRFX_TWIM0_ENABLED)
|
||||
// SPIM0 and TWIM0 share an address.
|
||||
{ .twim = NRFX_TWIM_INSTANCE(0),
|
||||
|
|
@ -40,28 +41,10 @@ static twim_peripheral_t twim_peripherals[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static bool never_reset[MP_ARRAY_SIZE(twim_peripherals)];
|
||||
|
||||
void i2c_reset(void) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
|
||||
if (never_reset[i]) {
|
||||
continue;
|
||||
}
|
||||
nrfx_twim_uninit(&twim_peripherals[i].twim);
|
||||
twim_peripherals[i].in_use = false;
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
|
||||
if (self->twim_peripheral == &twim_peripherals[i]) {
|
||||
never_reset[i] = true;
|
||||
|
||||
never_reset_pin_number(self->scl_pin_number);
|
||||
never_reset_pin_number(self->sda_pin_number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
never_reset_pin_number(self->scl_pin_number);
|
||||
never_reset_pin_number(self->sda_pin_number);
|
||||
}
|
||||
|
||||
static uint8_t twi_error_to_mp(const nrfx_err_t err) {
|
||||
|
|
@ -176,6 +159,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
self->scl_pin_number = NO_PIN;
|
||||
|
||||
self->twim_peripheral->in_use = false;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda_pin_number = NO_PIN;
|
||||
}
|
||||
|
||||
// nrfx_twim_tx doesn't support 0-length data so we fall back to the hal API
|
||||
|
|
|
|||
|
|
@ -25,5 +25,3 @@ typedef struct {
|
|||
uint8_t scl_pin_number;
|
||||
uint8_t sda_pin_number;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void i2c_reset(void);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/alarm/time/TimeAlarm.h"
|
||||
#include "common-hal/analogio/AnalogIn.h"
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "common-hal/busio/UART.h"
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
|
|
@ -190,7 +189,6 @@ safe_mode_t port_init(void) {
|
|||
|
||||
void reset_port(void) {
|
||||
#if CIRCUITPY_BUSIO
|
||||
i2c_reset();
|
||||
spi_reset();
|
||||
uart_reset();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,19 +22,8 @@
|
|||
// One second
|
||||
#define BUS_TIMEOUT_US 1000000
|
||||
|
||||
static bool never_reset_i2c[2];
|
||||
static i2c_inst_t *i2c[2] = {i2c0, i2c1};
|
||||
|
||||
void reset_i2c(void) {
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
if (never_reset_i2c[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
i2c_deinit(i2c[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
self->peripheral = NULL;
|
||||
|
|
@ -115,7 +104,6 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
if (common_hal_busio_i2c_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
never_reset_i2c[i2c_hw_index(self->peripheral)] = false;
|
||||
|
||||
i2c_deinit(self->peripheral);
|
||||
|
||||
|
|
@ -123,6 +111,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
reset_pin_number(self->scl_pin);
|
||||
self->sda_pin = NO_PIN;
|
||||
self->scl_pin = NO_PIN;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda_pin = NO_PIN;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
|
|
@ -219,8 +212,6 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr,
|
|||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset_i2c[i2c_hw_index(self->peripheral)] = true;
|
||||
|
||||
never_reset_pin_number(self->scl_pin);
|
||||
never_reset_pin_number(self->sda_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,5 +22,3 @@ typedef struct {
|
|||
uint8_t scl_pin;
|
||||
uint8_t sda_pin;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void reset_i2c(void);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "bindings/rp2pio/StateMachine.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "shared-bindings/busio/I2C.h"
|
||||
#include "shared-bindings/busio/SPI.h"
|
||||
#include "shared-bindings/countio/Counter.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
|
@ -367,7 +366,6 @@ safe_mode_t port_init(void) {
|
|||
|
||||
void reset_port(void) {
|
||||
#if CIRCUITPY_BUSIO
|
||||
reset_i2c();
|
||||
reset_spi();
|
||||
reset_uart();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,17 +30,8 @@
|
|||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
static I2CSPM_Init_TypeDef i2cspm_init;
|
||||
static bool in_used = false;
|
||||
static bool never_reset = false;
|
||||
|
||||
// Reser I2C peripheral
|
||||
void i2c_reset(void) {
|
||||
if ((!never_reset) && in_used) {
|
||||
I2C_Reset(DEFAULT_I2C_PERIPHERAL);
|
||||
in_used = false;
|
||||
}
|
||||
}
|
||||
STATIC I2CSPM_Init_TypeDef i2cspm_init;
|
||||
STATIC bool in_used = false;
|
||||
|
||||
// Construct I2C protocol, this function init i2c peripheral
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
|
|
@ -80,7 +71,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
|||
|
||||
// Never reset I2C obj when reload
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
never_reset = true;
|
||||
common_hal_never_reset_pin(self->sda);
|
||||
common_hal_never_reset_pin(self->scl);
|
||||
}
|
||||
|
|
@ -102,6 +92,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
self->scl = NULL;
|
||||
self->i2cspm = NULL;
|
||||
in_used = false;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda = NULL;
|
||||
}
|
||||
|
||||
// Probe device in I2C bus
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H
|
||||
#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H
|
||||
#pragma once
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "peripherals/periph.h"
|
||||
|
|
@ -40,7 +39,3 @@ typedef struct {
|
|||
const mcu_pin_obj_t *scl;
|
||||
const mcu_pin_obj_t *sda;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void i2c_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#if CIRCUITPY_BUSIO
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "common-hal/busio/UART.h"
|
||||
#endif
|
||||
|
|
@ -160,7 +159,6 @@ void reset_port(void) {
|
|||
reset_all_pins();
|
||||
|
||||
#if CIRCUITPY_BUSIO
|
||||
i2c_reset();
|
||||
spi_reset();
|
||||
uart_reset();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,26 +40,13 @@
|
|||
// Arrays use 0 based numbering: I2C1 is stored at index 0
|
||||
#define MAX_I2C 4
|
||||
|
||||
static bool reserved_i2c[MAX_I2C];
|
||||
static bool never_reset_i2c[MAX_I2C];
|
||||
STATIC bool reserved_i2c[MAX_I2C];
|
||||
|
||||
#define ALL_CLOCKS 0xFF
|
||||
static void i2c_clock_enable(uint8_t mask);
|
||||
static void i2c_clock_disable(uint8_t mask);
|
||||
static void i2c_assign_irq(busio_i2c_obj_t *self, I2C_TypeDef *I2Cx);
|
||||
|
||||
void i2c_reset(void) {
|
||||
uint16_t never_reset_mask = 0x00;
|
||||
for (int i = 0; i < MAX_I2C; i++) {
|
||||
if (!never_reset_i2c[i]) {
|
||||
reserved_i2c[i] = false;
|
||||
} else {
|
||||
never_reset_mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
i2c_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
|
@ -163,15 +150,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
|||
}
|
||||
|
||||
void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) {
|
||||
if (self->handle.Instance == mcu_i2c_banks[i]) {
|
||||
never_reset_i2c[i] = true;
|
||||
|
||||
never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
|
||||
never_reset_pin_number(self->sda->pin->port, self->sda->pin->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
never_reset_pin_number(self->scl->pin->port, self->scl->pin->number);
|
||||
never_reset_pin_number(self->sda->pin->port, self->sda->pin->number);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
|
|
@ -185,12 +165,16 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
|
|||
|
||||
i2c_clock_disable(1 << (self->sda->periph_index - 1));
|
||||
reserved_i2c[self->sda->periph_index - 1] = false;
|
||||
never_reset_i2c[self->sda->periph_index - 1] = false;
|
||||
|
||||
reset_pin_number(self->sda->pin->port, self->sda->pin->number);
|
||||
reset_pin_number(self->scl->pin->port, self->scl->pin->number);
|
||||
self->sda = NULL;
|
||||
self->scl = NULL;
|
||||
common_hal_busio_i2c_mark_deinit(self);
|
||||
}
|
||||
|
||||
void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) {
|
||||
self->sda = NULL;
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
|
||||
|
|
|
|||
|
|
@ -22,5 +22,3 @@ typedef struct {
|
|||
const mcu_periph_obj_t *scl;
|
||||
const mcu_periph_obj_t *sda;
|
||||
} busio_i2c_obj_t;
|
||||
|
||||
void i2c_reset(void);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#if CIRCUITPY_BUSIO
|
||||
#include "common-hal/busio/I2C.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "common-hal/busio/UART.h"
|
||||
#endif
|
||||
|
|
@ -219,7 +218,6 @@ void reset_port(void) {
|
|||
#endif
|
||||
|
||||
#if CIRCUITPY_BUSIO
|
||||
i2c_reset();
|
||||
spi_reset();
|
||||
uart_reset();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ static mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
|
|||
const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl);
|
||||
const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda);
|
||||
|
||||
bitbangio_i2c_obj_t *self = mp_obj_malloc(bitbangio_i2c_obj_t, &bitbangio_i2c_type);
|
||||
bitbangio_i2c_obj_t *self = m_new_obj_with_finaliser(bitbangio_i2c_obj_t);
|
||||
self->base.type = &bitbangio_i2c_type;
|
||||
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
//| :param ~microcontroller.Pin scl: The clock pin
|
||||
//| :param ~microcontroller.Pin sda: The data pin
|
||||
//| :param int frequency: The clock frequency in Hertz
|
||||
//| :param int timeout: The maximum clock stretching timeut - (used only for
|
||||
//| :param int timeout: The maximum clock stretching timeout - (used only for
|
||||
//| :class:`bitbangio.I2C`; ignored for :class:`busio.I2C`)
|
||||
//| """
|
||||
//| ...
|
||||
|
|
@ -62,6 +62,8 @@ static mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||
const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl);
|
||||
const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda);
|
||||
|
||||
busio_i2c_obj_t *self = m_new_obj_with_finaliser(busio_i2c_obj_t);
|
||||
self->base.type = &busio_i2c_type;
|
||||
common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
|
||||
return (mp_obj_t)self;
|
||||
#else
|
||||
|
|
@ -96,12 +98,12 @@ static void check_for_deinit(busio_i2c_obj_t *self) {
|
|||
//| """Automatically deinitializes the hardware on context exit. See
|
||||
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||
//| ...
|
||||
static mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
common_hal_busio_i2c_deinit(MP_OBJ_TO_PTR(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i2c_obj___exit__);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i2c_obj___exit__);
|
||||
|
||||
static void check_lock(busio_i2c_obj_t *self) {
|
||||
asm ("");
|
||||
|
|
|
|||
|
|
@ -19,11 +19,15 @@ extern 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);
|
||||
uint32_t timeout_ms);
|
||||
|
||||
extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self);
|
||||
extern bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self);
|
||||
|
||||
// Mark as deinit without deiniting. This is used by displayio after copying the
|
||||
// object elsewhere and prevents the heap from deiniting the object.
|
||||
extern void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self);
|
||||
|
||||
extern bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self);
|
||||
extern bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self);
|
||||
extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
#include "shared-bindings/busio/I2C.h"
|
||||
#include "shared-bindings/displayio/Bitmap.h"
|
||||
#include "shared-bindings/displayio/Group.h"
|
||||
#include "shared-bindings/displayio/Palette.h"
|
||||
|
|
@ -236,6 +237,8 @@ void reset_displays(void) {
|
|||
display_buses[j].i2cdisplay_bus.bus = &i2c->inline_bus;
|
||||
}
|
||||
}
|
||||
// Mark the old i2c object so it is considered deinit.
|
||||
common_hal_busio_i2c_mark_deinit(original_i2c);
|
||||
}
|
||||
#endif
|
||||
#if CIRCUITPY_RGBMATRIX
|
||||
|
|
|
|||
Loading…
Reference in a new issue