首页 > 解决方案 > 从 AVR 转移到 ESP32 r 使用 1 针和 SPI/DMA 控制 LED 灯条

问题描述

我正在开发一个基于 AVR 的旧项目,该项目使用 1 个引脚和 DMA 中的 SPI 高频控制 LED 条。(42 个 LED)

我正在将代码转换为 esp-idf,但我遇到了一些问题,可能基于总线/配置参数。

这些是代码:

AVR:

    USART_SPI_RGB_OPTIONS.baudrate = USART_SPI_RGB_BAUDRATE;
    USART_SPI_RGB_OPTIONS.spimode = USART_SPI_RGB_CHMODE;
    USART_SPI_RGB_OPTIONS.data_order = USART_SPI_RGB_DATA_ORDER;

    usart_init_spi(USART_SPI_RGB_PORT, &USART_SPI_RGB_OPTIONS);


void dma_init(void){
    struct dma_channel_config dmach_conf;
    memset(&dmach_conf, 0, sizeof(dmach_conf));
    dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
    dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
    dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
    dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_NONE_gc);
    dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
    dma_channel_set_source_address(&dmach_conf, (uint16_t)(uintptr_t)RGBMemoryMap);
    dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_FIXED_gc);
    dma_channel_set_destination_address(&dmach_conf, (uint16_t)(uintptr_t)USART_SPI_RGB_PORT.DATA);
    dma_channel_set_trigger_source(&dmach_conf, DMA_CH_TRIGSRC_USARTD0_DRE_gc);
    dma_channel_set_single_shot(&dmach_conf);
    dma_enable();
    dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
    dma_channel_enable(DMA_CHANNEL);
}

ESP-IDF:

void initSPISettings()
{
    //memset(&SPI_settings, 0, sizeof(SPI_settings));
    SPI_settings.host = HSPI_HOST,
    SPI_settings.dma_chan = SPI_DMA_CH2;
    
    // buscfg
    SPI_settings.buscfg.flags = 0;
    SPI_settings.buscfg.miso_io_num = -1;
    SPI_settings.buscfg.mosi_io_num = GPIO_NUM_32;
    SPI_settings.buscfg.sclk_io_num = -1;
    SPI_settings.buscfg.quadwp_io_num = -1;
    SPI_settings.buscfg.quadhd_io_num = -1;
    SPI_settings.buscfg.max_transfer_sz = LED_DMA_BUFFER_SIZE;
    
    // devcfg
    SPI_settings.devcfg.clock_speed_hz = DMA_SPEED;
    SPI_settings.devcfg.dummy_bits = 0;
    SPI_settings.devcfg.mode = 0;
    SPI_settings.devcfg.flags = SPI_DEVICE_NO_DUMMY;
    SPI_settings.devcfg.spics_io_num = -1;
    SPI_settings.devcfg.queue_size = 1;
    SPI_settings.devcfg.command_bits = 0;
    SPI_settings.devcfg.address_bits = 0;
}
void initSPI()
{
    esp_err_t err;
    
    initSPISettings();
    
    err = spi_bus_initialize(SPI_settings.host, &SPI_settings.buscfg, SPI_settings.dma_chan);
    ESP_ERROR_CHECK(err);

    //Attach the Accel to the SPI bus
    err = spi_bus_add_device(SPI_settings.host, &SPI_settings.devcfg, &SPI_settings.spi);
    ESP_ERROR_CHECK(err);

}

void updateRGB()
{
    spi_transaction_t t;
    esp_err_t err;
    
    printf("Start transaction to DMA...\r\n");

//  for (int i = (LED_DMA_BUFFER_SIZE - LED_RESET_COUNT); i < LED_DMA_BUFFER_SIZE; i++) {
//      //Setting more bytes to 0x00 at the end of memory map to assure correct RGB init
//      ledDMAbuffer[i] = 0x00; 
//  }

    t.flags = 0;
    t.length = LED_DMA_BUFFER_SIZE * 8;    //length is in bits
    t.tx_buffer = ledDMAbuffer;
    t.rx_buffer = NULL;
    t.rxlength = 0;
    
    err = spi_device_transmit(SPI_settings.spi, &t);
    ESP_ERROR_CHECK(err);
}

ledDMAbuffer = heap_caps_malloc(LED_DMA_BUFFER_SIZE, MALLOC_CAP_DMA);    // Critical to be DMA memory.

你有什么想法我想念的吗?我以正确的方式填写数据(我很确定)。如果我尝试控制 1 个 LED 完全没有问题,同时增加控制的 LED 数量我有奇怪的行为(例如,2 个 LED 闪烁红色/绿色,第一个工作正常,而第二个只是红色)

谢谢大家

标签: esp32leddmaesp-idf

解决方案


推荐阅读