Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Tue Dec 31, 2024 11:39 am

Dear espressif programmers,

I would like to trigger SPI DMA transmission by a GPIO - data ready DRDY falling edge from a SPI slave device. The DRDY is set by the SPI slave device every 1ms with 27 bytes of data ready to readout by the SPI master (ESP32-S3). The goal is to use DMA to automatically trigger SPI DMA transmittions in 27 bytes blocks to sequentially fill up two 1350 bytes ping-pong buffers and trigger an interrupt only when one of the ping-pong buffers is filled without the CPU interaction in each DRDY event.

1. Is it possible to directly connect a GPIO to trigger SPI DMA transmissions (e.g. by gpio_matrix_in) in ESP32-S3 ?
2. Or is it possible to use RMT module for this purpose instead ? Are there any disadvantages compared to direct GPIO-DMA connection ?
3. DMA-Controlled Configurable Segmented Transfer - is it possible to start transfer of individual segments using DMA RMT ?
4. Is there any other better solution ?

Thank you,
best regards,
Jan Kijonka

Bryght-Richard
Posts: 54
Joined: Thu Feb 22, 2024 3:59 pm

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Bryght-Richard » Tue Jan 07, 2025 12:02 am

I'm not sure if you could do this with the normal SPI+DMA, but you could implement this by using the ULP, which could monitor the GPIO and do the transfer for you.

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Thu Jan 09, 2025 9:10 am

Thank you for the suggested solution. As I can see, the ULP coprocessor does not have the capability to use the SPI interface; it would likely have to be solved by manually generating the clock and reading data using standard GPIO. For communication, I would need a clock of at least 1 MHz. The question would be the power consumption of the ULP module, as well as the accuracy of clock generation and reading data from the SPI slave module.

I'm currently able to generate RMT events (RX_DONE or EVENT_RX_THRES) to trigger a DMA channel. If a DMA channel could trigger SPI transmittion, it could be the solution. Could be it implemented by dma linked list descriptors ?

User avatar
ok-home
Posts: 111
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby ok-home » Thu Jan 09, 2025 2:24 pm

spi-dma master can only be started programmatically
The best solution is to put spi-dma in slave mode and your spi-slave device in master mode if possible.
If not, there's no prohibition against putting both devices into slave mode.
sclk can be generated by the mcpwm module with carier filling
https://docs.espressif.com/projects/esp ... rs-by-gpio
spi-dma will receive as much data as you want, interruptions can be received from dma itself, for example after processing one dma frame (1350), if you set such frame size in linkedlist.

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Wed Jan 15, 2025 6:59 pm

Thank you for suggestions for the solution! I am currently working on SPI DMA segmented transfer using one DMA channel and reading events on a GPIO pin by RMT using second DMA channel. Is it possible to synchronize DMA channels of these peripherals so that the RMT DMA channel triggers the SPI DMA channel by linked list of DMA descriptors?

PS: I came across segment-based SPI transfer in the ESP32-S3 reference manual, where a single execution of GPSPI2.cmd.usr = 1 can start any number of SPI transfers, and each segment can be configured during the DMA transfer without CPU intervention. This works.

User avatar
ok-home
Posts: 111
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby ok-home » Thu Jan 16, 2025 2:56 am

the dma channel is nothing more than an interface between the peripheral device and the memory,
it is fully controlled by the device to which it is connected,
if the device gives a command to write/read from the memory, the dma channel executes this command
by itself the dma channel cannot start the transfer, let alone transfer control to another dma channel/device.

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Fri Jan 17, 2025 3:28 pm

