ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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
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
-
- Posts: 9727
- Joined: Thu Nov 26, 2015 4:08 am
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
What specifically do you want to use DMA for? It's generally already integrated in the drivers that benefit from it.
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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?
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?
-
- Posts: 9727
- Joined: Thu Nov 26, 2015 4:08 am
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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.
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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?
-
- Posts: 1705
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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?
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?
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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.....
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.....
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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.
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.");
*/
}
Re: ESP32-WROOM-32U-N16 -> DMA (Direct Memory Access)
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?
Please advise how I can read an attachment value with RMT.
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;
Who is online
Users browsing this forum: No registered users and 81 guests