Skip to content

Commit 31a2ae6

Browse files
committed
fix(tests): Fix periman and add missing diagrams
1 parent b859bdf commit 31a2ae6

File tree

7 files changed

+405
-76
lines changed

7 files changed

+405
-76
lines changed

cores/esp32/esp32-hal-adc.c

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "esp_adc/adc_oneshot.h"
2121
#include "esp_adc/adc_continuous.h"
2222
#include "esp_adc/adc_cali_scheme.h"
23+
#include "esp_heap_caps.h"
2324

2425
#if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP32P4_REV_MIN_FULL >= 300
2526
// NOTE: These weak definitions allow successful linkage if the real efuse calibration functions are missing.
@@ -403,43 +404,39 @@ adc_continuous_result_t *adc_result = NULL;
403404
static bool adcContinuousDetachBus(void *adc_unit_number) {
404405
adc_unit_t adc_unit = (adc_unit_t)adc_unit_number - 1;
405406

407+
// Guard against double-cleanup: check if already cleaned up
406408
if (adc_handle[adc_unit].adc_continuous_handle == NULL) {
407409
return true;
408-
} else {
409-
esp_err_t err = adc_continuous_deinit(adc_handle[adc_unit].adc_continuous_handle);
410+
}
411+
412+
// Clean up ADC driver
413+
esp_err_t err = adc_continuous_deinit(adc_handle[adc_unit].adc_continuous_handle);
414+
if (err != ESP_OK) {
415+
return false;
416+
}
417+
adc_handle[adc_unit].adc_continuous_handle = NULL;
418+
419+
// Clean up calibration handle if exists
420+
if (adc_handle[adc_unit].adc_cali_handle != NULL) {
421+
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
422+
err = adc_cali_delete_scheme_curve_fitting(adc_handle[adc_unit].adc_cali_handle);
410423
if (err != ESP_OK) {
411424
return false;
412425
}
413-
adc_handle[adc_unit].adc_continuous_handle = NULL;
414-
if (adc_handle[adc_unit].adc_cali_handle != NULL) {
415-
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
416-
err = adc_cali_delete_scheme_curve_fitting(adc_handle[adc_unit].adc_cali_handle);
417-
if (err != ESP_OK) {
418-
return false;
419-
}
420426
#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
421-
err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
422-
if (err != ESP_OK) {
423-
return false;
424-
}
425-
#else
426-
log_e("ADC Calibration scheme is not supported!");
427+
err = adc_cali_delete_scheme_line_fitting(adc_handle[adc_unit].adc_cali_handle);
428+
if (err != ESP_OK) {
427429
return false;
428-
#endif
429430
}
431+
#else
432+
log_e("ADC Calibration scheme is not supported!");
433+
return false;
434+
#endif
430435
adc_handle[adc_unit].adc_cali_handle = NULL;
431-
432-
//set all used pins to INIT state
433-
for (uint8_t channel = 0; channel < SOC_ADC_CHANNEL_NUM(adc_unit); channel++) {
434-
int io_pin;
435-
adc_oneshot_channel_to_io(adc_unit, channel, &io_pin);
436-
if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
437-
if (!perimanClearPinBus(io_pin)) {
438-
return false;
439-
}
440-
}
441-
}
442436
}
437+
438+
// Don't call perimanClearPinBus() here - the peripheral manager already handles it
439+
// This callback is only responsible for cleaning up the ADC driver itself
443440
return true;
444441
}
445442

@@ -549,6 +546,14 @@ bool analogContinuous(const uint8_t pins[], size_t pins_count, uint32_t conversi
549546
}
550547
#endif
551548

549+
#if CONFIG_IDF_TARGET_ESP32P4
550+
// Align conversion frame size to cache line size (required for DMA on targets with cache)
551+
uint32_t alignment_remainder = adc_handle[adc_unit].conversion_frame_size % CONFIG_CACHE_L1_CACHE_LINE_SIZE;
552+
if (alignment_remainder != 0) {
553+
adc_handle[adc_unit].conversion_frame_size += (CONFIG_CACHE_L1_CACHE_LINE_SIZE - alignment_remainder);
554+
}
555+
#endif
556+
552557
adc_handle[adc_unit].buffer_size = adc_handle[adc_unit].conversion_frame_size * 2;
553558

