KL46 I2S MCLCK question

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

KL46 I2S MCLCK question

Jump to solution
2,551 Views
jasonzhu
Contributor II

In use process, we found that the I2S' MCLCK  output frequency

is the same as the system clock, no matter how to set up 

registers of I2S related, all can't change the I2S MCLCK output

frequency.

Please who can provide the register operation related routines,which can

change the I2S MCLCK output frequency.

thanks

Tags (4)
1 Solution
2,013 Views
carlos_neri
NXP Employee
NXP Employee

There are some considerations for the I2S module on KL46. This is a smaller version from the one found on K60.

I wasn't able to find the code you attached on the last post, but I assume you want to use the fractional divider to get a proper MCLK (256*FS) from the internal PLL? If so, that won't be possible since the I2S module on KL46 does not support fractional dividers. From chapter 3 of the RM:

"The module's MCLK Divide Register (MDR) is not used to control MCLK generation"

That being said, there are 2 alternatives for this:

- Use a dedicated oscillator for the MCLK you need e.g. 12.288Mhz

- If you're using an audio codec that implements a PLL, you could output the crystal frequency (select OSCERCLK on I2S0_MCR[MICS]) and then configure the audio codec PLL to generate BCLK and LRCLK. In this case, KL46 will be the I2S slave. I've done this using the ARD-AUDIO-DA7212 and FDRM-KL46 and works pretty good.

View solution in original post

7 Replies
2,013 Views
perlam_i_au
Senior Contributor I

I would like to see your code, could you please share your project?

2,013 Views
jasonzhu
Contributor II

hi,

The attachment is the I2S initialization, code transplanted from K60.

Hope to be able to provide KL46 I2S routines

Thanks

0 Kudos
Reply
2,014 Views
carlos_neri
NXP Employee
NXP Employee

There are some considerations for the I2S module on KL46. This is a smaller version from the one found on K60.

I wasn't able to find the code you attached on the last post, but I assume you want to use the fractional divider to get a proper MCLK (256*FS) from the internal PLL? If so, that won't be possible since the I2S module on KL46 does not support fractional dividers. From chapter 3 of the RM:

"The module's MCLK Divide Register (MDR) is not used to control MCLK generation"

That being said, there are 2 alternatives for this:

- Use a dedicated oscillator for the MCLK you need e.g. 12.288Mhz

- If you're using an audio codec that implements a PLL, you could output the crystal frequency (select OSCERCLK on I2S0_MCR[MICS]) and then configure the audio codec PLL to generate BCLK and LRCLK. In this case, KL46 will be the I2S slave. I've done this using the ARD-AUDIO-DA7212 and FDRM-KL46 and works pretty good.

2,013 Views
creddy
Contributor I

Dear Carlos Neri

Seems you were able to use ARD-AUDIO-DA7212 and FDRM-KL46 for audio.

I'm also using same Hardware boards to see the USB Speakers demo.

Following the document below, but stuck at section 4.1

http://cache.nxp.com/files/32bit/doc/user_guide/USBSPRDUG.pdf

I could not find the  USB Speakers demo software on Freescale.

Could you please share it ?

Reddy

0 Kudos
Reply
2,013 Views
jasonzhu
Contributor II

hi,

Thank you for your help.

We now are ready to use audio chips that generates the clock signal .

Hope to be able to obtain results as soon as possible

0 Kudos
Reply
2,013 Views
ajaypatel
Contributor I

Hello All,

I also want to configure the I2S for KL46Z board. I want to implement the test in which I2S is integrated with audio codec chip SGTL5000. The aim of my test is to get the audio out from the KL46 using audio sgtl. I have following HW setup :

1. TWR-KL46Z board.

2. AUDIO-SGTL board.

3. TWR boards.

Please see below are the my configuration for the GPIO, I2C, I2s and DMA in my test for KL46Z. I have used the reference audio out test ( loopback test ) for the k60 and I have modified the PIN setting for the KL46Z.

GPIO :

SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK|SIM_SCGC5_PORTE_MASK|SIM_SCGC5_PORTC_MASK;
/* Configure SW 1 */
PORTA_PCR19 = PORT_PCR_IRQC(10)|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK|PORT_PCR_MUX(1);
u32fnNVIC_EnableIRQ((INT_PORTA-16UL));
PORTA_PCR4 = PORT_PCR_MUX(1);
PORTA_PCR5 = PORT_PCR_MUX(1);
PORTA_PCR12 = PORT_PCR_MUX(1);
PORTA_PCR13 = PORT_PCR_MUX(1);
GPIOC_PDDR |= (1 << 0);
GPIOA_PDDR |= (1 << 11);
GPIOA_PTOR |= (1 << 11);

I2C :

SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;
SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK | SIM_SCGC5_PORTB_MASK;
/* configure IIC registers */

    IIC_CLOCK_RATE(IIC_CLOCK_RATE_VALUE);

    IIC_CLOCK_DIV(IIC_CLOCK_DIV_VALUE);

    IIC_CONTROL_REGISTER = I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK; //enable IIC with interrupts

    /* initialize to idle all state machine variables */

u8IICDriverStatus |= (1<<IIC_FLAGS_IDLE);

    sIICStateMachine.ActualState = IIC_IDLE_STATE;

    sIICStateMachine.NextState = IIC_IDLE_STATE;

    sIICStateMachine.PrevState = IIC_IDLE_STATE;

