SGPIO with External Clock on LPC4330 does not work--unless I've missed something.
I boiled this down to the minimum:
SGPIO8 (slice A) is a clock source running at ~12MHz. It uses CLK output, which is inverted. SGPIO8 is a valid choice for external clock input to a Slice that requests external input (per documentation).
SGPIO1 (Slice D) is a clock source running at ~12MHz. It uses CLK output non-inverted. Slice D is a valid choice for external clock input to a Slice that requests external input (per documentation)
SGPIO5 (Slice F) is set to output CLK on SGPIO5 non-inverted. It can select input from the COUNT register, or from external clocks (SGPIO8 and Slice D) above.
With Slice F configured for COUNT clock (SLICE_MUX_CFG[Slice_F] = (0 << 3)), and with the COUNTER set to divide the same input clock by 4, we get the first picture on the output pins for all three. This is expected. (See attached JPG image)
However, when Slice F configured to use External Clock as input (SLICE_MUX_CFG[Slice_F] = (1 << 3)), which selects an external clock (should pick up SGPIO8) as described in the documentation, the input provides no signal. The only change is the bit 3 of SLICE_MUX_CFG. The output of SGPIO5 should be showing a ~12MHz signal. (See attached JPG image)
Here is the actual code:
Chip_SCU_PinMuxSet(1, 12, SCU_MODE_FUNC6); //Slice A, SGPIO8
Chip_SCU_PinMuxSet(0, 1, SCU_MODE_FUNC3); //Slice D, SGPIO1
Chip_SCU_PinMuxSet(2, 1, SCU_MODE_FUNC0); //Slice F, SGPIO5
Chip_Clock_SetBaseClock(CLK_BASE_PERIPH, CLKIN_IDIVC, TRUE, FALSE); //For SGPIOs
/* Setup Slice A, SGPIO8 for CLKOUT */
LPC_SGPIO->PRESET[SGPIO_SLICE_A]= 0; //Set COUNT (PRESET) to count-1
LPC_SGPIO->COUNT[SGPIO_SLICE_A] = 0; //Initialize counter as well
LPC_SGPIO->OUT_MUX_CFG[8] = //SGPIO8
SGPIO_OUT_MUXCFG_OUTCFG_CLKOUT
| SGPIO_OUT_MUXCFG_OECFG_GPIOOE;
LPC_SGPIO->SLICE_MUX_CFG[SGPIO_SLICE_A]= (1 << 3); //Slice A Invert clock output
LPC_SGPIO->SGPIO_MUX_CFG[SGPIO_SLICE_A]= 0; //Defaults
LPC_SGPIO->GPIO_OENREG |= (1 << 8); //Output Enable SGPIO8
/* Setup Slice D, CLKOUT */
LPC_SGPIO->PRESET[SGPIO_SLICE_D]= 0; //Set COUNT (PRESET) to count-1
LPC_SGPIO->COUNT[SGPIO_SLICE_D] = 0; //Initialize counter as well
LPC_SGPIO->OUT_MUX_CFG[1] = //SGPIO1
SGPIO_OUT_MUXCFG_OUTCFG_CLKOUT
| SGPIO_OUT_MUXCFG_OECFG_GPIOOE;
LPC_SGPIO->SLICE_MUX_CFG[SGPIO_SLICE_D]= 0; //Default
LPC_SGPIO->SGPIO_MUX_CFG[SGPIO_SLICE_D]= 0; //Default
LPC_SGPIO->GPIO_OENREG |= (1 << 1); //Output Enable SGPIO1
/* Setup Slice F, SGPIO5 as CLKOUT using External Clock for input */
LPC_SGPIO->PRESET[SGPIO_SLICE_F]= 3; //Divide PERIPH rate by 4 so we can
LPC_SGPIO->COUNT[SGPIO_SLICE_F] = 3; //see the difference from ExtClocks
LPC_SGPIO->OUT_MUX_CFG[5] = //SGPIO5
SGPIO_OUT_MUXCFG_OUTCFG_CLKOUT //Clock out to measure
| SGPIO_OUT_MUXCFG_OECFG_GPIOOE;
LPC_SGPIO->SLICE_MUX_CFG[SGPIO_SLICE_F]= //Slice F
SGPIO_SLICE_MUXCFG_CLKGEN; //External Clock
LPC_SGPIO->SGPIO_MUX_CFG[SGPIO_SLICE_F]= //Slice F
SGPIO_MUXCFG_EXTCLK_ENABLE //Enable external clock (1 for SPGIO8, possibly 0 for Slice D?)
| SGPIO_MUXCFG_CS_PMODE_SGPIO8 //External clock SGPIO8
| SGPIO_MUXCFG_CS_SMODE_SLICED //External clock on Slice D
| SGPIO_MUXCFG_QUAL_MODE_ENABLE; //Qualifier input always enabled
LPC_SGPIO->GPIO_OENREG |= (1 << 5); //Output Enable SGPIO5
/* Go */
LPC_SGPIO->CTRL_DISABLED = ~((1 << SGPIO_SLICE_A) | (1 << SGPIO_SLICE_D) | (1 << SGPIO_SLICE_F)); //Slice A, D, F
LPC_SGPIO->CTRL_ENABLED = (1 << SGPIO_SLICE_A) | (1 << SGPIO_SLICE_D) | (1 << SGPIO_SLICE_F); //Slice A, D, F
I have tried many variations on this test, but the results are always the same,
fully repeatable. The lack of external clock input is contrary to the documentation
but is demonstrated by this test to not work. When the external clock source is selected
the no clock is provided at all.
I realize that I must have missed something in the setup, but I have been over this
literally dozens of times, I have read every article online about SGPIO and
external clocks. The proof is in the simplified example. I cannot figure out a solution
to get an external clock to drive any SGPIO input.
Please look over the example in detail and tell me how to get an external
clock as an external clock input to and SGPIO slice.
Thank you,
Hi,
I have asked AE team for the SGPIO module question.
BR
XiangJun Rong
Thank you for looking deeper into this. To help you and them,
I have additional information that may be helpful, and I have found one method to (sort of) make this work.
First, it is possible that SGPIO8 as a clock source, solely means that the SGPIO8 DIN pin provides an external clock outside of the SGPIO system. Trying to generate a clock on Slice F and connect the output to SGPIO8 does not appear to work (well, it works, but it can’t be used as an external clock to another slice). Is it possible that the SGPIO8 connection only works with a truly external signal connected to P1_12? I cannot find documentation on how to make SGPIO8 DIN an input for another slice. Is there any?
Second, I was able to make the slice clock for Slice D generate a clock that can be picked up by another slice, such as Slice A. But it requires some special considerations:
There may be ways to get this to work the way I need it to—but I’m disappointed with the lack of clarity in the documentation, and the inconsistencies in SGPIO. We selected the LPC4330 partially because of the seemingly powerful SGPIO capabilities required for our heavily streaming app. Unfortunately, SGPIOs don’t seem to work as advertised.