2
\$\begingroup\$

I build a Keil project for my STM32F103 MCU with STM32CubeMx.

My goal is use the TIM1 channel 2 for control a Buzzer. I want to generate a PWM at 4KHz through TIM1 channel 2. I configured, with STM32CubeMx, the TIM1_Channel2 as "PWM Generator CH2".

The problem regards the debug session. In particular, when I start the debug session and when the MCU executes the macro "__HAL_AFIO_REMAP_TIM1_ENABLE()" the debug session crash.

This is the timer initialisation code generated by STM32CubeMx:

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(htim->Instance==TIM1)
  {
  /* USER CODE BEGIN TIM1_MspPostInit 0 */

  /* USER CODE END TIM1_MspPostInit 0 */

    /**TIM1 GPIO Configuration   
    PE11     ------> TIM1_CH2
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_TIM1_ENABLE();

  /* USER CODE BEGIN TIM1_MspPostInit 1 */

  /* USER CODE END TIM1_MspPostInit 1 */
  }

}

This issue is related to Timer1 pin full remap.

Anyone have the same issue?

Thanks!

=== UPDATE ===

Finally I found some time to test the solution proposed by @SamGibson an it works! And thanks to @Rafiq Rahman for his code!

Thanks guys for your time!

This is the code that I used to remap the TIM1 and maintain the ability to generate the code with the Stm32CubeMX.

if(htim->Instance==TIM1)
{
  /* USER CODE BEGIN TIM1_MspPostInit 0 */
  #undef __HAL_AFIO_REMAP_TIM1_ENABLE
  #define __HAL_AFIO_REMAP_TIM1_ENABLE()  (0)
  /* USER CODE END TIM1_MspPostInit 0 */

    /**TIM1 GPIO Configuration    
    PE11     ------> TIM1_CH2 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_TIM1_ENABLE();

  /* USER CODE BEGIN TIM1_MspPostInit 1 */
  /* Make a copy of AFIO register */
  volatile uint32_t afioRegisterCopy = AFIO->MAPR;

  /* Clear Timer1 remap bits and + JTAG/SWD bits */
  afioRegisterCopy &= ~((7 << 24) + (3 << 6));

  /* To perform a full remap Timer1, bit 6-7 of 
     AFIO->MAPR must be set. Mask is 3 (11b)    */
  afioRegisterCopy |= (3 << 6);

  /* Apply the new register configuration*/
  AFIO->MAPR = afioRegisterCopy; 
  /* USER CODE END TIM1_MspPostInit 1 */
}
\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

STM32F103 [...] STM32CubeMx [...] when I start the debug session and when the MCU executes the macro "__HAL_AFIO_REMAP_TIM1_ENABLE()" the debug session crash.

I don't use the STM32CubeMX HAL, but I can explain the issue and the workaround.

The problem is that the STM32F1 series has one register AFIO_MAPR which contains the settings for remapping various peripherals and for enabling/disabling the JTAG/SWD connection to your debugger. And to make this more complicated, the bits in that register which enable/disable the JTAG/SWD settings (bits 24-26) are write-only so their existing state cannot be read.

See this extract from the STM32F1 Reference Manual:


Extract from STM32F1 Reference Manual


This means that any attempt to change the settings of the various "peripheral remap" bits, by doing a read-modify-write sequence to this register, could read different values instead of the real current values in the JTAG/SWD bits. Then, when the write to the register is done, your debugger access stops because whatever was read from those JTAG/SWD bits, is written back to them. (Other effects have also been reported, but I won't go into that now).

From what I could find without installing the HAL, the macros used are:

#define __HAL_AFIO_REMAP_TIM1_ENABLE() MODIFY_REG(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)

and MODIFY_REG is:

#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))

So as you see, MODIFY_REG is doing a read-modify-write and you don't know what values it will read from JTAG/SWD bits 24-26 and hence what values it will write back to there! The values read from those bits are "undefined" (to quote ST) and I know I have read different values from the same STM32F1 at different times.

The "fix" I have used with the SPL, is to change any remapping code to specifically set the JTAG/SWD bits which you want, whenever you write to the AFIO_MAPR register. You will need to figure out how you want to do the same with the HAL code. One way is to use a temporary variable so, from memory, the sequence becomes:

  • Read AFIO_MAPR register into temp variable
  • Change desired peripheral remap bits in the temp variable
  • Mask out bits 24-26 in the temp variable
  • Set bits 24-26 in the temp variable to whatever I wanted (therefore ignoring whatever their, likely incorrect, "read" value was)
  • Write temp variable to AFIO_MAPR

Thankfully ST changed to a better register arrangement in later STM32 models (e.g. STM32F4).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for your reply. Great explanation! Unfortunately my works is changed towards an high priority project. When I solved the problem I switch back to Timer1 Problem. Thanks Again \$\endgroup\$
    – Federico
    Commented Oct 6, 2016 at 7:32
2
\$\begingroup\$

Here is a working piece of code to illustrate the steps proposed by @SamGibson. It works for me like a charm. First thing to do is to comment out the __HAL_AFIO_REMAP_TIM1_ENABLE(); in stm32f1xx_hal_msp.c and fill in with the remap code as follow:

//__HAL_AFIO_REMAP_TIM1_ENABLE();

/* USER CODE BEGIN TIM1_MspPostInit 1 */

volatile uint32_t map_copy = AFIO->MAPR;

map_copy &= ~((7 << 24) + (3 << 6)); // Clear desired bitfields + debug bits


// 5(101b) shifted left 24 for CoreSight SW-DP (What Keil Ulink2 and St-LinkV2
//use for debugging in either Keil IDE or SW4STM32 IDE)

// The (3 << 6) is me wanting to fully remap the TIM1 AF pins for 
//Complementary PWM Generation

map_copy |= (5 << 24) + (3 << 6);

AFIO->MAPR = map_copy;

/* USER CODE END TIM1_MspPostInit 1 */

Just be on the lookout for other MspPostInit calls...

Cheers.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.