/*Multiplexing of the IIC pin signals PTD8(SDL) and PTD9(SDA) with open drain enabled*/

    PORTB_PCR0 = PORT_PCR_MUX(2);

    PORTE_PCR25 = PORT_PCR_MUX(5);

/* enable IIC IRQ */
u32fnNVIC_EnableIRQ((INT_I2C0-16UL));

I2S :

/* Enable SSI CLK from SIM */

    SIM_SCGC6 |= SIM_SCGC6_I2S_MASK;

    SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK|SIM_SCGC5_PORTC_MASK;

    /* Enable SAI pins */

/* TX BCLK */

    PORTA_PCR5 |= PORT_PCR_MUX(0x6);

    /*TX Data line*/

    PORTA_PCR12 |= PORT_PCR_MUX(0x6);

    /*TX Frame Sync*/

    PORTA_PCR13 |= PORT_PCR_MUX(0x6);

    /* RX BCLK */

    PORTA_PCR14 |= PORT_PCR_MUX(0x6);

    /* RX Frame Sync */

    PORTA_PCR16 |= PORT_PCR_MUX(0x6);

    /* RX Data line*/

    PORTA_PCR15 |= PORT_PCR_MUX(0x6);

/*Tx*/
/* For using TX BLCK and FS CLK in synch mode, TX must be Asynch and Rx synch */
I2S_TCR2 = I2S_TCR2_SYNC(0)|I2S_TCR2_BCP_MASK;
I2S_MCR &= ~I2S_MCR_MOE_MASK;
/*transmit data channel 1 enabled */
I2S_TCR3 = I2S_TCR3_WDFL(0)|I2S_TCR3_TCE(1);
/* 2 slot on a frame, Fsynch of 32 clocks */
I2S_TCR4 =  I2S_TCR4_FRSZ(1)|I2S_TCR4_FSE_MASK|I2S_TCR4_SYWD(31)|I2S_TCR4_MF_MASK|I2S_TCR4_FSP_MASK;
I2S_TCR4 &= ~(I2S_TCR4_FSD_MASK);
/*32-bit first and following words */
I2S_TCR5 = I2S_TCR5_WNW(31)|I2S_TCR5_W0W(31)|I2S_TCR5_FBT(31);
/* enable DMA transfer on FIFO WM */
I2S_TCSR |= I2S_TCSR_FRDE_MASK|I2S_TCSR_FR_MASK;
/* RX */
I2S_RCR1 = I2S_RCR1_RFW((u32RxFIFOWm-1));
I2S_RCR2 = I2S_RCR2_SYNC(1);
I2S_RCR3 = I2S_RCR3_WDFL(0)|I2S_RCR3_RCE(1);

I2S_RCR4 =  I2S_RCR4_FRSZ(1)|I2S_RCR4_FSE_MASK|I2S_RCR4_SYWD(31)|I2S_RCR4_MF_MASK|I2S_RCR4_FSP_MASK;
I2S_RCR4 &= ~(I2S_RCR4_FSD_MASK);
I2S_RCR5 = I2S_RCR5_WNW(31)|I2S_RCR5_W0W(31)|I2S_RCR5_FBT(31);
I2S_RCSR |= I2S_RCSR_FRDE_MASK|I2S_RCSR_FR_MASK;

DMA :

memset(&state, 0, sizeof(dma_state_t));

    DMA_DRV_Init(&state);

    if (kDmaInvalidChannel == DMA_DRV_RequestChannel(channel_IN, kDmaRequestMux0AlwaysOn62, &chnState_IN))

     {

         printf("\r\nCannot request channel No. %d", channel_IN);

         DMA_DRV_Deinit();

         return;

     }

     // Configure a channel.

     DMA_DRV_ConfigTransfer(&chnState_IN,          

   kDmaPeripheralToMemory, 

                            4,      

                            (uint32_t)&I2S_RDR0,   /*source*/

                            (uint32_t)&gau32Audio_InputRingBuffer[0], /*destination*/

                            AUDIO_INPUT_RING_BUFFER_SIZE);

     // Add callback for dma handler

     DMA_DRV_RegisterCallback(&chnState_IN, vfnAudioBufferHandler_DMARxCallback, NULL);

     if (kDmaInvalidChannel == DMA_DRV_RequestChannel(channel_OUT, kDmaRequestMux0AlwaysOn63, &chnState_OUT))

      {

          printf("\r\nCannot request channel No. %d", channel_OUT);

          DMA_DRV_Deinit();

          return;

      }

      // Configure a channel.

      DMA_DRV_ConfigTransfer(&chnState_OUT,          

           kDmaMemoryToPeripheral,//kDmaMemoryToMemory, 

                             4,      

                             (uint32_t)&gau32Audio_OutputRingBuffer[0],   /*source*/

                             (uint32_t)&I2S_TDR0, /*destination*/

                             AUDIO_OUTPUT_RING_BUFFER_SIZE);

      // Add callback for dma handler

      DMA_DRV_RegisterCallback(&chnState_OUT, vfnAudioBufferHandler_DMATxCallback, NULL);

With all above initialization change, my test is still not working. I found that my DMA callbacks executes only once to transfer the data.

Please help me if I missed any configuration setting.

Please provide me if any working test available for KL46Z board works with audio SGTL.

Thanks in advance.

Ajay-

0 Kudos
Reply
2,013 Views
Wlodek_D_
Senior Contributor II

Hello,

Thank you for your post, however please consider moving it to the right community place (e.g. Kinetis Microcontrollers ) to get it visible for active members.

For details please see general advice Where to post a Discussion?

Thank you for using Freescale Community.