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

10 REPLIES 10
OlivierK
ST Employee

​Hi Machilus (Community Member),

​There should be no influence at all of M4 clock init code in production mode since all the clock settings are initialized exclusively by the Linux DT in production mode. Mixing M4 code calling RCC clock setting such as the prescaler is conflicting with openstlinux RCC init in DT.

Therefore this LL_SPI_BAUDRATEPRESCALER_DIV2 may work in engineering mode where the M4 is isolated from the Cortex A7 and Linux, but not in production mode.

So I would strip out first all the RCC code settings from the M4, regenerate/reload the .elf file. Refer to the CubeMX code generator tool to generate the clock tree (including the clock prescalers) in production mode and see how it goes.

you can refer to the wiki ressources for that if not clear:

https://wiki.st.com/stm32mpu/wiki/Getting_started/STM32MP1_boards/STM32MP157x-DK2/Develop_on_Arm®_Cortex®-M4/Modify,_rebuild_and_reload_a_firmware

Regards,

Olivier