Skip to content

Commit 85294ca

Browse files
committed
drivers: adc: esp32: enable adc dma on non gdma socs
Enables adc dma on: - esp32 - esp32-s2 Signed-off-by: Marcio Ribeiro <[email protected]>
1 parent 697fe3e commit 85294ca

File tree

4 files changed

+189
-28
lines changed

4 files changed

+189
-28
lines changed

drivers/adc/Kconfig.esp32

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ if ADC_ESP32
1313

1414
config ADC_ESP32_DMA
1515
bool "ESP32 ADC DMA Support"
16-
depends on DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED
16+
select DMA if DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED
1717
help
18-
Enable the ADC DMA mode for ADC instances
19-
that enable dma channels in their device tree node.
18+
Enable the ADC DMA mode
2019

2120
endif

drivers/adc/adc_esp32.c

Lines changed: 185 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,48 @@
1919
#include <esp_private/adc_share_hw_ctrl.h>
2020

2121
#if defined(CONFIG_ADC_ESP32_DMA)
22-
#if !SOC_GDMA_SUPPORTED
23-
#error "SoCs without GDMA peripheral are not supported!"
24-
#endif
22+
#if SOC_GDMA_SUPPORTED
2523
#include <zephyr/drivers/dma.h>
2624
#include <zephyr/drivers/dma/dma_esp32.h>
27-
#endif
25+
#else
26+
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
27+
#include <soc/lldesc.h>
28+
29+
#if CONFIG_SOC_SERIES_ESP32
30+
#include <zephyr/dt-bindings/interrupt-controller/esp-xtensa-intmux.h>
31+
32+
#define ADC_DMA_I2S_HOST 0
33+
#define ADC_DMA_INTR_MASK BIT(9)
34+
#define ADC_DMA_DEV I2S_LL_GET_HW(ADC_DMA_I2S_HOST)
35+
#define ADC_DMA_CHANNEL 0
36+
#define adc_dma_check_event(dev, mask) (i2s_ll_get_intr_status(dev) & mask)
37+
#define adc_dma_digi_clr_intr(dev, mask) i2s_ll_clear_intr_status(dev, mask)
38+
39+
#define I2S0_NODE_ID DT_NODELABEL(i2s0)
40+
#define I2S0_DEV ((const struct device *)DEVICE_DT_GET_OR_NULL(I2S0_NODE_ID))
41+
#define I2S0_CLK_DEV ((const struct device *)DEVICE_DT_GET(DT_CLOCKS_CTLR(I2S0_NODE_ID)))
42+
#define I2S0_CLK_SUBSYS ((clock_control_subsys_t)DT_CLOCKS_CELL(I2S0_NODE_ID, offset))
43+
#endif /* CONFIG_SOC_SERIES_ESP32 */
44+
45+
#if CONFIG_SOC_SERIES_ESP32S2
46+
#include <zephyr/dt-bindings/interrupt-controller/esp32s2-xtensa-intmux.h>
47+
48+
#define ADC_DMA_SPI_HOST SPI3_HOST
49+
#define ADC_DMA_INTR_MASK SPI_LL_INTR_IN_SUC_EOF
50+
#define ADC_DMA_DEV SPI_LL_GET_HW(ADC_DMA_SPI_HOST)
51+
#define ADC_DMA_CHANNEL (DT_PROP(DT_NODELABEL(spi3), dma_host) + 1)
52+
#define adc_dma_check_event(dev, mask) spi_ll_get_intr(dev, mask)
53+
#define adc_dma_digi_clr_intr(dev, mask) spi_ll_clear_intr(dev, mask)
54+
55+
#define SPI3_NODE_ID DT_NODELABEL(spi3)
56+
#define SPI3_DEV ((const struct device *)DEVICE_DT_GET_OR_NULL(SPI3_NODE_ID))
57+
#define SPI3_CLK_DEV ((const struct device *)DEVICE_DT_GET(DT_CLOCKS_CTLR(SPI3_NODE_ID)))
58+
#define SPI3_CLK_SUBSYS ((clock_control_subsys_t)DT_CLOCKS_CELL(SPI3_NODE_ID, offset))
59+
#define SPI3_DMA_CLK_SUBSYS ((clock_control_subsys_t)DT_PROP(SPI3_NODE_ID, dma_clk))
60+
#endif /* CONFIG_SOC_SERIES_ESP32 */
61+
62+
#endif /* SOC_GDMA_SUPPORTED */
63+
#endif /* defined(CONFIG_ADC_ESP32_DMA) */
2864

