ESP, IoT Скетч ESP32 для управления бесконтроллерным ЖК дисплеем по протоколу I2S LCD-mode

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Доброго времени суток! Мне достался монохромный ЖК 320Х240 судя по даташиту, он бесконтроллерный и управляется интерфейсом I2S ( 4 линии данных и 3 управляющих сигнала : HS, VS, Frame/ горизонтальная синхронизация, вертикальная синхронизация и смена кадра) Я поначалу пробовал управлять им с помощью Wemos LGT8F и добился некоторых эффектов в виде заполнения экрана полосами, путем подачи ШИМ на управляющие линии, но для формирования изображения у wemos не хватает мощности и ресурсов, потомуобратил внимание на ESP32 WROOM, нашел на гитхабе несколько проектов, но все они оказались не рабочие. Теперь пытаюсь написать свой скетч с нуля: используя I2S DMA. Если кто связывался с чем-то подобным, подскажите куда копать.
 

Вложения

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
работа вам предстоит приличная, но вполне реализуемо.
Смотрите эту библиотеку. Она конечно не оч удобная в плане адаптации к другому протоколу, но смысл работы и механизмы инициализации i2s там понять можно. С учетом того что экран монохромный у вас всё будет сильно проще, можно использовать 8 битный i2s.
Можно еще посмотреть на LCD API, но я детально не разбирался оберткой над чем он является.
 
  • Лойс +1
Реакции: Наз

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
@poty, Вы путаете протоколы: I2C (читается: ай-ту-си) и I2S (читается : ай-сквер-эс), с первым и так всё ясно, со вторым дела обстоят сложнее: это стандарт разработанный Филипс для связи аудио устройств, в последствие адаптированный для параллельной передачи видеоданных.
 

poty

★★★★★★✩
19 Фев 2020
3,230
940
@Наз, да, с буквой перепутал, но I2S - тоже протокол последовательной передачи данных и требует только 3-х проводов.
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Добавлю ещё пару фоток дисплея, тем более сегодня на работе нашёл аналогичный, но с меньшим разрешением и люминисцентной подсветкой.
Питание аналогичное +5в для логики и -22вольта для матрицы, таже шина I2S( с этим надо разбираться, ковырять даташит в поисках распиновки). Питание матрицы (отрицательное относительно GND напряжение -22в) я реализовал на повышайке MT3608, поставив после дросселя кондер и полумост из шоттки. Если кому интересна тема бесконтроллерных дисплеев, могу выслать один по почте.
 

Вложения

  • Лойс +1
Реакции: vortigont

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
еще можете вот эту либу посмотреть - LovyanGFX. Она довольно сложная, но хорошо структурированна. Думаю врезать в нее свой i2s драйвер будет проще чем писать всё с нуля.
 
  • Лойс +1
Реакции: Наз

Геннадий П

★★★★★★✩
14 Апр 2021
1,969
632
44
Хватит уже называть параллельный интерфейс неправильным названием. I2S это стандарт передачи цифрового аудио сигнала, и к дисплеям никоим образом не относится.
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Нарыл на буржуйских сайтах код, он рассчитан на дисплей 240х160, но эта мелочь легко поправима, можно пересчитать тайминги и изменить частоты и объем буфера. Но проблема в другом, код не хочет компилироваться Arduino-ide ESP, постоянно жалуется на недостающие библиотеки хедеры. А так, случай почти мой:

Управление жк массивом:
#include <adc1_private.h>
#include <i2s.h>
#include <sdmmc_private.h>
#include <sdspi_crc.h>
#include <sdspi_private.h>

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"

#include "soc/i2s_struct.h"
#include "soc/i2s_reg.h"
#include "driver/periph_ctrl.h"
#include "soc/io_mux_reg.h"
#include "rom/lldesc.h"
#include "esp_heap_caps.h"
#include "i2s_parallel.h"

