La reasignación del temporizador1 causa un bloqueo de depuración en STM32F103

2

Construyo un proyecto Keil para mi MCU STM32F103 con STM32CubeMx.

Mi objetivo es usar el canal TIM1 2 para controlar un zumbador. Quiero generar un PWM a 4KHz a través del canal 2 de TIM1. Configuré, con STM32CubeMx, el TIM1_Channel2 como "PWM Generator CH2".

El problema se refiere a la sesión de depuración. En particular, cuando inicio la sesión de depuración y cuando la MCU ejecuta la macro "__HAL_AFIO_REMAP_TIM1_ENABLE ()", la sesión de depuración se bloquea.

Este es el código de inicialización del temporizador generado por 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 */
  }

}

Este problema está relacionado con la reasignación completa del pin Timer1.

¿Alguien tiene el mismo problema?

¡Gracias!

=== ACTUALIZACIÓN ===

¡Finalmente encontré algo de tiempo para probar la solución propuesta por @SamGibson y funciona! ¡Y gracias a @Rafiq Rahman por su código!

Gracias chicos por tu tiempo!

Este es el código que utilicé para volver a asignar el TIM1 y mantener la capacidad de generar el código con el 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 */
}
    
pregunta Federico

2 respuestas

6
  

STM32F103 [...] STM32CubeMx [...] cuando inicio la sesión de depuración y cuando la MCU ejecuta la macro "__HAL_AFIO_REMAP_TIM1_ENABLE ()" la caída de la sesión de depuración.

No uso la HAL STM32CubeMX, pero puedo explicar el problema y la solución.

El problema es que la serie STM32F1 tiene un registro AFIO_MAPR que contiene las configuraciones para volver a asignar varios periféricos y para habilitar / deshabilitar la conexión JTAG / SWD a su depurador. Y para hacer esto más complicado, los bits en ese registro que habilitan / inhabilitan la configuración JTAG / SWD ( bits 24-26 ) son de solo escritura , por lo que su estado actual es no se puede leer .

Vea este extracto en el STM32F1 Reference Manual :

Estosignificaquecualquierintentodecambiarlaconfiguracióndelosdistintosbitsde"reasignación periférica", al hacer una secuencia de lectura-modificación-escritura en este registro, podría leer diferentes valores en lugar de valores reales actuales en los bits JTAG / SWD. Luego, cuando se realiza la escritura en el registro, el acceso al depurador se detiene porque lo que se leyó de esos bits JTAG / SWD se vuelve a escribir en ellos. (También se han informado otros efectos, pero no voy a entrar en eso ahora).

Por lo que pude encontrar sin instalar la HAL, las macros utilizadas son:

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

y MODIFY_REG es:

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

Entonces, como ves, MODIFY_REG está haciendo una lectura-modificación-escritura y no sabes qué valores leerá de JTAG / SWD bits 24-26 y, por lo tanto, ¡qué valores escribirá allí! Los valores leídos de esos bits son "indefinidos" (para citar ST) y sé que he leído diferentes valores del mismo STM32F1 en diferentes momentos.

El "arreglo" que he usado con el SPL es cambiar cualquier código de reasignación para establecer específicamente los bits JTAG / SWD que desee, siempre que escriba en el registro AFIO_MAPR . Deberá averiguar cómo desea hacer lo mismo con el código HAL. Una forma es usar una variable temporal para que, desde la memoria, la secuencia se convierta en:

  • Lea el registro AFIO_MAPR en la variable temporal
  • Cambie los bits de reasignación de periféricos deseados en la variable temporal
  • Enmascara los bits 24-26 en la variable temporal
  • Establezca los bits 24-26 en la variable temporal a lo que yo quisiera (por lo tanto, ignorar el valor de "lectura", probablemente incorrecto)
  • Escriba la variable temporal en AFIO_MAPR

Afortunadamente, ST cambió a una mejor disposición de registro en los modelos STM32 posteriores (por ejemplo, STM32F4).

    
respondido por el SamGibson
2

Aquí hay un código de trabajo para ilustrar los pasos propuestos por @SamGibson. Funciona para mí como un encanto. Lo primero que debe hacer es comentar el __HAL_AFIO_REMAP_TIM1_ENABLE(); en stm32f1xx_hal_msp.c y completar el código de reasignación de la siguiente manera:

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

Solo esté atento a otras llamadas de MspPostInit ...

Saludos.

    
respondido por el Rafiq Rahman

Lea otras preguntas en las etiquetas