cancel
Showing results for 
Search instead for 
Did you mean: 

Questions about setting the spi clock (devicetree file, M4 Core side)

Machilus
Associate III

Hi ST.

I set the clock in the dts file as below.

&rcc {

st,hsi-cal;

st,csi-cal;

st,cal-sec = <60>;

st,clksrc = <

CLK_MPU_PLL1P

CLK_AXI_PLL2P

CLK_MCU_PLL3P

CLK_PLL12_HSE

CLK_PLL3_HSE

CLK_PLL4_HSE

CLK_RTC_LSE

CLK_MCO1_DISABLED

CLK_MCO2_DISABLED

>;

st,clkdiv = <

1 /*MPU*/

0 /*AXI*/

0 /*MCU*/

1 /*APB1*/

1 /*APB2*/

1 /*APB3*/

1 /*APB4*/

2 /*APB5*/

23 /*RTC*/

0 /*MCO1*/

0 /*MCO2*/

>;

st,pkcs = <

CLK_CKPER_HSI

CLK_QSPI_ACLK

CLK_ETH_DISABLED

CLK_SDMMC12_PLL4P

CLK_STGEN_HSE

CLK_USBPHY_HSE

CLK_SPI2S1_CKPER

CLK_SPI2S23_PLL3Q

CLK_SPI45_PLL4Q

CLK_SPI6_DISABLED

CLK_I2C46_HSI

CLK_SDMMC3_DISABLED

CLK_USBO_USBPHY

CLK_ADC_PLL4R

CLK_CEC_DISABLED

CLK_I2C12_HSI

CLK_I2C35_DISABLED

CLK_UART1_HSI

CLK_UART24_HSI

CLK_UART35_HSI

CLK_UART6_HSI

CLK_UART78_HSI

CLK_SPDIF_DISABLED

CLK_SAI1_DISABLED

CLK_SAI2_DISABLED

CLK_SAI3_DISABLED

CLK_SAI4_DISABLED

CLK_RNG1_LSI

CLK_RNG2_LSI

CLK_LPTIM1_PCLK1

CLK_LPTIM23_PCLK3

CLK_LPTIM45_LSE

>;

/* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */

pll2: st,pll@1 {

compatible = "st,stm32mp1-pll";

reg = <1>;

cfg = < 2 65 1 1 0 PQR(1,0,1) >;

frac = <0x1400>;

};

/* VCO = 600.0 MHz => P = 200, Q = 40, R = 60 */

pll3: st,pll@2 {

compatible = "st,stm32mp1-pll";

reg = <2>;

cfg = < 3 99 2 14 9 PQR(1,1,1) >;

/*

frac = <0x1a04>;

*/

};

/* VCO = 792.0 MHz => P = 99, Q = 66, R = 72 */

pll4: st,pll@3 {

compatible = "st,stm32mp1-pll";

reg = <3>;

cfg = < 5 197 7 11 10 PQR(1,1,1) >;

};

};

The following is the SPI setting part of M4 Core Side.

static void MX_SPI5_Init(void)