554559
//Conversion frame size buffer cant be bigger than 4092 bytes
@@ -626,8 +631,21 @@ bool analogContinuousRead(adc_continuous_result_t **buffer, uint32_t timeout_ms)
626631
uint32_t bytes_read = 0;
627632
uint32_t read_raw[used_adc_channels];
628633
uint32_t read_count[used_adc_channels];
629-
uint8_t adc_read[adc_handle[ADC_UNIT_1].conversion_frame_size];
630-
memset(adc_read, 0xcc, sizeof(adc_read));
634+
635+
// Allocate DMA buffer with cache line alignment (required for ESP32-P4 and other targets with cache)
636+
size_t buffer_size = adc_handle[ADC_UNIT_1].conversion_frame_size;
637+
#if CONFIG_IDF_TARGET_ESP32P4
638+
uint8_t *adc_read = (uint8_t *)heap_caps_aligned_alloc(CONFIG_CACHE_L1_CACHE_LINE_SIZE, buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
639+
#else
640+
uint8_t *adc_read = (uint8_t *)heap_caps_malloc(buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
641+
#endif
642+
if (adc_read == NULL) {
643+
log_e("Failed to allocate DMA buffer");
644+
*buffer = NULL;
645+
return false;
646+
}
647+
648+
memset(adc_read, 0xcc, buffer_size);
631649
memset(read_raw, 0, sizeof(read_raw));
632650
memset(read_count, 0, sizeof(read_count));
633651

@@ -638,6 +656,8 @@ bool analogContinuousRead(adc_continuous_result_t **buffer, uint32_t timeout_ms)
638656
} else {
639657
log_e("Reading data failed with error: %X", err);
640658
}
659+
free(adc_read);
660+
adc_read = NULL;
641661
*buffer = NULL;
642662
return false;
643663
}
@@ -676,6 +696,8 @@ bool analogContinuousRead(adc_continuous_result_t **buffer, uint32_t timeout_ms)
676696
}
677697
}
678698

699+
free(adc_read);
700+
adc_read = NULL;
679701
*buffer = adc_result;
680702
return true;
681703

@@ -708,16 +730,29 @@ bool analogContinuousStop() {
708730
}
709731

710732
bool analogContinuousDeinit() {
711-
if (adc_handle[ADC_UNIT_1].adc_continuous_handle != NULL) {
712-
esp_err_t err = adc_continuous_deinit(adc_handle[ADC_UNIT_1].adc_continuous_handle);
713-
if (err != ESP_OK) {
714-
return false;
733+
if (adc_handle[ADC_UNIT_1].adc_continuous_handle == NULL) {
734+
log_i("ADC Continuous was not initialized");
735+
return true;
736+
}
737+
738+
// Clear all used pins from peripheral manager
739+
// This will trigger adcContinuousDetachBus() callback which cleans up the ADC driver
740+
for (uint8_t channel = 0; channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1); channel++) {
741+
int io_pin;
742+
adc_oneshot_channel_to_io(ADC_UNIT_1, channel, &io_pin);
743+
if (perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_CONT) {
744+
if (!perimanClearPinBus(io_pin)) {
745+
return false;
746+
}
715747
}
748+
}
749+
750+
// Free the result buffer (callback doesn't do this)
751+
if (adc_result != NULL) {
716752
free(adc_result);
717-
adc_handle[ADC_UNIT_1].adc_continuous_handle = NULL;
718-
} else {
719-
log_i("ADC Continuous was not initialized");
753+
adc_result = NULL;
720754
}
755+
721756
return true;
722757
}
723758

tests/validation/periman/ci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
platforms:
22
qemu: false
33
wokwi: false
4-
5-
targets:
6-
esp32p4: false

0 commit comments

Comments
 (0)