Skip to content

Commit

Permalink
I2C - Peripheral manager implementation (#8220)
Browse files Browse the repository at this point in the history
* i2c-master periman initial commit

* i2c-master make detachbus static + comment remove

* i2c-slave periman implementation

* SetPinBus to INIT on i2cDeinits

* Fix slave pins deinit

* remove dbg logs

* set ret to ESP_FAIL instead of returning
  • Loading branch information
P-R-O-C-H-Y committed May 31, 2023
1 parent 66c88fa commit 3d5b570
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
30 changes: 29 additions & 1 deletion cores/esp32/esp32-hal-i2c-slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "hal/clk_gate_ll.h"
#include "esp32-hal-log.h"
#include "esp32-hal-i2c-slave.h"
#include "esp32-hal-periman.h"

#define I2C_SLAVE_USE_RX_QUEUE 0 // 1: Queue, 0: RingBuffer

Expand Down Expand Up @@ -194,7 +195,7 @@ static bool i2c_slave_handle_rx_fifo_full(i2c_slave_struct_t * i2c, uint32_t len
static size_t i2c_slave_read_rx(i2c_slave_struct_t * i2c, uint8_t * data, size_t len);
static void i2c_slave_isr_handler(void* arg);
static void i2c_slave_task(void *pv_args);

static bool i2cSlaveDetachBus(void * bus_i2c_num);

//=====================================================================================================================
//-------------------------------------- Public Functions -------------------------------------------------------------
Expand Down Expand Up @@ -231,6 +232,11 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
frequency = 1000000;
}

perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_SLAVE, i2cSlaveDetachBus);
if(!perimanSetPinBus(sda, ESP32_BUS_TYPE_INIT, NULL) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_INIT, NULL)){
return false;
}

log_i("Initialising I2C Slave: sda=%d scl=%d freq=%d, addr=0x%x", sda, scl, frequency, slaveID);

i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
Expand Down Expand Up @@ -344,6 +350,10 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
i2c_ll_slave_enable_rx_it(i2c->dev);
i2c_ll_set_stretch(i2c->dev, 0x3FF);
i2c_ll_update(i2c->dev);
if(!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_SLAVE, (void *)(i2c->num+1)) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_SLAVE, (void *)(i2c->num+1))){
i2cSlaveDetachBus((void *)(i2c->num+1));
ret = ESP_FAIL;
}
I2C_SLAVE_MUTEX_UNLOCK();
return ret;

Expand All @@ -367,7 +377,11 @@ esp_err_t i2cSlaveDeinit(uint8_t num){
}
#endif
I2C_SLAVE_MUTEX_LOCK();
int scl = i2c->scl;
int sda = i2c->sda;
i2c_slave_free_resources(i2c);
perimanSetPinBus(scl, ESP32_BUS_TYPE_INIT, NULL);
perimanSetPinBus(sda, ESP32_BUS_TYPE_INIT, NULL);
I2C_SLAVE_MUTEX_UNLOCK();
return ESP_OK;
}
Expand Down Expand Up @@ -846,3 +860,17 @@ static void i2c_slave_task(void *pv_args)
}
vTaskDelete(NULL);
}

static bool i2cSlaveDetachBus(void * bus_i2c_num){
uint8_t num = (int)bus_i2c_num - 1;
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
if (i2c->scl == -1 && i2c->sda == -1) {
return true;
}
esp_err_t err = i2cSlaveDeinit(num);
if(err != ESP_OK){
log_e("i2cSlaveDeinit failed with error: %d", err);
return false;
}
return true;
}
32 changes: 32 additions & 0 deletions cores/esp32/esp32-hal-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,33 @@
#include "hal/i2c_hal.h"
#include "hal/i2c_ll.h"
#include "driver/i2c.h"
#include "esp32-hal-periman.h"

typedef volatile struct {
bool initialized;
uint32_t frequency;
#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t lock;
int8_t scl;
int8_t sda;
#endif
} i2c_bus_t;

static i2c_bus_t bus[SOC_I2C_NUM];

static bool i2cDetachBus(void * bus_i2c_num){
uint8_t i2c_num = (int)bus_i2c_num - 1;
if(!bus[i2c_num].initialized){
return true;
}
esp_err_t err = i2cDeinit(i2c_num);
if(err != ESP_OK){
log_e("i2cDeinit failed with error: %d", err);
return false;
}
return true;
}

bool i2cIsInit(uint8_t i2c_num){
if(i2c_num >= SOC_I2C_NUM){
return false;
Expand Down Expand Up @@ -72,6 +88,12 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency){
} else if(frequency > 1000000UL){
frequency = 1000000UL;
}

perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER, i2cDetachBus);
if(!perimanSetPinBus(sda, ESP32_BUS_TYPE_INIT, NULL) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_INIT, NULL)){
return false;
}

log_i("Initialising I2C Master: sda=%d scl=%d freq=%d", sda, scl, frequency);

i2c_config_t conf = { };
Expand All @@ -93,8 +115,14 @@ esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency){
} else {
bus[i2c_num].initialized = true;
bus[i2c_num].frequency = frequency;
bus[i2c_num].scl = scl;
bus[i2c_num].sda = sda;
//Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2
i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
if(!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER, (void *)(i2c_num+1)) || !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER, (void *)(i2c_num+1))){
i2cDetachBus((void *)(i2c_num+1));
return false;
}
}
}
#if !CONFIG_DISABLE_HAL_LOCKS
Expand Down Expand Up @@ -122,6 +150,10 @@ esp_err_t i2cDeinit(uint8_t i2c_num){
err = i2c_driver_delete((i2c_port_t)i2c_num);
if(err == ESP_OK){
bus[i2c_num].initialized = false;
perimanSetPinBus(bus[i2c_num].scl, ESP32_BUS_TYPE_INIT, NULL);
perimanSetPinBus(bus[i2c_num].sda, ESP32_BUS_TYPE_INIT, NULL);
bus[i2c_num].scl = -1;
bus[i2c_num].sda = -1;
}
}
#if !CONFIG_DISABLE_HAL_LOCKS
Expand Down

0 comments on commit 3d5b570

Please sign in to comment.