2965
#include <zephyr/kernel.h>
3066
#include <zephyr/device.h>
@@ -53,10 +89,10 @@ struct adc_esp32_conf {
5389
adc_unit_t unit;
5490
uint8_t channel_count;
5591
const struct device *gpio_port;
56-
#if defined(CONFIG_ADC_ESP32_DMA)
92+
#if defined(CONFIG_ADC_ESP32_DMA) && SOC_GDMA_SUPPORTED
5793
const struct device *dma_dev;
5894
uint8_t dma_channel;
59-
#endif /* defined(CONFIG_ADC_ESP32_DMA) */
95+
#endif /* defined(CONFIG_ADC_ESP32_DMA) && SOC_GDMA_SUPPORTED */
6096
};
6197

6298
struct adc_esp32_data {
@@ -70,6 +106,10 @@ struct adc_esp32_data {
70106
adc_hal_dma_ctx_t adc_hal_dma_ctx;
71107
uint8_t *dma_buffer;
72108
struct k_sem dma_conv_wait_lock;
109+
#if !SOC_GDMA_SUPPORTED
110+
lldesc_t dma_desc;
111+
struct intr_handle_data_t *irq_handle;
112+
#endif /* !SOC_GDMA_SUPPORTED */
73113
#endif /* defined(CONFIG_ADC_ESP32_DMA) */
74114
};
75115

@@ -149,6 +189,8 @@ static void adc_hw_calibration(adc_unit_t unit)
149189

150190
#if defined(CONFIG_ADC_ESP32_DMA)
151191

192+
#if SOC_GDMA_SUPPORTED
193+
152194
static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void *user_data,
153195
uint32_t channel, int status)
154196
{
@@ -161,11 +203,33 @@ static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void
161203
k_sem_give(&data->dma_conv_wait_lock);
162204
}
163205

