【CH32V305FBP6】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 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;
    }
}

相关推荐

  1. CH32V305FBP6USBD 初始化分析

    2024-07-12 07:32:04       26 阅读
  2. 【国产MCU】-CH32V307-GPIO控制-外部中断

    2024-07-12 07:32:04       51 阅读
  3. 【国产MCU】-CH32V307-模拟/数字转换器(ADC)

    2024-07-12 07:32:04       50 阅读
  4. 【国产MCU】-CH32V307-触摸按键检测(TKEY)

    2024-07-12 07:32:04       52 阅读
  5. 沁恒CH32V30X学习笔记10---pwm输出

    2024-07-12 07:32:04       42 阅读
  6. 沁恒CH32V30X学习笔记04--外部中断

    2024-07-12 07:32:04       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 07:32:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 07:32:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 07:32:04       57 阅读
  4. Python语言-面向对象

    2024-07-12 07:32:04       68 阅读

热门阅读

  1. Ansible的Playbook

    2024-07-12 07:32:04       24 阅读
  2. Ansible

    2024-07-12 07:32:04       22 阅读
  3. RabbitMQ保证消息被成功发送和消费

    2024-07-12 07:32:04       23 阅读
  4. Python实现一对多WebSocket发送给指定多个客户端

    2024-07-12 07:32:04       26 阅读
  5. React 18 + Babel 7 + Webpack 5 开发环境搭建

    2024-07-12 07:32:04       27 阅读
  6. flutter常用库的介绍(1)

    2024-07-12 07:32:04       31 阅读
  7. 用Python和TensorFlow实现图像分类:从零开始

    2024-07-12 07:32:04       28 阅读
  8. 鸿蒙开发工程师面试题-架构篇

    2024-07-12 07:32:04       29 阅读
  9. 递推(C语言)

    2024-07-12 07:32:04       18 阅读
  10. C语言 输出图案

    2024-07-12 07:32:04       25 阅读
  11. Python Linux下编译

    2024-07-12 07:32:04       26 阅读