I am using the M4 core in an LPC4330 processor using SGPIO to emulate a TDM interface reading in data an ADC. I am using SGPIO in TDM format because the onboard I2S versions only allow two audio channels, and the TDM version allows up to 8 channels—this is the kind of thing for which SGPIO was created.
Here are the details.
The BCLK clock is generated using SGPIO slice A, using the clock pass-through outputting to pin SGPIO8. In other words, using the Peripheral clock input, dividing using the COUNTER register (with PRESET), then outputting directly to SGPIO8, skipping the POS counter and shift clock. This works, and we can see the clock with a logic analyzer on P1_12 (assigned to SGPIO8). All other signals work as expected—except Data in (SDI) on SGPIO6/Slice F.
Data In is being presented at pin SGPIO6, DIN, on P2_2 (confirmed). The goal is to have BCLK on SGPIO8 drive the external clock option for Slice F, SGPIO6 to correctly capture the data. The documentation says this should be possible—in fact, recommended. Here is how the relevant registers are set:
SGPIO_MUX[SGPIO_SLICE_F] =
(1 << 0) // EXT_CLK_ENABLE – should select the external clock (pin) per documentation
(0b00 << 1) //CLK_SOURCE_PIN_MODE – 0b00 == select SGPIO8 as source pin
(0b00 << 3) //CLK_SOURCE_SLICE_MODE – tried this as well, no go. Prefer to use pin input.
(0b00 << 5) //QUALIFIER_MODE – set to 0b00 == always enable the shift clock
(0b00 << 7) //QUALIFIER_PIN_MODE – should not be relevant
(0b00 << 9) //QUALIFIER_SLICE_MODE – should not be relevant
(0b0 << 11) //CONCAT_ENABLE – set to 0 == input from external DIN pin per documentation (note that data can be captured using a COUNTER clock, but not using external clock)
(0b00 << 12) //CONCAT_ORDER – should not be relevant
//All other register bit settings reserved.
SLICE_MUX[SGPIO_SLICE_F] =
(0 << 0) //MATCH_MODE – set to not match data
(0 << 1) //CLK_CAPTURE_MODE – at this point doesn’t matter if rising or falling
(1 << 2) //CLKGEN_MODE – 1: 0b1 == use external clock from a pin or other slice
(0 << 3) //INV_OUT_CLK – invert clock, not necessary at this point
(0b00 << 4) //DATA_CAPTURE_MODE – 0b00 == rising edge
(0b00 << 6) //PARALLEL_MODE – 0b00 == shift 1 bit per clock
(0 <<
//All other register settings reserved.
With this configuration, and after enabling all slices (using CTRL_ENABLE), there is no shift clock, and Data In is not clocked in. In other words, the external clock is not driving the shift clock as it should. I can use the COUNTER to shift the clock, so we know the rest of the system works (but the COUNTER clock is the wrong phase for shifting data in, hence the need to use BCLK on SGPIO8 as the external clock input).
Again, the external clock on pin SGPIO8 is NOT generating a shift clock, in fact, any effort to use an external clock (including trying other slices (D) and SGPIO pins (11)) does not work. The only clock that works is the COUNTER clock. Why is that? The documentation says an external clock should work. Am I missing a register setting somewhere?
If you have an external clock for any SGPIO working, please tell me how! Help would be appreciated!
Thank you for the response. However, I am quite familiar with that and other articles about using SGPIO. The problem is that I have tried to setup SGPIO exactly as in the examples and the articles, but the external clock connection does not work. I have searched the documentation for some additional register that must be set, but have found nothing. Please look over the settings I specify above and help me understand what needs to be done to make the external clock work.
Thank you!
Hi,
Yes, I see that the I2S module of LPC4330 only supports I2S protocol with only two slots, it does not support TDM with multiple slots.
For the SGPIO to simulate the I2S, pls refer to the ticket:
https://community.nxp.com/t5/LPC-Microcontrollers/I2s-In-out-slave-with-SGPIO/m-p/615269
I suppose it is helpful
BR
XiangJun Rong