ESAI send 2 slots in one frame

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ESAI send 2 slots in one frame

606 Views
tobias_mrs
Contributor III

Hello

I develop bare-metal on the i.MX6 and have to use the ESAI to send two 16 bit values in a 32 bit slot.
At the moment I have a working ESAI interface but my values are not send correct.
ESAI registers after init:
ESAI register dump:
ECR: 0x00000001
ESR: 0x00000500
TFCR: 0x000C020D
TFSR: 0x00000000
TCR: 0x0001C903
TCCR: 0x00E00200
TSMA: 0x00000003
TSMB: 0x00000000
PRRC: 0x00000C18
PCRC: 0x00000C18


No I would send  two 16 bit values
0xAAAA 0xBBBB

int write_esai_tx1( uint16_t value1, uint16_t value2 )
{
    writel( (uint32_t) value1, (void *) ESAI_BASE + ETDR ); 
    while( !( ( readl( (void *) ESAI_BASE + ESR ) ) & 0x00000100 ) )
         ; // wait for TFE bit

    writel( (uint32_t) value2, (void *) ESAI_BASE + ETDR );
    while( !( ( readl( (void *) ESAI_BASE + ESR ) ) & 0x00000100 ) )
        ; // wait for TFE bit

    return 0;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

but  as output on the TX1 line I get
0xAAAA 0xAAAA

Could anyone help me?
regards
Tobias

Labels (1)
0 Kudos
3 Replies

453 Views
tobias_mrs
Contributor III

Now I have a solution for my problem.
I have analyzed your example again and then I have changed my code a little bit.
The main problem was that I enabled the transmitter only one time and not before every send process.
Now I have a 32 bit frame with two 16bit slots and 8 MHz on TX1.
ESAI register dump:
ECR: 0x00000001
ESR: 0x00000100
TFCR: 0x000C0F0D
TFSR: 0x00000002
TCR: 0x00018900
TCCR: 0x00E00200
TSMA: 0x00000003
TSMB: 0x00000000
PRRC: 0x00000C18
PCRC: 0x00000C18
clock CCGR1 bit 16 17: 0xF03F0000

The send procedure is as follows:

int write_esai_tx1( uint16_t slot0, uint16_t slot1 )
{
    setb( 1, (void *) ESAI_BASE + TCR ); // set TE1 bit to send on TE1
    while( !( ( readl( (void *) ESAI_BASE + SAISR ) ) & (1<<14)) )
        ; // wait for TUE bit

    writel( 0, (void *) ESAI_BASE + ETDR ); // write to slot0 TX0
    writel( (uint32_t) slot0, (void *) ESAI_BASE + ETDR ); // write to slot0 TX1
    writel( 0, (void *) ESAI_BASE + ETDR );  // write to slot1 TX0
    writel( (uint32_t) slot1, (void *) ESAI_BASE + ETDR );  // write to slot1 TX1
    while( !( ( readl( (void *) ESAI_BASE + ESR ) ) & (1<<8) ) )
        ; // wait for TFE bit

    while( !( ( readl( (void *) ESAI_BASE + SAISR ) ) & (1<<14)) )
        ; // read SAISR TUE to clear transmit underrun error flag
    clearb( 1, (void *) ESAI_BASE + TCR ); // clear TE1 bit

    return 0;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

But I don't understand why I have the copied bits in the second frame.

oszi2.png

I also don't know how too use the watermark.
It don' change anything If I change the value.

regards

Tobias

0 Kudos

453 Views
tobias_mrs
Contributor III

Hello
I know that.
I'm sorry for the wrong formulation.
I would to send 2 16bit slots with 16bit words within 32bit.
That work for now. I have change my configuration.

For the moment I have enabled TX0 and TX1
ESAI register dump:
ECR: 0x00000001
ESR: 0x00000100
TFCR: 0x000C0F0D
TFSR: 0x00000000
TCR: 0x00018903
TCCR: 0x00E00200
TSMA: 0x00000003
TSMB: 0x00000000
PRRC: 0x00000C18
PCRC: 0x00000C18
clock CCGR1 bit 16 17: 0xF03F0000

But the main problem still exists.
If I would send 0xAAAA 0xBBBB, I get 0xAAAA 0xAAAA on TX0 and 0xBBBB 0xBBBB on TX1 line.

I have tried this send processes:

int write_esai_tx( uint16_t slot0, uint16_t slot1 )
{
   writel( (uint32_t) slot0, (void *) ESAI_BASE + ETDR ); 
   writel( (uint32_t) slot1, (void *) ESAI_BASE + ETDR ); 

   while( !( ( readl( (void *) ESAI_BASE + ESR ) ) & 0x00000100 ) )  
      ; // wait for TFE bit

   while( !( ( readl( (void *) ESAI_BASE + SAISR ) ) & 0x00004000 /*(1<<14)*/) )
        ; // read SAISR TUE to clear transmit underrun error flag
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

and also:

int write_esai_tx1( uint16_t slot0, uint16_t slot1 )
{ 
    writel( 0xEEEE, (void *) ESAI_BASE + ETDR );
    writel( (uint32_t) slot0, (void *) ESAI_BASE + ETDR );

    writel( 0xCCCC, (void *) ESAI_BASE + ETDR );
    writel( (uint32_t) slot1, (void *) ESAI_BASE + ETDR );

    while( !( ( readl( (void *) ESAI_BASE + ESR ) ) & 0x00000100 ) )
        ; // wait for TFE bit    while( !( ( readl( (void *) ESAI_BASE + SAISR ) ) & 0x00004000 /*(1<<14)*/) )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

with this one I get 0xCCCC 0xCCCC on TX0 line and 0xBBBB 0xBBBB on TX1 line

I guess I have done something wrong with the FIFO. But I don't find it.
I will try to use your example.

Best regards

Tobias

0 Kudos

453 Views
igorpadykov
NXP Employee
NXP Employee

Hi Tobias

for baremetal esai one can check attached sdk examples.

However one slot can have only one data, up to 24 bits only

according to Figure 25-2,3 ESAI Data Path i.MX6DQ Reference Manual

http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf

and Figure 4-4  AN1848 ENHANCED SERIAL AUDIO INTERFACE (ESAI)
http://cache.nxp.com/assets/documents/data/en/application-notes/AN1848.pdf

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos