# Timer1 remap cause debug crash on STM32F103

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!

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 */
}


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:

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).

• 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 – Federico Oct 6 '16 at 7:32

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.