文章目录
前言
分析 V305 USBD 初始化程序。
实现
初始化
/* main.c */
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
SystemCoreClockUpdate();
// USB 初始化
USBHS_RCC_Init();
USBHS_Device_Init(ENABLE);
while(1);
}
初始化时钟
USBHS_RCC_Init();
初始化 USBD 设备
USBHS_Device_Init(ENABLE);
时钟初始化分析
void USBHS_RCC_Init( void )
{
// 时钟源选择:USB PHY
RCC_USBCLK48MConfig( RCC_USBCLK48MCLKSource_USBPHY );
// USBHS PLL 参考源选择:HSE
RCC_USBHSPLLCLKConfig( RCC_HSBHSPLLCLKSource_HSE );
// USBHS PLL 参考源分频:2分频
RCC_USBHSConfig( RCC_USBPLL_Div2 );
// USBHS PLL 参考时钟频率选择:4MHz
RCC_USBHSPLLCKREFCLKConfig( RCC_USBHSPLLCKREFCLK_4M );
// USBHS PLL 内部 PLL 控制使能
RCC_USBHSPHYPLLALIVEcmd( ENABLE );
// USBHS 模块时钟使能
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_USBHS, ENABLE );
}
USBD 设备初始化分析
void USBHS_Device_Init ( FunctionalState sta )
{
if( sta )
{
USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
Delay_Us(10);
USBHSD->CONTROL &= ~USBHS_UC_RESET_SIE;
USBHSD->HOST_CTRL = USBHS_UH_PHY_SUSPENDM;
USBHSD->CONTROL = USBHS_UC_DMA_EN | USBHS_UC_INT_BUSY | USBHS_UC_SPEED_HIGH;
USBHSD->INT_EN = USBHS_UIE_SETUP_ACT | USBHS_UIE_TRANSFER | USBHS_UIE_DETECT | USBHS_UIE_SUSPEND;
// 端点初始化
USBHS_Device_Endp_Init( );
USBHSD->CONTROL |= USBHS_UC_DEV_PU_EN;
NVIC_EnableIRQ( USBHS_IRQn );
}
else
{
USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
Delay_Us(10);
USBHSD->CONTROL = 0;
NVIC_DisableIRQ( USBHS_IRQn );
}
}
端点初始化分析
void USBHS_Device_Endp_Init ( void )
{
// 端点发送和接收使能:端点1-15,端点0的收发使能信号始终有效
USBHSD->ENDP_CONFIG = USBHS_UEP3_T_EN | USBHS_UEP3_R_EN |
USBHS_UEP2_T_EN | USBHS_UEP2_R_EN |
USBHS_UEP4_T_EN | USBHS_UEP4_R_EN;
// 端点n最大长度包:可接收数据最大长度,超出部分丢弃,不写入缓存
// 端口0最大支持 64 字节包,其他端点最大支持 1024 字节包
USBHSD->UEP0_MAX_LEN = DEF_USBD_UEP0_SIZE; // 64
USBHSD->UEP2_MAX_LEN = DEF_USB_EP2_HS_SIZE; // 512
USBHSD->UEP3_MAX_LEN = DEF_USB_EP3_HS_SIZE;
USBHSD->UEP4_MAX_LEN = DEF_USB_EP4_HS_SIZE;
// 端点0缓冲区起始地址,4字节对齐
USBHSD->UEP0_DMA = (uint32_t)(uint8_t *)USBHS_EP0_Buf;
// 端点n收发缓冲区起始地址,4字节对齐
USBHSD->UEP2_RX_DMA = (uint32_t)(uint8_t *)&UART2_Tx_Buf[ 0 ];
USBHSD->UEP2_TX_DMA = (uint32_t)(uint8_t *)USBHS_EP2_Tx_Buf;
USBHSD->UEP3_RX_DMA = (uint32_t)(uint8_t *)USBHS_EP3_Tx_Buf;
USBHSD->UEP4_TX_DMA = (uint32_t)(uint8_t *)USBHS_EP4_Tx_Buf;
USBHSD->UEP4_RX_DMA = (uint32_t)(uint8_t *)USBHS_EP4_Rx_Buf;
// 设置端点n准备发送的数据字节数,对于端点0,低7位有效
USBHSD->UEP0_TX_LEN = 0;
// 端点n发送控制寄存器,应答 NAK 或忙
USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_RES_NAK;
// 端点n接收控制寄存器,数据就绪并期望 ACK
USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_RES_ACK;
USBHSD->UEP2_TX_LEN = 0;
USBHSD->UEP2_TX_CTRL = USBHS_UEP_T_RES_NAK;
USBHSD->UEP2_RX_CTRL = USBHS_UEP_R_RES_ACK;
USBHSD->UEP3_TX_LEN = 0;
USBHSD->UEP3_TX_CTRL = USBHS_UEP_T_RES_NAK;
USBHSD->UEP3_RX_CTRL = USBHS_UEP_R_RES_ACK;
USBHSD->UEP4_TX_LEN = 0;
USBHSD->UEP4_TX_CTRL = USBHS_UEP_T_RES_NAK;
USBHSD->UEP4_RX_CTRL = USBHS_UEP_R_RES_ACK;
/* Clear End-points Busy Status */
for(uint8_t i=0; i<DEF_UEP_NUM; i++ )
{
USBHS_Endp_Busy[ i ] = 0;
}
}