Skip to content

Commit b145e65

Browse files
committed
API Optimizations
- Support Wire::end() for Slave - Prevent Master operations when in Slave mode
1 parent 951c320 commit b145e65

File tree

4 files changed

+206
-155
lines changed

4 files changed

+206
-155
lines changed

cores/esp32/esp32-hal-i2c-slave.c

+76-57
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ static inline bool i2c_ll_slave_rw(i2c_dev_t *hw)//not exposed by hal_ll
181181
}
182182

183183
//-------------------------------------- PRIVATE (Function Prototypes) ------------------------------------------------
184+
static void i2c_slave_free_resources(i2c_slave_struct_t * i2c);
184185
static void i2c_slave_delay_us(uint64_t us);
185186
static void i2c_slave_gpio_mode(int8_t pin, gpio_mode_t mode);
186187
static bool i2c_slave_check_line_state(int8_t sda, int8_t scl);
@@ -199,7 +200,7 @@ static void i2c_slave_task(void *pv_args);
199200
//-------------------------------------- Public Functions -------------------------------------------------------------
200201
//=====================================================================================================================
201202

202-
esp_err_t i2c_slave_attach_callbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void * arg){
203+
esp_err_t i2cSlaveAttachCallbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void * arg){
203204
if(num >= SOC_I2C_NUM){
204205
log_e("Invalid port num: %u", num);
205206
return ESP_ERR_INVALID_ARG;
@@ -213,57 +214,7 @@ esp_err_t i2c_slave_attach_callbacks(uint8_t num, i2c_slave_request_cb_t request
213214
return ESP_OK;
214215
}
215216

216-
esp_err_t i2c_slave_deinit(uint8_t num){
217-
if(num >= SOC_I2C_NUM){
218-
log_e("Invalid port num: %u", num);
219-
return ESP_ERR_INVALID_ARG;
220-
}
221-
222-
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
223-
I2C_SLAVE_MUTEX_LOCK();
224-
i2c_slave_detach_gpio(i2c);
225-
i2c_ll_set_slave_addr(i2c->dev, 0, false);
226-
i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
227-
i2c_ll_clr_intsts_mask(i2c->dev, I2C_LL_INTR_MASK);
228-
229-
if (i2c->intr_handle) {
230-
esp_intr_free(i2c->intr_handle);
231-
i2c->intr_handle = NULL;
232-
}
233-
234-
if(i2c->task_handle){
235-
vTaskDelete(i2c->task_handle);
236-
i2c->task_handle = NULL;
237-
}
238-
239-
#if I2C_SLAVE_USE_RX_QUEUE
240-
if (i2c->rx_queue) {
241-
vQueueDelete(i2c->rx_queue);
242-
i2c->rx_queue = NULL;
243-
}
244-
#else
245-
if (i2c->rx_ring_buf) {
246-
vRingbufferDelete(i2c->rx_ring_buf);
247-
i2c->rx_ring_buf = NULL;
248-
}
249-
#endif
250-
251-
if (i2c->tx_queue) {
252-
vQueueDelete(i2c->tx_queue);
253-
i2c->tx_queue = NULL;
254-
}
255-
256-
if (i2c->event_queue) {
257-
vQueueDelete(i2c->event_queue);
258-
i2c->event_queue = NULL;
259-
}
260-
261-
i2c->rx_data_count = 0;
262-
I2C_SLAVE_MUTEX_UNLOCK();
263-
return ESP_OK;
264-
}
265-
266-
esp_err_t i2c_slave_init(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency, size_t rx_len, size_t tx_len) {
217+
esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency, size_t rx_len, size_t tx_len) {
267218
if(num >= SOC_I2C_NUM){
268219
log_e("Invalid port num: %u", num);
269220
return ESP_ERR_INVALID_ARG;
@@ -274,6 +225,12 @@ esp_err_t i2c_slave_init(uint8_t num, int sda, int scl, uint16_t slaveID, uint32
274225
return ESP_ERR_INVALID_ARG;
275226
}
276227

228+
if(!frequency){
229+
frequency = 100000;
230+
} else if(frequency > 1000000){
231+
frequency = 1000000;
232+
}
233+
277234
log_i("Initialising I2C Slave: sda=%d scl=%d freq=%d, addr=0x%x", sda, scl, frequency, slaveID);
278235

279236
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
@@ -288,9 +245,9 @@ esp_err_t i2c_slave_init(uint8_t num, int sda, int scl, uint16_t slaveID, uint32
288245
}
289246
}
290247
#endif
291-
i2c_slave_deinit(num);
292248

293249
I2C_SLAVE_MUTEX_LOCK();
250+
i2c_slave_free_resources(i2c);
294251

295252
#if I2C_SLAVE_USE_RX_QUEUE
296253
i2c->rx_queue = xQueueCreate(rx_len, sizeof(uint8_t));
@@ -391,18 +348,39 @@ esp_err_t i2c_slave_init(uint8_t num, int sda, int scl, uint16_t slaveID, uint32
391348
return ret;
392349

393350
fail:
351+
i2c_slave_free_resources(i2c);
394352
I2C_SLAVE_MUTEX_UNLOCK();
395-
i2c_slave_deinit(num);
396353
return ret;
397354
}
398355

399-
size_t i2c_slave_write(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t timeout_ms) {
356+
esp_err_t i2cSlaveDeinit(uint8_t num){
357+
if(num >= SOC_I2C_NUM){
358+
log_e("Invalid port num: %u", num);
359+
return ESP_ERR_INVALID_ARG;
360+
}
361+
362+
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
363+
if(!i2c->lock){
364+
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
365+
return ESP_ERR_NO_MEM;
366+
}
367+
I2C_SLAVE_MUTEX_LOCK();
368+
i2c_slave_free_resources(i2c);
369+
I2C_SLAVE_MUTEX_UNLOCK();
370+
return ESP_OK;
371+
}
372+
373+
size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t timeout_ms) {
400374
if(num >= SOC_I2C_NUM){
401375
log_e("Invalid port num: %u", num);
402376
return 0;
403377
}
404378
size_t to_queue = 0, to_fifo = 0;
405379
i2c_slave_struct_t * i2c = &_i2c_bus_array[num];
380+
if(!i2c->lock){
381+
log_e("Lock is not initialized! Did you call i2c_slave_init()?");
382+
return ESP_ERR_NO_MEM;
383+
}
406384
if(!i2c->tx_queue){
407385
return 0;
408386
}
@@ -460,6 +438,47 @@ size_t i2c_slave_write(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t t
460438
//-------------------------------------- Private Functions ------------------------------------------------------------
461439
//=====================================================================================================================
462440

441+
static void i2c_slave_free_resources(i2c_slave_struct_t * i2c){
442+
i2c_slave_detach_gpio(i2c);
443+
i2c_ll_set_slave_addr(i2c->dev, 0, false);
444+
i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK);
445+
i2c_ll_clr_intsts_mask(i2c->dev, I2C_LL_INTR_MASK);
446+
447+
if (i2c->intr_handle) {
448+
esp_intr_free(i2c->intr_handle);
449+
i2c->intr_handle = NULL;
450+
}
451+
452+
if(i2c->task_handle){
453+
vTaskDelete(i2c->task_handle);
454+
i2c->task_handle = NULL;
455+
}
456+
457+
#if I2C_SLAVE_USE_RX_QUEUE
458+
if (i2c->rx_queue) {
459+
vQueueDelete(i2c->rx_queue);
460+
i2c->rx_queue = NULL;
461+
}
462+
#else
463+
if (i2c->rx_ring_buf) {
464+
vRingbufferDelete(i2c->rx_ring_buf);
465+
i2c->rx_ring_buf = NULL;
466+
}
467+
#endif
468+
469+
if (i2c->tx_queue) {
470+
vQueueDelete(i2c->tx_queue);
471+
i2c->tx_queue = NULL;
472+
}
473+
474+
if (i2c->event_queue) {
475+
vQueueDelete(i2c->event_queue);
476+
i2c->event_queue = NULL;
477+
}
478+
479+
i2c->rx_data_count = 0;
480+
}
481+
463482
static bool i2c_slave_set_frequency(i2c_slave_struct_t * i2c, uint32_t clk_speed)
464483
{
465484
if (i2c == NULL) {
@@ -610,7 +629,7 @@ static bool i2c_slave_send_event(i2c_slave_struct_t * i2c, i2c_slave_queue_event
610629
bool pxHigherPriorityTaskWoken = false;
611630
if(i2c->event_queue) {
612631
if(xQueueSendFromISR(i2c->event_queue, event, (BaseType_t * const)&pxHigherPriorityTaskWoken) != pdTRUE){
613-
log_e("event_queue_full");
632+
//log_e("event_queue_full");
614633
}
615634
}
616635
return pxHigherPriorityTaskWoken;
@@ -684,7 +703,7 @@ static void i2c_slave_isr_handler(void* arg)
684703
if(rx_fifo_len){ //READ RX FIFO
685704
pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full(i2c, rx_fifo_len);
686705
}
687-
if(!slave_rw || i2c->rx_data_count){ //WRITE or RepeatedStart
706+
if(i2c->rx_data_count){ //WRITE or RepeatedStart
688707
//SEND RX Event
689708
i2c_slave_queue_event_t event;
690709
event.event = I2C_SLAVE_EVT_RX;

cores/esp32/esp32-hal-i2c-slave.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ extern "C" {
2424

2525
typedef void (*i2c_slave_request_cb_t) (uint8_t num, void * arg);
2626
typedef void (*i2c_slave_receive_cb_t) (uint8_t num, uint8_t * data, size_t len, bool stop, void * arg);
27-
esp_err_t i2c_slave_attach_callbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void * arg);
27+
esp_err_t i2cSlaveAttachCallbacks(uint8_t num, i2c_slave_request_cb_t request_callback, i2c_slave_receive_cb_t receive_callback, void * arg);
2828

29-
esp_err_t i2c_slave_init(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency, size_t rx_len, size_t tx_len);
30-
esp_err_t i2c_slave_deinit(uint8_t num);
31-
size_t i2c_slave_write(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t timeout_ms);
29+
esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t frequency, size_t rx_len, size_t tx_len);
30+
esp_err_t i2cSlaveDeinit(uint8_t num);
31+
size_t i2cSlaveWrite(uint8_t num, const uint8_t *buf, uint32_t len, uint32_t timeout_ms);
3232

3333
#ifdef __cplusplus
3434
}

0 commit comments

Comments
 (0)