文章目录
- 前言
- 实现
- 时钟初始化分析
- USBD 设备初始化分析
- 端点初始化分析
前言
分析 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 PHYRCC_USBCLK48MConfig( RCC_USBCLK48MCLKSource_USBPHY );// USBHS PLL 参考源选择:HSERCC_USBHSPLLCLKConfig( RCC_HSBHSPLLCLKSource_HSE );// USBHS PLL 参考源分频:2分频RCC_USBHSConfig( RCC_USBPLL_Div2 );// USBHS PLL 参考时钟频率选择:4MHzRCC_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; // 64USBHSD->UEP2_MAX_LEN = DEF_USB_EP2_HS_SIZE; // 512USBHSD->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接收控制寄存器,数据就绪并期望 ACKUSBHSD->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;}
}