How to make DMA interrupt

z43740979
Posts: 17
Joined: Wed May 31, 2017 2:46 am

How to make DMA interrupt

Postby z43740979 » Tue Jun 20, 2017 1:09 am

Using IIS to make a music player . I need a interrupt when DMA send half data of buffer , but i dont find how to set the interrupt with ESP-IDF . I'd appreciate a little help :D :D :D

cnlohr
Posts: 65
Joined: Sat Dec 03, 2016 5:39 am

Re: How to make DMA interrupt

Postby cnlohr » Tue Jun 20, 2017 3:39 am

I've got some I2S examples here:

https://github.com/cnlohr/esp32-cnlohr- ... aster/main

Just uncomment the lines that enable the interrupt in i2s_fill_buf... and it should start making that call!

You will have to look at what's actually being sent in as the last DMA element.

In order to detect "half full" you can just load up multiple DMA elements as some get finished, you can replenish them.

z43740979
Posts: 17
Joined: Wed May 31, 2017 2:46 am

Re: How to make DMA interrupt

Postby z43740979 » Thu Jun 29, 2017 3:22 am

Thanks for ur dem sir :)
But can we call some library functions instead of configuring the registers :? :? :?

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: How to make DMA interrupt

Postby ESP_Sprite » Thu Jun 29, 2017 6:48 am

You can make use of the I2S driver as is implemented in esp-idf already. It has a bunch of buffers and implements these in such a way that all you have to do is to push data into the driver; it'll handle the flow control based on DMA interrupts all by itself.

z43740979
Posts: 17
Joined: Wed May 31, 2017 2:46 am

Re: How to make DMA interrupt

Postby z43740979 » Thu Jun 29, 2017 8:53 am

yeah~ I did it ,thanks for ur idea

FloridaMan
Posts: 4
Joined: Tue Sep 29, 2020 3:45 pm

Re: How to make DMA interrupt

Postby FloridaMan » Wed Oct 21, 2020 6:59 pm

Just thought I'd add to this thread. The DMA stuff in ESP32 took me a minute to wrap my head around and I think I've got it figured out. It seems that setting the .eof flag to 1 in the lldesc_t will fire an interrupt on I2Sx.int_ena.eof_out when enabled. It doesn't have to literally be the EOF and I've found it to be a good way to set a position in the buffer chain to fire an interrupt. I assume the interrupt fires at the end of the buffer's RX or TX.

The important thing to understand is the lldesc_t struct and how it relates to DMA.

Code: Select all

//This is in "rom/lldesc.h"
typedef struct lldesc_s {
    volatile uint32_t size  :12,
                        length:12,
                        offset: 5, /* h/w reserved 5bit, s/w use it as offset in buffer */
                        sosf  : 1, /* start of sub-frame */
                        eof   : 1, /* end of frame */
                        owner : 1; /* hw or sw */
    volatile uint8_t *buf;       /* point to buffer data */
    union{
        volatile uint32_t empty;
        STAILQ_ENTRY(lldesc_s) qe;  /* pointing to the next desc */
    };
} lldesc_t;
lldesc_t is a linked list. I based my work the esp_parallel example provided by ESP_Sprite and make the assumptions that he was correct in his sizes, et cetera. While the .size field is 12 bits, MAX_DMA as ESP_Sprite defined it was 4096-4, so 4092 bytes.

Who is online

Users browsing this forum: Google [Bot] and 122 guests