typedef struct {
    volatile lldesc_t* dmadesc_a;
    volatile lldesc_t* dmadesc_b;
    int desccount_a;
    int    desccount_b;
} i2s_parallel_state_t;

static i2s_parallel_state_t* i2s_state[2] = {NULL, NULL};

#define DMA_MAX (4096-4)


static int calc_needed_dma_descs_for(i2s_parallel_buffer_desc_t *desc) {
    int ret = (desc->size + DMA_MAX - 1)/DMA_MAX;
    return ret;
    }

static void fill_dma_desc(volatile lldesc_t* dmadesc, i2s_parallel_buffer_desc_t* bufdesc) {
    int n = 0;
    int len = bufdesc->size;
    uint8_t* data = (uint8_t*)bufdesc->memory;
    while(len) {
        int dmalen = len;
        if (dmalen > DMA_MAX) dmalen = DMA_MAX;
        dmadesc[n].size = dmalen;
        dmadesc[n].length = dmalen;
        dmadesc[n].buf = data;
        dmadesc[n].eof = 0;
        dmadesc[n].sosf = 0;
        dmadesc[n].owner = 1;
        dmadesc[n].qe.stqe_next = (lldesc_t*)&dmadesc[n+1];
        dmadesc[n].offset = 0;
        len -= dmalen;
        data += dmalen;
        n++;
        }
    
    dmadesc[n-1].qe.stqe_next=(lldesc_t*)&dmadesc[0];
    printf("fill_dma_desc: filled %d descriptors\n", n);
}

static void gpio_setup_out(int gpio, int sig, int inv) {
    if (gpio == -1) return;
    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
    gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT);
    gpio_matrix_out(gpio, sig, inv, false);
    }


static void dma_reset(i2s_dev_t *dev) {
    dev->lc_conf.in_rst=1;
    dev->lc_conf.in_rst=0;
    dev->lc_conf.out_rst=1;
    dev->lc_conf.out_rst=0;
    }

static void fifo_reset(i2s_dev_t *dev) {
    dev->conf.rx_fifo_reset=1;
    dev->conf.rx_fifo_reset=0;
    dev->conf.tx_fifo_reset=1;
    dev->conf.tx_fifo_reset=0;
    }

static int i2snum(i2s_dev_t *dev) {
    return (dev == &I2S0)? 0 : 1;
    }

