V2.31
This commit is contained in:
@@ -0,0 +1,578 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbfs_device.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2024/01/06
|
||||
* Description : This file provides all the USBFS 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_usbfs_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 USBFS_Dev_SetupReqLen = 0x00;
|
||||
volatile UINT8 USBFS_Dev_Config = 0x00;
|
||||
volatile UINT8 USBFS_Dev_Address = 0x00;
|
||||
volatile UINT8 USBFS_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 USBFS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSD_DeviceInit
|
||||
*
|
||||
* @brief Initializes USB device.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBDeviceInit( void )
|
||||
{
|
||||
USBFSD->BASE_CTRL = 0x00;
|
||||
|
||||
USBFSD->UEP2_3_MOD = USBFS_UEP2_RX_EN|USBFS_UEP2_TX_EN;
|
||||
USBFSD->UEP0_DMA = (UINT32)pEP0_RAM_Addr;
|
||||
USBFSD->UEP2_DMA = (UINT32)pEP2_RAM_Addr;
|
||||
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
USBFSD->UEP1_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
USBFSD->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
USBFSD->UEP3_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
USBFSD->UEP4_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
USBFSD->UEP5_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
USBFSD->UEP6_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
USBFSD->UEP7_RX_CTRL = USBFS_UEP_R_RES_NAK;
|
||||
|
||||
USBFSD->UEP2_TX_LEN = 8;
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->UEP2_TX_CTRL = USBFS_UEP_T_RES_ACK|USBFS_UEP_AUTO_TOG;
|
||||
|
||||
USBFSD->INT_FG = 0xFF;
|
||||
USBFSD->INT_EN = USBFS_UIE_SUSPEND | USBFS_UIE_BUS_RST | USBFS_UIE_TRANSFER;
|
||||
USBFSD->DEV_ADDR = 0x00;
|
||||
|
||||
USBFSD->BASE_CTRL = USBFS_UC_DEV_PU_EN | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
|
||||
USBFSD->UDEV_CTRL = USBFS_UD_PD_DIS|USBFS_UD_PORT_EN;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFS_RCC_Init
|
||||
*
|
||||
* @brief Initializes the usbfs clock configuration.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_RCC_Init(void)
|
||||
{
|
||||
RCC_ClocksTypeDef RCC_ClocksStatus={0};
|
||||
RCC_GetClocksFreq(&RCC_ClocksStatus);
|
||||
if( RCC_ClocksStatus.SYSCLK_Frequency == 144000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div3 );
|
||||
}
|
||||
else if( RCC_ClocksStatus.SYSCLK_Frequency == 96000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div2 );
|
||||
}
|
||||
else if( RCC_ClocksStatus.SYSCLK_Frequency == 48000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div1 );
|
||||
}
|
||||
#if defined(CH32V20x_D8W) || defined(CH32V20x_D8)
|
||||
else if ( RCC_ClocksStatus.SYSCLK_Frequency == 240000000 && RCC_USB5PRE_JUDGE() == SET )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div5 );
|
||||
}
|
||||
#endif
|
||||
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_USBFS, ENABLE );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFS_Init
|
||||
*
|
||||
* @brief Initializes the USB full speed device.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_Init( void )
|
||||
{
|
||||
pEP0_RAM_Addr = EP0_DatabufHD;
|
||||
pEP2_RAM_Addr = EP2_DatabufHD;
|
||||
USBFS_RCC_Init( );
|
||||
Delay_Us(100);
|
||||
USBDeviceInit( );
|
||||
NVIC_EnableIRQ( USBFS_IRQn );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFS_IRQHandler
|
||||
*
|
||||
* @brief This function handles OTG_FS exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_IRQHandler( void )
|
||||
{
|
||||
UINT8 len, chtype;
|
||||
UINT8 intflag, errflag = 0;
|
||||
|
||||
intflag = USBFSD->INT_FG;
|
||||
|
||||
if( intflag & USBFS_UIF_TRANSFER )
|
||||
{
|
||||
switch ( USBFSD->INT_ST & USBFS_UIS_TOKEN_MASK )
|
||||
{
|
||||
/* SETUP */
|
||||
case USBFS_UIS_TOKEN_SETUP:
|
||||
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_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 = ( USBFS_Dev_SetupReqLen >= DevEP0SIZE ) ? DevEP0SIZE : USBFS_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:
|
||||
USBFSD->UEP2_TX_CTRL = (USBFSD->UEP2_TX_CTRL & ~( USBFS_UEP_T_TOG|USBFS_UEP_T_RES_MASK )) | USBFS_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
USBFSD->UEP2_RX_CTRL = (USBFSD->UEP2_RX_CTRL & ~( USBFS_UEP_R_TOG|USBFS_UEP_R_RES_MASK )) | USBFS_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
USBFSD->UEP1_TX_CTRL = (USBFSD->UEP1_TX_CTRL & ~( USBFS_UEP_T_TOG|USBFS_UEP_T_RES_MASK )) | USBFS_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
USBFSD->UEP1_RX_CTRL = (USBFSD->UEP1_RX_CTRL & ~( USBFS_UEP_R_TOG|USBFS_UEP_R_RES_MASK )) | USBFS_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 )
|
||||
{
|
||||
USBFS_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:
|
||||
USBFSD->UEP2_TX_CTRL = ( USBFSD->UEP2_TX_CTRL &= ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
USBFSD->UEP2_RX_CTRL = ( USBFSD->UEP2_RX_CTRL &= ~USBFS_UEP_R_RES_MASK ) | USBFS_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( USBFS_Dev_SetupReqLen > 1 )
|
||||
{
|
||||
USBFS_Dev_SetupReqLen = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_GET_STATUS:
|
||||
EP0_DatabufHD[ 0 ] = 0x00;
|
||||
EP0_DatabufHD[ 1 ] = 0x00;
|
||||
if( pMySetupReqPakHD->wIndex == 0x81 )
|
||||
{
|
||||
if( ( USBFSD->UEP1_TX_CTRL & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x01 )
|
||||
{
|
||||
if( ( USBFSD->UEP1_RX_CTRL & USBFS_UEP_R_RES_MASK ) == USBFS_UEP_R_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x82 )
|
||||
{
|
||||
if( ( USBFSD->UEP2_TX_CTRL & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
else if( pMySetupReqPakHD->wIndex == 0x02 )
|
||||
{
|
||||
if( ( USBFSD->UEP2_RX_CTRL & USBFS_UEP_R_RES_MASK ) == USBFS_UEP_R_RES_STALL )
|
||||
{
|
||||
EP0_DatabufHD[ 0 ] = 0x01;
|
||||
}
|
||||
}
|
||||
if( USBFS_Dev_SetupReqLen > 2 )
|
||||
{
|
||||
USBFS_Dev_SetupReqLen = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( errflag == 0xff)
|
||||
{
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_STALL;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_STALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( chtype & 0x80 )
|
||||
{
|
||||
len = (SetupReqLen>DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
|
||||
SetupReqLen -= len;
|
||||
}
|
||||
else len = 0;
|
||||
|
||||
USBFSD->UEP0_TX_LEN = len;
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_ACK;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_ACK;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBFS_UIS_TOKEN_IN:
|
||||
switch ( USBFSD->INT_ST & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) )
|
||||
{
|
||||
case USBFS_UIS_TOKEN_IN:
|
||||
switch( SetupReqCode )
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen;
|
||||
memcpy( pEP0_DataBuf, pDescr, len );
|
||||
SetupReqLen -= len;
|
||||
pDescr += len;
|
||||
USBFSD->UEP0_TX_LEN = len;
|
||||
USBFSD->UEP0_TX_CTRL ^= USBFS_UEP_T_TOG;
|
||||
break;
|
||||
|
||||
case USB_SET_ADDRESS:
|
||||
USBFSD->DEV_ADDR = (USBFSD->DEV_ADDR&USBFS_UDA_GP_BIT) | SetupReqLen;
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
default:
|
||||
USBFSD->UEP0_TX_LEN = 0;
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case USBFS_UIS_TOKEN_IN | 2:
|
||||
|
||||
USBFSD->UEP2_TX_CTRL ^= USBFS_UEP_T_TOG;
|
||||
USBFSD->UEP2_TX_CTRL = (USBFSD->UEP2_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case USBFS_UIS_TOKEN_OUT:
|
||||
switch ( USBFSD->INT_ST & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) )
|
||||
{
|
||||
case USBFS_UIS_TOKEN_OUT:
|
||||
len = USBFSD->RX_LEN;
|
||||
break;
|
||||
|
||||
case USBFS_UIS_TOKEN_OUT | 2:
|
||||
if ( USBFSD->INT_ST & USBFS_UIS_TOG_OK )
|
||||
{
|
||||
USBFSD->UEP2_RX_CTRL ^= USBFS_UEP_R_TOG;
|
||||
len = USBFSD->RX_LEN;
|
||||
DevEP2_OUT_Deal( len );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
USBFSD->INT_FG = USBFS_UIF_TRANSFER;
|
||||
}
|
||||
else if( intflag & USBFS_UIF_BUS_RST )
|
||||
{
|
||||
USBFSD->DEV_ADDR = 0;
|
||||
USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
USBFSD->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK;
|
||||
USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->UEP2_TX_CTRL = USBFS_UEP_T_RES_NAK;
|
||||
USBFSD->INT_FG |= USBFS_UIF_BUS_RST;
|
||||
}
|
||||
else if( intflag & USBFS_UIF_SUSPEND )
|
||||
{
|
||||
if ( USBFSD->MIS_ST & USBFS_UMS_SUSPEND ) {;}
|
||||
else{;}
|
||||
USBFSD->INT_FG = USBFS_UIF_SUSPEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBFSD->INT_FG = intflag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP2_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint2 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP2_IN_Deal( UINT8 l )
|
||||
{
|
||||
USBFSD->UEP2_TX_LEN = l;
|
||||
USBFSD->UEP2_TX_CTRL = (USBFSD->UEP2_TX_CTRL & ~USBFS_UEP_T_RES_MASK)| USBFS_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,716 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbfs_device.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file provides all the USBFS 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_USBFS_DEVICE_H_
|
||||
#define __CH32V20x_USBFS_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 USBFS_HOST 0
|
||||
//#define USB_OTG 0
|
||||
|
||||
/******************************************************************************/
|
||||
/* USBFSD DEVICE USB_CONTROL */
|
||||
/* BASE USB_CTRL */
|
||||
#define USBFS_BASE_CTRL (USBFSD->BASE_CTRL) // USB base control
|
||||
#define USBFS_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
|
||||
#define USBFS_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
|
||||
#define USBFS_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
|
||||
#define USBFS_UC_SYS_CTRL1 0x20 // USB system control high bit
|
||||
#define USBFS_UC_SYS_CTRL0 0x10 // USB system control low bit
|
||||
#define USBFS_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 USBFS_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
|
||||
#define USBFS_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
|
||||
#define USBFS_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
|
||||
#define USBFS_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
|
||||
/* DEVICE USB_CTRL */
|
||||
#define USBFS_UDEV_CTRL (USBFSD->UDEV_CTRL) // USB device physical prot control
|
||||
#define USBFS_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UD_GP_BIT 0x02 // general purpose bit
|
||||
#define USBFS_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
|
||||
/* USB INT EN */
|
||||
#define USBFS_INT_EN (USBFSD->INT_EN) // USB interrupt enable
|
||||
#define USBFS_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
|
||||
#define USBFS_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
|
||||
#define USBFS_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
|
||||
#define USBFS_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
|
||||
#define USBFS_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
|
||||
#define USBFS_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
|
||||
#define USBFS_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
|
||||
/* USB_DEV_ADDR */
|
||||
#define USBFS_DEV_ADDR (USBFSD->DEV_ADDR) // USB device address
|
||||
#define USBFS_UDA_GP_BIT 0x80 // general purpose bit
|
||||
#define USBFS_USB_ADDR_MASK 0x7F // bit mask for USB device address
|
||||
/* USBFSD DEVICE USB_STATUS */
|
||||
/* USB_MIS_ST */
|
||||
#define USBFS_MIS_ST (USBFSD->MIS_ST) // USB miscellaneous status
|
||||
#define USBFS_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
|
||||
#define USBFS_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
|
||||
#define USBFS_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBFS_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
|
||||
#define USBFS_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
|
||||
#define USBFS_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
|
||||
#define USBFS_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
|
||||
#define USBFS_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
|
||||
/* USB_INT_FG */
|
||||
#define USBFS_INT_FG (USBFSD->INT_FG) // USB interrupt flag
|
||||
#define USBFS_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
|
||||
#define USBFS_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBFS_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
|
||||
#define USBFS_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 USBFS_INT_ST (USBFSD->INT_ST) // USB interrupt flag
|
||||
#define USBFS_UIS_IS_SETUP 0x80 // RO, indicate current USB transfer is setup received for USB device mode
|
||||
#define USBFS_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
|
||||
#define USBFS_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
|
||||
#define USBFS_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
|
||||
#define USBFS_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
|
||||
#define USBFS_UIS_TOKEN_OUT 0x00
|
||||
#define USBFS_UIS_TOKEN_IN 0x20
|
||||
#define USBFS_UIS_TOKEN_SETUP 0x30
|
||||
// UIS_TOKEN1 & UIS_TOKEN0: current token PID code received for USB device mode
|
||||
// 00: OUT token PID received
|
||||
// 10: IN token PID received
|
||||
// 11: SETUP token PID received
|
||||
#define USBFS_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
|
||||
/* USB_RX_LEN */
|
||||
#define USBFS_RX_LEN (USBFSD->Rx_Len) // USB receiving length
|
||||
/* USB_BUF_MOD */
|
||||
#define USBFS_UEP4_1_MOD (USBFSD->UEP4_1_MOD) // endpoint 4/1 mode
|
||||
#define USBFS_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
|
||||
#define USBFS_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
|
||||
#define USBFS_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 USBFS_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
|
||||
#define USBFS_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 USBFS_UEP2_3_MOD (USBFSD->UEP2_3_MOD) // endpoint 2/3 mode
|
||||
#define USBFS_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
|
||||
#define USBFS_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
|
||||
#define USBFS_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
|
||||
#define USBFS_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
|
||||
#define USBFS_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
|
||||
#define USBFS_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
|
||||
|
||||
#define USBFS_UEP5_6_MOD (USBFSD->UEP5_6_MOD) // endpoint 5/6 mode
|
||||
#define USBFS_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
|
||||
#define USBFS_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
|
||||
#define USBFS_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
|
||||
#define USBFS_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
|
||||
#define USBFS_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
|
||||
#define USBFS_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
|
||||
|
||||
#define USBFS_UEP7_MOD (USBFSD->UEP7_MOD) // endpoint 7 mode
|
||||
#define USBFS_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
|
||||
#define USBFS_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
|
||||
#define USBFS_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
|
||||
/* USB_DMA */
|
||||
#define USBFS_UEP0_DMA (USBFSD->UEP0_DMA) // endpoint 0 DMA buffer address
|
||||
//#define USBFS_UEP1_DMA (USBFSD->UEP1_DMA) // endpoint 1 DMA buffer address
|
||||
#define USBFS_UEP2_DMA (USBFSD->UEP2_DMA) // endpoint 2 DMA buffer address
|
||||
//#define USBFS_UEP3_DMA (USBFSD->UEP3_DMA) // endpoint 3 DMA buffer address
|
||||
//#define USBFS_UEP4_DMA (USBFSD->UEP4_DMA) // endpoint 4 DMA buffer address
|
||||
//#define USBFS_UEP5_DMA (USBFSD->UEP5_DMA) // endpoint 5 DMA buffer address
|
||||
//#define USBFS_UEP6_DMA (USBFSD->UEP6_DMA) // endpoint 6 DMA buffer address
|
||||
//#define USBFS_UEP7_DMA (USBFSD->UEP7_DMA) // endpoint 7 DMA buffer address
|
||||
/* USB_EP_CTRL */
|
||||
#define USBFS_UEP0_T_LEN (USBFSD->UEP0_TX_LEN) // endpoint 0 transmittal length
|
||||
#define USBFS_UEP0_TX_CTRL (USBFSD->UEP0_TX_CTRL) // endpoint 0 control
|
||||
#define USBFS_UEP0_RX_CTRL (USBFSD->UEP0_RX_CTRL) // endpoint 0 control
|
||||
|
||||
//#define USBFS_UEP1_T_LEN (USBFSD->UEP1_TX_LEN) // endpoint 1 transmittal length
|
||||
//#define USBFS_UEP1_TX_CTRL (USBFSD->UEP1_TX_CTRL) // endpoint 1 control
|
||||
//#define USBFS_UEP1_RX_CTRL (USBFSD->UEP1_RX_CTRL) // endpoint 1 control
|
||||
|
||||
#define USBFS_UEP2_T_LEN (USBFSD->UEP2_TX_LEN) // endpoint 2 transmittal length
|
||||
#define USBFS_UEP2_TX_CTRL (USBFSD->UEP2_TX_CTRL) // endpoint 2 control
|
||||
#define USBFS_UEP2_RX_CTRL (USBFSD->UEP2_RX_CTRL) // endpoint 2 control
|
||||
|
||||
//#define USBFS_UEP3_T_LEN (USBFSD->UEP3_TX_LEN) // endpoint 3 transmittal length
|
||||
//#define USBFS_UEP3_TX_CTRL (USBFSD->UEP3_TX_CTRL) // endpoint 3 control
|
||||
//#define USBFS_UEP3_RX_CTRL (USBFSD->UEP3_RX_CTRL) // endpoint 3 control
|
||||
//
|
||||
//#define USBFS_UEP4_T_LEN (USBFSD->UEP4_TX_LEN) // endpoint 4 transmittal length
|
||||
//#define USBFS_UEP4_TX_CTRL (USBFSD->UEP4_TX_CTRL) // endpoint 4 control
|
||||
//#define USBFS_UEP4_RX_CTRL (USBFSD->UEP4_RX_CTRL) // endpoint 4 control
|
||||
//
|
||||
//#define USBFS_UEP5_T_LEN (USBFSD->UEP5_TX_LEN) // endpoint 5 transmittal length
|
||||
//#define USBFS_UEP5_TX_CTRL (USBFSD->UEP5_TX_CTRL) // endpoint 5 control
|
||||
//#define USBFS_UEP5_RX_CTRL (USBFSD->UEP5_RX_CTRL) // endpoint 5 control
|
||||
//
|
||||
//#define USBFS_UEP6_T_LEN (USBFSD->UEP6_TX_LEN) // endpoint 6 transmittal length
|
||||
//#define USBFS_UEP6_TX_CTRL (USBFSD->UEP6_TX_CTRL) // endpoint 6 control
|
||||
//#define USBFS_UEP6_RX_CTRL (USBFSD->UEP6_RX_CTRL) // endpoint 6 control
|
||||
//
|
||||
//#define USBFS_UEP7_T_LEN (USBFSD->UEP7_TX_LEN) // endpoint 7 transmittal length
|
||||
//#define USBFS_UEP7_TX_CTRL (USBFSD->UEP7_TX_CTRL) // endpoint 7 control
|
||||
//#define USBFS_UEP7_RX_CTRL (USBFSD->UEP7_RX_CTRL) // endpoint 7 control
|
||||
|
||||
#define USBFS_UEP_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
|
||||
|
||||
#define USBFS_UEP_R_RES1 0x02 // handshake response type high bit for USB endpoint X receiving (OUT)
|
||||
#define USBFS_UEP_R_RES0 0x01 // handshake response type low bit for USB endpoint X receiving (OUT)
|
||||
#define USBFS_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
|
||||
#define USBFS_UEP_R_RES_ACK 0x00
|
||||
#define USBFS_UEP_R_RES_TOUT 0x01
|
||||
#define USBFS_UEP_R_RES_NAK 0x02
|
||||
#define USBFS_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 USBFS_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
|
||||
#define USBFS_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
|
||||
#define USBFS_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
|
||||
#define USBFS_UEP_T_RES_ACK 0x00
|
||||
#define USBFS_UEP_T_RES_TOUT 0x01
|
||||
#define USBFS_UEP_T_RES_NAK 0x02
|
||||
#define USBFS_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 USBFS_HOST
|
||||
/* USBFSD HOST CONTROL&CFG */
|
||||
/* HOST USB_CTRL */
|
||||
#define USBFS_UHOST_CTRL (USBFSD->UDEV_CTRL) // USB host physical prot control
|
||||
#define USBFS_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
|
||||
#define USBFS_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
|
||||
/* USB_INT_ST */
|
||||
#define USBFS_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 USBFS_UH_EP_MOD USBFS_UEP2_3_MOD //host endpoint mode
|
||||
#define USBFS__UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
|
||||
#define USBFS__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 USBFS_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
|
||||
#define USBFS_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 USBFS_UH_RX_DMA USBFS_UEP2_DMA // host rx endpoint buffer high address
|
||||
#define USBFS_UH_TX_DMA USBFS_UEP3_DMA // host tx endpoint buffer high address
|
||||
/* USB_HOST_SETUP */
|
||||
#define USBFS_UH_SETUP (*((PUINT16V)(0x50000036))) // host aux setup
|
||||
#define USBFS_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub
|
||||
#define USBFS_UH_SOF_EN 0x04 // USB host automatic SOF enable
|
||||
#define USBFS_UH_EP_PID USBFS_UEP2_T_LEN // host endpoint and PID
|
||||
#define USBFS_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer
|
||||
#define USBFS_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer
|
||||
|
||||
#define USBFS_UH_RX_CTRL USBFS_UEP2_RX_CTRL // host receiver endpoint control
|
||||
#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_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 USBFS_UH_RX_CTRL USBFS_UEP2_RX_CTRL // host receiver endpoint control
|
||||
#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_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 USBFS_UH_TX_LEN USBFS_UEP3_T_LEN // host transmittal endpoint transmittal length
|
||||
|
||||
#define USBFS_UH_TX_CTRL USBFS_UEP3_TX_CTRL // host transmittal endpoint control
|
||||
#define USBFS_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_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 (USBFSD->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 (USBFSD->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 USBFS_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 USBFS_Init( void );
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.1
|
||||
* Date : 2025/01/23
|
||||
* Description : CH32V203 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 Verify_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,20 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : falsh.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.1
|
||||
* Date : 2025/01/23
|
||||
* 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,260 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.2
|
||||
* Date : 2025/10/27
|
||||
* 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 USBD_DATA_SIZE 64
|
||||
iapfun jump2app;
|
||||
vu32 Program_addr = FLASH_Base;
|
||||
vu32 Verify_addr = FLASH_Base;
|
||||
u32 User_APP_Addr_offset = 0x5000;
|
||||
vu8 Verify_Star_flag = 0;
|
||||
u8 Fast_Program_Buf[390];
|
||||
vu32 CodeLen = 0;
|
||||
vu8 End_Flag = 0;
|
||||
u8 EP2_Rx_Buffer[USBD_DATA_SIZE+4];
|
||||
#define isp_cmd_t ((isp_cmd *)EP2_Rx_Buffer)
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RecData_Deal
|
||||
*
|
||||
* @brief UART-USB deal data
|
||||
*
|
||||
* @return ERR_ERROR - ERROR
|
||||
* ERR_SUCCESS - SUCCESS
|
||||
* ERR_End - End
|
||||
*/
|
||||
u8 RecData_Deal(void)
|
||||
{
|
||||
u8 s;
|
||||
|
||||
switch ( isp_cmd_t->other.buf[0]) {
|
||||
case CMD_IAP_ERASE:
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
|
||||
case CMD_IAP_PROM:
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
|
||||
case CMD_IAP_VERIFY:
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
|
||||
case CMD_IAP_END:
|
||||
s = ERR_ERROR;
|
||||
break;
|
||||
|
||||
case CMD_JUMP_IAP:
|
||||
FLASH_Unlock_Fast();
|
||||
FLASH_ProgramWord(CalAddr, 0x5aa55aa5);
|
||||
FLASH->CTLR |= ((uint32_t)0x00008000);
|
||||
FLASH->CTLR |= ((uint32_t)0x00000080);
|
||||
|
||||
s = ERR_SUCCESS;
|
||||
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 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_SendData
|
||||
*
|
||||
* @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;
|
||||
u16 Data_add = 0;
|
||||
|
||||
if (Uart3_Rx() == Uart_Sync_Head1)
|
||||
{
|
||||
if (Uart3_Rx() == Uart_Sync_Head2)
|
||||
{
|
||||
isp_cmd_t->UART.Cmd = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->UART.Cmd;
|
||||
isp_cmd_t->UART.Len = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->UART.Len;
|
||||
|
||||
if(isp_cmd_t->UART.Cmd == CMD_IAP_ERASE ||isp_cmd_t->UART.Cmd == CMD_IAP_VERIFY)
|
||||
{
|
||||
isp_cmd_t->other.buf[2] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->other.buf[2];
|
||||
isp_cmd_t->other.buf[3] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->other.buf[3];
|
||||
isp_cmd_t->other.buf[4] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->other.buf[4];
|
||||
isp_cmd_t->other.buf[5] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->other.buf[5];
|
||||
}
|
||||
if ((isp_cmd_t->other.buf[0] == CMD_IAP_PROM) || (isp_cmd_t->other.buf[0] == CMD_IAP_VERIFY))
|
||||
{
|
||||
for (i = 0; i < isp_cmd_t->UART.Len; i++) {
|
||||
isp_cmd_t->UART.data[i] = Uart3_Rx();
|
||||
Data_add += isp_cmd_t->UART.data[i];
|
||||
}
|
||||
}
|
||||
if (Uart3_Rx() == (uint8_t)(Data_add & 0xFF))
|
||||
{
|
||||
if(Uart3_Rx() == (uint8_t)(Data_add >>8))
|
||||
{
|
||||
if (Uart3_Rx() == Uart_Sync_Head2)
|
||||
{
|
||||
if (Uart3_Rx() == Uart_Sync_Head1)
|
||||
{
|
||||
s = RecData_Deal();
|
||||
|
||||
if (s != ERR_End)
|
||||
{
|
||||
UART3_SendData(Uart_Sync_Head1);
|
||||
UART3_SendData(Uart_Sync_Head2);
|
||||
UART3_SendData(0x00);
|
||||
if (s == ERR_ERROR)
|
||||
{
|
||||
UART3_SendData(0x01);
|
||||
}
|
||||
else
|
||||
{
|
||||
UART3_SendData(0x00);
|
||||
}
|
||||
UART3_SendData(Uart_Sync_Head2);
|
||||
UART3_SendData(Uart_Sync_Head1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : iap.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.1
|
||||
* Date : 2025/01/09
|
||||
* 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_usbfs_device.h"
|
||||
|
||||
#define USBD_DATA_SIZE 64
|
||||
#define FLASH_Base 0x08005000
|
||||
|
||||
#define Uart_Sync_Head1 0xaa
|
||||
#define Uart_Sync_Head2 0x55
|
||||
|
||||
#define CMD_IAP_PROM 0x80
|
||||
#define CMD_IAP_ERASE 0x81
|
||||
#define CMD_IAP_VERIFY 0x82
|
||||
#define CMD_IAP_END 0x83
|
||||
#define CMD_JUMP_IAP 0x84
|
||||
|
||||
#define ERR_SUCCESS 0x00
|
||||
#define ERR_ERROR 0x01
|
||||
#define ERR_End 0x02
|
||||
|
||||
#define CalAddr (0x08038000-4)
|
||||
#define CheckNum (0x5aa55aa5)
|
||||
|
||||
typedef union __attribute__ ((aligned(4)))_ISP_CMD {
|
||||
|
||||
struct{
|
||||
|
||||
u8 Cmd;
|
||||
u8 Len;
|
||||
u8 data[64];
|
||||
}UART;
|
||||
|
||||
struct{
|
||||
u8 Cmd;
|
||||
u8 Len;
|
||||
u8 data[62];
|
||||
}program;
|
||||
|
||||
struct{
|
||||
u8 Cmd;
|
||||
u8 Len;
|
||||
u8 addr[4];
|
||||
u8 data[56];
|
||||
}verify;
|
||||
|
||||
struct{
|
||||
u8 buf[64+4];
|
||||
}other;
|
||||
|
||||
} isp_cmd;
|
||||
|
||||
typedef void (*iapfun)(void);
|
||||
extern u32 Program_Verify_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+4];
|
||||
|
||||
u8 RecData_Deal(void);
|
||||
void EP2_RecData_Deal(void);
|
||||
void EP2_IN_Tx_Deal(void);
|
||||
void USART3_CFG(u32 baudrate);
|
||||
|
||||
void UART_Rx_Deal(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Version : V1.0.2
|
||||
* Date : 2025/10/27
|
||||
* Description : Main program body.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
@@ -11,18 +11,25 @@
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
*@Note
|
||||
*ADC uses DMA sampling routine:
|
||||
*ADC channel 1 (PA1), the rule group channel obtains ADC conversion data
|
||||
*for 1024 consecutive times through DMA.
|
||||
*
|
||||
* APP routine: this routine support USB and UART mode,
|
||||
* and you can choose the command method to jump to the IAP .
|
||||
* Key parameters: CalAddr - address in flash(same in IAP), note that this address needs to be unused.
|
||||
* CheckNum - The value of 'CalAddr' that needs to be modified.
|
||||
* Tips :the routine need IAP software version 1.50.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "ch32v20x_usbfs_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"
|
||||
|
||||
/* Global Variable */
|
||||
u16 TxBuf[1024];
|
||||
s16 Calibrattion_Val = 0;
|
||||
vs16 Calibrattion_Val = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ADC_Function_Init
|
||||
@@ -157,6 +164,43 @@ u16 Get_ConversionVal(s16 val)
|
||||
return (val + Calibrattion_Val);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn APP_2_IAP
|
||||
*
|
||||
* @brief APP_2_IAP program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void APP_2_IAP(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
while(1){
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USART3_IT_CFG
|
||||
*
|
||||
* @brief USART3 IT config program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USART3_IT_CFG(void)
|
||||
{
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
@@ -186,17 +230,47 @@ int main(void)
|
||||
Delay_Ms(50);
|
||||
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
|
||||
|
||||
for(i = 0; i < 1024; i++){
|
||||
for(i = 0; i < 64; i++){
|
||||
printf("%04d\r\n", Get_ConversionVal(TxBuf[i]));
|
||||
Delay_Ms(10);
|
||||
}
|
||||
|
||||
while(1);
|
||||
//USB-USART ENABLE
|
||||
Set_USBConfig();
|
||||
USB_Init();
|
||||
USB_Port_Set(DISABLE, DISABLE);
|
||||
Delay_Ms(700);
|
||||
USB_Port_Set(ENABLE, ENABLE);
|
||||
USB_Interrupts_Config();
|
||||
|
||||
USBFS_Init();
|
||||
USART3_CFG(460800);
|
||||
USART3_IT_CFG();
|
||||
|
||||
while(1)
|
||||
{
|
||||
EP2_RecData_Deal();
|
||||
if(*(vu32 *)CalAddr == CheckNum)
|
||||
{
|
||||
Delay_Ms(10);
|
||||
APP_2_IAP();
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
/*********************************************************************
|
||||
* @fn USART3_IRQHandler
|
||||
*
|
||||
* @brief This function handles USART3 global interrupt request.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
if( USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UART_Rx_Deal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
|
||||
Reference in New Issue
Block a user