ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Sat Feb 11, 2023 11:07 am

Hy,
I'm trying to use DMA on my ESP32-WROOM-32U-N16 and I'm new to this topic.
1) Can the chip do that at all?... I can't find anything about it in the documentation.
https://www.espressif.com/sites/default ... eet_en.pdf
2) why is the <driver/dma.h> not in my Arduino IDE?
3) Are there any other instructions or things worth knowing about this topic?

please support and your expertise.

thx

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

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby ESP_Sprite » Sun Feb 12, 2023 1:31 am

What specifically do you want to use DMA for? It's generally already integrated in the drivers that benefit from it.

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Sun Feb 12, 2023 9:12 am

That's good news... since it's not in the Arduino IDE library, I was afraid that this wasn't possible.
I would like to take 20 cyclic measurements of the input value from an ADC in 1 millisecond and then the values can be further processed by the user program.
The aim is to capture the high value of a 1kHz PWM signal even if the duty cycle is only 5%, i.e. 5 microseconds.

Unfortunately, interrupt functions or mcpwm do not bring stable results.
I think that's possible with DMA right?
I'm just beginning to read the documentation... what needs to be considered?

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

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby ESP_Sprite » Sun Feb 12, 2023 2:24 pm

I honestly don't quite know if the Arduino SDK has any support for this (don't know that SDK that well), but ESP-IDF does; on the ESP32, you use the I2S peripheral to DMA data from the ADC. There's an example here: https://github.com/espressif/esp-idf/tr ... 2s_adc_dac , or here https://github.com/espressif/esp-idf/tr ... nuous_read for newer SDKs. Arduino is based on ESP-IDF, so if you don't want to switch, you may be able to import one of those examples into your Arduino code somehow.

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Mon Feb 13, 2023 6:32 am

Thanks for the link but can I do something with it? These are roof instructions for ESP-IDF in a requesting environment than Arduino IDE?

MicroController
Posts: 1705
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby MicroController » Thu Feb 16, 2023 1:20 pm

Using an ADC to sample a PWM signal does not sound right. - It could make sense if you feed the PWM through an LPF to convert it to an analog signal.
Why/how does the MC PWM's capture feature fail to meet your requirements?
Alternatively, have you looked into using the RMT peripheral's receiver?

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Thu Feb 16, 2023 9:48 pm

Thanks for your answer.
MCPWM is not entirely out of the question.
But thanks for the tip with RMT. I still have absolutely no idea how to do this, but it seems promising.
The way I read it, it's something similar to generating a PWM, just the other way around for reading. at least you can use it for that.

But how exactly does that work with RMT... do you have an example code for me? I'm just pondering a bit.....

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Fri Feb 17, 2023 7:28 am

I have now managed to use the RMT function to access data from my GPIO, but the output only shows 1,1,1,1,1,1.
Now how do I make it write the analog value 0 - 4096 of this GPIO to the buffer?

Here my code:
short explanation. A 1kHz signal is generated with GPIO 32 and read back on GPIO 35. Now the analogue value (0-4096) should be written into the buffer.

Code: Select all

#include <Arduino.h>
#include <esp_err.h>
#include <esp_log.h>
#include <driver/rmt.h>
#include <driver/periph_ctrl.h>
#include <soc/rmt_reg.h>

// PWM
#define PWM1_Ch       0
#define PWM1_Res      10     // 10 bits = 1024 levels = 0,05859375A per step
#define PWM1_Freq     1000   // 980 - 1020 range, 1000 nominal
int PWM1_DutyCycle =  1000;  // 0= -12V  1000= 12V
#define CTRL_PILOT    32
#include <driver/adc.h>


//#define DATA_433 GPIO_NUM_35

#define ADC1_GPIO (adc1_channel_t)35
#define RMT_RX_CHANNEL RMT_CHANNEL_0
#define RMT_TICK_10_US (80000000/RMT_CLK_DIV/100000) /*!< RMT counter value for 10 us.(Source clock is APB clock) */

