first submission
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x_it.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void SW_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn SW_Handler
|
||||
*
|
||||
* @brief This function handles Software exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SW_Handler(void) {
|
||||
__asm("li a6, 0x5000");
|
||||
__asm("jr a6");
|
||||
|
||||
while(1);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbotg_device.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file provides all the USBOTG firmware functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x_usbotg_device.h"
|
||||
#include "iap.h"
|
||||
/* Global define */
|
||||
/* OTH */
|
||||
#define pMySetupReqPakHD ((PUSB_SETUP_REQ)EP0_DatabufHD)
|
||||
#define RepDescSize 62
|
||||
#define DevEP0SIZE 0x40
|
||||
#define PID_OUT 0
|
||||
#define PID_SOF 1
|
||||
#define PID_IN 2
|
||||
#define PID_SETUP 3
|
||||
#define Version_Num 0x0100 //V0100
|
||||
u8 EP2_Tx_Buffer[2];
|
||||
/******************************************************************************/
|
||||
/* Endpoint Buffer */
|
||||
__attribute__ ((aligned(4))) UINT8 EP0_DatabufHD[64]; //ep0(64)
|
||||
__attribute__ ((aligned(4))) UINT8 EP2_DatabufHD[64+64]; //ep2_out(64)+ep2_in(64)
|
||||
|
||||
PUINT8 pEP0_RAM_Addr; //ep0(64)
|
||||
PUINT8 pEP2_RAM_Addr; //ep2_out(64)+ep2_in(64)
|
||||
|
||||
|
||||
const UINT8 *pDescr;
|
||||
|
||||
volatile UINT16 USBHD_Dev_SetupReqLen = 0x00;
|
||||
volatile UINT8 USBHD_Dev_Config = 0x00;
|
||||
volatile UINT8 USBHD_Dev_Address = 0x00;
|
||||
volatile UINT8 USBHD_Dev_SleepStatus = 0x00;
|
||||
volatile UINT8 DevConfig;
|
||||
volatile UINT8 SetupReqCode;
|
||||
volatile UINT16 SetupReqLen;
|
||||
/******************************************************************************/
|
||||
/* Device Descriptor */
|
||||
const UINT8 MyDevDescrHD[] = { 0x12, 0x01, 0x10, 0x01, 0xFF, 0x80, 0x55,
|
||||
DevEP0SIZE, 0x48, 0x43, 0xe0, 0x55, //USB MODULE
|
||||
(u8) Version_Num, (u8) (Version_Num >> 8),
|
||||
0x00, 0x00, 0x00, 0x01 };
|
||||
|
||||
/* Configration Descriptor */
|
||||
const UINT8 MyCfgDescrHD[] = { 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80,
|
||||
0x32, 0x09, 0x04, 0x00, 0x00, 0x02, 0xFF, 0x80, 0x55, 0x00, 0x07, 0x05,
|
||||
0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00 };
|
||||
|
||||
void USBHD_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBOTG_FS_DeviceInit
|
||||
*
|
||||
* @brief Initializes USB device.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBDeviceInit( void )
|
||||
{
|
||||
USBOTG_FS->BASE_CTRL = 0x00;
|
||||
|
||||
USBOTG_FS->UEP2_3_MOD = USBHD_UEP2_RX_EN|USBHD_UEP2_TX_EN;
|
||||
USBOTG_FS->UEP0_DMA = (UINT32)pEP0_RAM_Addr;
|
||||
USBOTG_FS->UEP2_DMA = (UINT32)pEP2_RAM_Addr;
|
||||
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP1_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP3_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
USBOTG_FS->UEP4_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
USBOTG_FS->UEP5_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
USBOTG_FS->UEP6_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
USBOTG_FS->UEP7_RX_CTRL = USBHD_UEP_R_RES_NAK;
|
||||
|
||||
USBOTG_FS->UEP2_TX_LEN = 8;
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_ACK|USBHD_UEP_AUTO_TOG;
|
||||
|
||||
USBOTG_FS->INT_FG = 0xFF;
|
||||
USBOTG_FS->INT_EN = USBHD_UIE_SUSPEND | USBHD_UIE_BUS_RST | USBHD_UIE_TRANSFER;
|
||||
USBOTG_FS->DEV_ADDR = 0x00;
|
||||
|
||||
USBOTG_FS->BASE_CTRL = USBHD_UC_DEV_PU_EN | USBHD_UC_INT_BUSY | USBHD_UC_DMA_EN;
|
||||
USBOTG_FS->UDEV_CTRL = USBHD_UD_PD_DIS|USBHD_UD_PORT_EN;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBOTG_RCC_Init
|
||||
*
|
||||
* @brief Initializes the usbotg clock configuration.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBOTG_RCC_Init(void)
|
||||
{
|
||||
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2);
|
||||
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_OTG_FS, ENABLE );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBOTG_Init
|
||||
*
|
||||
* @brief Initializes the USBOTG full speed device.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBOTG_Init( void )
|
||||
{
|
||||
pEP0_RAM_Addr = EP0_DatabufHD;
|
||||
pEP2_RAM_Addr = EP2_DatabufHD;
|
||||
USBOTG_RCC_Init( );
|
||||
Delay_Us(100);
|
||||
USBDeviceInit( );
|
||||
NVIC_EnableIRQ( USBHD_IRQn );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBHD_IRQHandler
|
||||
*
|
||||
* @brief This function handles OTG_FS exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBHD_IRQHandler( void )
|
||||
{
|
||||
UINT8 len, chtype;
|
||||
UINT8 intflag, errflag = 0;
|
||||
|
||||
intflag = USBOTG_FS->INT_FG;
|
||||
|
||||
if( intflag & USBHD_UIF_TRANSFER )
|
||||
{
|
||||
switch ( USBOTG_FS->INT_ST & USBHD_UIS_TOKEN_MASK )
|
||||
{
|
||||
/* SETUP */
|
||||
case USBHD_UIS_TOKEN_SETUP:
|
||||
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG|USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG|USBHD_UEP_R_RES_ACK;
|
||||
SetupReqLen = pSetupReqPakHD->wLength;
|
||||
SetupReqCode = pSetupReqPakHD->bRequest;
|
||||
chtype = pSetupReqPakHD->bRequestType;
|
||||
len = 0;
|
||||
errflag = 0;
|
||||
|
||||
if ( ( pSetupReqPakHD->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )
|
||||
{
|
||||
if( pSetupReqPakHD->bRequestType & 0x40 )
|
||||
{
|
||||
switch( pSetupReqPakHD->bRequest )
|
||||
{
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( pSetupReqPakHD->bRequestType & 0x20 )
|
||||
{
|
||||
switch( pSetupReqPakHD->bRequest )
|
||||
{
|
||||
case 0x01: //GetReport
|
||||
break;
|
||||
case 0x02: //GetIdle
|
||||
break;
|
||||
case 0x03: //GetProtocol
|
||||
break;
|
||||
case 0x09: //SetReport
|
||||
break;
|
||||
case 0x0A: //SetIdle
|
||||
break;
|
||||
case 0x0B: //SetProtocol
|
||||
break;
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( errflag != 0xFF )
|
||||
{
|
||||
if( SetupReqLen > len )
|
||||
{
|
||||
SetupReqLen = len;
|
||||
}
|
||||
len = ( USBHD_Dev_SetupReqLen >= DevEP0SIZE ) ? DevEP0SIZE : USBHD_Dev_SetupReqLen;
|
||||
memcpy( EP0_DatabufHD, pDescr, len );
|
||||
pDescr += len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( SetupReqCode )
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
{
|
||||
switch( ((pSetupReqPakHD->wValue)>>8) )
|
||||
{
|
||||
case USB_DESCR_TYP_DEVICE:
|
||||
pDescr = MyDevDescrHD;
|
||||
len = MyDevDescrHD[0];
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_CONFIG:
|
||||
pDescr = MyCfgDescrHD;
|
||||
len = MyCfgDescrHD[2];
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_STRING:
|
||||
switch( (pSetupReqPakHD->wValue)&0xff )
|
||||
{
|
||||
case 0:
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_REPORT:
|
||||
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_QUALIF:
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
errflag = 0xff;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if( SetupReqLen>len ) SetupReqLen = len;
|
||||
len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
|
||||
memcpy( pEP0_DataBuf, pDescr, len );
|
||||
pDescr += len;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_SET_ADDRESS:
|
||||
SetupReqLen = (pSetupReqPakHD->wValue)&0xff;
|
||||
break;
|
||||
|
||||
case USB_GET_CONFIGURATION:
|
||||
pEP0_DataBuf[0] = DevConfig;
|
||||
if ( SetupReqLen > 1 ) SetupReqLen = 1;
|
||||
break;
|
||||
|
||||
case USB_SET_CONFIGURATION:
|
||||
DevConfig = (pSetupReqPakHD->wValue)&0xff;
|
||||
break;
|
||||
|
||||
case USB_CLEAR_FEATURE:
|
||||
if ( ( pSetupReqPakHD->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )
|
||||
{
|
||||
switch( (pSetupReqPakHD->wIndex)&0xff )
|
||||
{
|
||||
case 0x82:
|
||||
USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~( USBHD_UEP_T_TOG|USBHD_UEP_T_RES_MASK )) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
USBOTG_FS->UEP2_RX_CTRL = (USBOTG_FS->UEP2_RX_CTRL & ~( USBHD_UEP_R_TOG|USBHD_UEP_R_RES_MASK )) | USBHD_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~( USBHD_UEP_T_TOG|USBHD_UEP_T_RES_MASK )) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
USBOTG_FS->UEP1_RX_CTRL = (USBOTG_FS->UEP1_RX_CTRL & ~( USBHD_UEP_R_TOG|USBHD_UEP_R_RES_MASK )) | USBHD_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else errflag = 0xFF;
|
||||
break;
|
||||
|
||||
case USB_SET_FEATURE:
|
||||
if( ( pMySetupReqPakHD->bRequestType & 0x1F ) == 0x00 )
|
||||
{
|
||||
if( pMySetupReqPakHD->wValue == 0x01 )
|
||||
{
|
||||
if( MyCfgDescrHD[ 7 ] & 0x20 )
|
||||
{
|
||||
USBHD_Dev_SleepStatus = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else if( ( pMySetupReqPakHD->bRequestType & 0x1F ) == 0x02 )
|
||||
{
|
||||
if( pMySetupReqPakHD->wValue == 0x00 )
|
||||
{
|
||||
switch( ( pMySetupReqPakHD->wIndex ) & 0xff )
|
||||
{
|
||||
case 0x82:
|
||||
USBOTG_FS->UEP2_TX_CTRL = ( USBOTG_FS->UEP2_TX_CTRL &= ~USBHD_UEP_T_RES_MASK ) | USBHD_UEP_T_RES_STALL;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
USBOTG_FS->UEP2_RX_CTRL = ( USBOTG_FS->UEP2_RX_CTRL &= ~USBHD_UEP_R_RES_MASK ) | USBHD_UEP_R_RES_STALL;
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_GET_INTERFACE:
|
||||
pEP0_DataBuf[0] = 0x00;
|
||||
if ( SetupReqLen > 1 ) SetupReqLen = 1;
|
||||
break;
|
||||
|
||||
case USB_SET_INTERFACE:
|
||||
EP0_DatabufHD[ 0 ] = 0x00;
|
||||
if( USBHD_Dev_SetupReqLen > 1 )
|
||||
{
|
||||
USBHD_Dev_SetupReqLen = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_GET_STATUS:
|
||||
EP0_DatabufHD[ 0 ] = 0x00;
|
||||
EP0_DatabufHD[ 1 ] = 0x00;
|
||||
if( pMySetupReqPakHD->wIndex == 0x81 )
|
||||
{
|
||||
if( ( USBOTG_FS->UEP1_TX_CTRL & USBHD_UEP_T_RES_MASK ) == USBHD_UEP_T_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x01 )
|
||||
{
|
||||
if( ( USBOTG_FS->UEP1_RX_CTRL & USBHD_UEP_R_RES_MASK ) == USBHD_UEP_R_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x82 )
|
||||
{
|
||||
if( ( USBOTG_FS->UEP2_TX_CTRL & USBHD_UEP_T_RES_MASK ) == USBHD_UEP_T_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x02 )
|
||||
{
|
||||
if( ( USBOTG_FS->UEP2_RX_CTRL & USBHD_UEP_R_RES_MASK ) == USBHD_UEP_R_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
if( USBHD_Dev_SetupReqLen > 2 )
|
||||
{
|
||||
USBHD_Dev_SetupReqLen = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( errflag == 0xff)
|
||||
{
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG|USBHD_UEP_T_RES_STALL;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG|USBHD_UEP_R_RES_STALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( chtype & 0x80 )
|
||||
{
|
||||
len = (SetupReqLen>DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
|
||||
SetupReqLen -= len;
|
||||
}
|
||||
else len = 0;
|
||||
|
||||
USBOTG_FS->UEP0_TX_LEN = len;
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG|USBHD_UEP_T_RES_ACK;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG|USBHD_UEP_R_RES_ACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN:
|
||||
switch ( USBOTG_FS->INT_ST & ( USBHD_UIS_TOKEN_MASK | USBHD_UIS_ENDP_MASK ) )
|
||||
{
|
||||
case USBHD_UIS_TOKEN_IN:
|
||||
switch( SetupReqCode )
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen;
|
||||
memcpy( pEP0_DataBuf, pDescr, len );
|
||||
SetupReqLen -= len;
|
||||
pDescr += len;
|
||||
USBOTG_FS->UEP0_TX_LEN = len;
|
||||
USBOTG_FS->UEP0_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
break;
|
||||
|
||||
case USB_SET_ADDRESS:
|
||||
USBOTG_FS->DEV_ADDR = (USBOTG_FS->DEV_ADDR&USBHD_UDA_GP_BIT) | SetupReqLen;
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
default:
|
||||
USBOTG_FS->UEP0_TX_LEN = 0;
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 2:
|
||||
|
||||
USBOTG_FS->UEP2_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT:
|
||||
switch ( USBOTG_FS->INT_ST & ( USBHD_UIS_TOKEN_MASK | USBHD_UIS_ENDP_MASK ) )
|
||||
{
|
||||
case USBHD_UIS_TOKEN_OUT:
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 2:
|
||||
if ( USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK )
|
||||
{
|
||||
USBOTG_FS->UEP2_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP2_OUT_Deal( len );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_SOF:
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
USBOTG_FS->INT_FG = USBHD_UIF_TRANSFER;
|
||||
}
|
||||
else if( intflag & USBHD_UIF_BUS_RST )
|
||||
{
|
||||
USBOTG_FS->DEV_ADDR = 0;
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->INT_FG |= USBHD_UIF_BUS_RST;
|
||||
}
|
||||
else if( intflag & USBHD_UIF_SUSPEND )
|
||||
{
|
||||
if ( USBOTG_FS->MIS_ST & USBHD_UMS_SUSPEND ) {;}
|
||||
else{;}
|
||||
USBOTG_FS->INT_FG = USBHD_UIF_SUSPEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_FS->INT_FG = intflag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP2_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint2 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP2_IN_Deal( UINT8 l )
|
||||
{
|
||||
USBOTG_FS->UEP2_TX_LEN = l;
|
||||
USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~USBHD_UEP_T_RES_MASK)| USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP2_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 2 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP2_OUT_Deal( UINT8 l )
|
||||
{
|
||||
UINT8 s ,EP2_Tx_Cnt;
|
||||
|
||||
memcpy(EP2_Rx_Buffer, pEP2_OUT_DataBuf, l);
|
||||
s = RecData_Deal();
|
||||
if (s != ERR_End) {
|
||||
EP2_Tx_Buffer[0] = 0x00;
|
||||
if (s == ERR_ERROR)
|
||||
{
|
||||
pEP2_IN_DataBuf[1] = 0x01;
|
||||
}
|
||||
else
|
||||
pEP2_IN_DataBuf[1] = 0x00;
|
||||
EP2_Tx_Cnt = 2;
|
||||
DevEP2_IN_Deal(EP2_Tx_Cnt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,719 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbotg_device.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file provides all the USBOTG firmware functions.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_USBOTG_DEVICE_H_
|
||||
#define __CH32V20x_USBOTG_DEVICE_H_
|
||||
|
||||
#include "debug.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
#endif
|
||||
#ifndef CONST
|
||||
#define CONST const
|
||||
#endif
|
||||
#ifndef BOOL
|
||||
typedef unsigned char BOOL;
|
||||
#endif
|
||||
#ifndef BOOLEAN
|
||||
typedef unsigned char BOOLEAN;
|
||||
#endif
|
||||
#ifndef CHAR
|
||||
typedef char CHAR;
|
||||
#endif
|
||||
#ifndef INT8
|
||||
typedef char INT8;
|
||||
#endif
|
||||
#ifndef INT16
|
||||
typedef short INT16;
|
||||
#endif
|
||||
#ifndef INT32
|
||||
typedef long INT32;
|
||||
#endif
|
||||
#ifndef UINT8
|
||||
typedef unsigned char UINT8;
|
||||
#endif
|
||||
#ifndef UINT16
|
||||
typedef unsigned short UINT16;
|
||||
#endif
|
||||
#ifndef UINT32
|
||||
typedef unsigned long UINT32;
|
||||
#endif
|
||||
#ifndef UINT8V
|
||||
typedef unsigned char volatile UINT8V;
|
||||
#endif
|
||||
#ifndef UINT16V
|
||||
typedef unsigned short volatile UINT16V;
|
||||
#endif
|
||||
#ifndef UINT32V
|
||||
typedef unsigned long volatile UINT32V;
|
||||
#endif
|
||||
|
||||
#ifndef PVOID
|
||||
typedef void *PVOID;
|
||||
#endif
|
||||
#ifndef PCHAR
|
||||
typedef char *PCHAR;
|
||||
#endif
|
||||
#ifndef PCHAR
|
||||
typedef const char *PCCHAR;
|
||||
#endif
|
||||
#ifndef PINT8
|
||||
typedef char *PINT8;
|
||||
#endif
|
||||
#ifndef PINT16
|
||||
typedef short *PINT16;
|
||||
#endif
|
||||
#ifndef PINT32
|
||||
typedef long *PINT32;
|
||||
#endif
|
||||
#ifndef PUINT8
|
||||
typedef unsigned char *PUINT8;
|
||||
#endif
|
||||
#ifndef PUINT16
|
||||
typedef unsigned short *PUINT16;
|
||||
#endif
|
||||
#ifndef PUINT32
|
||||
typedef unsigned long *PUINT32;
|
||||
#endif
|
||||
#ifndef PUINT8V
|
||||
typedef volatile unsigned char *PUINT8V;
|
||||
#endif
|
||||
#ifndef PUINT16V
|
||||
typedef volatile unsigned short *PUINT16V;
|
||||
#endif
|
||||
#ifndef PUINT32V
|
||||
typedef volatile unsigned long *PUINT32V;
|
||||
#endif
|
||||
|
||||
|
||||
/* USB constant and structure define */
|
||||
|
||||
/* USB PID */
|
||||
#ifndef USB_PID_SETUP
|
||||
#define USB_PID_NULL 0x00 /* reserved PID */
|
||||
#define USB_PID_SOF 0x05
|
||||
#define USB_PID_SETUP 0x0D
|
||||
#define USB_PID_IN 0x09
|
||||
#define USB_PID_OUT 0x01
|
||||
#define USB_PID_ACK 0x02
|
||||
#define USB_PID_NAK 0x0A
|
||||
#define USB_PID_STALL 0x0E
|
||||
#define USB_PID_DATA0 0x03
|
||||
#define USB_PID_DATA1 0x0B
|
||||
#define USB_PID_PRE 0x0C
|
||||
#endif
|
||||
|
||||
/* USB standard device request code */
|
||||
#ifndef USB_GET_DESCRIPTOR
|
||||
#define USB_GET_STATUS 0x00
|
||||
#define USB_CLEAR_FEATURE 0x01
|
||||
#define USB_SET_FEATURE 0x03
|
||||
#define USB_SET_ADDRESS 0x05
|
||||
#define USB_GET_DESCRIPTOR 0x06
|
||||
#define USB_SET_DESCRIPTOR 0x07
|
||||
#define USB_GET_CONFIGURATION 0x08
|
||||
#define USB_SET_CONFIGURATION 0x09
|
||||
#define USB_GET_INTERFACE 0x0A
|
||||
#define USB_SET_INTERFACE 0x0B
|
||||
#define USB_SYNCH_FRAME 0x0C
|
||||
#endif
|
||||
|
||||
/* USB hub class request code */
|
||||
#ifndef HUB_GET_DESCRIPTOR
|
||||
#define HUB_GET_STATUS 0x00
|
||||
#define HUB_CLEAR_FEATURE 0x01
|
||||
#define HUB_GET_STATE 0x02
|
||||
#define HUB_SET_FEATURE 0x03
|
||||
#define HUB_GET_DESCRIPTOR 0x06
|
||||
#define HUB_SET_DESCRIPTOR 0x07
|
||||
#endif
|
||||
|
||||
/* USB HID class request code */
|
||||
#ifndef HID_GET_REPORT
|
||||
#define HID_GET_REPORT 0x01
|
||||
#define HID_GET_IDLE 0x02
|
||||
#define HID_GET_PROTOCOL 0x03
|
||||
#define HID_SET_REPORT 0x09
|
||||
#define HID_SET_IDLE 0x0A
|
||||
#define HID_SET_PROTOCOL 0x0B
|
||||
#endif
|
||||
|
||||
/* Bit define for USB request type */
|
||||
#ifndef USB_REQ_TYP_MASK
|
||||
#define USB_REQ_TYP_IN 0x80 /* control IN, device to host */
|
||||
#define USB_REQ_TYP_OUT 0x00 /* control OUT, host to device */
|
||||
#define USB_REQ_TYP_READ 0x80 /* control read, device to host */
|
||||
#define USB_REQ_TYP_WRITE 0x00 /* control write, host to device */
|
||||
#define USB_REQ_TYP_MASK 0x60 /* bit mask of request type */
|
||||
#define USB_REQ_TYP_STANDARD 0x00
|
||||
#define USB_REQ_TYP_CLASS 0x20
|
||||
#define USB_REQ_TYP_VENDOR 0x40
|
||||
#define USB_REQ_TYP_RESERVED 0x60
|
||||
#define USB_REQ_RECIP_MASK 0x1F /* bit mask of request recipient */
|
||||
#define USB_REQ_RECIP_DEVICE 0x00
|
||||
#define USB_REQ_RECIP_INTERF 0x01
|
||||
#define USB_REQ_RECIP_ENDP 0x02
|
||||
#define USB_REQ_RECIP_OTHER 0x03
|
||||
#endif
|
||||
|
||||
/* USB request type for hub class request */
|
||||
#ifndef HUB_GET_HUB_DESCRIPTOR
|
||||
#define HUB_CLEAR_HUB_FEATURE 0x20
|
||||
#define HUB_CLEAR_PORT_FEATURE 0x23
|
||||
#define HUB_GET_BUS_STATE 0xA3
|
||||
#define HUB_GET_HUB_DESCRIPTOR 0xA0
|
||||
#define HUB_GET_HUB_STATUS 0xA0
|
||||
#define HUB_GET_PORT_STATUS 0xA3
|
||||
#define HUB_SET_HUB_DESCRIPTOR 0x20
|
||||
#define HUB_SET_HUB_FEATURE 0x20
|
||||
#define HUB_SET_PORT_FEATURE 0x23
|
||||
#endif
|
||||
|
||||
/* Hub class feature selectors */
|
||||
#ifndef HUB_PORT_RESET
|
||||
#define HUB_C_HUB_LOCAL_POWER 0
|
||||
#define HUB_C_HUB_OVER_CURRENT 1
|
||||
#define HUB_PORT_CONNECTION 0
|
||||
#define HUB_PORT_ENABLE 1
|
||||
#define HUB_PORT_SUSPEND 2
|
||||
#define HUB_PORT_OVER_CURRENT 3
|
||||
#define HUB_PORT_RESET 4
|
||||
#define HUB_PORT_POWER 8
|
||||
#define HUB_PORT_LOW_SPEED 9
|
||||
#define HUB_C_PORT_CONNECTION 16
|
||||
#define HUB_C_PORT_ENABLE 17
|
||||
#define HUB_C_PORT_SUSPEND 18
|
||||
#define HUB_C_PORT_OVER_CURRENT 19
|
||||
#define HUB_C_PORT_RESET 20
|
||||
#endif
|
||||
|
||||
/* USB descriptor type */
|
||||
#ifndef USB_DESCR_TYP_DEVICE
|
||||
#define USB_DESCR_TYP_DEVICE 0x01
|
||||
#define USB_DESCR_TYP_CONFIG 0x02
|
||||
#define USB_DESCR_TYP_STRING 0x03
|
||||
#define USB_DESCR_TYP_INTERF 0x04
|
||||
#define USB_DESCR_TYP_ENDP 0x05
|
||||
#define USB_DESCR_TYP_QUALIF 0x06
|
||||
#define USB_DESCR_TYP_SPEED 0x07
|
||||
#define USB_DESCR_TYP_OTG 0x09
|
||||
#define USB_DESCR_TYP_BOS 0X0F
|
||||
#define USB_DESCR_TYP_HID 0x21
|
||||
#define USB_DESCR_TYP_REPORT 0x22
|
||||
#define USB_DESCR_TYP_PHYSIC 0x23
|
||||
#define USB_DESCR_TYP_CS_INTF 0x24
|
||||
#define USB_DESCR_TYP_CS_ENDP 0x25
|
||||
#define USB_DESCR_TYP_HUB 0x29
|
||||
#endif
|
||||
|
||||
/* USB device class */
|
||||
#ifndef USB_DEV_CLASS_HUB
|
||||
#define USB_DEV_CLASS_RESERVED 0x00
|
||||
#define USB_DEV_CLASS_AUDIO 0x01
|
||||
#define USB_DEV_CLASS_COMMUNIC 0x02
|
||||
#define USB_DEV_CLASS_HID 0x03
|
||||
#define USB_DEV_CLASS_MONITOR 0x04
|
||||
#define USB_DEV_CLASS_PHYSIC_IF 0x05
|
||||
#define USB_DEV_CLASS_POWER 0x06
|
||||
#define USB_DEV_CLASS_PRINTER 0x07
|
||||
#define USB_DEV_CLASS_STORAGE 0x08
|
||||
#define USB_DEV_CLASS_HUB 0x09
|
||||
#define USB_DEV_CLASS_VEN_SPEC 0xFF
|
||||
#endif
|
||||
|
||||
/* USB endpoint type and attributes */
|
||||
#ifndef USB_ENDP_TYPE_MASK
|
||||
#define USB_ENDP_DIR_MASK 0x80
|
||||
#define USB_ENDP_ADDR_MASK 0x0F
|
||||
#define USB_ENDP_TYPE_MASK 0x03
|
||||
#define USB_ENDP_TYPE_CTRL 0x00
|
||||
#define USB_ENDP_TYPE_ISOCH 0x01
|
||||
#define USB_ENDP_TYPE_BULK 0x02
|
||||
#define USB_ENDP_TYPE_INTER 0x03
|
||||
#endif
|
||||
|
||||
#ifndef USB_DEVICE_ADDR
|
||||
#define USB_DEVICE_ADDR 0x02
|
||||
#endif
|
||||
#ifndef DEFAULT_ENDP0_SIZE
|
||||
#define DEFAULT_ENDP0_SIZE 8 /* default maximum packet size for endpoint 0 */
|
||||
#endif
|
||||
#ifndef MAX_PACKET_SIZE
|
||||
#define MAX_PACKET_SIZE 64 /* maximum packet size */
|
||||
#endif
|
||||
#ifndef USB_BO_CBW_SIZE
|
||||
#define USB_BO_CBW_SIZE 0x1F
|
||||
#define USB_BO_CSW_SIZE 0x0D
|
||||
#endif
|
||||
#ifndef USB_BO_CBW_SIG0
|
||||
#define USB_BO_CBW_SIG0 0x55
|
||||
#define USB_BO_CBW_SIG1 0x53
|
||||
#define USB_BO_CBW_SIG2 0x42
|
||||
#define USB_BO_CBW_SIG3 0x43
|
||||
#define USB_BO_CSW_SIG0 0x55
|
||||
#define USB_BO_CSW_SIG1 0x53
|
||||
#define USB_BO_CSW_SIG2 0x42
|
||||
#define USB_BO_CSW_SIG3 0x53
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
typedef struct __PACKED _USB_SETUP_REQ {
|
||||
UINT8 bRequestType;
|
||||
UINT8 bRequest;
|
||||
UINT16 wValue;
|
||||
UINT16 wIndex;
|
||||
UINT16 wLength;
|
||||
} USB_SETUP_REQ, *PUSB_SETUP_REQ;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_DEVICE_DESCR {
|
||||
UINT8 bLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT16 bcdUSB;
|
||||
UINT8 bDeviceClass;
|
||||
UINT8 bDeviceSubClass;
|
||||
UINT8 bDeviceProtocol;
|
||||
UINT8 bMaxPacketSize0;
|
||||
UINT16 idVendor;
|
||||
UINT16 idProduct;
|
||||
UINT16 bcdDevice;
|
||||
UINT8 iManufacturer;
|
||||
UINT8 iProduct;
|
||||
UINT8 iSerialNumber;
|
||||
UINT8 bNumConfigurations;
|
||||
} USB_DEV_DESCR, *PUSB_DEV_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_CONFIG_DESCR {
|
||||
UINT8 bLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT16 wTotalLength;
|
||||
UINT8 bNumInterfaces;
|
||||
UINT8 bConfigurationValue;
|
||||
UINT8 iConfiguration;
|
||||
UINT8 bmAttributes;
|
||||
UINT8 MaxPower;
|
||||
} USB_CFG_DESCR, *PUSB_CFG_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_INTERF_DESCR {
|
||||
UINT8 bLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT8 bInterfaceNumber;
|
||||
UINT8 bAlternateSetting;
|
||||
UINT8 bNumEndpoints;
|
||||
UINT8 bInterfaceClass;
|
||||
UINT8 bInterfaceSubClass;
|
||||
UINT8 bInterfaceProtocol;
|
||||
UINT8 iInterface;
|
||||
} USB_ITF_DESCR, *PUSB_ITF_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_ENDPOINT_DESCR {
|
||||
UINT8 bLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT8 bEndpointAddress;
|
||||
UINT8 bmAttributes;
|
||||
UINT16 wMaxPacketSize;
|
||||
UINT8 bInterval;
|
||||
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_CONFIG_DESCR_LONG {
|
||||
USB_CFG_DESCR cfg_descr;
|
||||
USB_ITF_DESCR itf_descr;
|
||||
USB_ENDP_DESCR endp_descr[1];
|
||||
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_HUB_DESCR {
|
||||
UINT8 bDescLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT8 bNbrPorts;
|
||||
UINT8 wHubCharacteristicsL;
|
||||
UINT8 wHubCharacteristicsH;
|
||||
UINT8 bPwrOn2PwrGood;
|
||||
UINT8 bHubContrCurrent;
|
||||
UINT8 DeviceRemovable;
|
||||
UINT8 PortPwrCtrlMask;
|
||||
} USB_HUB_DESCR, *PUSB_HUB_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _USB_HID_DESCR {
|
||||
UINT8 bLength;
|
||||
UINT8 bDescriptorType;
|
||||
UINT16 bcdHID;
|
||||
UINT8 bCountryCode;
|
||||
UINT8 bNumDescriptors;
|
||||
UINT8 bDescriptorTypeX;
|
||||
UINT8 wDescriptorLengthL;
|
||||
UINT8 wDescriptorLengthH;
|
||||
} USB_HID_DESCR, *PUSB_HID_DESCR;
|
||||
|
||||
|
||||
typedef struct __PACKED _UDISK_BOC_CBW {/* command of BulkOnly USB-FlashDisk */
|
||||
UINT32 mCBW_Sig;
|
||||
UINT32 mCBW_Tag;
|
||||
UINT32 mCBW_DataLen; /* uppest byte of data length, always is 0 */
|
||||
UINT8 mCBW_Flag; /* transfer direction and etc. */
|
||||
UINT8 mCBW_LUN;
|
||||
UINT8 mCBW_CB_Len; /* length of command block */
|
||||
UINT8 mCBW_CB_Buf[16]; /* command block buffer */
|
||||
} UDISK_BOC_CBW, *PXUDISK_BOC_CBW;
|
||||
|
||||
|
||||
typedef struct __PACKED _UDISK_BOC_CSW {/* status of BulkOnly USB-FlashDisk */
|
||||
UINT32 mCBW_Sig;
|
||||
UINT32 mCBW_Tag;
|
||||
UINT32 mCSW_Residue; /* return: remainder bytes */ /* uppest byte of remainder length, always is 0 */
|
||||
UINT8 mCSW_Status; /* return: result status */
|
||||
} UDISK_BOC_CSW, *PXUDISK_BOC_CSW;
|
||||
|
||||
|
||||
#define USE_SYS_CLK 0
|
||||
//#define USBHD_HOST 0
|
||||
//#define USB_OTG 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* USBOTG_FS DEVICE USB_CONTROL */
|
||||
/* BASE USB_CTRL */
|
||||
#define USBHD_BASE_CTRL (USBOTG_FS->BASE_CTRL) // USB base control
|
||||
#define USBHD_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
|
||||
#define USBHD_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
|
||||
#define USBHD_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
|
||||
#define USBHD_UC_SYS_CTRL1 0x20 // USB system control high bit
|
||||
#define USBHD_UC_SYS_CTRL0 0x10 // USB system control low bit
|
||||
#define USBHD_UC_SYS_CTRL_MASK 0x30 // bit mask of USB system control
|
||||
// UC_HOST_MODE & UC_SYS_CTRL1 & UC_SYS_CTRL0: USB system control
|
||||
// 0 00: disable USB device and disable internal pullup resistance
|
||||
// 0 01: enable USB device and disable internal pullup resistance, need external pullup resistance
|
||||
// 0 1x: enable USB device and enable internal pullup resistance
|
||||
// 1 00: enable USB host and normal status
|
||||
// 1 01: enable USB host and force UDP/UDM output SE0 state
|
||||
// 1 10: enable USB host and force UDP/UDM output J state
|
||||
// 1 11: enable USB host and force UDP/UDM output resume or K state
|
||||
#define USBHD_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
|
||||
#define USBHD_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
|
||||
#define USBHD_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
|
||||
#define USBHD_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
|
||||
/* DEVICE USB_CTRL */
|
||||
#define USBHD_UDEV_CTRL (USBOTG_FS->UDEV_CTRL) // USB device physical prot control
|
||||
#define USBHD_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBHD_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBHD_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBHD_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
|
||||
#define USBHD_UD_GP_BIT 0x02 // general purpose bit
|
||||
#define USBHD_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
|
||||
/* USB INT EN */
|
||||
#define USBHD_INT_EN (USBOTG_FS->INT_EN) // USB interrupt enable
|
||||
#define USBHD_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
|
||||
#define USBHD_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
|
||||
#define USBHD_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
|
||||
#define USBHD_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
|
||||
#define USBHD_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
|
||||
#define USBHD_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
|
||||
#define USBHD_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
|
||||
#define USBHD_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
|
||||
/* USB_DEV_ADDR */
|
||||
#define USBHD_DEV_ADDR (USBOTG_FS->DEV_ADDR) // USB device address
|
||||
#define USBHD_UDA_GP_BIT 0x80 // general purpose bit
|
||||
#define USBHD_USB_ADDR_MASK 0x7F // bit mask for USB device address
|
||||
/* USBOTG_FS DEVICE USB_STATUS */
|
||||
/* USB_MIS_ST */
|
||||
#define USBHD_MIS_ST (USBOTG_FS->MIS_ST) // USB miscellaneous status
|
||||
#define USBHD_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
|
||||
#define USBHD_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
|
||||
#define USBHD_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBHD_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
|
||||
#define USBHD_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
|
||||
#define USBHD_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
|
||||
#define USBHD_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
|
||||
#define USBHD_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
|
||||
/* USB_INT_FG */
|
||||
#define USBHD_INT_FG (USBOTG_FS->INT_FG) // USB interrupt flag
|
||||
#define USBHD_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
|
||||
#define USBHD_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBHD_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBHD_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
|
||||
#define USBHD_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
|
||||
#define USBHD_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBHD_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBHD_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
|
||||
#define USBHD_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
|
||||
/* USB_INT_ST */
|
||||
#define USBHD_INT_ST (USBOTG_FS->INT_ST) // USB interrupt flag
|
||||
#define USBHD_UIS_IS_SETUP 0x80 // RO, indicate current USB transfer is setup received for USB device mode
|
||||
#define USBHD_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
|
||||
#define USBHD_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBHD_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
|
||||
#define USBHD_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
|
||||
#define USBHD_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
|
||||
#define USBHD_UIS_TOKEN_OUT 0x00
|
||||
#define USBHD_UIS_TOKEN_SOF 0x10
|
||||
#define USBHD_UIS_TOKEN_IN 0x20
|
||||
#define USBHD_UIS_TOKEN_SETUP 0x30
|
||||
// UIS_TOKEN1 & UIS_TOKEN0: current token PID code received for USB device mode
|
||||
// 00: OUT token PID received
|
||||
// 01: SOF token PID received
|
||||
// 10: IN token PID received
|
||||
// 11: SETUP token PID received
|
||||
#define USBHD_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
|
||||
/* USB_RX_LEN */
|
||||
#define USBHD_RX_LEN (USBOTG_FS->Rx_Len) // USB receiving length
|
||||
/* USB_BUF_MOD */
|
||||
#define USBHD_UEP4_1_MOD (USBOTG_FS->UEP4_1_MOD) // endpoint 4/1 mode
|
||||
#define USBHD_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
|
||||
#define USBHD_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
|
||||
#define USBHD_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
|
||||
// UEPn_RX_EN & UEPn_TX_EN & UEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
|
||||
// 0 0 x: disable endpoint and disable buffer
|
||||
// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
|
||||
// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
|
||||
// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
|
||||
// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
|
||||
#define USBHD_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
|
||||
#define USBHD_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
|
||||
// UEP4_RX_EN & UEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
|
||||
// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
|
||||
// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
|
||||
// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
|
||||
|
||||
#define USBHD_UEP2_3_MOD (USBOTG_FS->UEP2_3_MOD) // endpoint 2/3 mode
|
||||
#define USBHD_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
|
||||
#define USBHD_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
|
||||
#define USBHD_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
|
||||
#define USBHD_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
|
||||
#define USBHD_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
|
||||
#define USBHD_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
|
||||
|
||||
#define USBHD_UEP5_6_MOD (USBOTG_FS->UEP5_6_MOD) // endpoint 5/6 mode
|
||||
#define USBHD_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
|
||||
#define USBHD_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
|
||||
#define USBHD_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
|
||||
#define USBHD_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
|
||||
#define USBHD_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
|
||||
#define USBHD_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
|
||||
|
||||
#define USBHD_UEP7_MOD (USBOTG_FS->UEP7_MOD) // endpoint 7 mode
|
||||
#define USBHD_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
|
||||
#define USBHD_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
|
||||
#define USBHD_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
|
||||
/* USB_DMA */
|
||||
#define USBHD_UEP0_DMA (USBOTG_FS->UEP0_DMA) // endpoint 0 DMA buffer address
|
||||
//#define USBHD_UEP1_DMA (USBOTG_FS->UEP1_DMA) // endpoint 1 DMA buffer address
|
||||
#define USBHD_UEP2_DMA (USBOTG_FS->UEP2_DMA) // endpoint 2 DMA buffer address
|
||||
//#define USBHD_UEP3_DMA (USBOTG_FS->UEP3_DMA) // endpoint 3 DMA buffer address
|
||||
//#define USBHD_UEP4_DMA (USBOTG_FS->UEP4_DMA) // endpoint 4 DMA buffer address
|
||||
//#define USBHD_UEP5_DMA (USBOTG_FS->UEP5_DMA) // endpoint 5 DMA buffer address
|
||||
//#define USBHD_UEP6_DMA (USBOTG_FS->UEP6_DMA) // endpoint 6 DMA buffer address
|
||||
//#define USBHD_UEP7_DMA (USBOTG_FS->UEP7_DMA) // endpoint 7 DMA buffer address
|
||||
/* USB_EP_CTRL */
|
||||
#define USBHD_UEP0_T_LEN (USBOTG_FS->UEP0_TX_LEN) // endpoint 0 transmittal length
|
||||
#define USBHD_UEP0_TX_CTRL (USBOTG_FS->UEP0_TX_CTRL) // endpoint 0 control
|
||||
#define USBHD_UEP0_RX_CTRL (USBOTG_FS->UEP0_RX_CTRL) // endpoint 0 control
|
||||
|
||||
//#define USBHD_UEP1_T_LEN (USBOTG_FS->UEP1_TX_LEN) // endpoint 1 transmittal length
|
||||
//#define USBHD_UEP1_TX_CTRL (USBOTG_FS->UEP1_TX_CTRL) // endpoint 1 control
|
||||
//#define USBHD_UEP1_RX_CTRL (USBOTG_FS->UEP1_RX_CTRL) // endpoint 1 control
|
||||
|
||||
#define USBHD_UEP2_T_LEN (USBOTG_FS->UEP2_TX_LEN) // endpoint 2 transmittal length
|
||||
#define USBHD_UEP2_TX_CTRL (USBOTG_FS->UEP2_TX_CTRL) // endpoint 2 control
|
||||
#define USBHD_UEP2_RX_CTRL (USBOTG_FS->UEP2_RX_CTRL) // endpoint 2 control
|
||||
|
||||
//#define USBHD_UEP3_T_LEN (USBOTG_FS->UEP3_TX_LEN) // endpoint 3 transmittal length
|
||||
//#define USBHD_UEP3_TX_CTRL (USBOTG_FS->UEP3_TX_CTRL) // endpoint 3 control
|
||||
//#define USBHD_UEP3_RX_CTRL (USBOTG_FS->UEP3_RX_CTRL) // endpoint 3 control
|
||||
//
|
||||
//#define USBHD_UEP4_T_LEN (USBOTG_FS->UEP4_TX_LEN) // endpoint 4 transmittal length
|
||||
//#define USBHD_UEP4_TX_CTRL (USBOTG_FS->UEP4_TX_CTRL) // endpoint 4 control
|
||||
//#define USBHD_UEP4_RX_CTRL (USBOTG_FS->UEP4_RX_CTRL) // endpoint 4 control
|
||||
//
|
||||
//#define USBHD_UEP5_T_LEN (USBOTG_FS->UEP5_TX_LEN) // endpoint 5 transmittal length
|
||||
//#define USBHD_UEP5_TX_CTRL (USBOTG_FS->UEP5_TX_CTRL) // endpoint 5 control
|
||||
//#define USBHD_UEP5_RX_CTRL (USBOTG_FS->UEP5_RX_CTRL) // endpoint 5 control
|
||||
//
|
||||
//#define USBHD_UEP6_T_LEN (USBOTG_FS->UEP6_TX_LEN) // endpoint 6 transmittal length
|
||||
//#define USBHD_UEP6_TX_CTRL (USBOTG_FS->UEP6_TX_CTRL) // endpoint 6 control
|
||||
//#define USBHD_UEP6_RX_CTRL (USBOTG_FS->UEP6_RX_CTRL) // endpoint 6 control
|
||||
//
|
||||
//#define USBHD_UEP7_T_LEN (USBOTG_FS->UEP7_TX_LEN) // endpoint 7 transmittal length
|
||||
//#define USBHD_UEP7_TX_CTRL (USBOTG_FS->UEP7_TX_CTRL) // endpoint 7 control
|
||||
//#define USBHD_UEP7_RX_CTRL (USBOTG_FS->UEP7_RX_CTRL) // endpoint 7 control
|
||||
|
||||
#define USBHD_UEP_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBHD_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
|
||||
#define USBHD_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
|
||||
|
||||
#define USBHD_UEP_R_RES1 0x02 // handshake response type high bit for USB endpoint X receiving (OUT)
|
||||
#define USBHD_UEP_R_RES0 0x01 // handshake response type low bit for USB endpoint X receiving (OUT)
|
||||
#define USBHD_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
|
||||
#define USBHD_UEP_R_RES_ACK 0x00
|
||||
#define USBHD_UEP_R_RES_TOUT 0x01
|
||||
#define USBHD_UEP_R_RES_NAK 0x02
|
||||
#define USBHD_UEP_R_RES_STALL 0x03
|
||||
// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
|
||||
// 00: ACK (ready)
|
||||
// 01: no response, time out to host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: STALL (error)
|
||||
#define USBHD_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
|
||||
#define USBHD_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
|
||||
#define USBHD_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
|
||||
#define USBHD_UEP_T_RES_ACK 0x00
|
||||
#define USBHD_UEP_T_RES_TOUT 0x01
|
||||
#define USBHD_UEP_T_RES_NAK 0x02
|
||||
#define USBHD_UEP_T_RES_STALL 0x03
|
||||
// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
|
||||
// 00: DATA0 or DATA1 then expecting ACK (ready)
|
||||
// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: TALL (error)
|
||||
|
||||
#ifdef USBHD_HOST
|
||||
/* USBOTG_FS HOST CONTROL&CFG */
|
||||
/* HOST USB_CTRL */
|
||||
#define USBHD_UHOST_CTRL (USBOTG_FS->UDEV_CTRL) // USB host physical prot control
|
||||
#define USBHD_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBHD_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBHD_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBHD_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
|
||||
#define USBHD_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
|
||||
#define USBHD_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
|
||||
/* USB_INT_ST */
|
||||
#define USBHD_UIS_H_RES_MASK 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
|
||||
/* USB_BUF_MOD */
|
||||
#define USBHD_UH_EP_MOD USBHD_UEP2_3_MOD //host endpoint mode
|
||||
#define USBHD__UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
|
||||
#define USBHD__UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
|
||||
// UH_EP_TX_EN & UH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
|
||||
// 0 x: disable endpoint and disable buffer
|
||||
// 1 0: 64 bytes buffer for transmittal (OUT endpoint)
|
||||
// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
|
||||
#define USBHD_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
|
||||
#define USBHD_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
|
||||
// UH_EP_RX_EN & UH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
|
||||
// 0 x: disable endpoint and disable buffer
|
||||
// 1 0: 64 bytes buffer for receiving (IN endpoint)
|
||||
// 1 1: dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
|
||||
/* USB_DMA */
|
||||
#define USBHD_UH_RX_DMA USBHD_UEP2_DMA // host rx endpoint buffer high address
|
||||
#define USBHD_UH_TX_DMA USBHD_UEP3_DMA // host tx endpoint buffer high address
|
||||
/* USB_HOST_SETUP */
|
||||
#define USBHD_UH_SETUP (*((PUINT16V)(0x50000036))) // host aux setup
|
||||
#define USBHD_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub
|
||||
#define USBHD_UH_SOF_EN 0x04 // USB host automatic SOF enable
|
||||
#define USBHD_UH_EP_PID USBHD_UEP2_T_LEN // host endpoint and PID
|
||||
#define USBHD_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer
|
||||
#define USBHD_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer
|
||||
|
||||
#define USBHD_UH_RX_CTRL USBHD_UEP2_RX_CTRL // host receiver endpoint control
|
||||
#define USBHD_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBHD_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBHD_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
|
||||
|
||||
#define USBHD_UH_RX_CTRL USBHD_UEP2_RX_CTRL // host receiver endpoint control
|
||||
#define USBHD_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBHD_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBHD_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
|
||||
#define USBHD_UH_TX_LEN USBHD_UEP3_T_LEN // host transmittal endpoint transmittal length
|
||||
|
||||
#define USBHD_UH_TX_CTRL USBHD_UEP3_TX_CTRL // host transmittal endpoint control
|
||||
#define USBHD_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBHD_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
|
||||
#define USBHD_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
|
||||
#endif
|
||||
#ifdef USB_OTG
|
||||
#define USB_OTG_CR (USBOTG_FS->OTG_CR) // usb otg control
|
||||
#define USB_OTG_CR_SESS 0x20
|
||||
#define USB_OTG_CR_VBUS 0x10
|
||||
#define USB_OTG_CR_OTG_EN 0x08
|
||||
#define USB_OTG_CR_IDPU 0x04
|
||||
#define USB_OTG_CR_CHARGEVBUS 0x02
|
||||
#define USB_OTG_CR_DISCHARGEVBUS 0x01
|
||||
|
||||
#define USB_OTG_SR (USBOTG_FS->OTG_CR)
|
||||
#define USB_OTG_SR_VBUS_VLD 0x01
|
||||
#define USB_OTG_SR_SESS_VLD 0x02
|
||||
#define USB_OTG_SR_SESS_END 0x04
|
||||
#define USB_OTG_SR_ID_DIG 0x08
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USBHS_EXIST
|
||||
#define USB_48M_CLK_SRC_MASK (1<<31)
|
||||
#define USB_48M_CLK_SRC_SYS (0<<31)
|
||||
#define USB_48M_CLK_SRC_PHY (1<<31)
|
||||
|
||||
#define USBHS_PLL_ALIVE (1<<30)
|
||||
|
||||
#define USBHS_PLL_CKREF_MASK (3<<28)
|
||||
#define USBHS_PLL_CKREF_3M (0<<28)
|
||||
#define USBHS_PLL_CKREF_4M (1<<28)
|
||||
#define USBHS_PLL_CKREF_8M (2<<28)
|
||||
#define USBHS_PLL_CKREF_5M (3<<28)
|
||||
|
||||
#define USBHS_PLL_SRC_MASK (1<<27)
|
||||
#define USBHS_PLL_SRC_HSE (0<<27)
|
||||
#define USBHS_PLL_SRC_HSI (1<<27)
|
||||
|
||||
#define USBHS_PLL_SRC_PRE_MASK (7<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV1 (0<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV2 (1<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV3 (2<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV4 (3<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV5 (4<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV6 (5<<24)
|
||||
#define USBHS_PLL_SRC_PRE_DIV7 (6<<24)
|
||||
|
||||
|
||||
#define DEF_USB_FS_EP_SIZE 64
|
||||
#endif
|
||||
|
||||
|
||||
#define RCC_USBFS_CLK_DIV_1 (0<<22)
|
||||
#define RCC_USBFS_CLK_DIV_2 (1<<22)
|
||||
#define RCC_USBFS_CLK_DIV_3 (2<<22)
|
||||
#define RCC_USBFS_CLK_SRC (1<<31)
|
||||
|
||||
|
||||
extern PUINT8 pEP0_RAM_Addr; //ep0(64)
|
||||
extern PUINT8 pEP2_RAM_Addr; //ep2_out(64)+ep2_in(64)
|
||||
|
||||
extern volatile UINT8 USBHD_Endp1_Down_Flag;
|
||||
|
||||
#define pSetupReqPakHD ((PUSB_SETUP_REQ)pEP0_RAM_Addr)
|
||||
#define pEP0_DataBuf (pEP0_RAM_Addr)
|
||||
#define pEP2_OUT_DataBuf (pEP2_RAM_Addr)
|
||||
#define pEP2_IN_DataBuf (pEP2_RAM_Addr+64)
|
||||
|
||||
#define EP2_GetINSta() (R8_UEP2_CTRL&UEP_T_RES_NAK)
|
||||
|
||||
|
||||
extern void DevEP2_OUT_Deal( UINT8 l );
|
||||
extern void DevEP2_IN_Deal( UINT8 l );
|
||||
extern void USBDeviceInit( void );
|
||||
extern void USBOTG_Init( void );
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2020/12/16
|
||||
* Description : CH32F103 fast program
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "flash.h"
|
||||
#include "string.h"
|
||||
|
||||
u32 Verity_buf[32];
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CH32_IAP_Program
|
||||
*
|
||||
* @brief adr - the date address
|
||||
* buf - the date buffer
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void CH32_IAP_Program(u32 adr, u32* buf)
|
||||
{
|
||||
FLASH_ProgramPage_Fast(adr, buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : falsh.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2020/12/16
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __FLASH_H
|
||||
#define __FLASH_H
|
||||
|
||||
#include "ch32v20x_it.h"
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
void CH32_IAP_Program(u32 adr, u32* buf);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,342 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2020/12/16
|
||||
* Description : IAP
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "iap.h"
|
||||
#include "string.h"
|
||||
#include "flash.h"
|
||||
#include "core_riscv.h"
|
||||
#include "usb_istr.h"
|
||||
#include "usb_lib.h"
|
||||
/******************************************************************************/
|
||||
|
||||
#define FLASH_Base 0x08005000
|
||||
#define USBD_DATA_SIZE 64
|
||||
iapfun jump2app;
|
||||
u32 Program_addr = FLASH_Base;
|
||||
u32 Verity_addr = FLASH_Base;
|
||||
u32 User_APP_Addr_offset = 0x5000;
|
||||
u8 Verity_Star_flag = 0;
|
||||
u8 Fast_Program_Buf[390];
|
||||
u32 CodeLen = 0;
|
||||
u8 End_Flag = 0;
|
||||
u8 EP2_Rx_Buffer[USBD_DATA_SIZE];
|
||||
#define isp_cmd_t ((isp_cmd *)EP2_Rx_Buffer)
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RecData_Deal
|
||||
*
|
||||
* @brief UART-USB deal date
|
||||
*
|
||||
* @return ERR_ERROR - ERROR
|
||||
* ERR_SCUESS - SCUESS
|
||||
* ERR_End - End
|
||||
*/
|
||||
|
||||
u8 RecData_Deal(void)
|
||||
{
|
||||
u8 i, s, Lenth;
|
||||
|
||||
Lenth = isp_cmd_t->Len;
|
||||
|
||||
switch ( isp_cmd_t->Cmd) {
|
||||
case CMD_IAP_ERASE:
|
||||
FLASH_Unlock_Fast();
|
||||
s = ERR_SCUESS;
|
||||
break;
|
||||
|
||||
case CMD_IAP_PROM:
|
||||
for (i = 0; i < Lenth; i++) {
|
||||
Fast_Program_Buf[CodeLen + i] = isp_cmd_t->data[i];
|
||||
}
|
||||
CodeLen += Lenth;
|
||||
if (CodeLen >= 256) {
|
||||
FLASH_Unlock_Fast();
|
||||
FLASH_ErasePage_Fast(Program_addr);
|
||||
CH32_IAP_Program(Program_addr, (u32*) Fast_Program_Buf);
|
||||
CodeLen -= 256;
|
||||
for (i = 0; i < CodeLen; i++) {
|
||||
Fast_Program_Buf[i] = Fast_Program_Buf[256 + i];
|
||||
}
|
||||
|
||||
Program_addr += 0x100;
|
||||
|
||||
}
|
||||
s = ERR_SCUESS;
|
||||
break;
|
||||
|
||||
case CMD_IAP_VERIFY:
|
||||
if (Verity_Star_flag == 0) {
|
||||
Verity_Star_flag = 1;
|
||||
|
||||
for (i = 0; i < (256 - CodeLen); i++) {
|
||||
Fast_Program_Buf[CodeLen + i] = 0xff;
|
||||
}
|
||||
|
||||
FLASH_ErasePage_Fast(Program_addr);
|
||||
CH32_IAP_Program(Program_addr, (u32*) Fast_Program_Buf);
|
||||
CodeLen = 0;
|
||||
}
|
||||
|
||||
s = ERR_SCUESS;
|
||||
for (i = 0; i < Lenth; i++) {
|
||||
if (isp_cmd_t->data[i] != *(u8*) (Verity_addr + i)) {
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Verity_addr += Lenth;
|
||||
|
||||
break;
|
||||
|
||||
case CMD_IAP_END:
|
||||
Verity_Star_flag = 0;
|
||||
End_Flag = 1;
|
||||
Program_addr = FLASH_Base;
|
||||
Verity_addr = FLASH_Base;
|
||||
|
||||
s = ERR_End;
|
||||
break;
|
||||
|
||||
default:
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn EP2_RecData_Deal
|
||||
*
|
||||
* @brief EP2 out date deal
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void EP2_IN_Tx_Deal(void)
|
||||
{
|
||||
UserToPMABufferCopy(EP2_Tx_Buffer, ENDP2_TXADDR, EP2_Tx_Cnt);
|
||||
SetEPTxCount(ENDP2, EP2_Tx_Cnt);
|
||||
SetEPTxValid(ENDP2);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn EP2_RecData_Deal
|
||||
*
|
||||
* @brief EP2 out date deal
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void EP2_RecData_Deal(void)
|
||||
{
|
||||
u8 s;
|
||||
|
||||
if(EP2_OUT_Flag){
|
||||
EP2_OUT_Flag = 0;
|
||||
EP2_Rx_Cnt = USB_SIL_Read(EP2_OUT, EP2_Rx_Buffer);
|
||||
|
||||
s = RecData_Deal();
|
||||
|
||||
if(s!=ERR_End){
|
||||
EP2_Tx_Buffer[0] = 0x00;
|
||||
if(s==ERR_ERROR) EP2_Tx_Buffer[1] = 0x01; //err
|
||||
else EP2_Tx_Buffer[1] = 0x00;
|
||||
EP2_Tx_Cnt = 2;
|
||||
EP2_IN_Tx_Deal();
|
||||
}
|
||||
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn GPIO_Cfg_init
|
||||
*
|
||||
* @brief GPIO init
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void GPIO_Cfg_init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn PA0_Check
|
||||
*
|
||||
* @brief Check PA0 state
|
||||
*
|
||||
* @return 1 - IAP
|
||||
* 0 - APP
|
||||
*/
|
||||
u8 PA0_Check(void)
|
||||
{
|
||||
u8 i, cnt=0;
|
||||
|
||||
GPIO_Cfg_init();
|
||||
|
||||
for(i=0; i<10; i++){
|
||||
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0) cnt++;
|
||||
Delay_Ms(5);
|
||||
}
|
||||
|
||||
if(cnt>6) return 0;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USART3_CFG
|
||||
*
|
||||
* @brief baudrate:UART3 baudrate
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USART3_CFG(u32 baudrate)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
USART_InitTypeDef USART_InitStructure = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
USART_InitStructure.USART_BaudRate = baudrate;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl =
|
||||
USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
|
||||
USART_Init(USART3, &USART_InitStructure);
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn UART3_SendMultiyData
|
||||
*
|
||||
* @brief Deal device Endpoint 3 OUT.
|
||||
*
|
||||
* @param l: Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UART3_SendMultiyData(u8* pbuf, u8 num)
|
||||
{
|
||||
u8 i = 0;
|
||||
|
||||
while(i<num)
|
||||
{
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
|
||||
USART_SendData(USART3, pbuf[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn UART3_SendMultiyData
|
||||
*
|
||||
* @brief USART3 send date
|
||||
*
|
||||
* @param pbuf - Packet to be sent
|
||||
* num - the number of date
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UART3_SendData(u8 data)
|
||||
{
|
||||
while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
|
||||
USART_SendData(USART3, data);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Uart3_Rx
|
||||
*
|
||||
* @brief Uart3 receive date
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
u8 Uart3_Rx(void)
|
||||
{
|
||||
while( USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
|
||||
return USART_ReceiveData( USART3);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UART_Rx_Deal
|
||||
*
|
||||
* @brief UART Rx data deal
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void UART_Rx_Deal(void)
|
||||
{
|
||||
u8 i, s;
|
||||
u8 Data_add = 0;
|
||||
|
||||
if (Uart3_Rx() == Uart_Sync_Head1)
|
||||
{
|
||||
if (Uart3_Rx() == Uart_Sync_Head2)
|
||||
{
|
||||
isp_cmd_t->Cmd = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->Cmd;
|
||||
isp_cmd_t->Len = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->Len;
|
||||
isp_cmd_t->Rev[0] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->Rev[0];
|
||||
isp_cmd_t->Rev[1] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->Rev[1];
|
||||
|
||||
if ((isp_cmd_t->Cmd == CMD_IAP_PROM) || (isp_cmd_t->Cmd == CMD_IAP_VERIFY))
|
||||
{
|
||||
for (i = 0; i < isp_cmd_t->Len; i++) {
|
||||
isp_cmd_t->data[i] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (Uart3_Rx() == Data_add)
|
||||
{
|
||||
s = RecData_Deal();
|
||||
|
||||
if (s != ERR_End)
|
||||
{
|
||||
UART3_SendData(0x00);
|
||||
if (s == ERR_ERROR)
|
||||
{
|
||||
UART3_SendData(0x01);
|
||||
}
|
||||
else
|
||||
{
|
||||
UART3_SendData(0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2020/12/16
|
||||
* Description : IAP
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __IAP_H
|
||||
#define __IAP_H
|
||||
|
||||
#include "ch32v20x.h"
|
||||
#include "stdio.h"
|
||||
#include "ch32v20x_usbotg_device.h"
|
||||
|
||||
#define USBD_DATA_SIZE 64
|
||||
|
||||
#define BUILD_UINT16(loByte, hiByte) ((UINT16)(((loByte) & 0x00FF) | (((hiByte) & 0x00FF) << 8)))
|
||||
#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \
|
||||
((UINT32)((UINT32)((Byte0) & 0x00FF) \
|
||||
+ ((((UINT32)Byte1) & 0x00FF) << 8) \
|
||||
+ ((((UINT32)Byte2) & 0x00FF) << 16) \
|
||||
+ ((((UINT32)Byte3) & 0x00FF) << 24)))
|
||||
|
||||
#define Uart_Sync_Head1 0x57
|
||||
#define Uart_Sync_Head2 0xab
|
||||
|
||||
#define CMD_IAP_PROM 0x80
|
||||
#define CMD_IAP_ERASE 0x81
|
||||
#define CMD_IAP_VERIFY 0x82
|
||||
#define CMD_IAP_END 0x83
|
||||
|
||||
#define ERR_SCUESS 0x00
|
||||
#define ERR_ERROR 0x01
|
||||
#define ERR_End 0x02
|
||||
|
||||
typedef struct __attribute__ ((aligned(4)))_ISP_CMD {
|
||||
u8 Cmd;
|
||||
u8 Len;
|
||||
u8 Rev[2];
|
||||
u8 data[60];
|
||||
} isp_cmd;
|
||||
|
||||
typedef void (*iapfun)(void);
|
||||
extern u32 Program_Verity_addr;
|
||||
extern u32 User_APP_Addr_offset;
|
||||
extern u8 EP2_IN_Flag;
|
||||
extern u8 EP2_OUT_Flag;
|
||||
extern u16 EP2_Rx_Cnt;
|
||||
extern u8 EP2_Tx_Buffer[2];
|
||||
extern u16 EP2_Tx_Cnt;
|
||||
extern u8 EP2_Rx_Buffer[USBD_DATA_SIZE];
|
||||
|
||||
u8 RecData_Deal(void);
|
||||
void GPIO_Cfg_init(void);
|
||||
u8 PA0_Check(void);
|
||||
void EP2_RecData_Deal(void);
|
||||
void EP2_IN_Tx_Deal(void);
|
||||
void USART3_CFG(u32 baudrate);
|
||||
|
||||
void UART_Rx_Deal(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Main program body.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
*@Note
|
||||
IAP upgrade routine:
|
||||
Support serial port and USB for FLASH burning
|
||||
|
||||
1. Use the IAP download tool to realize the download PA0 floating (default pull-up input)
|
||||
2. After downloading the APP, connect PA0 to ground (low level input), and press
|
||||
the reset button to run the APP program.
|
||||
3. The routine needs to install the CH372 driver.
|
||||
Note: FLASH operation keeps the frequency below 100Mhz, it is recommended that the main
|
||||
frequency of IAP be below 100Mhz
|
||||
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "ch32v20x_usbotg_device.h"
|
||||
#include "iap.h"
|
||||
#include "usb_istr.h"
|
||||
#include "usb_desc.h"
|
||||
#include "usb_lib.h"
|
||||
#include "hw_config.h"
|
||||
#include "usb_pwr.h"
|
||||
extern u8 End_Flag;
|
||||
/*********************************************************************
|
||||
* @fn IAP_2_APP
|
||||
*
|
||||
* @brief IAP_2_APP program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void IAP_2_APP(void) {
|
||||
USB_Port_Set(DISABLE, DISABLE);
|
||||
USBOTG_H_FS->HOST_CTRL = 0x00;
|
||||
USBOTG_FS->BASE_CTRL = 0x00;
|
||||
USBOTG_FS->INT_EN = 0x00;
|
||||
USBOTG_FS->UEP2_3_MOD = 0x00;
|
||||
USBOTG_FS->BASE_CTRL |= (1 << 1) | (1 << 2);
|
||||
Delay_Ms(50);
|
||||
printf("jump APP\r\n");
|
||||
Delay_Ms(10);
|
||||
NVIC_EnableIRQ(Software_IRQn);
|
||||
NVIC_SetPendingIRQ(Software_IRQn);
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void) {
|
||||
Delay_Init();
|
||||
USART_Printf_Init(115200);
|
||||
printf("SystemClk:%d\r\n", SystemCoreClock);
|
||||
|
||||
Set_USBConfig();
|
||||
USB_Init();
|
||||
USB_Port_Set(DISABLE, DISABLE);
|
||||
Delay_Ms(700);
|
||||
USB_Port_Set(ENABLE, ENABLE);
|
||||
USB_Interrupts_Config();
|
||||
|
||||
USBOTG_Init();
|
||||
USART3_CFG(57600);
|
||||
while(1)
|
||||
{
|
||||
EP2_RecData_Deal();
|
||||
if( USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET) {
|
||||
UART_Rx_Deal();
|
||||
}
|
||||
if (End_Flag)
|
||||
{
|
||||
Delay_Ms(10);
|
||||
IAP_2_APP();
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,819 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
// #define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
/* #define SYSCLK_FREQ_24MHz 24000000 */
|
||||
//#define SYSCLK_FREQ_48MHz 48000000
|
||||
/* #define SYSCLK_FREQ_56MHz 56000000 */
|
||||
//#define SYSCLK_FREQ_72MHz 72000000
|
||||
#define SYSCLK_FREQ_96MHz 96000000
|
||||
//#define SYSCLK_FREQ_120MHz 120000000
|
||||
//#define SYSCLK_FREQ_144MHz 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#else /* HSI Selected as System Clock source */
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE(void);
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
static void SetSysClockTo24(void);
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
static void SetSysClockTo48(void);
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
static void SetSysClockTo56(void);
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
static void SetSysClockTo72(void);
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
static void SetSysClockTo96(void);
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
static void SetSysClockTo120(void);
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
static void SetSysClockTo144(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF8FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
SetSysClockTo24();
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
SetSysClockTo48();
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
SetSysClockTo56();
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
SetSysClockTo72();
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
SetSysClockTo96();
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
SetSysClockTo120();
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
SetSysClockTo144();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_24MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo24
|
||||
*
|
||||
* @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo24(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 3 = 24 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 3 = 24 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 3 = 24 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL3);
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_144MHz
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user