void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg) {
    
    printf("Setting up parallel I2S bus at I2S%d\n", i2snum(dev));
    int sig_data_base, sig_clk;
    if (dev == &I2S0) {
        sig_data_base = I2S0O_DATA_OUT0_IDX;
        sig_clk = I2S0O_WS_OUT_IDX;
        }
    else {
        if (cfg->bits == I2S_PARALLEL_BITS_32 ) {
            sig_data_base = I2S1O_DATA_OUT0_IDX;
            }
        else
        if (cfg->bits == I2S_PARALLEL_BITS_8 ) {
            sig_data_base = I2S1O_DATA_OUT0_IDX;
            }
        else {
            
            sig_data_base = I2S1O_DATA_OUT8_IDX;
            }
        sig_clk = I2S1O_WS_OUT_IDX;
        }
    
    
    gpio_setup_out(cfg->gpio_bus[0], sig_data_base+0, false); // D0
    gpio_setup_out(cfg->gpio_bus[1], sig_data_base+1, false); // D1
    gpio_setup_out(cfg->gpio_bus[2], sig_data_base+2, false); // D2
    gpio_setup_out(cfg->gpio_bus[3], sig_data_base+3, false); // D3
    gpio_setup_out(cfg->gpio_bus[4], sig_data_base+4, false); // HS
    gpio_setup_out(cfg->gpio_bus[5], sig_data_base+5, false); // VS
    gpio_setup_out(cfg->gpio_bus[6], sig_data_base+6, false); // FR
        
    
    gpio_setup_out(cfg->gpio_clk, sig_clk, false);
    
    
    if (dev == &I2S0) {
        periph_module_enable(PERIPH_I2S0_MODULE);
        }
    else {
        periph_module_enable(PERIPH_I2S1_MODULE);
        }
    
    dev->conf.rx_reset = 1;
    dev->conf.rx_reset = 0;
    dev->conf.tx_reset = 1;
    dev->conf.tx_reset = 0;
    dma_reset(dev);
    fifo_reset(dev);
    
    
    dev->conf2.val = 0;
    dev->conf2.lcd_en = 1;
    dev->conf2.lcd_tx_wrx2_en = 1;
    dev->conf2.lcd_tx_sdx2_en = 0;
    
    dev->sample_rate_conf.val = 0;
    dev->sample_rate_conf.rx_bits_mod = cfg->bits;
    dev->sample_rate_conf.tx_bits_mod = cfg->bits;
    dev->sample_rate_conf.rx_bck_div_num = 4;
    dev->sample_rate_conf.tx_bck_div_num = 4;
    
    dev->clkm_conf.val = 0;
    dev->clkm_conf.clka_en = 0;
    dev->clkm_conf.clkm_div_a = 63;
    dev->clkm_conf.clkm_div_b = 63;
    
    dev->clkm_conf.clkm_div_num = 80000000L/cfg->clkspeed_hz;
    
    dev->fifo_conf.val = 0;
    dev->fifo_conf.rx_fifo_mod_force_en = 1;
    dev->fifo_conf.tx_fifo_mod_force_en = 1;
    dev->fifo_conf.tx_fifo_mod = 1;
    dev->fifo_conf.tx_fifo_mod = 1;
    dev->fifo_conf.rx_data_num = 32; 
    dev->fifo_conf.tx_data_num = 32;
    dev->fifo_conf.dscr_en = 1;
    
    
    
    dev->conf1.val = 0;
    dev->conf1.tx_stop_en = 0;
    dev->conf1.tx_pcm_bypass = 1;
    
    dev->conf_chan.val = 0;
    dev->conf_chan.tx_chan_mod = 1; // HN
    dev->conf_chan.rx_chan_mod = 1;
    
    
    dev->conf.tx_right_first = 1;
    dev->conf.rx_right_first = 1;
    
    dev->timing.val = 0;
    
    
    i2s_state[i2snum(dev)] = malloc(sizeof(i2s_parallel_state_t));
    i2s_parallel_state_t *st = i2s_state[i2snum(dev)];
    st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
    printf("st->descccount_a = %d\r\n", st->desccount_a);
    st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
    printf("st->descccount_b = %d\r\n", st->desccount_b);
    st->dmadesc_a = heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
    st->dmadesc_b = heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA);
    
    
    fill_dma_desc(st->dmadesc_a, cfg->bufa);
    fill_dma_desc(st->dmadesc_b, cfg->bufb);
    
    
    dev->lc_conf.in_rst = 1;
    dev->lc_conf.out_rst = 1;
    dev->lc_conf.ahbm_rst = 1;
    dev->lc_conf.ahbm_fifo_rst = 1;
    dev->lc_conf.in_rst = 0;
    dev->lc_conf.out_rst = 0;
    dev->lc_conf.ahbm_rst = 0;
    dev->lc_conf.ahbm_fifo_rst = 0;
    dev->conf.tx_reset = 1;
    dev->conf.tx_fifo_reset = 1;
    dev->conf.rx_fifo_reset = 1;
    dev->conf.tx_reset = 0;
    dev->conf.tx_fifo_reset = 0;
    dev->conf.rx_fifo_reset = 0;
    
    
    dev->lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN;
    dev->out_link.addr = ((uint32_t)(&st->dmadesc_a[0]));
    dev->out_link.start = 1;
    dev->conf.tx_start = 1;
    }