As I understand, my idea that the SPI descriptor would transition to the RMT descriptor, where the RMT RX END operation would be awaited (code shown below), is incorrect :-(. Therefore, I will attempt to implement the solution using your suggested approach. I will configure the ESP32-S3 as an SPI slave, with separate generation of the CS low enable signal and SPI CLK, because my external SPI devices do not support SPI master configuration. In fact, I will have two external SPI slave devices to communicate with, where data should be read from the first SPI device (CS device1 low) on the falling edge of DRDY, and then immediately from the second SPI device (CS device2 low). Both external SPI devices are synchronized by the CLK and generate the DRDY signal simultaneously.

spi_conf_desc[0].size = 12; // Size of SPI CONF buffer
spi_conf_desc[0].length = 12;
spi_conf_desc[0].buf = (uint8_t *)&spi_conf_buffer; // CONF buffer pointer
spi_conf_desc[0].sosf = 0;
spi_conf_desc[0].eof = 0;
spi_conf_desc[0].owner = 1;
spi_conf_desc[0].qe.stqe_next = &spi_data_desc[0]; // Go to SPI TX data

spi_data_desc[0].size = 1;
spi_data_desc[0].length = 1;
spi_data_desc[0].buf = (uint8_t *)&spi_tx_buffer[0]; // SPI TX buffer pointer
spi_data_desc[0].sosf = 0;
spi_data_desc[0].eof = 0;
spi_data_desc[0].owner = 1;
spi_data_desc[0].qe.stqe_next = &rmt_data_desc[0]; // Go to RMT RX data descriptor to WAIT for RMT TX END or THRESHOLD event

rmt_data_desc[0].size = 1;
rmt_data_desc[0].length = 1;
rmt_data_desc[0].buf = (uint8_t *)&rmt_rx_buffer[0]; // RMT RX data pointer
rmt_data_desc[0].sosf = 0;
rmt_data_desc[0].eof = 0;
rmt_data_desc[0].owner = 1;
rmt_data_desc[0].qe.stqe_next = &spi_conf_desc[0]; // GO back to the SPI CONF descriptor (LOOP)

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Sun Jan 19, 2025 9:49 am

Hello,
I'm trying a basic PWM generator, but there is some problem. If I add carrier filling block (the code below), there is always only the first pulse (1 us) generated on scope. I have tried various frequencies and settings of the mcpwm timer. The PWM is generated according to assumptions, but the carrier is not filling the PWM high/or low pulse.

// Add Carrier Filling
mcpwm_carrier_config_t carrier_config = {
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.first_pulse_duration_us = 1, // First pulse 1 us
.frequency_hz = 1000000, // Frekvence carrieru 1 MHz
// .flags.invert_before_modulate = true,
.duty_cycle = 30, // 30% duty cycle
};
ESP_ERROR_CHECK(mcpwm_operator_apply_carrier(oper, &carrier_config));
Attachments
main.c
(3.2 KiB) Downloaded 67 times

User avatar
ok-home
Posts: 111
Joined: Sun May 02, 2021 7:23 pm
Location: Russia Novosibirsk
Contact:

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby ok-home » Sun Jan 19, 2025 2:09 pm

Code: Select all

.duty_cycle = 30, // 30% duty cycle
should be

Code: Select all

.duty_cycle = 0.3, // 30% duty cycle
carrier.JPG
carrier.JPG (63.43 KiB) Viewed 1801 times

Honzik321
Posts: 47
Joined: Mon Apr 06, 2020 11:17 pm
Location: Czech Republic

Re: Start a SPI DMA transmission by GPIO trigger ? - ESP32-S3 Forum

Postby Honzik321 » Sun Jan 19, 2025 3:14 pm

Perfect, the carrier filling works now! Thank you! I'm adding my project main file. The GPIO 5 works now as sync for three PWM signals generated on GPIO 0, GPIO2 and GPIO 4. Signal on GPIO 0 is carrier filled (could be used as SCLK for SPI) and signal on GPIO 2 or 4 could be used as CS for SPI.

Could I ask how to now configure the triggering of PWM using the falling edge of DRDY? Or is the synchronization (GPIO 5) supposed to serve as a triggering mechanism for the SPI transfer, and the PWM high level should be sufficiently long to prevent another activation of CS between two DRDY signals?
Attachments
main_carrier.c
(7.84 KiB) Downloaded 56 times

Who is online

Users browsing this forum: No registered users and 20 guests