i2s parallel only works with one dma descriptor

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Wed Nov 27, 2019 3:15 am

Hi,

However the i2s module is still sending twice as long.

It looks like the i2s module is sending the descriptor twice.

The D0 channel appears that weird data do not exist anymore.

Apparently the data is correct, the only problem is that data is being sent twice.

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Wed Nov 27, 2019 4:19 am

Hi,

The first burst of dma descriptor seems to be correct. 7680 bytes / 10 000 000 = 768 us.

After first burst of dma descriptor the 7680 bytes / 10 000 000 = 1536 us.


I filled the buffer with 0xFF00.

buffer_a are uint16_t.

Code: Select all

for ( uint32_t i = 0 ; i < 15360 ; i++ )
{        
    buffer_a[i].full = 0xFF00;  // FF byte more significant.  00 byte less significant.
}
The byte order of the first burst of dma descriptor(768 us) seems to be correct( ie: first clock rising edge = 0 and second clock rising edge = 1 ).

The byte order after first burst of dma descriptor(1536 us) seems to be reversed( ie: first clock rising edge = 1 and second clock rising edge = 0 ).

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Thu Nov 28, 2019 1:47 am

Hi,

Please Espressif team.

I've been trying for a long time to make this i2s module work.

I am using the clock source APLL_CLK.
When i enable clock PLL_D2_CLK, only firt burst work and i2s module freezes.

There are a lot of bugs in one single place.

I opened a technical inquire and i dont know if espressif will return to me.

Give me a light, please.


Thank's for the help.

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Thu Nov 28, 2019 10:30 pm

Hi,

Now i put "dma_tx_reset( )" after this instruction:

I2SX.fifo_conf.dscr_en = 0; // Set this bit to disable I2S DMA mode. (R/W).

example:
I2SX.fifo_conf.dscr_en = 0; // Set this bit to disable I2S DMA mode. (R/W).
dma_tx_reset( );

Code: Select all

static void dma_tx_reset( )
{   
    I2SX.lc_conf.out_rst = 1;    // Set this bit to reset out DMA FSM. (R/W)
    I2SX.lc_conf.out_rst = 0;    // FSM = Finite State Machine.
}

The first burst is apparently ok ( 768 us ) and data are ok.

All bursts after first burst now they have 768 us, but the first two bytes are inverted. The rest of bytes seem to be correct.

Example:

Code: Select all

uint16_t buffer_a[15360];  // the correct buffer size value is 3840 uint16_t, but this has no influence beyond memory waste.

for ( uint32_t i = 0 ; i < 15360 ; i++ )
{        
    buffer_a[i] = 0xFF00;  // FF most significant byte. 00 least significant byte.
}    
The first two bytes are inverted:
buffer_a[ 0 ].low = 0xFF;
buffer_a[ 0 ].high = 0x00;

The correct way:
buffer_a[ 0 ].low = 0x00;
buffer_a[ 0 ].high = 0xFF;

ESP_houwenxiang
Posts: 98
Joined: Tue Jun 26, 2018 3:09 am

Re: i2s parallel only works with one dma descriptor

Postby ESP_houwenxiang » Fri Nov 29, 2019 6:31 am

Hi,

I think it's no use to reset the tx fifo, can you try resetting the tx module with the following code?

Code: Select all

void i2s_reset(void)
{
        I2SX.conf.tx_reset = 1;
        I2SX.conf.tx_reset = 0;
}
wookooho

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Fri Nov 29, 2019 5:48 pm

Hi ESP_houwenxiang,

"I think it's no use to reset the tx fifo, can you try resetting the tx module with the following code ?"
I am already doing this.

Code: Select all