void setup() {
   Serial.begin(115200);

 adc1_config_width(ADC_WIDTH_BIT_12);
 adc1_config_channel_atten(ADC1_GPIO, ADC_ATTEN_DB_11); 


  // Configure RMT
  rmt_config_t rmt_rx;
  rmt_rx.channel = (rmt_channel_t)RMT_RX_CHANNEL;          // RMT channel
  rmt_rx.gpio_num = (gpio_num_t)ADC1_GPIO;     // GPIO pin
  rmt_rx.clk_div = 80;               // Clock divider
  rmt_rx.mem_block_num = 1;                   // number of mem blocks used
  rmt_rx.rmt_mode = RMT_MODE_RX;              // Receive mode
  rmt_rx.rx_config.filter_en = false;          // Enable filter
//  rmt_rx.rx_config.filter_ticks_thresh = 100; // Filter all shorter than 100 ticks
  rmt_rx.rx_config.idle_threshold = 1000;     // Timeout after 2000 ticks
  rmt_config(&rmt_rx);                        // Init channel
  rmt_driver_install(rmt_rx.channel, 4000, 0); // Install driver with ring buffer size 1000
  rmt_rx_start(RMT_RX_CHANNEL, true);

  ledcAttachPin(CTRL_PILOT, PWM1_Ch);
  ledcSetup(PWM1_Ch, PWM1_Freq, PWM1_Res);
  ledcWrite(PWM1_Ch, 500);    
  
}

void loop() {
 RingbufHandle_t rb = NULL;
  uint32_t cnt = 0;

      Serial.print("\n\rTEST");


  // Get RMT RX ring buffer
  rmt_get_ringbuf_handle(RMT_RX_CHANNEL, &rb);

  if (rb) {
    size_t rx_size = 0;
    rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);

    while (item) {
      for (uint32_t i = 0; i < rx_size / sizeof(rmt_item32_t); i++) {
        Serial.print(item[i].duration0);
        Serial.print(",");
      }
      Serial.println();

      vRingbufferReturnItem(rb, (void*) item);
      item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);
    }
  }

  delay(100);
 /*
    RingbufHandle_t rb = NULL;
    uint32_t cnt = 0;
    //get RMT RX ringbuffer
    rmt_get_ringbuf_handle((rmt_channel_t)RMT_RX_CHANNEL, &rb);
    rmt_rx_start((rmt_channel_t)RMT_RX_CHANNEL, 1);
    if(rb) {
        size_t rx_size = 0;
        //try to receive data from ringbuffer.
        //RMT driver will push all the data it receives to its ringbuffer.
        //We just need to parse the value and return the spaces of ringbuffer.
        rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);
        while(item) {
          char buffer[120];
          rmt_item32_t *it = item;

          for(uint32_t i=0;i<rx_size/sizeof(rmt_item32_t);i++)
          {
             Serial.print("here");         
            Serial.print(buffer);
            it++;
          }
          vRingbufferReturnItem(rb, (void*) item);
          item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 500);
        }
      }
      Serial.println("No more items.");

      */
}

sevi_at
Posts: 8
Joined: Fri Feb 10, 2023 9:39 pm

Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)

Postby sevi_at » Fri Feb 17, 2023 1:44 pm

it's me again. I've now dealt with the structure rmt_item32_t very intensively and I don't think that analogues will be able to be read out directly with RMT functions. Am I correct?

Code: Select all

ypedef struct {
    union {
        struct {
            uint32_t duration0:15;      /*!< duration of RMT carrier */
            uint32_t level0:1;           /*!< level of RMT carrier */
            uint32_t duration1:15;      /*!< duration of RMT carrier */
            uint32_t level1:1;           /*!< level of RMT carrier */
        };
        uint32_t val;
    };
} rmt_item32_t;
Please advise how I can read an attachment value with RMT.

Who is online

Users browsing this forum: No registered users and 95 guests