206+
#else
207+
208+
static IRAM_ATTR void adc_esp32_dma_intr_handler(void *arg)
209+
{
210+
if (arg == NULL) {
211+
return;
212+
}
213+
214+
const struct device *dev = arg;
215+
struct adc_esp32_data *data = dev->data;
216+
217+
bool conv_completed = adc_dma_check_event(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
218+
if (conv_completed) {
219+
adc_dma_digi_clr_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
220+
221+
k_sem_give(&data->dma_conv_wait_lock);
222+
}
223+
}
224+
225+
#endif /* SOC_GDMA_SUPPORTED */
226+
164227
static int adc_esp32_dma_start(const struct device *dev, uint8_t *buf, size_t len)
165228
{
229+
#if SOC_GDMA_SUPPORTED
166230
const struct adc_esp32_conf *conf = dev->config;
167-
168231
int err = 0;
232+
169233
struct dma_config dma_cfg = {0};
170234
struct dma_status dma_status = {0};
171235
struct dma_block_config dma_blk = {0};
@@ -208,10 +272,42 @@ static int adc_esp32_dma_start(const struct device *dev, uint8_t *buf, size_t le
208272
unlock:
209273
irq_unlock(key);
210274
return err;
275+
#else
276+
struct adc_esp32_data *data = dev->data;
277+
// #error "Tentar reutilizar data->adc_hal_dma_ctx.rx_desc"
278+
lldesc_t *dma_desc = &data->dma_desc;
279+
280+
memset(dma_desc, 0, sizeof(lldesc_t));
281+
dma_desc->owner = 1;
282+
dma_desc->sosf = 0;
283+
dma_desc->buf = buf;
284+
dma_desc->offset = 0;
285+
dma_desc->length = len;
286+
dma_desc->size = len;
287+
dma_desc->eof = 0;
288+
289+
#ifdef CONFIG_SOC_SERIES_ESP32
290+
i2s_ll_clear_intr_status(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
291+
i2s_ll_enable_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK, true);
292+
293+
i2s_ll_rx_reset_dma(ADC_DMA_DEV);
294+
i2s_ll_enable_dma(ADC_DMA_DEV, true);
295+
i2s_ll_rx_start_link(ADC_DMA_DEV, (uint32_t)&data->dma_desc);
296+
#endif /* CONFIG_SOC_SERIES_ESP32 */
297+
298+
#ifdef CONFIG_SOC_SERIES_ESP32S2
299+
spi_ll_clear_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
300+
spi_ll_enable_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
301+
spi_dma_ll_rx_start(ADC_DMA_DEV, 0, &data->dma_desc);
302+
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
303+
304+
return 0;
305+
#endif /* SOC_GDMA_SUPPORTED */
211306
}
212307

213308
static int adc_esp32_dma_stop(const struct device *dev)
214309
{
310+
#if SOC_GDMA_SUPPORTED
215311
const struct adc_esp32_conf *conf = dev->config;
216312
unsigned int key = irq_lock();
217313
int err = 0;
@@ -223,6 +319,21 @@ static int adc_esp32_dma_stop(const struct device *dev)
223319

224320
irq_unlock(key);
225321
return err;
322+
#else
323+
#ifdef CONFIG_SOC_SERIES_ESP32
324+
i2s_ll_enable_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK, false);
325+
i2s_ll_clear_intr_status(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
326+
i2s_ll_rx_stop_link(ADC_DMA_DEV);
327+
#endif /* CONFIG_SOC_SERIES_ESP32 */
328+
329+
#ifdef CONFIG_SOC_SERIES_ESP32S2
330+
spi_ll_disable_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
331+
spi_ll_clear_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
332+
spi_dma_ll_rx_stop(ADC_DMA_DEV, 0);
333+
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
334+
335+
return 0;
336+
#endif /* SOC_GDMA_SUPPORTED */
226337
}
227338

228339
static int adc_esp32_fill_digi_pattern(const struct device *dev, const struct adc_sequence *seq,
@@ -312,10 +423,15 @@ static void adc_esp32_digi_start(const struct device *dev, void *pattern_config,
312423
uint32_t number_of_adc_digi_samples = number_of_samplings * pattern_len;
313424

314425
adc_hal_dma_config_t adc_hal_dma_config = {
426+
#if SOC_GDMA_SUPPORTED
315427
.dev = (void *)GDMA_LL_GET_HW(0),
428+
.dma_chan = conf->dma_channel,
429+
#else
430+
.dev = (void *)ADC_DMA_DEV,
431+
.dma_chan = ADC_DMA_CHANNEL,
432+
#endif /* SOC_GDMA_SUPPORTED */
316433
.eof_desc_num = 1,
317434
.eof_step = 1,
318-
.dma_chan = conf->dma_channel,
319435
.eof_num = number_of_adc_digi_samples,
320436
};
321437

@@ -687,8 +803,7 @@ static int adc_esp32_init(const struct device *dev)
687803
return -ENODEV;
688804
}
689805

690-
#if defined(CONFIG_ADC_ESP32_DMA)
691-
806+
#ifdef CONFIG_ADC_ESP32_DMA
692807
if (k_sem_init(&data->dma_conv_wait_lock, 0, 1)) {
693808
LOG_ERR("dma_conv_wait_lock initialization failed!");
694809
return -EINVAL;
@@ -709,7 +824,56 @@ static int adc_esp32_init(const struct device *dev)
709824
}
710825
LOG_DBG("data->dma_buffer = 0x%08X", (unsigned int)data->dma_buffer);
711826

712-
#endif /* defined(CONFIG_ADC_ESP32_DMA) */
827+
#ifdef CONFIG_SOC_SERIES_ESP32
828+
const struct device *i2s0_dev = I2S0_DEV;
829+
830+
if (i2s0_dev != NULL) {
831+
LOG_ERR("I2S0 not available");
832+
return -1;
833+
}
834+
835+
if (!device_is_ready(I2S0_CLK_DEV)) {
836+
return -ENODEV;
837+
}
838+
839+
// periph_module_enable(PERIPH_I2S0_MODULE);
840+
clock_control_on(I2S0_CLK_DEV, I2S0_CLK_SUBSYS);
841+
i2s_ll_enable_clock(ADC_DMA_DEV);
842+
843+
int err = esp_intr_alloc(I2S0_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED,
844+
adc_esp32_dma_intr_handler, (void *)dev, &(data->irq_handle));
845+
if (err != 0) {
846+
LOG_ERR("Could not allocate interrupt (err %d)", err);
847+
return err;
848+
}
849+
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
850+
851+
#ifdef CONFIG_SOC_SERIES_ESP32S2
852+
const struct device *spi3_dev = SPI3_DEV;
853+
854+
if (spi3_dev != NULL) {
855+
LOG_ERR("SPI3 not available");
856+
return -1;
857+
}
858+
859+
if (!device_is_ready(SPI3_CLK_DEV)) {
860+
return -ENODEV;
861+
}
862+
863+
// spi_success = spicommon_periph_claim(SPI3_HOST, "adc");
864+
clock_control_on(SPI3_CLK_DEV, SPI3_CLK_SUBSYS);
865+
// ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan);
866+
clock_control_on(SPI3_CLK_DEV, SPI3_DMA_CLK_SUBSYS);
867+
868+
int err = esp_intr_alloc(SPI3_DMA_INTR_SOURCE,
869+
ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED,
870+
adc_esp32_dma_intr_handler, (void *)dev, &(data->irq_handle));
871+
if (err != 0) {
872+
LOG_ERR("Could not allocate interrupt (err %d)", err);
873+
return err;
874+
}
875+
#endif /* CONFIG_SOC_SERIES_ESP32S2 */
876+
#endif /* CONFIG_ADC_ESP32_DMA */
713877

714878
for (uint8_t i = 0; i < SOC_ADC_MAX_CHANNEL_NUM; i++) {
715879
data->resolution[i] = ADC_RESOLUTION_MAX;
@@ -734,21 +898,16 @@ static DEVICE_API(adc, api_esp32_driver_api) = {
734898
.ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL,
735899
};
736900

737-
#define ADC_ESP32_CONF_GPIO_PORT_INIT .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
738-
739901
#if defined(CONFIG_ADC_ESP32_DMA)
740-
741-
#define ADC_ESP32_CONF_DMA_INIT(n) \
742-
.dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
743-
(DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0))), \
744-
(NULL)), \
745-
.dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
746-
(DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)), \
747-
(0xff)),
902+
#if SOC_GDMA_SUPPORTED
903+
#define ADC_ESP32_CONF_INIT(n) \
904+
.dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
905+
(DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0))), (NULL)), \
906+
.dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
907+
(DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)), (0xff))
748908
#else
749-
750-
#define ADC_ESP32_CONF_DMA_INIT(inst)
751-
909+
#define ADC_ESP32_CONF_INIT(n)
910+
#endif /* SOC_GDMA_SUPPORTED */
752911
#endif /* defined(CONFIG_ADC_ESP32_DMA) */
753912

