Code: Select all
#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_private/gdma.h"
#include "hal/gdma_ll.h"
#include "hal/gdma_types.h"
#include "hal/dma_types.h"
#include "hal/gdma_hal.h"
#include "esp_heap_caps.h"
#include "soc/gdma_struct.h"
#include "soc/gdma_channel.h"
#include "freertos/FreeRTOS.h"
#include "freertos/Task.h"
//static const char *TAG = "GDMA_Memory_Transfer";
// Source and destination memory addresses
#define BUF_SIZE 1024
dma_descriptor_t *tx_desc;
char *tx_dma_buf = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod mi eget elit fermentum, sit amet hendrerit purus ornare. Etiam congue diam quis mauris auctor malesuada\n"
"In non mauris ligula. Donec maximus enim in sapien convallis gravida. Phasellus at ipsum ultricies, gravida neque vel, venenatis libero. Sed faucibus placerat consectetur. Nunc\n"
"tincidunt dui non felis accumsan commodo sed id magna.\n"
"Donec sit amet odio sit amet ante iaculis fringilla a laoreet tellus. Cras purus massa, sagittis rutrum euismod at, auctor eget neque. Sed eget velit id massa volutpat convallis\n"
"quis vitae nibh. Quisque egestas, nisi nec pretium eleifend, arcu massa congue arcu, quis eleifend lorem arcu ac nunc. Nullam tempus nulla eget suscipit ultrices. Morbi suscipit\n"
"tortor a augue feugiat, at faucibus lectus gravida. Vestibulum non dapibus nulla.\n"
"Fusce eu lacinia lorem. Vestibulum mollis metus consectetur, consectetur mi at, tempor justo. Aliquam bibendum pretium eros, eu imperdiet augue fermentum feugiat. Pellentesque\n"
"est.\r\n";
char *rx_dma_buf = (char *)malloc(sizeof(*tx_dma_buf));
gdma_channel_handle_t gdma_handle_mem2mem; // Mem to Mem handle DMA channel
static IRAM_ATTR bool dma_callback(gdma_channel_handle_t dma_chan,
gdma_event_data_t *event_data,
void *user_data)
{
// DMA callback seems to occur a moment before the last data has issued
// (perhaps buffering between DMA and the LCD peripheral?), so pause a
// moment before clearing the lcd_start flag. This figure was determined
// empirically, not science...may need to increase if last-pixel trouble.
// lastBitTime is NOT set in the callback because it would periodically
// have a 'too early' value. Instead, it's set in the show() function
// after the lcd_start flag is clear...which shouldn't make a difference,
// but does. The result is that it's periodically 'too late' in that
// case...but this just results in an infrequent slightly-long latch,
// rather than a too-short one that could cause refresh problems.
return true;
}
esp_err_t buf_gdma_init(void)
{
esp_err_t ret;
gdma_channel_alloc_config_t config_tx_dma_buf =
{
.sibling_chan = NULL,
.direction = GDMA_CHANNEL_DIRECTION_TX,
.flags =
{
.reserve_sibling = 0
},
};
GDMA.channel[0].out.conf0.out_rst = 1;
//GDMA.channel[0].in.conf0.in_rst = 1;
ret = gdma_new_channel(&config_tx_dma_buf, &gdma_handle_mem2mem);
if(ret != ESP_OK)
{
printf("error ret = %d \n",ret);
}
gdma_connect(gdma_handle_mem2mem,GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M,0));// trig_periph.instance_id ==2 // gdma_types.h
gdma_strategy_config_t strategy_config =
{
.owner_check = false,
.auto_update_desc = false,
};
gdma_apply_strategy(gdma_handle_mem2mem, &strategy_config);
gdma_tx_event_callbacks_t tx_cbs = {.on_trans_eof = dma_callback};
gdma_register_tx_event_callbacks(gdma_handle_mem2mem, &tx_cbs, NULL);
tx_desc = (dma_descriptor_t*)heap_caps_calloc(1, (sizeof(dma_descriptor_t)), MALLOC_CAP_DMA);
tx_desc->dw0.size = BUF_SIZE;
tx_desc->dw0.length = BUF_SIZE;
tx_desc->dw0.suc_eof = 1;
tx_desc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
tx_desc->buffer = tx_dma_buf;
tx_desc->next = tx_desc;
ret = gdma_get_channel_id(gdma_handle_mem2mem, (int*)rx_dma_buf);
if(ret==ESP_OK)
{
printf("channel_id = 0x%X \n",(int)rx_dma_buf);
//printf("channel_id = %s \n",(char*)rx_dma_buf[0]);
}
gdma_start( gdma_handle_mem2mem, (uint32_t)&tx_dma_buf);
//GDMA.channel[0].in.conf0.mem_trans_en = 1;
GDMA.channel[0].out.conf0.out_data_burst_en = 1;
//GDMA.channel[0].out.conf0.outdscr_burst_en = 1;
return ESP_OK;
}
extern "C" void app_main(void)
{
// Copy data to tx_dma_buf
int i=0;
buf_gdma_init();
while(1)
{
if(i==1023)
i=0;
vTaskDelay(pdMS_TO_TICKS(1000));
printf("%c -> %c \n",tx_dma_buf[i],rx_dma_buf[i]);
i+=1;
}
vTaskDelay(pdMS_TO_TICKS(1000));
}