int i2s_lcd_write_data ( uint32_t length, bool buffer_id )  // length = number in bytes. length <= 7680.
{
    static uint32_t i;
    static uint8_t* ptr = NULL; 


    if ( length > pixels_size_in_bytes )    // Length > buffer capacity. pixels_size_in_bytes = 7680 bytes. 
    {
        printf( "Error: length > %d. \n\n", pixels_size_in_bytes );
        return -1;
    }     

    
    if ( buffer_id == 0 )    
    {   
        ptr = (uint8_t *) &buffer_a;    // buffer_a is uint16_t.

        /*
        printf( "\n&buf_a = %p\n", &buf_a );
        printf( "&buffer_a = %p\n", &buffer_a );
        printf( "ptr = %p\n\n", ptr );
        */

        for ( i = 0 ; i < length ; i = i + 2 )    // length <= 7680 bytes.  loop max 7680/2 = 3840 times.
        {        
            buf_a[ i ] = ptr[ i ];    // The address of buf_a increment in 4 bytes while the address of buffer_a(ptr) increment in 1 byte.
            buf_a[ i + 1 ] = ptr[ i + 1 ];

            /*           
            printf( "&ptr[ %d ] = %p\n", i, &ptr[ i ] );
            printf( "ptr[ %d ] = 0x%02X\n", i, ptr[ i ] );

            printf( "&ptr[ %d ] = %p\n", i+1, &ptr[ i+1 ] );
            printf( "ptr[ %d ] = 0x%02X\n", i+1, ptr[ i+1 ] );

            printf( "&buf_a[ %d ] = %p\n", i, &buf_a[ i ] );      
            printf( "buf_a[ %d ] = 0x%08X\n", i,  buf_a[ i ] );

            printf( "&buf_a[ %d ] = %p\n", i+1, &buf_a[ i+1 ] );
            printf( "buf_a[ %d ] = 0x%08X\n", i+1,  buf_a[ i+1 ] );           

            printf("\n");
            */
        }
    
        fill_dma_descriptor_a( (uint32_t) 4 * length );               // ( 4 * length ) = change from byte(8 bits) to word(32bits). 
        I2SX.out_link.addr = (uint32_t) &dma_desc_buf_a[0];    // ( (uint32_t) ( &dma_desc_buf_a[0] ) ) & I2S_OUTLINK_ADDR;  
    }
    else
    {
        ptr = (uint8_t *) &buffer_b;   

        for ( i = 0 ; i < length ; i = i + 2 )    
        {        
            buf_b[ i ] = ptr[ i ];    
            buf_b[ i + 1 ] = ptr[ i + 1 ];
        }         
         
        fill_dma_descriptor_b( (uint32_t) 4 * length );  
        I2SX.out_link.addr = (uint32_t) &dma_desc_buf_b[0];
    }


    I2SX.out_link.start = 1;          // Set this bit to start outlink descriptor. (R/W).
    I2SX.fifo_conf.dscr_en = 1;    // Set this bit to enable I2S DMA mode. (R/W).   
    I2SX.conf.tx_start = 1;          // Set this bit to start transmitting data. (R/W).  
    
    
    while ( ! ( I2SX.state.tx_idle ) )   // The status bit of the transmitter. 1: the transmitter is idle. 0: the transmitter is busy.(RO)
    { }
    

    I2SX.conf.tx_start = 0;           // Set this bit to start transmitting data. (R/W).    
    I2SX.fifo_conf.dscr_en = 0;    // Set this bit to enable I2S DMA mode. (R/W).


    tx_reset( );            // Set this bit to reset the transmitter. (R/W)
    dma_tx_reset( );    // Set this bit to reset out DMA FSM. FSM = Finite State Machine. (R/W)

/*
    I2SX.lc_conf.ahbm_rst = 1; 
    I2SX.lc_conf.ahbm_rst = 0;
    
    I2SX.lc_conf.ahbm_fifo_rst = 1;
    I2SX.lc_conf.ahbm_fifo_rst = 0;
*/

    return 2019;
}
I already tried with all possibilities with different sequential order using:
* tx_reset( );
* dma_tx_reset( );
* fifo_tx_reset( ):

And enable only tx_reset( ).
After tx_reset( ) and fifo_tx_reset( ) and dma_tx_reset( ) and so on.

I am try this to:

I2SX.lc_conf.ahbm_rst = 1;
I2SX.lc_conf.ahbm_rst = 0;

I2SX.lc_conf.ahbm_fifo_rst = 1;
I2SX.lc_conf.ahbm_fifo_rst = 0;


But nothing solved the problem.


Thank's for the help.

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Fri Nov 29, 2019 7:28 pm

Hi again,

Could these compiler warnings have any influence on this problem ?


#warning rom/lldesc.h is deprecated, please use esp32/rom/lldesc.h instead

#warning esp_intr.h is deprecated, please include esp_intr_alloc.h instead


Thank's.

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Fri Nov 29, 2019 8:07 pm

Hi,

I changed the headers:

#include "rom/lldesc.h"
#include "esp_intr.h"


To headers:

#include "esp32/rom/lldesc.h"
#include "esp_intr_alloc.h"


And the same problem persists.


Thank's.

ESP_houwenxiang
Posts: 98
Joined: Tue Jun 26, 2018 3:09 am

Re: i2s parallel only works with one dma descriptor

Postby ESP_houwenxiang » Mon Dec 02, 2019 2:29 am

Hi, Baldhead

Can you provide a simple project that can reproduce your issue? I don't need your entire project, just an example that can make I2S work in your configuration. The code you provided before is missing the I2S configuration and I cannot make it work in my environment. I would appreciate it if you could rearrange the issues you encountered.

thanks !!
wookooho

Baldhead
Posts: 79
Joined: Sun Mar 31, 2019 5:16 am

Re: i2s parallel only works with one dma descriptor

Postby Baldhead » Mon Dec 02, 2019 4:41 am

Hi,

I send the code via technical inquire. I can send via technical inquire again with the bugs that i encontered after send first time corrected.

Or i can send via private message maybe.

But at the moment i am traveling.

Here in Brazil are 1:37 hrs of sunday dawn to monday.

Thank's.

Who is online

Users browsing this forum: Google [Bot], MSN [Bot] and 8 guests