背景
由于项目需要,使用的SWD调试对芯片进行下载与调试,未使用JTAG相关功能,同时GPIO引脚不够用,于是需要将PB03(JTDO/SWO)和PA15(JTDI)设置为普通的GPIO来使用;
问题
由于PB03(JTDO/SWO)和PA15(JTDI)默认用于JTAG功能,其无法直接像普通的IO口那样直接配置引脚复用,需要先关闭引脚对应的debug功能。
直接像普通GPIO引脚一样配置是无效的。
处理方法
使用GPIO_SetDebugPort函数进行配置。
该函数位于hc32_II_gpio.c文件中,函数定义如下:
c
/**
* @brief GPIO debug port configure. Set debug pins to GPIO
* @param [in] u8DebugPort: @ref GPIO_DebugPin_Sel for each product
* @param [in] enNewState: An @ref en_functional_state_t enumeration value.
* @arg ENABLE: set to debug port (SWD/JTAG)
* @arg DISABLE: set to GPIO
* @retval None
*/
void GPIO_SetDebugPort(uint8_t u8DebugPort, en_functional_state_t enNewState)
{
/* Parameter validity checking */
DDL_ASSERT(IS_GPIO_DEBUG_PORT(u8DebugPort));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
DDL_ASSERT(IS_GPIO_UNLOCK());
if (ENABLE == enNewState) {
SET_REG16_BIT(CM_GPIO->PSPCR, ((uint16_t)u8DebugPort & GPIO_PSPCR_SPFE));
} else {
CLR_REG16_BIT(CM_GPIO->PSPCR, ((uint16_t)u8DebugPort & GPIO_PSPCR_SPFE));
}
}
其中输入参数定义为:
c
/**
* @defgroup GPIO_DebugPin_Sel GPIO Debug Pin Selection
* @{
*/
#define GPIO_PIN_TCK (0x01U)
#define GPIO_PIN_TMS (0x02U)
#define GPIO_PIN_TDO (0x04U)
#define GPIO_PIN_TDI (0x08U)
#define GPIO_PIN_TRST (0x10U)
#define GPIO_PIN_DEBUG_JTAG (0x1FU)
#define GPIO_PIN_SWCLK (0x01U)
#define GPIO_PIN_SWDIO (0x02U)
#define GPIO_PIN_SWO (0x04U)
#define GPIO_PIN_DEBUG_SWD (0x07U)
#define GPIO_PIN_DEBUG (0x1FU)
/**
* @brief Functional state
*/
typedef enum {
DISABLE = 0U,
ENABLE = 1U,
} en_functional_state_t;
针对于我的关闭PA15和PB03的需求,进行如下配置即可:
c
// 关闭 PA15 (JTDI) 的调试功能,释放为普通 GPIO
GPIO_SetDebugPort(GPIO_PIN_TDI, DISABLE);
// 关闭 PB03 (JTDO/TRACESWO) 的调试功能,释放为普通 GPIO
GPIO_SetDebugPort(GPIO_PIN_TDO, DISABLE);
而后即可按照普通的GPIO进行配置。
额外需要注意的
观察GPIO_DebugPin_Sel 的定义可以发现,JTAG和SWD的部分引脚底层是相同的,例如:
#define GPIO_PIN_TCK (0x01U)
#define GPIO_PIN_SWCLK (0x01U)
#define GPIO_PIN_TMS (0x02U)
#define GPIO_PIN_SWDIO (0x02U)
这意味着部分JTAG功能引脚被关闭会导致SWD引脚也无法工作。
例如关闭JTAG所有功能GPIO_PIN_DEBUG_JTAG,或TCK和SWCLK,均会导致SWD调试下载使用的GPIO_PIN_SWCLK、GPIO_PIN_SWDIO无法工作。
进而导致你没有一个口可用于调试和下载了。
此时,只能通过在线烧录器或离线烧录器,按下图所示,将芯片切换到串口烧写模式,从而擦除错误的代码,抢救芯片。
