在HAL_PCD_MspInit()中执行__HAL_RCC_USB_CLK_ENABLE()宏时,是什么初始化了STM32的USB BTABLE的内容?
What initialises the contents of the STM32's USB BTABLE when the __HAL_RCC_USB_CLK_ENABLE() macro is executed in HAL_PCD_MspInit()?
我已经使用STM32CubeMX/IDE为STM32F3DISCOVERY板生成USB HID工程。
USB BTABLE 寄存器为零,表明BTABLE 位于数据包存储区的开始。
(我在程序开始时将整个 PMA 归零,以避免过时的值。)
就在 __HAL_RCC_USB_CLK_ENABLE
宏执行之前(在 usbd_conf.c
中的 HAL_PCD_MspInit()
中)BTABLE 的值(从索引零开始,在 PMA 中)是:
执行该宏后,值为:
宏扩展为:
do { \
volatile uint32_t tmpreg; \
((((RCC_TypeDef *) ((0x40000000UL + 0x00020000UL) + 0x00001000UL))->APB1ENR) |= ((0x1UL << (23U))));\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = ((((RCC_TypeDef *) ((0x40000000UL + 0x00020000UL) + 0x00001000UL))->APB1ENR) & ((0x1UL << (23U))));\
(void)tmpreg; \
} while(0U)
这个宏是如何初始化 BTABLE 的?
(我需要 pma[12]
为 0x100
而不是 0x0
因为我想在复合设备中使用端点 3 作为 HID 接口。我正在使用这个简单的 HID 设备测试不同端点的使用。在 USBD_LL_Init()
和 #define HID_EPIN_ADDR
中将 0x81
更改为 0x83
不足以更改 pma[12]
的值。不正确的 TX pma[12]
处的指针被使用,并且在 wireshark 中观察到损坏的数据。)
更新:
如果我添加代码以手动将 pma[12]
设置为 0x100
:
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
uint16_t ep_addr,
uint16_t ep_kind,
uint32_t pmaadress)
...
/* Here we check if the endpoint is single or double Buffer*/
if (ep_kind == PCD_SNG_BUF)
{
/* Single Buffer */
ep->doublebuffer = 0U;
/* Configure the PMA */
ep->pmaadress = (uint16_t)pmaadress;
// correct PMA BTABLE
uint32_t *btable = (uint32_t *) USB_PMAADDR; // Test this.
if (ep->is_in) {
btable[ep->num * 4] = pmaadress;
}
}
pam[12]
处的值确实已设置,但稍后被覆盖:
__HAL_RCC_USB_CLK_ENABLE() 为 USB 块启用时钟。在启用之前,所有外设位置都被读取为零。启用时钟后,实际的 PMA 内容变得可见,无论是复位前写入的内容还是上电后留下的随机垃圾。所以执行 __HAL_RCC_USB_CLK_ENABLE() 与你的问题无关。
我不知道端点 3 的 TX 缓冲区地址在哪里被覆盖,但我猜是 Cube 在决定在端点上发送数据时设置它。我不熟悉Cube,它有API发送USB数据包吗?
此外,请仔细检查您的 pma 阵列是否具有正确的定义。在 F1 上,我可能在 F3 上,每个 32 位位置都有一个 2 字节的值。
UPD:抱歉,我先看到这个问题,但您真正的问题是为什么 TX addr 被覆盖或设置不正确。
我已经使用STM32CubeMX/IDE为STM32F3DISCOVERY板生成USB HID工程。
USB BTABLE 寄存器为零,表明BTABLE 位于数据包存储区的开始。
(我在程序开始时将整个 PMA 归零,以避免过时的值。)
就在 __HAL_RCC_USB_CLK_ENABLE
宏执行之前(在 usbd_conf.c
中的 HAL_PCD_MspInit()
中)BTABLE 的值(从索引零开始,在 PMA 中)是:
执行该宏后,值为:
宏扩展为:
do { \
volatile uint32_t tmpreg; \
((((RCC_TypeDef *) ((0x40000000UL + 0x00020000UL) + 0x00001000UL))->APB1ENR) |= ((0x1UL << (23U))));\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = ((((RCC_TypeDef *) ((0x40000000UL + 0x00020000UL) + 0x00001000UL))->APB1ENR) & ((0x1UL << (23U))));\
(void)tmpreg; \
} while(0U)
这个宏是如何初始化 BTABLE 的?
(我需要 pma[12]
为 0x100
而不是 0x0
因为我想在复合设备中使用端点 3 作为 HID 接口。我正在使用这个简单的 HID 设备测试不同端点的使用。在 USBD_LL_Init()
和 #define HID_EPIN_ADDR
中将 0x81
更改为 0x83
不足以更改 pma[12]
的值。不正确的 TX pma[12]
处的指针被使用,并且在 wireshark 中观察到损坏的数据。)
更新:
如果我添加代码以手动将 pma[12]
设置为 0x100
:
HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
uint16_t ep_addr,
uint16_t ep_kind,
uint32_t pmaadress)
...
/* Here we check if the endpoint is single or double Buffer*/
if (ep_kind == PCD_SNG_BUF)
{
/* Single Buffer */
ep->doublebuffer = 0U;
/* Configure the PMA */
ep->pmaadress = (uint16_t)pmaadress;
// correct PMA BTABLE
uint32_t *btable = (uint32_t *) USB_PMAADDR; // Test this.
if (ep->is_in) {
btable[ep->num * 4] = pmaadress;
}
}
pam[12]
处的值确实已设置,但稍后被覆盖:
__HAL_RCC_USB_CLK_ENABLE() 为 USB 块启用时钟。在启用之前,所有外设位置都被读取为零。启用时钟后,实际的 PMA 内容变得可见,无论是复位前写入的内容还是上电后留下的随机垃圾。所以执行 __HAL_RCC_USB_CLK_ENABLE() 与你的问题无关。
我不知道端点 3 的 TX 缓冲区地址在哪里被覆盖,但我猜是 Cube 在决定在端点上发送数据时设置它。我不熟悉Cube,它有API发送USB数据包吗?
此外,请仔细检查您的 pma 阵列是否具有正确的定义。在 F1 上,我可能在 F3 上,每个 32 位位置都有一个 2 字节的值。
UPD:抱歉,我先看到这个问题,但您真正的问题是为什么 TX addr 被覆盖或设置不正确。