void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid) {
    int no = i2snum(dev);
    if (i2s_state[no] == NULL) return;
    lldesc_t *active_dma_chain;
    if (bufid == 0) {
        active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_a[0];
        }
    else {
        active_dma_chain = (lldesc_t*)&i2s_state[no]->dmadesc_b[0];
        }

    i2s_state[no]->dmadesc_a[i2s_state[no]->desccount_a-1].qe.stqe_next = active_dma_chain;
    i2s_state[no]->dmadesc_b[i2s_state[no]->desccount_b-1].qe.stqe_next = active_dma_chain;
    }
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
@Геннадий П, Это протокол передачи сигнала, а использовать его могут хоть для чтения ПЗУ в параллельном режиме.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,969
632
44
@Наз, I2S это конкретный протокол для передачи конкретных данных в определённом формате по определённым физическим линиям.
И да, по нему не получится ПЗУ читать, разные протоколы.
 
  • Лойс +1
Реакции: poty

poty

★★★★★★✩
19 Фев 2020
3,230
940
@vortigont,в datasheet, выдержки из которого приведены здесь, ни о каком I2S речи нет. Судя по описанию - модуль не имеет памяти и требует постоянной перезаписи информации на экране. Т.е., о "протоколе" можно говорить только с большой натяжкой.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
@poty, я имел ввиду i2s движек на есп32. Почему еспрессиф называет его i2s - я не знаю. Наверное потому что кроме всего прочего он умеет выводить и звук по протоколу филисового i2s. В выше приведенных ссылках на либы движек i2s используется для вывода данных на дисплеи и rgb панель
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Подобрал и установил нужные библиотеки, компиляция вроде запустилась, но выдала кучу ошибок в одной функции:
Функция с ошибками в нескольких блоках:
void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg) {
    
    printf("Setting up parallel I2S bus at I2S%d\n", i2snum(dev));
    int sig_data_base, sig_clk;
    if (dev == &I2S0) {
        sig_data_base = I2S0O_DATA_OUT0_IDX;
        sig_clk = I2S0O_WS_OUT_IDX;
        }
    else {    //errors begin
        if (cfg->bits == I2S_PARALLEL_BITS_32 ) {
            sig_data_base = I2S1O_DATA_OUT0_IDX;
            }
        else
        if (cfg->bits == I2S_PARALLEL_BITS_8 ) {
            sig_data_base = I2S1O_DATA_OUT0_IDX;
            }
        else {
            
            sig_data_base = I2S1O_DATA_OUT8_IDX;
            }
        sig_clk = I2S1O_WS_OUT_IDX;
        }
    
    
    gpio_setup_out(cfg->gpio_bus[0], sig_data_base+0, false); // D0
    gpio_setup_out(cfg->gpio_bus[1], sig_data_base+1, false); // D1
    gpio_setup_out(cfg->gpio_bus[2], sig_data_base+2, false); // D2
    gpio_setup_out(cfg->gpio_bus[3], sig_data_base+3, false); // D3
    gpio_setup_out(cfg->gpio_bus[4], sig_data_base+4, false); // HS
    gpio_setup_out(cfg->gpio_bus[5], sig_data_base+5, false); // VS
    gpio_setup_out(cfg->gpio_bus[6], sig_data_base+6, false); // FR
        
    
    gpio_setup_out(cfg->gpio_clk, sig_clk, false);
    
    
    if (dev == &I2S0) {
        periph_module_enable(PERIPH_I2S0_MODULE);
        }
    else {
        periph_module_enable(PERIPH_I2S1_MODULE);
        }
    
    dev->conf.rx_reset = 1;
    dev->conf.rx_reset = 0;
    dev->conf.tx_reset = 1;
    dev->conf.tx_reset = 0;
    dma_reset(dev);
    fifo_reset(dev);
    
    
    dev->conf2.val = 0;
    dev->conf2.lcd_en = 1;
    dev->conf2.lcd_tx_wrx2_en = 1;
    dev->conf2.lcd_tx_sdx2_en = 0;
    
    dev->sample_rate_conf.val = 0;
    dev->sample_rate_conf.rx_bits_mod = cfg->bits;
    dev->sample_rate_conf.tx_bits_mod = cfg->bits;
    dev->sample_rate_conf.rx_bck_div_num = 4;
    dev->sample_rate_conf.tx_bck_div_num = 4;
    
    dev->clkm_conf.val = 0;
    dev->clkm_conf.clka_en = 0;
    dev->clkm_conf.clkm_div_a = 63;
    dev->clkm_conf.clkm_div_b = 63;
    
    dev->clkm_conf.clkm_div_num = 80000000L/cfg->clkspeed_hz;
    
    dev->fifo_conf.val = 0;
    dev->fifo_conf.rx_fifo_mod_force_en = 1;
    dev->fifo_conf.tx_fifo_mod_force_en = 1;
    dev->fifo_conf.tx_fifo_mod = 1;
    dev->fifo_conf.tx_fifo_mod = 1;
    dev->fifo_conf.rx_data_num = 32; 
    dev->fifo_conf.tx_data_num = 32;
    dev->fifo_conf.dscr_en = 1;
    
    
    
    dev->conf1.val = 0;
    dev->conf1.tx_stop_en = 0;
    dev->conf1.tx_pcm_bypass = 1;
    
    dev->conf_chan.val = 0;
    dev->conf_chan.tx_chan_mod = 1; // HN
    dev->conf_chan.rx_chan_mod = 1;
    
    
    dev->conf.tx_right_first = 1;
    dev->conf.rx_right_first = 1;
    
    dev->timing.val = 0;
    
    
    i2s_state[i2snum(dev)] = malloc(sizeof(i2s_parallel_state_t));
    i2s_parallel_state_t *st = i2s_state[i2snum(dev)];
    st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
    printf("st->descccount_a = %d\r\n", st->desccount_a);
    st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
    printf("st->descccount_b = %d\r\n", st->desccount_b);
    st->dmadesc_a = heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
    st->dmadesc_b = heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA);
    
    
    fill_dma_desc(st->dmadesc_a, cfg->bufa);
    fill_dma_desc(st->dmadesc_b, cfg->bufb);
       //errors fin
    
    dev->lc_conf.in_rst = 1;
    dev->lc_conf.out_rst = 1;
    dev->lc_conf.ahbm_rst = 1;
    dev->lc_conf.ahbm_fifo_rst = 1;
    dev->lc_conf.in_rst = 0;
    dev->lc_conf.out_rst = 0;
    dev->lc_conf.ahbm_rst = 0;
    dev->lc_conf.ahbm_fifo_rst = 0;
    dev->conf.tx_reset = 1;
    dev->conf.tx_fifo_reset = 1;
    dev->conf.rx_fifo_reset = 1;
    dev->conf.tx_reset = 0;
    dev->conf.tx_fifo_reset = 0;
    dev->conf.rx_fifo_reset = 0;
    
    
    dev->lc_conf.val = I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN;
    dev->out_link.addr = ((uint32_t)(&st->dmadesc_a[0]));
    dev->out_link.start = 1;
    dev->conf.tx_start = 1;
    }
