We are using a SHARC 21489 to interface to a DAC in TDM16 mode with 16-bit audio at 16KHz. My math is:
I want 16KHz audio and PCLK is 200MHz. I need 16 channels, so 200M / ( 16 chan * 4 * 16K * 16 bits ) - 1 = 11.20703125 round to 11 and it will be slightly fast, which is probably OK.
16-bit audio, so SLEN = 16 bits
To get the frequency right for the frame sync, FSDIV = ( SCLK / FSCLK ) - 1, and must be >= SLEN
SCLK = 4.096MHz
FSCLK = 16KHz
FSDIV = 255
So, here's the code:
*pDIV0 = ( 255u << 16u ) | ( 11u << 1u );
*pSPCTL0 = SPTRAN | BHD | IFS | ICLK | SLEN16 | SPEN_A;
*pSPMCTL0 = NCH16 | MFD1 | MCEA;
*pSP0CS0 = 0x0001u; /* just for now, to only have one of those channels active */
/* all other SPORT0 registers are 0 */
I can see the BCLK and the FS on my scope, and they look good - BCLK is 4.096MHz and FS is 16KHz. (Both are a little faster than that because of the rounding in CLKDIV, but they are reasonably close to the correct values.)
Just as a proof of concept, I've only enabled the first channel. I initialized my peripherals, and then instead of starting my scheduler, I drop into a very tight loop where I check the DXS0_A and DXS1_A bits in SPCTL0, and if the FIFO is not full, I write in the next value in a fixed pattern.
for ( ; ; )
if ( ( *pSPCTL0 & ( DXS0_A | DXS1_A ) ) != ( DXS0_A | DXS1_A ) ) // check if TX buffer full
*pTXSP0A = pattern[ cnt % 4 ];
What I see on my scope is that the data line alternates between having data and being zero with each FS pulse. The data follows the pattern I'm writing, so I get pattern after an FS pulse, all 0's (instead of pattern) at the next FS, and then pattern at the 3rd FS pulse, repeat ad infinitum.
For reasons that are more involved than I want to explain right now, we will not be using an interrupt to service the SPORT. However, I did try it as an experiment (borrowing liberally from the Power-On Self Test demo application that came with the 21489 evaluation kit), and saw the same results - every other word seemed to come out as zero on the TX line.
We will probably move to using DMA, but due to the nature of the system, we won't feed the audio output very much data ahead of time. It seemed like a reasonable proof-of-concept to use core writes to ensure that the SPORT is configured properly.
See attached scope capture. The top trace is BCLK, the middle trace is FS, and the bottom trace is TX.
Any suggestions or insight will be greatly appreciated!