{

  LL_SPI_InitTypeDef SPI_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  if (IS_ENGINEERING_BOOT_MODE())

  {

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI45;

    PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PLL4;

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

    {

      Error_Handler();

    }

  }

  else

{

  if (!LL_RCC_PLL4_IsReady())

{

LL_RCC_PLL4_Enable();

}

LL_RCC_PLL4Q_Enable();

}

  // Peripheral clock enable

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI5);

  LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOK);

  LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOJ);

  /* SPI5 GPIO Configuration

    PK0  ------> SPI5_SCK

    PJ10  ------> SPI5_MOSI

  */

  GPIO_InitStruct.Pin = LL_GPIO_PIN_0;

  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;

  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;

  LL_GPIO_Init(GPIOK, &GPIO_InitStruct);`

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;

  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;

  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;

  LL_GPIO_Init(GPIOJ, &GPIO_InitStruct);

  SPI_InitStruct.TransferDirection = LL_SPI_SIMPLEX_TX;

  SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;

  SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_16BIT;

  SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;

  SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;

  SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;

  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;

  SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;

  SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;

  SPI_InitStruct.CRCPoly = 0x0;

  LL_SPI_Init(SPI5, &SPI_InitStruct);

  LL_SPI_SetStandard(SPI5, LL_SPI_PROTOCOL_MOTOROLA);

}

The following is the part that transmits data using SPI in M4 Core Side.

uint16_t uData = 0xFF0F;

LL_SPI_SetTransferSize(SPI5, 1);

LL_SPI_Enable(SPI5);

LL_SPI_StartMasterTransfer(SPI5);

LL_SPI_TransmitData16(SPI5, uData);

while (LL_SPI_IsActiveFlag_EOT(SPI5) == 0);

LL_SPI_ClearFlag_EOT(SPI5);

LL_SPI_ClearFlag_TXTF(SPI5);

LL_SPI_SuspendMasterTransfer(SPI5);

LL_SPI_Disable(SPI5);

SPI5 uses PLL4Q.

PLL4Q = 66Mhz -> 66/2 -> 33Mhz

The clock of SPI5 should operate at 33Mhz, but as a result of checking with an actual oscilloscope, it is about 2.6Mhz.

When I check it with an oscilloscope in Engineering Mode, it is about 33Mhz, but it is 2.6Mhz in Production Mode (Linux).

Am I wrong clock or SPI5 settings?

Below is the development environment.

Board : Custom board using stm32mp151c chip.

OS : Ecosystem 2.1.0 (202-11-12)

IDE : STM32CubeIDE

Debugger : STLINK-V3SET

Please tell me a solution.

Regards

Machilus

1 ACCEPTED SOLUTION

Accepted Solutions
PatrickF
ST Employee

Hello,

Did you use CubeMx ? Is the SPI5 correctly assigned to M4 in the Linux Device Tree ?

You should see something like:

m4_spi5_pins_mx: m4_spi5_mx-0 {
      pins {
         pinmux = <STM32_PINMUX('J', 10, RSVD)>, /* SPI5_MOSI */
               <STM32_PINMUX('J', 11, RSVD)>, /* SPI5_MISO */
               <STM32_PINMUX('K', 0, RSVD)>; /* SPI5_SCK */
      };
   };
.....
&m4_spi5{
   pinctrl-names = "default";
   pinctrl-0 = <&m4_spi5_pins_mx>;
   status = "okay";
};

Otherwise, I think related clock/pll is maybe not setup by Linux (and so SPI5 might be still on pclk2).

Btw, in production mode, GPIO are set by Linux, so using LL_GPIO_Init( ) could result in conflicts hard to debug.

To debug clock, you could also use cat /sys/kernel/debug/clk/clk_summary on Linux to see which frequencies are set in production mode.

Maybe https://wiki.st.com/stm32mpu/wiki/How_to_configure_system_resources#Configuring_clock_and_regulator_system_resources could help you.

Regards.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

View solution in original post

10 REPLIES 10
PatrickF
ST Employee

Hello,

Did you use CubeMx ? Is the SPI5 correctly assigned to M4 in the Linux Device Tree ?

You should see something like:

m4_spi5_pins_mx: m4_spi5_mx-0 {
      pins {
         pinmux = <STM32_PINMUX('J', 10, RSVD)>, /* SPI5_MOSI */
               <STM32_PINMUX('J', 11, RSVD)>, /* SPI5_MISO */
               <STM32_PINMUX('K', 0, RSVD)>; /* SPI5_SCK */
      };
   };
.....
&m4_spi5{
   pinctrl-names = "default";
   pinctrl-0 = <&m4_spi5_pins_mx>;
   status = "okay";
};

Otherwise, I think related clock/pll is maybe not setup by Linux (and so SPI5 might be still on pclk2).

Btw, in production mode, GPIO are set by Linux, so using LL_GPIO_Init( ) could result in conflicts hard to debug.

To debug clock, you could also use cat /sys/kernel/debug/clk/clk_summary on Linux to see which frequencies are set in production mode.

Maybe https://wiki.st.com/stm32mpu/wiki/How_to_configure_system_resources#Configuring_clock_and_regulator_system_resources could help you.

Regards.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Hi PatrickF (ST Employee)

I modified DTS and Firware by referring to the advice.

I looked at it using the command "cat /sys/kernel/debug/clk/clk_summary" and spi5_k was assigned to "pll4_q".

But didn't solve the problem.

If you set "PCLK2", "HSI", "CSI" and "HSE" in the SPI5 clock mux, it operates normally.

However, only "PLL4Q" does not generate the clock as set.

Is there anything else we need to look into?

P.S : SPI1, SPI2, and SPI3 generate normal clocks as set regardless of the clock source.

Regards

Machilus

OlivierK
ST Employee

​Hi Machilus (Community Member)

Could you please share your DTS? and .ioc file if generated by CubeMX/CubeIDE?

When you say SPI1, SPI2, and SPI3 generate normal clocks as set, does it includes PLL4_P as clk source for instance?

Regards,

Olivier

Hi OlivierK (ST Employee)

Please tell me the e-mail address to send dts and ioc files.

Regards

Machilus

Hi,

You could send Private Message using pop-up menu which appear when you leave the cursor on a name. You could also uses the Message area.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
OlivierK
ST Employee

​Hi Machilus (Community Member)

Regarding the linux side of your configuration, I've found your PLL4 freq out of spec. Did you use CubeMx to modify the clock tree? Also for the M4 configuration it would have been much safer to use this tool to prevent setup errors.

root@stm32mp1:~# cat /sys/kernel/debug/clk/clk_summary                                                    

    pll4                             2       2       0  792000000         0    0 50000                        

Using your setup, changing the TF-a clock settings on the DK2 board using the spi5 node with the CLK_SPI45_PLLQ

I found spi5_k  around 30MHz                  0       0       0   29700000         0    0 50000

Regards

                                     

Hi OlivierK (ST Employee)

I entered the same frequency settings into the STM32CubeMX as the shared DTS file, but there are no errors.

If I set "/6" in DIVM4, CubeMX will not throw an error if the condition of "400Mhz =< PLL4 <= 800Mhz" is met.

So setting "792Mhz" in PLL4 didn't cause any warnings or errors in CubeMX.

0693W000007EGA8QAO.jpg 

Is the STM32CubeMX wrong?, We can also share "ioc" files.

I used STM32CubeMX version 6.1.1

I look forward to your reply.

Thanks and regards

Machilus

OlivierK
ST Employee

​Hi Machilus (Community Member),

For the PLL VCO specifications it is indeed correct, anyway if you've generated your project with CubeMX it should be error free. I did not see the .ioc in the files you've shared, so I was assuming you didn't use CubeMX.

Anyway, I did use you settings in TF-a and regarding the spi5_k do you see the same once booted?

spi5_k                  0       0       0   29700000         0    0 50000

Regards,

Olivier

Hi OlivierK (ST Employee)

0693W000007ERSDQA4.jpgIn the picture above, you can see that "spi5_k" is set to 66Mhz in "PLL4Q".

Since the clock setting of "PLL4" is as follows, it is normal that 66Mhz appears in "PLL4Q".

/* VCO = 792.0 MHz => P = 99, Q = 66, R = 72 */

pll4: st,pll@3 {

compatible = "st,stm32mp1-pll";

reg = <3>;

cfg = < 5 197 7 11 10 PQR(1,1,1) >;

};

};

However, if i set the Baudrate of SPI5 of M4 firmware to "LL_SPI_BAUDRATEPRESCALER_DIV2" in production mode booted with Linux, "SPI5_SCK" will output 2.6Mhz instead of 33Mhz.

Regards

Machilus