Такой отчет выдаёт Arduino.ide:
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino: In function 'void i2s_parallel_setup(i2s_dev_t*, const i2s_parallel_config_t*)':
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:288:18: error: 'const struct i2s_parallel_config_t' has no member named 'bits'
if (cfg->bits == I2S_PARALLEL_BITS_32 ) {
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:288:26: error: 'I2S_PARALLEL_BITS_32' was not declared in this scope
if (cfg->bits == I2S_PARALLEL_BITS_32 ) {
^~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:288:26: note: suggested alternative: 'I2S_PARALLEL_WIDTH_24'
if (cfg->bits == I2S_PARALLEL_BITS_32 ) {
^~~~~~~~~~~~~~~~~~~~
I2S_PARALLEL_WIDTH_24
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:292:18: error: 'const struct i2s_parallel_config_t' has no member named 'bits'
if (cfg->bits == I2S_PARALLEL_BITS_8 ) {
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:292:26: error: 'I2S_PARALLEL_BITS_8' was not declared in this scope
if (cfg->bits == I2S_PARALLEL_BITS_8 ) {
^~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:292:26: note: suggested alternative: 'I2S_PARALLEL_WIDTH_8'
if (cfg->bits == I2S_PARALLEL_BITS_8 ) {
^~~~~~~~~~~~~~~~~~~
I2S_PARALLEL_WIDTH_8
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:303:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[0], sig_data_base+0, false); // D0
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:304:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[1], sig_data_base+1, false); // D1
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:305:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[2], sig_data_base+2, false); // D2
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:306:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[3], sig_data_base+3, false); // D3
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:307:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[4], sig_data_base+4, false); // HS
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:308:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[5], sig_data_base+5, false); // VS
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:309:25: error: 'const struct i2s_parallel_config_t' has no member named 'gpio_bus'; did you mean 'gpios_bus'?
gpio_setup_out(cfg->gpio_bus[6], sig_data_base+6, false); // FR
^~~~~~~~
gpios_bus
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:336:46: error: 'const struct i2s_parallel_config_t' has no member named 'bits'
dev->sample_rate_conf.rx_bits_mod = cfg->bits;
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:337:46: error: 'const struct i2s_parallel_config_t' has no member named 'bits'
dev->sample_rate_conf.tx_bits_mod = cfg->bits;
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:346:50: error: 'const struct i2s_parallel_config_t' has no member named 'clkspeed_hz'
dev->clkm_conf.clkm_div_num = 80000000L/cfg->clkspeed_hz;
^~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:374:36: error: invalid conversion from 'void*' to 'i2s_parallel_state_t*' [-fpermissive]
i2s_state[i2snum(dev)] = malloc(sizeof(i2s_parallel_state_t));
Код:
~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:376:54: error: 'const struct i2s_parallel_config_t' has no member named 'bufa'
     st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
                                                      ^
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:376:58: error: 'calc_needed_dma_descs_for' cannot be used as a function
st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
^
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:378:54: error: 'const struct i2s_parallel_config_t' has no member named 'bufb'
st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:378:58: error: 'calc_needed_dma_descs_for' cannot be used as a function
st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
^
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:380:37: error: invalid conversion from 'void*' to 'volatile lldesc_t*' {aka 'volatile lldesc_s*'} [-fpermissive]
st->dmadesc_a = heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
Код:
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:381:37: error: invalid conversion from 'void*' to 'volatile lldesc_t*' {aka 'volatile lldesc_s*'} [-fpermissive]
     st->dmadesc_b = heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA);
                     ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:384:39: error: 'const struct i2s_parallel_config_t' has no member named 'bufa'
