Hi everybody.
I’m facing to a problem with the SAI controller on a MPC5748G target.
I’m trying to configure the SAI controller to communicate with a DAC (ADAU1962) via an I2S bus. I want to push wav data on the DAC.
To do that, I followed the AN4800 which described the I2S configuration on a Kinetis target. The I2S controller seems to be the same.
When the software writes data on the I2S controller, I see that the FIFO Write counter is incremented but FIFO data are never consumed and nothing happens on I2S line.
To configure the MCLK, I used the FXOSC (40MHz) as the entry and I set the I2S0_MDR register to build a 12,288MHz (FRAC/DIVIDE = 192/625). I used this clock to manage 24 bits data samples at 32k.
The GPIOs seem to be rightly configured because, as soon as the I2S0_TCR2[BCP] is set to 1, the BCLK line state is changed. And as soon as the I2S0_TCR4[FSP] is set to 1 the SYNC line is changed too.
But, when the I2S0_TDR0 register is written, The I2S0_TFR0[WFP] field is incremented but no Data, SYNC nor BCLK line state is changed. SYNC and BCLK lines are stucked to high state and DATA line is stucked to low state.
Do you think the problem is due to a wrong clock configuration or something else I forgot to set in the target?
Regards,
Yoann
PS : hereafter is the I2S init sequence
/* Set SAI IO */
SIUL2.MSCR[PF1].R = 0x22800004; /* SAI0_BCLK (Out) (Pin 81) */
SIUL2.IMCR[488].R = 0x1;
SIUL2.MSCR[PF0].R = 0x20880007; /* SAI0_MCLK (In) (Pin 80) */
SIUL2.IMCR[489].R = 0x1;
SIUL2.MSCR[PB10].R = 0x22800004; /* SAI0_SYNC (Out) (Pin 26) */
SIUL2.IMCR[490].R = 0x1;
SIUL2.MSCR[PF5].R = 0x23800004; /* SAI0_D0 (Out) (Pin 85) */
SIUL2.IMCR[491].R = 0x1;
/* Set Clocks ratios */
pt_sai->pt_i2s->MCR.R =
(1<<30)| // MCLK divider enable
(2<<24); // MCLK SRC = FXOSC (40MHz)
//I2SClk = input *[(FRACT+1) / (DIVIDE+1) ] = (40MHz * (192/625)) = 12288000MHz
pt_sai->pt_i2s->MDR.B.FRACT = 192-1;
pt_sai->pt_i2s->MDR.B.DIVIDE = 625-1;
pt_sai->pt_i2s->TCR2.R = 7; // I2SClk/(32K*24bits) = 16, 16 = (DIV+1)*2, DIV = 7
pt_sai->pt_i2s->TCR1.R = 2; // water mark
pt_sai->pt_i2s->TCR2.R |=
(0<<30) | // Master mode(Async mode)
(1<<26) | // MSEL = MCLK
(1<<25) | // CLK = drive on falling edge
(1<<24) ; // CLK = OUTPUT (Master mode)
pt_sai->pt_i2s->TCR3.R = (1<<16); // enable channel 0
pt_sai->pt_i2s->TCR4.R =
((I2S_CONFIG_WORDS_IN_A_FRAME-1)<<16) | // words in a frame
((I2S_CONFIG_BITS_IN_A_WORD -1)<<8) | // bits in a word
(1<<4) | // MSB
(1<<3) | // frame sync asserts one bit before the first bit of the frame
(1<<1) | // frame sync active low
(1<<0) ; // frame sync generated internally (Master mode)
pt_sai->pt_i2s->TCR5.R =
((I2S_CONFIG_BITS_IN_A_WORD-1) <<24) | // word N width
((I2S_CONFIG_BITS_IN_A_WORD-1) <<16) | // word 0 width
(0x17<<8); // right adjust, where the first bit starts
// (0x1F<<8); // right adjust, where the first bit starts
pt_sai->pt_i2s->TMR.R = 0;
// enable TX
pt_sai->pt_i2s->TCSR.R =
(1<<31) | // enable tx
(1<<25) | // reset FIFO
(1<<28) | // enable bit clock
(1<<16) | // enable Req Flag
(1<<0); // enable DMA request