@@ -361,358 +361,356 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
361
361
362
362
if (!i2c -> intr_handle ) {
363
363
uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED ;
364
- #if !defined(CONFIG_IDF_TARGET_ESP32P4 )
365
364
if (i2c -> num == 0 ) {
365
+ #if !defined(CONFIG_IDF_TARGET_ESP32P4 )
366
366
ret = esp_intr_alloc (ETS_I2C_EXT0_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
367
+ #else
368
+ ret = esp_intr_alloc (ETS_I2C0_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
369
+ #endif
367
370
#if SOC_HP_I2C_NUM > 1
368
371
} else {
372
+ #if !defined(CONFIG_IDF_TARGET_ESP32P4 )
369
373
ret = esp_intr_alloc (ETS_I2C_EXT1_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
374
+ #else
375
+ ret = esp_intr_alloc (ETS_I2C1_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
370
376
#endif
371
- #endif // !defined(CONFIG_IDF_TARGET_ESP32P4)
372
- #ifdef CONFIG_IDF_TARGET_ESP32P4
373
- if (i2c -> num == 0 ) {
374
- ret = esp_intr_alloc (ETS_I2C0_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
375
- #if SOC_I2C_NUM > 1
376
- } else {
377
- ret = esp_intr_alloc (ETS_I2C1_INTR_SOURCE , flags , & i2c_slave_isr_handler , i2c , & i2c -> intr_handle );
378
377
#endif
379
- #endif // #ifdef CONFIG_IDF_TARGET_ESP32P4
380
- }
381
-
382
- if (ret != ESP_OK ) {
383
- log_e ("install interrupt handler Failed=%d" , ret );
384
- goto fail ;
385
- }
386
378
}
387
379
388
- i2c_ll_txfifo_rst (i2c -> dev );
389
- i2c_ll_rxfifo_rst (i2c -> dev );
390
- i2c_ll_slave_enable_rx_it (i2c -> dev );
391
- i2c_ll_set_stretch (i2c -> dev , 0x3FF );
392
- i2c_ll_update (i2c -> dev );
393
- if (!perimanSetPinBus (sda , ESP32_BUS_TYPE_I2C_SLAVE_SDA , (void * )(i2c -> num + 1 ), i2c -> num , -1 )
394
- || !perimanSetPinBus (scl , ESP32_BUS_TYPE_I2C_SLAVE_SCL , (void * )(i2c -> num + 1 ), i2c -> num , -1 )) {
395
- i2cSlaveDetachBus ((void * )(i2c -> num + 1 ));
396
- ret = ESP_FAIL ;
380
+ if (ret != ESP_OK ) {
381
+ log_e ("install interrupt handler Failed=%d" , ret );
382
+ goto fail ;
397
383
}
398
- I2C_SLAVE_MUTEX_UNLOCK ();
399
- return ret ;
384
+ }
400
385
401
- fail :
402
- i2c_slave_free_resources (i2c );
403
- I2C_SLAVE_MUTEX_UNLOCK ();
404
- return ret ;
386
+ i2c_ll_txfifo_rst (i2c -> dev );
387
+ i2c_ll_rxfifo_rst (i2c -> dev );
388
+ i2c_ll_slave_enable_rx_it (i2c -> dev );
389
+ i2c_ll_set_stretch (i2c -> dev , 0x3FF );
390
+ i2c_ll_update (i2c -> dev );
391
+ if (!perimanSetPinBus (sda , ESP32_BUS_TYPE_I2C_SLAVE_SDA , (void * )(i2c -> num + 1 ), i2c -> num , -1 )
392
+ || !perimanSetPinBus (scl , ESP32_BUS_TYPE_I2C_SLAVE_SCL , (void * )(i2c -> num + 1 ), i2c -> num , -1 )) {
393
+ i2cSlaveDetachBus ((void * )(i2c -> num + 1 ));
394
+ ret = ESP_FAIL ;
405
395
}
396
+ I2C_SLAVE_MUTEX_UNLOCK ();
397
+ return ret ;
406
398
407
- esp_err_t i2cSlaveDeinit (uint8_t num ) {
408
- if (num >= SOC_HP_I2C_NUM ) {
409
- log_e ("Invalid port num: %u" , num );
410
- return ESP_ERR_INVALID_ARG ;
411
- }
399
+ fail :
400
+ i2c_slave_free_resources (i2c );
401
+ I2C_SLAVE_MUTEX_UNLOCK ();
402
+ return ret ;
403
+ }
404
+
405
+ esp_err_t i2cSlaveDeinit (uint8_t num ) {
406
+ if (num >= SOC_HP_I2C_NUM ) {
407
+ log_e ("Invalid port num: %u" , num );
408
+ return ESP_ERR_INVALID_ARG ;
409
+ }
412
410
413
- i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
411
+ i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
414
412
#if !CONFIG_DISABLE_HAL_LOCKS
415
- if (!i2c -> lock ) {
416
- log_e ("Lock is not initialized! Did you call i2c_slave_init()?" );
417
- return ESP_ERR_NO_MEM ;
418
- }
413
+ if (!i2c -> lock ) {
414
+ log_e ("Lock is not initialized! Did you call i2c_slave_init()?" );
415
+ return ESP_ERR_NO_MEM ;
416
+ }
419
417
#endif
420
- I2C_SLAVE_MUTEX_LOCK ();
421
- int scl = i2c -> scl ;
422
- int sda = i2c -> sda ;
423
- i2c_slave_free_resources (i2c );
424
- perimanClearPinBus (scl );
425
- perimanClearPinBus (sda );
426
- I2C_SLAVE_MUTEX_UNLOCK ();
427
- return ESP_OK ;
428
- }
429
-
430
- size_t i2cSlaveWrite (uint8_t num , const uint8_t * buf , uint32_t len , uint32_t timeout_ms ) {
431
- if (num >= SOC_HP_I2C_NUM ) {
432
- log_e ("Invalid port num: %u" , num );
433
- return 0 ;
434
- }
435
- uint32_t to_queue = 0 , to_fifo = 0 ;
436
- i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
418
+ I2C_SLAVE_MUTEX_LOCK ();
419
+ int scl = i2c -> scl ;
420
+ int sda = i2c -> sda ;
421
+ i2c_slave_free_resources (i2c );
422
+ perimanClearPinBus (scl );
423
+ perimanClearPinBus (sda );
424
+ I2C_SLAVE_MUTEX_UNLOCK ();
425
+ return ESP_OK ;
426
+ }
427
+
428
+ size_t i2cSlaveWrite (uint8_t num , const uint8_t * buf , uint32_t len , uint32_t timeout_ms ) {
429
+ if (num >= SOC_HP_I2C_NUM ) {
430
+ log_e ("Invalid port num: %u" , num );
431
+ return 0 ;
432
+ }
433
+ uint32_t to_queue = 0 , to_fifo = 0 ;
434
+ i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
437
435
#if !CONFIG_DISABLE_HAL_LOCKS
438
- if (!i2c -> lock ) {
439
- log_e ("Lock is not initialized! Did you call i2c_slave_init()?" );
440
- return ESP_ERR_NO_MEM ;
441
- }
436
+ if (!i2c -> lock ) {
437
+ log_e ("Lock is not initialized! Did you call i2c_slave_init()?" );
438
+ return ESP_ERR_NO_MEM ;
439
+ }
442
440
#endif
443
- if (!i2c -> tx_queue ) {
444
- return 0 ;
445
- }
446
- I2C_SLAVE_MUTEX_LOCK ();
441
+ if (!i2c -> tx_queue ) {
442
+ return 0 ;
443
+ }
444
+ I2C_SLAVE_MUTEX_LOCK ();
447
445
#if CONFIG_IDF_TARGET_ESP32
448
- i2c_ll_slave_disable_tx_it (i2c -> dev );
449
- uint32_t txfifo_len = 0 ;
450
- i2c_ll_get_txfifo_len (i2c -> dev , & txfifo_len );
451
- if (txfifo_len < SOC_I2C_FIFO_LEN ) {
452
- i2c_ll_txfifo_rst (i2c -> dev );
453
- }
446
+ i2c_ll_slave_disable_tx_it (i2c -> dev );
447
+ uint32_t txfifo_len = 0 ;
448
+ i2c_ll_get_txfifo_len (i2c -> dev , & txfifo_len );
449
+ if (txfifo_len < SOC_I2C_FIFO_LEN ) {
450
+ i2c_ll_txfifo_rst (i2c -> dev );
451
+ }
454
452
#endif
455
- i2c_ll_get_txfifo_len (i2c -> dev , & to_fifo );
456
- if (to_fifo ) {
457
- if (len < to_fifo ) {
458
- to_fifo = len ;
453
+ i2c_ll_get_txfifo_len (i2c -> dev , & to_fifo );
454
+ if (to_fifo ) {
455
+ if (len < to_fifo ) {
456
+ to_fifo = len ;
457
+ }
458
+ i2c_ll_write_txfifo (i2c -> dev , (uint8_t * )buf , to_fifo );
459
+ buf += to_fifo ;
460
+ len -= to_fifo ;
461
+ //reset tx_queue
462
+ xQueueReset (i2c -> tx_queue );
463
+ //write the rest of the bytes to the queue
464
+ if (len ) {
465
+ to_queue = uxQueueSpacesAvailable (i2c -> tx_queue );
466
+ if (len < to_queue ) {
467
+ to_queue = len ;
459
468
}
460
- i2c_ll_write_txfifo (i2c -> dev , (uint8_t * )buf , to_fifo );
461
- buf += to_fifo ;
462
- len -= to_fifo ;
463
- //reset tx_queue
464
- xQueueReset (i2c -> tx_queue );
465
- //write the rest of the bytes to the queue
466
- if (len ) {
467
- to_queue = uxQueueSpacesAvailable (i2c -> tx_queue );
468
- if (len < to_queue ) {
469
- to_queue = len ;
470
- }
471
- for (size_t i = 0 ; i < to_queue ; i ++ ) {
472
- if (xQueueSend (i2c -> tx_queue , & buf [i ], timeout_ms / portTICK_PERIOD_MS ) != pdTRUE ) {
473
- xQueueReset (i2c -> tx_queue );
474
- to_queue = 0 ;
475
- break ;
476
- }
477
- }
478
- //no need to enable TX_EMPTY if tx_queue is empty
479
- if (to_queue ) {
480
- i2c_ll_slave_enable_tx_it (i2c -> dev );
469
+ for (size_t i = 0 ; i < to_queue ; i ++ ) {
470
+ if (xQueueSend (i2c -> tx_queue , & buf [i ], timeout_ms / portTICK_PERIOD_MS ) != pdTRUE ) {
471
+ xQueueReset (i2c -> tx_queue );
472
+ to_queue = 0 ;
473
+ break ;
481
474
}
482
475
}
476
+ //no need to enable TX_EMPTY if tx_queue is empty
477
+ if (to_queue ) {
478
+ i2c_ll_slave_enable_tx_it (i2c -> dev );
479
+ }
483
480
}
484
- I2C_SLAVE_MUTEX_UNLOCK ();
485
- return to_queue + to_fifo ;
486
481
}
482
+ I2C_SLAVE_MUTEX_UNLOCK ();
483
+ return to_queue + to_fifo ;
484
+ }
487
485
488
- //=====================================================================================================================
489
- //-------------------------------------- Private Functions ------------------------------------------------------------
490
- //=====================================================================================================================
486
+ //=====================================================================================================================
487
+ //-------------------------------------- Private Functions ------------------------------------------------------------
488
+ //=====================================================================================================================
491
489
492
- static void i2c_slave_free_resources (i2c_slave_struct_t * i2c ) {
493
- i2c_slave_detach_gpio (i2c );
494
- i2c_ll_set_slave_addr (i2c -> dev , 0 , false);
495
- i2c_ll_disable_intr_mask (i2c -> dev , I2C_LL_INTR_MASK );
496
- i2c_ll_clear_intr_mask (i2c -> dev , I2C_LL_INTR_MASK );
490
+ static void i2c_slave_free_resources (i2c_slave_struct_t * i2c ) {
491
+ i2c_slave_detach_gpio (i2c );
492
+ i2c_ll_set_slave_addr (i2c -> dev , 0 , false);
493
+ i2c_ll_disable_intr_mask (i2c -> dev , I2C_LL_INTR_MASK );
494
+ i2c_ll_clear_intr_mask (i2c -> dev , I2C_LL_INTR_MASK );
497
495
498
- if (i2c -> intr_handle ) {
499
- esp_intr_free (i2c -> intr_handle );
500
- i2c -> intr_handle = NULL ;
501
- }
496
+ if (i2c -> intr_handle ) {
497
+ esp_intr_free (i2c -> intr_handle );
498
+ i2c -> intr_handle = NULL ;
499
+ }
502
500
503
- if (i2c -> task_handle ) {
504
- vTaskDelete (i2c -> task_handle );
505
- i2c -> task_handle = NULL ;
506
- }
501
+ if (i2c -> task_handle ) {
502
+ vTaskDelete (i2c -> task_handle );
503
+ i2c -> task_handle = NULL ;
504
+ }
507
505
508
506
#if I2C_SLAVE_USE_RX_QUEUE
509
- if (i2c -> rx_queue ) {
510
- vQueueDelete (i2c -> rx_queue );
511
- i2c -> rx_queue = NULL ;
512
- }
507
+ if (i2c -> rx_queue ) {
508
+ vQueueDelete (i2c -> rx_queue );
509
+ i2c -> rx_queue = NULL ;
510
+ }
513
511
#else
514
512
if (i2c -> rx_ring_buf ) {
515
513
vRingbufferDelete (i2c -> rx_ring_buf );
516
514
i2c -> rx_ring_buf = NULL ;
517
515
}
518
516
#endif
519
517
520
- if (i2c -> tx_queue ) {
521
- vQueueDelete (i2c -> tx_queue );
522
- i2c -> tx_queue = NULL ;
523
- }
524
-
525
- if (i2c -> event_queue ) {
526
- vQueueDelete (i2c -> event_queue );
527
- i2c -> event_queue = NULL ;
528
- }
518
+ if (i2c -> tx_queue ) {
519
+ vQueueDelete (i2c -> tx_queue );
520
+ i2c -> tx_queue = NULL ;
521
+ }
529
522
530
- i2c -> rx_data_count = 0 ;
523
+ if (i2c -> event_queue ) {
524
+ vQueueDelete (i2c -> event_queue );
525
+ i2c -> event_queue = NULL ;
531
526
}
532
527
533
- static bool i2c_slave_set_frequency (i2c_slave_struct_t * i2c , uint32_t clk_speed ) {
534
- if (i2c == NULL ) {
535
- log_e ("no control buffer" );
536
- return false;
537
- }
538
- if (clk_speed > 1100000UL ) {
539
- clk_speed = 1100000UL ;
540
- }
528
+ i2c -> rx_data_count = 0 ;
529
+ }
530
+
531
+ static bool i2c_slave_set_frequency (i2c_slave_struct_t * i2c , uint32_t clk_speed ) {
532
+ if (i2c == NULL ) {
533
+ log_e ("no control buffer" );
534
+ return false;
535
+ }
536
+ if (clk_speed > 1100000UL ) {
537
+ clk_speed = 1100000UL ;
538
+ }
541
539
542
- // Adjust Fifo thresholds based on frequency
543
- uint32_t a = (clk_speed / 50000L ) + 2 ;
544
- log_d ("Fifo thresholds: rx_fifo_full = %d, tx_fifo_empty = %d" , SOC_I2C_FIFO_LEN - a , a );
540
+ // Adjust Fifo thresholds based on frequency
541
+ uint32_t a = (clk_speed / 50000L ) + 2 ;
542
+ log_d ("Fifo thresholds: rx_fifo_full = %d, tx_fifo_empty = %d" , SOC_I2C_FIFO_LEN - a , a );
545
543
546
- i2c_hal_clk_config_t clk_cal ;
544
+ i2c_hal_clk_config_t clk_cal ;
547
545
#if SOC_I2C_SUPPORT_APB
548
- i2c_ll_master_cal_bus_clk (APB_CLK_FREQ , clk_speed , & clk_cal );
549
- I2C_CLOCK_SRC_ATOMIC () {
550
- i2c_ll_set_source_clk (i2c -> dev , SOC_MOD_CLK_APB ); /*!< I2C source clock from APB, 80M*/
551
- }
546
+ i2c_ll_master_cal_bus_clk (APB_CLK_FREQ , clk_speed , & clk_cal );
547
+ I2C_CLOCK_SRC_ATOMIC () {
548
+ i2c_ll_set_source_clk (i2c -> dev , SOC_MOD_CLK_APB ); /*!< I2C source clock from APB, 80M*/
549
+ }
552
550
#elif SOC_I2C_SUPPORT_XTAL
553
551
i2c_ll_master_cal_bus_clk (XTAL_CLK_FREQ , clk_speed , & clk_cal );
554
552
I2C_CLOCK_SRC_ATOMIC () {
555
553
i2c_ll_set_source_clk (i2c -> dev , SOC_MOD_CLK_XTAL ); /*!< I2C source clock from XTAL, 40M */
556
554
}
557
555
#endif
558
- i2c_ll_set_txfifo_empty_thr (i2c -> dev , a );
559
- i2c_ll_set_rxfifo_full_thr (i2c -> dev , SOC_I2C_FIFO_LEN - a );
560
- i2c_ll_master_set_bus_timing (i2c -> dev , & clk_cal );
561
- i2c_ll_master_set_filter (i2c -> dev , 3 );
562
- return true;
563
- }
556
+ i2c_ll_set_txfifo_empty_thr (i2c -> dev , a );
557
+ i2c_ll_set_rxfifo_full_thr (i2c -> dev , SOC_I2C_FIFO_LEN - a );
558
+ i2c_ll_master_set_bus_timing (i2c -> dev , & clk_cal );
559
+ i2c_ll_master_set_filter (i2c -> dev , 3 );
560
+ return true;
561
+ }
564
562
565
- static void i2c_slave_delay_us (uint64_t us ) {
566
- uint64_t m = esp_timer_get_time ();
567
- if (us ) {
568
- uint64_t e = (m + us );
569
- if (m > e ) { //overflow
570
- while ((uint64_t )esp_timer_get_time () > e );
571
- }
572
- while ((uint64_t )esp_timer_get_time () < e );
563
+ static void i2c_slave_delay_us (uint64_t us ) {
564
+ uint64_t m = esp_timer_get_time ();
565
+ if (us ) {
566
+ uint64_t e = (m + us );
567
+ if (m > e ) { //overflow
568
+ while ((uint64_t )esp_timer_get_time () > e );
573
569
}
570
+ while ((uint64_t )esp_timer_get_time () < e );
574
571
}
572
+ }
575
573
576
- static void i2c_slave_gpio_mode (int8_t pin , gpio_mode_t mode ) {
577
- gpio_config_t conf = {
578
- .pin_bit_mask = 1LL << pin , .mode = mode , .pull_up_en = GPIO_PULLUP_ENABLE , .pull_down_en = GPIO_PULLDOWN_DISABLE , .intr_type = GPIO_INTR_DISABLE
579
- };
580
- gpio_config (& conf );
581
- }
574
+ static void i2c_slave_gpio_mode (int8_t pin , gpio_mode_t mode ) {
575
+ gpio_config_t conf = {
576
+ .pin_bit_mask = 1LL << pin , .mode = mode , .pull_up_en = GPIO_PULLUP_ENABLE , .pull_down_en = GPIO_PULLDOWN_DISABLE , .intr_type = GPIO_INTR_DISABLE
577
+ };
578
+ gpio_config (& conf );
579
+ }
582
580
583
- static bool i2c_slave_check_line_state (int8_t sda , int8_t scl ) {
584
- if (sda < 0 || scl < 0 ) {
585
- return false; //return false since there is nothing to do
586
- }
587
- // if the bus is not 'clear' try the cycling SCL until SDA goes High or 9 cycles
588
- gpio_set_level (sda , 1 );
589
- gpio_set_level (scl , 1 );
590
- i2c_slave_gpio_mode (sda , GPIO_MODE_INPUT | GPIO_MODE_DEF_OD );
591
- i2c_slave_gpio_mode (scl , GPIO_MODE_INPUT | GPIO_MODE_DEF_OD );
592
- gpio_set_level (scl , 1 );
593
-
594
- if (!gpio_get_level (sda ) || !gpio_get_level (scl )) { // bus in busy state
595
- log_w ("invalid state sda(%d)=%d, scl(%d)=%d" , sda , gpio_get_level (sda ), scl , gpio_get_level (scl ));
596
- for (uint8_t a = 0 ; a < 9 ; a ++ ) {
581
+ static bool i2c_slave_check_line_state (int8_t sda , int8_t scl ) {
582
+ if (sda < 0 || scl < 0 ) {
583
+ return false; //return false since there is nothing to do
584
+ }
585
+ // if the bus is not 'clear' try the cycling SCL until SDA goes High or 9 cycles
586
+ gpio_set_level (sda , 1 );
587
+ gpio_set_level (scl , 1 );
588
+ i2c_slave_gpio_mode (sda , GPIO_MODE_INPUT | GPIO_MODE_DEF_OD );
589
+ i2c_slave_gpio_mode (scl , GPIO_MODE_INPUT | GPIO_MODE_DEF_OD );
590
+ gpio_set_level (scl , 1 );
591
+
592
+ if (!gpio_get_level (sda ) || !gpio_get_level (scl )) { // bus in busy state
593
+ log_w ("invalid state sda(%d)=%d, scl(%d)=%d" , sda , gpio_get_level (sda ), scl , gpio_get_level (scl ));
594
+ for (uint8_t a = 0 ; a < 9 ; a ++ ) {
595
+ i2c_slave_delay_us (5 );
596
+ if (gpio_get_level (sda ) && gpio_get_level (scl )) { // bus recovered
597
+ log_w ("Recovered after %d Cycles" , a );
598
+ gpio_set_level (sda , 0 ); // start
597
599
i2c_slave_delay_us (5 );
598
- if (gpio_get_level (sda ) && gpio_get_level (scl )) { // bus recovered
599
- log_w ("Recovered after %d Cycles" , a );
600
- gpio_set_level (sda , 0 ); // start
601
- i2c_slave_delay_us (5 );
602
- for (uint8_t a = 0 ; a < 9 ; a ++ ) {
603
- gpio_set_level (scl , 1 );
604
- i2c_slave_delay_us (5 );
605
- gpio_set_level (scl , 0 );
606
- i2c_slave_delay_us (5 );
607
- }
600
+ for (uint8_t a = 0 ; a < 9 ; a ++ ) {
608
601
gpio_set_level (scl , 1 );
609
602
i2c_slave_delay_us (5 );
610
- gpio_set_level (sda , 1 ); // stop
611
- break ;
603
+ gpio_set_level (scl , 0 );
604
+ i2c_slave_delay_us ( 5 ) ;
612
605
}
613
- gpio_set_level (scl , 0 );
614
- i2c_slave_delay_us (5 );
615
606
gpio_set_level (scl , 1 );
607
+ i2c_slave_delay_us (5 );
608
+ gpio_set_level (sda , 1 ); // stop
609
+ break ;
616
610
}
611
+ gpio_set_level (scl , 0 );
612
+ i2c_slave_delay_us (5 );
613
+ gpio_set_level (scl , 1 );
617
614
}
615
+ }
618
616
619
- if (!gpio_get_level (sda ) || !gpio_get_level (scl )) { // bus in busy state
620
- log_e ("Bus Invalid State, Can't init sda=%d, scl=%d" , gpio_get_level (sda ), gpio_get_level (scl ));
621
- return false; // bus is busy
622
- }
623
- return true;
617
+ if (!gpio_get_level (sda ) || !gpio_get_level (scl )) { // bus in busy state
618
+ log_e ("Bus Invalid State, Can't init sda=%d, scl=%d" , gpio_get_level (sda ), gpio_get_level (scl ));
619
+ return false; // bus is busy
624
620
}
621
+ return true;
622
+ }
625
623
626
- static bool i2c_slave_attach_gpio (i2c_slave_struct_t * i2c , int8_t sda , int8_t scl ) {
627
- if (i2c == NULL ) {
628
- log_e ("no control block" );
629
- return false;
630
- }
624
+ static bool i2c_slave_attach_gpio (i2c_slave_struct_t * i2c , int8_t sda , int8_t scl ) {
625
+ if (i2c == NULL ) {
626
+ log_e ("no control block" );
627
+ return false;
628
+ }
631
629
632
- if ((sda < 0 ) || (scl < 0 )) {
633
- log_e ("bad pins sda=%d, scl=%d" , sda , scl );
634
- return false;
635
- }
630
+ if ((sda < 0 ) || (scl < 0 )) {
631
+ log_e ("bad pins sda=%d, scl=%d" , sda , scl );
632
+ return false;
633
+ }
636
634
637
- i2c -> scl = scl ;
638
- gpio_set_level (scl , 1 );
639
- i2c_slave_gpio_mode (scl , GPIO_MODE_INPUT_OUTPUT_OD );
640
- gpio_matrix_out (scl , I2C_SCL_IDX (i2c -> num ), false, false);
641
- gpio_matrix_in (scl , I2C_SCL_IDX (i2c -> num ), false);
635
+ i2c -> scl = scl ;
636
+ gpio_set_level (scl , 1 );
637
+ i2c_slave_gpio_mode (scl , GPIO_MODE_INPUT_OUTPUT_OD );
638
+ gpio_matrix_out (scl , I2C_SCL_IDX (i2c -> num ), false, false);
639
+ gpio_matrix_in (scl , I2C_SCL_IDX (i2c -> num ), false);
642
640
643
- i2c -> sda = sda ;
644
- gpio_set_level (sda , 1 );
645
- i2c_slave_gpio_mode (sda , GPIO_MODE_INPUT_OUTPUT_OD );
646
- gpio_matrix_out (sda , I2C_SDA_IDX (i2c -> num ), false, false);
647
- gpio_matrix_in (sda , I2C_SDA_IDX (i2c -> num ), false);
641
+ i2c -> sda = sda ;
642
+ gpio_set_level (sda , 1 );
643
+ i2c_slave_gpio_mode (sda , GPIO_MODE_INPUT_OUTPUT_OD );
644
+ gpio_matrix_out (sda , I2C_SDA_IDX (i2c -> num ), false, false);
645
+ gpio_matrix_in (sda , I2C_SDA_IDX (i2c -> num ), false);
648
646
649
- return true;
647
+ return true;
648
+ }
649
+
650
+ static bool i2c_slave_detach_gpio (i2c_slave_struct_t * i2c ) {
651
+ if (i2c == NULL ) {
652
+ log_e ("no control Block" );
653
+ return false;
654
+ }
655
+ if (i2c -> scl >= 0 ) {
656
+ gpio_matrix_out (i2c -> scl , 0x100 , false, false);
657
+ gpio_matrix_in (0x30 , I2C_SCL_IDX (i2c -> num ), false);
658
+ i2c_slave_gpio_mode (i2c -> scl , GPIO_MODE_INPUT );
659
+ i2c -> scl = -1 ; // un attached
650
660
}
661
+ if (i2c -> sda >= 0 ) {
662
+ gpio_matrix_out (i2c -> sda , 0x100 , false, false);
663
+ gpio_matrix_in (0x30 , I2C_SDA_IDX (i2c -> num ), false);
664
+ i2c_slave_gpio_mode (i2c -> sda , GPIO_MODE_INPUT );
665
+ i2c -> sda = -1 ; // un attached
666
+ }
667
+ return true;
668
+ }
651
669
652
- static bool i2c_slave_detach_gpio (i2c_slave_struct_t * i2c ) {
653
- if (i2c == NULL ) {
654
- log_e ("no control Block" );
655
- return false;
656
- }
657
- if (i2c -> scl >= 0 ) {
658
- gpio_matrix_out (i2c -> scl , 0x100 , false, false);
659
- gpio_matrix_in (0x30 , I2C_SCL_IDX (i2c -> num ), false);
660
- i2c_slave_gpio_mode (i2c -> scl , GPIO_MODE_INPUT );
661
- i2c -> scl = -1 ; // un attached
670
+ static bool i2c_slave_send_event (i2c_slave_struct_t * i2c , i2c_slave_queue_event_t * event ) {
671
+ bool pxHigherPriorityTaskWoken = false;
672
+ if (i2c -> event_queue ) {
673
+ if (xQueueSendFromISR (i2c -> event_queue , event , (BaseType_t * const )& pxHigherPriorityTaskWoken ) != pdTRUE ) {
674
+ //log_e("event_queue_full");
662
675
}
663
- if (i2c -> sda >= 0 ) {
664
- gpio_matrix_out (i2c -> sda , 0x100 , false, false);
665
- gpio_matrix_in (0x30 , I2C_SDA_IDX (i2c -> num ), false);
666
- i2c_slave_gpio_mode (i2c -> sda , GPIO_MODE_INPUT );
667
- i2c -> sda = -1 ; // un attached
668
- }
669
- return true;
670
676
}
677
+ return pxHigherPriorityTaskWoken ;
678
+ }
671
679
672
- static bool i2c_slave_send_event (i2c_slave_struct_t * i2c , i2c_slave_queue_event_t * event ) {
673
- bool pxHigherPriorityTaskWoken = false;
674
- if (i2c -> event_queue ) {
675
- if (xQueueSendFromISR (i2c -> event_queue , event , (BaseType_t * const )& pxHigherPriorityTaskWoken ) != pdTRUE ) {
676
- //log_e("event_queue_full");
677
- }
678
- }
679
- return pxHigherPriorityTaskWoken ;
680
- }
681
-
682
- static bool i2c_slave_handle_tx_fifo_empty (i2c_slave_struct_t * i2c ) {
683
- bool pxHigherPriorityTaskWoken = false;
684
- uint32_t d = 0 , moveCnt = 0 ;
685
- i2c_ll_get_txfifo_len (i2c -> dev , & moveCnt );
686
- while (moveCnt > 0 ) { // read tx queue until Fifo is full or queue is empty
687
- if (xQueueReceiveFromISR (i2c -> tx_queue , & d , (BaseType_t * const )& pxHigherPriorityTaskWoken ) == pdTRUE ) {
688
- i2c_ll_write_txfifo (i2c -> dev , (uint8_t * )& d , 1 );
689
- moveCnt -- ;
690
- } else {
691
- i2c_ll_slave_disable_tx_it (i2c -> dev );
692
- break ;
693
- }
680
+ static bool i2c_slave_handle_tx_fifo_empty (i2c_slave_struct_t * i2c ) {
681
+ bool pxHigherPriorityTaskWoken = false;
682
+ uint32_t d = 0 , moveCnt = 0 ;
683
+ i2c_ll_get_txfifo_len (i2c -> dev , & moveCnt );
684
+ while (moveCnt > 0 ) { // read tx queue until Fifo is full or queue is empty
685
+ if (xQueueReceiveFromISR (i2c -> tx_queue , & d , (BaseType_t * const )& pxHigherPriorityTaskWoken ) == pdTRUE ) {
686
+ i2c_ll_write_txfifo (i2c -> dev , (uint8_t * )& d , 1 );
687
+ moveCnt -- ;
688
+ } else {
689
+ i2c_ll_slave_disable_tx_it (i2c -> dev );
690
+ break ;
694
691
}
695
- return pxHigherPriorityTaskWoken ;
696
692
}
693
+ return pxHigherPriorityTaskWoken ;
694
+ }
697
695
698
- static bool i2c_slave_handle_rx_fifo_full (i2c_slave_struct_t * i2c , uint32_t len ) {
696
+ static bool i2c_slave_handle_rx_fifo_full (i2c_slave_struct_t * i2c , uint32_t len ) {
699
697
#if I2C_SLAVE_USE_RX_QUEUE
700
- uint32_t d = 0 ;
698
+ uint32_t d = 0 ;
701
699
#else
702
700
uint8_t data [SOC_I2C_FIFO_LEN ];
703
701
#endif
704
- bool pxHigherPriorityTaskWoken = false;
702
+ bool pxHigherPriorityTaskWoken = false;
705
703
#if I2C_SLAVE_USE_RX_QUEUE
706
- while (len > 0 ) {
707
- i2c_ll_read_rxfifo (i2c -> dev , (uint8_t * )& d , 1 );
708
- if (xQueueSendFromISR (i2c -> rx_queue , & d , (BaseType_t * const )& pxHigherPriorityTaskWoken ) != pdTRUE ) {
709
- log_e ("rx_queue_full" );
710
- } else {
711
- i2c -> rx_data_count ++ ;
712
- }
713
- if (-- len == 0 ) {
714
- len = i2c_ll_get_rxfifo_cnt (i2c -> dev );
715
- }
704
+ while (len > 0 ) {
705
+ i2c_ll_read_rxfifo (i2c -> dev , (uint8_t * )& d , 1 );
706
+ if (xQueueSendFromISR (i2c -> rx_queue , & d , (BaseType_t * const )& pxHigherPriorityTaskWoken ) != pdTRUE ) {
707
+ log_e ("rx_queue_full" );
708
+ } else {
709
+ i2c -> rx_data_count ++ ;
710
+ }
711
+ if (-- len == 0 ) {
712
+ len = i2c_ll_get_rxfifo_cnt (i2c -> dev );
713
+ }
716
714
#else
717
715
if (len ) {
718
716
i2c_ll_read_rxfifo (i2c -> dev , data , len );
@@ -722,109 +720,109 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
722
720
i2c -> rx_data_count += len ;
723
721
}
724
722
#endif
725
- }
726
- return pxHigherPriorityTaskWoken ;
727
723
}
724
+ return pxHigherPriorityTaskWoken ;
725
+ }
726
+
727
+ static void i2c_slave_isr_handler (void * arg ) {
728
+ bool pxHigherPriorityTaskWoken = false;
729
+ i2c_slave_struct_t * i2c = (i2c_slave_struct_t * )arg ; // recover data
728
730
729
- static void i2c_slave_isr_handler (void * arg ) {
730
- bool pxHigherPriorityTaskWoken = false;
731
- i2c_slave_struct_t * i2c = (i2c_slave_struct_t * )arg ; // recover data
731
+ uint32_t activeInt = 0 ;
732
+ i2c_ll_get_intr_mask (i2c -> dev , & activeInt );
733
+ i2c_ll_clear_intr_mask (i2c -> dev , activeInt );
734
+ uint32_t rx_fifo_len = 0 ;
735
+ i2c_ll_get_rxfifo_cnt (i2c -> dev , & rx_fifo_len );
736
+ bool slave_rw = i2c_ll_slave_rw (i2c -> dev );
732
737
733
- uint32_t activeInt = 0 ;
734
- i2c_ll_get_intr_mask (i2c -> dev , & activeInt );
735
- i2c_ll_clear_intr_mask (i2c -> dev , activeInt );
736
- uint32_t rx_fifo_len = 0 ;
737
- i2c_ll_get_rxfifo_cnt (i2c -> dev , & rx_fifo_len );
738
- bool slave_rw = i2c_ll_slave_rw (i2c -> dev );
738
+ if (activeInt & I2C_RXFIFO_WM_INT_ENA ) { // RX FiFo Full
739
+ pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
740
+ i2c_ll_slave_enable_rx_it (i2c -> dev ); //is this necessary?
741
+ }
739
742
740
- if (activeInt & I2C_RXFIFO_WM_INT_ENA ) { // RX FiFo Full
743
+ if (activeInt & I2C_TRANS_COMPLETE_INT_ENA ) { // STOP
744
+ if (rx_fifo_len ) { //READ RX FIFO
741
745
pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
742
- i2c_ll_slave_enable_rx_it (i2c -> dev ); //is this necessary?
743
746
}
744
-
745
- if (activeInt & I2C_TRANS_COMPLETE_INT_ENA ) { // STOP
746
- if (rx_fifo_len ) { //READ RX FIFO
747
- pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
748
- }
749
- if (i2c -> rx_data_count ) { //WRITE or RepeatedStart
750
- //SEND RX Event
747
+ if (i2c -> rx_data_count ) { //WRITE or RepeatedStart
748
+ //SEND RX Event
749
+ i2c_slave_queue_event_t event ;
750
+ event .event = I2C_SLAVE_EVT_RX ;
751
+ event .stop = !slave_rw ;
752
+ event .param = i2c -> rx_data_count ;
753
+ pxHigherPriorityTaskWoken |= i2c_slave_send_event (i2c , & event );
754
+ //Zero RX count
755
+ i2c -> rx_data_count = 0 ;
756
+ }
757
+ if (slave_rw ) { // READ
758
+ #if CONFIG_IDF_TARGET_ESP32
759
+ if (i2c -> dev -> status_reg .scl_main_state_last == 6 ) {
760
+ //SEND TX Event
751
761
i2c_slave_queue_event_t event ;
752
- event .event = I2C_SLAVE_EVT_RX ;
753
- event .stop = !slave_rw ;
754
- event .param = i2c -> rx_data_count ;
762
+ event .event = I2C_SLAVE_EVT_TX ;
755
763
pxHigherPriorityTaskWoken |= i2c_slave_send_event (i2c , & event );
756
- //Zero RX count
757
- i2c -> rx_data_count = 0 ;
758
764
}
759
- if (slave_rw ) { // READ
760
- #if CONFIG_IDF_TARGET_ESP32
761
- if (i2c -> dev -> status_reg .scl_main_state_last == 6 ) {
762
- //SEND TX Event
763
- i2c_slave_queue_event_t event ;
764
- event .event = I2C_SLAVE_EVT_TX ;
765
- pxHigherPriorityTaskWoken |= i2c_slave_send_event (i2c , & event );
766
- }
767
765
#else
768
766
//reset TX data
769
767
i2c_ll_txfifo_rst (i2c -> dev );
770
768
uint8_t d ;
771
769
while (xQueueReceiveFromISR (i2c -> tx_queue , & d , (BaseType_t * const )& pxHigherPriorityTaskWoken ) == pdTRUE ); //flush partial write
772
770
#endif
773
- }
774
771
}
772
+ }
775
773
776
774
#ifndef CONFIG_IDF_TARGET_ESP32
777
- if (activeInt & I2C_SLAVE_STRETCH_INT_ENA ) { // STRETCH
778
- i2c_stretch_cause_t cause = i2c_ll_stretch_cause (i2c -> dev );
779
- if (cause == I2C_STRETCH_CAUSE_MASTER_READ ) {
780
- //on C3 RX data disappears with repeated start, so we need to get it here
781
- if (rx_fifo_len ) {
782
- pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
783
- }
784
- //SEND TX Event
785
- i2c_slave_queue_event_t event ;
786
- event .event = I2C_SLAVE_EVT_TX ;
787
- pxHigherPriorityTaskWoken |= i2c_slave_send_event (i2c , & event );
788
- //will clear after execution
789
- } else if (cause == I2C_STRETCH_CAUSE_TX_FIFO_EMPTY ) {
790
- pxHigherPriorityTaskWoken |= i2c_slave_handle_tx_fifo_empty (i2c );
791
- i2c_ll_stretch_clr (i2c -> dev );
792
- } else if (cause == I2C_STRETCH_CAUSE_RX_FIFO_FULL ) {
775
+ if (activeInt & I2C_SLAVE_STRETCH_INT_ENA ) { // STRETCH
776
+ i2c_stretch_cause_t cause = i2c_ll_stretch_cause (i2c -> dev );
777
+ if (cause == I2C_STRETCH_CAUSE_MASTER_READ ) {
778
+ //on C3 RX data disappears with repeated start, so we need to get it here
779
+ if (rx_fifo_len ) {
793
780
pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
794
- i2c_ll_stretch_clr (i2c -> dev );
795
781
}
782
+ //SEND TX Event
783
+ i2c_slave_queue_event_t event ;
784
+ event .event = I2C_SLAVE_EVT_TX ;
785
+ pxHigherPriorityTaskWoken |= i2c_slave_send_event (i2c , & event );
786
+ //will clear after execution
787
+ } else if (cause == I2C_STRETCH_CAUSE_TX_FIFO_EMPTY ) {
788
+ pxHigherPriorityTaskWoken |= i2c_slave_handle_tx_fifo_empty (i2c );
789
+ i2c_ll_stretch_clr (i2c -> dev );
790
+ } else if (cause == I2C_STRETCH_CAUSE_RX_FIFO_FULL ) {
791
+ pxHigherPriorityTaskWoken |= i2c_slave_handle_rx_fifo_full (i2c , rx_fifo_len );
792
+ i2c_ll_stretch_clr (i2c -> dev );
796
793
}
794
+ }
797
795
#endif
798
796
799
- if (activeInt & I2C_TXFIFO_WM_INT_ENA ) { // TX FiFo Empty
800
- pxHigherPriorityTaskWoken |= i2c_slave_handle_tx_fifo_empty (i2c );
801
- }
797
+ if (activeInt & I2C_TXFIFO_WM_INT_ENA ) { // TX FiFo Empty
798
+ pxHigherPriorityTaskWoken |= i2c_slave_handle_tx_fifo_empty (i2c );
799
+ }
802
800
803
- if (pxHigherPriorityTaskWoken ) {
804
- portYIELD_FROM_ISR ();
805
- }
801
+ if (pxHigherPriorityTaskWoken ) {
802
+ portYIELD_FROM_ISR ();
806
803
}
804
+ }
807
805
808
- static size_t i2c_slave_read_rx (i2c_slave_struct_t * i2c , uint8_t * data , size_t len ) {
809
- if (!len ) {
810
- return 0 ;
811
- }
806
+ static size_t i2c_slave_read_rx (i2c_slave_struct_t * i2c , uint8_t * data , size_t len ) {
807
+ if (!len ) {
808
+ return 0 ;
809
+ }
812
810
#if I2C_SLAVE_USE_RX_QUEUE
813
- uint8_t d = 0 ;
814
- BaseType_t res = pdTRUE ;
815
- for (size_t i = 0 ; i < len ; i ++ ) {
816
- if (data ) {
817
- res = xQueueReceive (i2c -> rx_queue , & data [i ], 0 );
818
- } else {
819
- res = xQueueReceive (i2c -> rx_queue , & d , 0 );
820
- }
821
- if (res != pdTRUE ) {
822
- log_e ("Read Queue(%u) Failed" , i );
823
- len = i ;
824
- break ;
825
- }
811
+ uint8_t d = 0 ;
812
+ BaseType_t res = pdTRUE ;
813
+ for (size_t i = 0 ; i < len ; i ++ ) {
814
+ if (data ) {
815
+ res = xQueueReceive (i2c -> rx_queue , & data [i ], 0 );
816
+ } else {
817
+ res = xQueueReceive (i2c -> rx_queue , & d , 0 );
818
+ }
819
+ if (res != pdTRUE ) {
820
+ log_e ("Read Queue(%u) Failed" , i );
821
+ len = i ;
822
+ break ;
826
823
}
827
- return (data ) ? len : 0 ;
824
+ }
825
+ return (data ) ? len : 0 ;
828
826
#else
829
827
size_t dlen = 0 , to_read = len , so_far = 0 , available = 0 ;
830
828
uint8_t * rx_data = NULL ;
@@ -851,55 +849,55 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t
851
849
}
852
850
return (data ) ? so_far : 0 ;
853
851
#endif
854
- }
852
+ }
855
853
856
- static void i2c_slave_task (void * pv_args ) {
857
- i2c_slave_struct_t * i2c = (i2c_slave_struct_t * )pv_args ;
858
- i2c_slave_queue_event_t event ;
859
- size_t len = 0 ;
860
- bool stop = false;
861
- uint8_t * data = NULL ;
862
- for (;;) {
863
- if (xQueueReceive (i2c -> event_queue , & event , portMAX_DELAY ) == pdTRUE ) {
864
- // Write
865
- if (event .event == I2C_SLAVE_EVT_RX ) {
866
- len = event .param ;
867
- stop = event .stop ;
868
- data = (len > 0 ) ? (uint8_t * )malloc (len ) : NULL ;
869
-
870
- if (len && data == NULL ) {
871
- log_e ("Malloc (%u) Failed" , len );
872
- }
873
- len = i2c_slave_read_rx (i2c , data , len );
874
- if (i2c -> receive_callback ) {
875
- i2c -> receive_callback (i2c -> num , data , len , stop , i2c -> arg );
876
- }
877
- free (data );
878
-
879
- // Read
880
- } else if (event .event == I2C_SLAVE_EVT_TX ) {
881
- if (i2c -> request_callback ) {
882
- i2c -> request_callback (i2c -> num , i2c -> arg );
883
- }
884
- i2c_ll_stretch_clr (i2c -> dev );
854
+ static void i2c_slave_task (void * pv_args ) {
855
+ i2c_slave_struct_t * i2c = (i2c_slave_struct_t * )pv_args ;
856
+ i2c_slave_queue_event_t event ;
857
+ size_t len = 0 ;
858
+ bool stop = false;
859
+ uint8_t * data = NULL ;
860
+ for (;;) {
861
+ if (xQueueReceive (i2c -> event_queue , & event , portMAX_DELAY ) == pdTRUE ) {
862
+ // Write
863
+ if (event .event == I2C_SLAVE_EVT_RX ) {
864
+ len = event .param ;
865
+ stop = event .stop ;
866
+ data = (len > 0 ) ? (uint8_t * )malloc (len ) : NULL ;
867
+
868
+ if (len && data == NULL ) {
869
+ log_e ("Malloc (%u) Failed" , len );
885
870
}
871
+ len = i2c_slave_read_rx (i2c , data , len );
872
+ if (i2c -> receive_callback ) {
873
+ i2c -> receive_callback (i2c -> num , data , len , stop , i2c -> arg );
874
+ }
875
+ free (data );
876
+
877
+ // Read
878
+ } else if (event .event == I2C_SLAVE_EVT_TX ) {
879
+ if (i2c -> request_callback ) {
880
+ i2c -> request_callback (i2c -> num , i2c -> arg );
881
+ }
882
+ i2c_ll_stretch_clr (i2c -> dev );
886
883
}
887
884
}
888
- vTaskDelete (NULL );
889
885
}
886
+ vTaskDelete (NULL );
887
+ }
890
888
891
- static bool i2cSlaveDetachBus (void * bus_i2c_num ) {
892
- uint8_t num = (int )bus_i2c_num - 1 ;
893
- i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
894
- if (i2c -> scl == -1 && i2c -> sda == -1 ) {
895
- return true;
896
- }
897
- esp_err_t err = i2cSlaveDeinit (num );
898
- if (err != ESP_OK ) {
899
- log_e ("i2cSlaveDeinit failed with error: %d" , err );
900
- return false;
901
- }
889
+ static bool i2cSlaveDetachBus (void * bus_i2c_num ) {
890
+ uint8_t num = (int )bus_i2c_num - 1 ;
891
+ i2c_slave_struct_t * i2c = & _i2c_bus_array [num ];
892
+ if (i2c -> scl == -1 && i2c -> sda == -1 ) {
902
893
return true;
903
894
}
895
+ esp_err_t err = i2cSlaveDeinit (num );
896
+ if (err != ESP_OK ) {
897
+ log_e ("i2cSlaveDeinit failed with error: %d" , err );
898
+ return false;
899
+ }
900
+ return true;
901
+ }
904
902
905
903
#endif /* SOC_I2C_SUPPORT_SLAVE */
0 commit comments