fill_dma_desc(st->dmadesc_a, cfg->bufa);
^~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:385:39: error: 'const struct i2s_parallel_config_t' has no member named 'bufb'
fill_dma_desc(st->dmadesc_b, cfg->bufb);
^~~~

exit status 1

Compilation error: 'i2s_parallel_buffer_desc_t' was not declared in this scope
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
Подобрал и установил нужные библиотеки
судя по всему подобрали неправильно, ищите там откуда сам код брали какие нужно к нему еще файлы.
struct i2s_parallel_config_t' has no member named 'bits' означает что в структуре нет такого члена. Найдите в каком .h файле декларируется эта структура и что там описано. Гугл нашел такой хедер, там bits определён. Однако это еще не значит что надо тащить его бездумно )
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
@vortigont, Спасибо. Поменял библиотеку i2s_parallel, целиком. Теперь выдвёт другую ошибку, жалуется на функцию:

/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino: In function 'void i2s_parallel_setup(i2s_dev_t*, const i2s_parallel_config_t*)':
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:374:36: error: invalid conversion from 'void*' to 'i2s_parallel_state_t*' [-fpermissive]
i2s_state[i2snum(dev)] = malloc(sizeof(i2s_parallel_state_t));
Код:
~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:376:54: error: 'const struct i2s_parallel_config_t' has no member named 'bufa'; did you mean 'buf'?
     st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
                                                      ^