754913
#define ADC_ESP32_CHECK_CHANNEL_REF(chan) \
@@ -764,7 +923,8 @@ static DEVICE_API(adc, api_esp32_driver_api) = {
764923
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, offset), \
765924
.unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \
766925
.channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \
767-
ADC_ESP32_CONF_GPIO_PORT_INIT ADC_ESP32_CONF_DMA_INIT(inst)}; \
926+
.gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)), \
927+
ADC_ESP32_CONF_INIT(inst)}; \
768928
\
769929
static struct adc_esp32_data adc_esp32_data_##inst = { \
770930
.hal = \

dts/xtensa/espressif/esp32/esp32_common.dtsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@
519519
compatible = "espressif,esp32-adc";
520520
reg = <0x3ff48800 10>;
521521
clocks = <&clock ESP32_SARADC_MODULE>;
522+
interrupt-parent = <&intc>;
522523
unit = <1>;
523524
channel-count = <8>;
524525
#io-channel-cells = <1>;

dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@
398398
compatible = "espressif,esp32-adc";
399399
reg = <0x3f440018 100>;
400400
clocks = <&clock ESP32_PERIPH_SARADC_MODULE>;
401+
interrupt-parent = <&intc>;
401402
unit = <1>;
402403
channel-count = <10>;
403404
#io-channel-cells = <1>;

0 commit comments

Comments
 (0)