cancel
Showing results for 
Search instead for 
Did you mean: 

The PWM wave is interrupted in mass production mode

Wjian.1
Associate II

Hi:

Dear friends, there is a very strange problem here. I use timer 1(STM32MP157AAC) to output PWM wave. In engineering mode, the output of PWM wave is normal, but when it comes to mass production mode, the waveform is interrupted. Here are my configuration steps:

1)First of all, I configure the clock to be 209 MB, the frequency to be 800K, and the duty cycle to be 50%, as follows:

htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 250-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 125;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.BreakFilter = 0;
  sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }

2)Configure the device tree as follows:

&pinctrl {
        u-boot,dm-pre-reloc;
 
        m4_tim1_pwm_pins_mx: m4_tim1_pwm_mx-0 {
                pins {
                        pinmux = <STM32_PINMUX('E', 13, RSVD)>; /* TIM1_CH3 */
                };
        };
};
 
&m4_timers1{
        pinctrl-names = "default";
        pinctrl-0 = <&m4_tim1_pwm_pins_mx>;
        status = "okay";
 
        /* USER CODE BEGIN m4_timers1 */
        /* USER CODE END m4_timers1 */
};

3)TF-A is configured as follows:

DECPROT(STM32MP1_ETZPC_TIM1_ID, DECPROT_MCU_ISOLATION, DECPROT_UNLOCK)

4)Test waveform of mass production mode:

0693W000008yagZQAQ.png

​5)Could you tell me the solution?

8 REPLIES 8
Wjian.1
Associate II

In addition, when you keep pressing the oscilloscope "SINGLE" button, the waveform interruption will be collected

PatrickF
ST Employee

Hi,

Did you have a fixed or a random recurrence of the 'missing PWM pulse' ?

Is the 'missing PWM pulse' always similar or have various location in the waveform ?

Could you zoom around the 'missing pulse' and check if the time between pulses is stretched (which might be linked to an unwanted short clock gating) or not (which might be linked to a timer signal output masked for a short period).

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:

Thank you for your reply. This "missing PWM pulse" in the mass production mode is not random. It is the "missing PWM pulse" every time you press the "single" button of the oscilloscope. This is not the case when debugging with IDE alone.The missing part only occurs in a single PWM cycle (1.25us)

HI:

I have solved the by mask the "st,hsi-cal-input"

&timers15 {
        secure-status = "okay";
//      st,hsi-cal-input = <7>;
//      st,csi-cal-input = <8>;
};

Hi,

Nice to see your solved the issue.

Anyway, to be complete, could you confirm you are using HSE to clock the Cortex-M4 subsystem (the 209MHz) and so the TIM1.

In our default setting, the 209MHz is built from HSE, so HSI calibration should not have impact.

I assume you put the clock settings under if(IS_ENGINEERING_BOOT_MODE()) as described in https://wiki.st.com/stm32mpu/wiki/STM32CubeMP1_development_guidelines#Cortex-M4_Startup_in_Production_mode.

It would be nice if you could provide your complete Device Tree (using Private Message if you don't want to disclose in forum).

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:

1)Yes!In the production mode, the peripheral clock is provided by A7, so in the M4 firmware, I put the clock settings under  if(IS_ENGINEERING_BOOT_MODE()) since the clock is initialized after TF-A, I use 209M by default.However, I noticed that the timers15 node of TF-A device tree has the following attributes: st, hsi-cal-input = < 7 >; st, csi- cal- input = < 8 >;It seems that this property will cause clock reallocation when I look at the corresponding driver source code,eg:

   vi <TF-A source>/drivers/st/timer/stm32_timer.c
.....................
  cuint = fdt_getprop(fdt, node, "st,hsi-cal-input",
                                            NULL);
                        if (cuint != NULL) {
                                timer = &stm32_timer[HSI_CAL];
                                timer->base = dt_timer.base;
                                timer->clk = dt_timer.clock;
                                timer->freq =
                                        stm32mp_clk_timer_get_rate(timer->clk);
                                timer->cal_input =
                                        (uint8_t)fdt32_to_cpu(*cuint);
                                if (stm32_timer_config(timer) < 0) {
                                        timer->base = 0;
                                        continue;
                                }
                        }

In addition, I attached my TF-A device tree

2)In addition, I also found another problem. When I don't allocate peripherals to M4, the M4 firmware can work normally in production mode

Hi,

thanks for the valuable feedback.

To go further on the analyze, could you try replacing:

&timers15 {
               secure-status = "okay";
               st,hsi-cal-input = <7>;
               st,csi-cal-input = <8>;
};

by:

&timers12 {
               secure-status = "okay";
               st,hsi-cal-input = <1>;
               st,csi-cal-input = <2>;
};

And see if the issue is still present.

We are investigating this potential issue on our side as well.

Could you clarify your point 2) above ? Does it mean that without &m4_timer1 declaration your application work well without output 'glitch' ?

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:

After replacing with timer12 node, it works normally.Yes, I didn't add &m4_timer1 in the kernel device tree and it works well.