#esp32 #led #dma #esp-idf
Вопрос:
я работаю над старым проектом, основанным на AVR, который управляет светодиодной полосой, используя 1 вывод с высокой частотой SPI в DMA. (42 светодиода)
Я преобразую код в 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, amp;USART_SPI_RGB_OPTIONS);
void dma_init(void){
struct dma_channel_config dmach_conf;
memset(amp;dmach_conf, 0, sizeof(dmach_conf));
dma_channel_set_burst_length(amp;dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
dma_channel_set_transfer_count(amp;dmach_conf, DMA_BUFFER_SIZE);
dma_channel_set_src_reload_mode(amp;dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
dma_channel_set_dest_reload_mode(amp;dmach_conf, DMA_CH_DESTRELOAD_NONE_gc);
dma_channel_set_src_dir_mode(amp;dmach_conf, DMA_CH_SRCDIR_INC_gc);
dma_channel_set_source_address(amp;dmach_conf, (uint16_t)(uintptr_t)RGBMemoryMap);
dma_channel_set_dest_dir_mode(amp;dmach_conf, DMA_CH_DESTDIR_FIXED_gc);
dma_channel_set_destination_address(amp;dmach_conf, (uint16_t)(uintptr_t)USART_SPI_RGB_PORT.DATA);
dma_channel_set_trigger_source(amp;dmach_conf, DMA_CH_TRIGSRC_USARTD0_DRE_gc);
dma_channel_set_single_shot(amp;dmach_conf);
dma_enable();
dma_channel_write_config(DMA_CHANNEL, amp;dmach_conf);
dma_channel_enable(DMA_CHANNEL);
}
ESP-IDF:
void initSPISettings()
{
//memset(amp;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, amp;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, amp;SPI_settings.devcfg, amp;SPI_settings.spi);
ESP_ERROR_CHECK(err);
}
void updateRGB()
{
spi_transaction_t t;
esp_err_t err;
printf("Start transaction to DMA...rn");
// 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, amp;t);
ESP_ERROR_CHECK(err);
}
ledDMAbuffer = heap_caps_malloc(LED_DMA_BUFFER_SIZE, MALLOC_CAP_DMA); // Critical to be DMA memory.
У тебя есть какие-нибудь идеи, чего мне не хватает?
Я заполняю данные правильно (я в этом уверен). Если я попытаюсь управлять 1 светодиодом, никаких проблем не возникнет, при увеличении количества управляемых светодиодов у меня будет странное поведение (например, когда 2 светодиода мигают красным/зеленым, первый работает правильно, а второй просто красный).
Thanks to all