buf
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:378:54: error: 'const struct i2s_parallel_config_t' has no member named 'bufb'; did you mean 'buf'?
st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
^~~~
buf
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:380:37: error: invalid conversion from 'void*' to 'volatile lldesc_t*' {aka 'volatile lldesc_s*'} [-fpermissive]
st->dmadesc_a = heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
Код:
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:381:37: error: invalid conversion from 'void*' to 'volatile lldesc_t*' {aka 'volatile lldesc_s*'} [-fpermissive]
     st->dmadesc_b = heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA);
                     ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/naz/Arduino/I2S_ESP32/I2S_ESP32.ino:385:39: error: 'const struct i2s_parallel_config_t' has no member named 'bufb'; did you mean 'buf'?
fill_dma_desc(st->dmadesc_b, cfg->bufb);
^~~~
buf

exit status 1

Compilation error: invalid conversion from 'int' to 'gpio_num_t' [-fpermissive]
В функции void, в этом блоке::
i2s_state[i2snum(dev)] = malloc(sizeof(i2s_parallel_state_t));
    i2s_parallel_state_t *st = i2s_state[i2snum(dev)];
    st->desccount_a = calc_needed_dma_descs_for(cfg->bufa);
    printf("st->descccount_a = %d\r\n", st->desccount_a);
    st->desccount_b = calc_needed_dma_descs_for(cfg->bufb);
    printf("st->descccount_b = %d\r\n", st->desccount_b);
    st->dmadesc_a = heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
    st->dmadesc_b = heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA);
    
    
    fill_dma_desc(st->dmadesc_a, cfg->buf);
    fill_dma_desc(st->dmadesc_b, cfg->bufb);
       //errors fin
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
ну мне так сложно что-то сказать по кускам кода вырваным откуда-то.
здесь должо быть

i2s_state[i2snum(dev)] = (i2s_parallel_state_t*)malloc(sizeof(i2s_parallel_state_t));

здесь полагаю
st->dmadesc_a = (lldesc_t*)heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA);
без деклараций не поймешь.

про это я не знаю,
Код:
error: 'const struct i2s_parallel_config_t' has no member named 'bufb'; did you mean 'buf'?
    fill_dma_desc(st->dmadesc_b, cfg->bufb);
опять вы, наверное, надергали куски из разных проектов и библиотек. Возмите за основу то что собирается, а не то что не собирается :)
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Сколько уже проектов нашел для I2s lcd, но ни один не собирается, компилятор обязательно выдает какую нибудь ошибку, а чаще всего целую кучу, вот и приходится рыться в навозных кучах нерабочего кода, пытаясь выбрать жемчужину.
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
приходится рыться в навозных кучах нерабочего кода, пытаясь выбрать жемчужину.
Пишите свой код, @vortigont вам верно говорит.
И еще - если вы затеяли сложный проект, то проявите больше настойчивости и желания разобратся самому, а не бегайте с каждой ошибкой на форум. Компилятор вам пишет описание ошибки - вот и пробуйте исправить.
 

Наз

✩✩✩✩✩✩✩
26 Фев 2024
9
1
Походу проблема в самом arduino ide, а точнее в дополнении ESP32. На нем не удалось даже blink скомпилировать, не подключает хедеры, не ищет библиотеки в esp components. Пробую переустановить , все равно бесполезно.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
542
Saint-Petersburg, Russia
Ну можно и нативный ESP IDF + cmake, но это реально неудобно. Платформио хорош тем что занимается скачиванием и установкой небходимыз версий тулов, библиотек и компонентов для проекта. Особенно если проект надо собирать в различных профилях.