first submission
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : RingMem.C
|
||||
* Author : Hikari
|
||||
* Version : V1.4
|
||||
* Date : 2019/12/20
|
||||
* Description :
|
||||
* NOTE : If use interrupts, you need to pay attention to the switch interrupt
|
||||
*********************************************************************************
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "RingMem.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
RingMemProtection_t RingMemProtection;
|
||||
/*********************************************************************
|
||||
* @fn RingMemInit
|
||||
*
|
||||
* @brief 初始化
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void RingMemInit( RingMemParm_t *Parm, uint8_t *StartAddr, uint32_t MaxLen, RingMemProtection_t Protection )
|
||||
{
|
||||
Parm->pData = StartAddr;
|
||||
Parm->pWrite = StartAddr;
|
||||
Parm->pRead = StartAddr;
|
||||
Parm->RemanentLen = MaxLen;
|
||||
Parm->CurrentLen = 0;
|
||||
Parm->pEnd = StartAddr + MaxLen;
|
||||
Parm->MaxLen = MaxLen;
|
||||
RingMemProtection = Protection;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingMemWrite
|
||||
*
|
||||
* @brief 往里写
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingMemWrite( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
|
||||
{
|
||||
uint32_t i,edgelen;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(ENABLE);
|
||||
}
|
||||
|
||||
if( len > Parm->RemanentLen )
|
||||
return !SUCCESS;
|
||||
|
||||
edgelen = Parm->pEnd - Parm->pWrite; //Calculate the length of the remaining to the boundary
|
||||
|
||||
if( len > edgelen )
|
||||
{
|
||||
for(i=0; i<edgelen; i++)
|
||||
{
|
||||
*Parm->pWrite++ = *pData++;
|
||||
}
|
||||
Parm->pWrite = Parm->pData;
|
||||
for(i=0; i<(len-edgelen); i++)
|
||||
{
|
||||
*Parm->pWrite++ = *pData++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
*Parm->pWrite++ = *pData++;
|
||||
}
|
||||
}
|
||||
|
||||
Parm->RemanentLen -= len;
|
||||
Parm->CurrentLen += len;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(DISABLE);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingMemRead
|
||||
*
|
||||
* @brief 往外读
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingMemRead( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
|
||||
{
|
||||
uint32_t i,edgelen;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(ENABLE);
|
||||
}
|
||||
|
||||
if( len > Parm->CurrentLen ) //Not enough reading length
|
||||
return !SUCCESS;
|
||||
|
||||
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundarythe length of the remaining to the boundary
|
||||
|
||||
if( len > edgelen )
|
||||
{
|
||||
for(i=0; i<edgelen; i++)
|
||||
{
|
||||
*pData++ = *Parm->pRead++;
|
||||
}
|
||||
Parm->pRead = Parm->pData;
|
||||
for(i=0; i<(len-edgelen); i++)
|
||||
{
|
||||
*pData++ = *Parm->pRead++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
*pData++ = *Parm->pRead++;
|
||||
}
|
||||
}
|
||||
|
||||
Parm->RemanentLen += len;
|
||||
Parm->CurrentLen -= len;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(DISABLE);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingMemCopy
|
||||
*
|
||||
* @brief Don't delete it after reading
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingMemCopy( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
|
||||
{
|
||||
uint32_t i,edgelen;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(ENABLE);
|
||||
}
|
||||
|
||||
uint8_t volatile *pRead = Parm->pRead;
|
||||
|
||||
if( len > Parm->CurrentLen ) //The length that can be copied is not enough
|
||||
return !SUCCESS;
|
||||
|
||||
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundary
|
||||
|
||||
if( len > edgelen )
|
||||
{
|
||||
for(i=0; i<edgelen; i++)
|
||||
{
|
||||
*pData++ = *pRead++;
|
||||
}
|
||||
pRead = Parm->pData;
|
||||
for(i=0; i<(len-edgelen); i++)
|
||||
{
|
||||
*pData++ = *pRead++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
*pData++ = *pRead++;
|
||||
}
|
||||
}
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(DISABLE);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingMemDelete
|
||||
*
|
||||
* @brief Delete directly
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingMemDelete( RingMemParm_t *Parm, uint32_t len )
|
||||
{
|
||||
uint32_t edgelen;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(ENABLE);
|
||||
}
|
||||
|
||||
if( len > Parm->CurrentLen ) //Can delete not enough length
|
||||
return !SUCCESS;
|
||||
|
||||
edgelen = Parm->pEnd - Parm->pRead; //Calculate the length of the remaining to the boundary
|
||||
|
||||
if( len > edgelen )
|
||||
{
|
||||
Parm->pRead+=edgelen;
|
||||
Parm->pRead = Parm->pData;
|
||||
Parm->pRead+=(len-edgelen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Parm->pRead+=len;
|
||||
}
|
||||
|
||||
Parm->RemanentLen += len;
|
||||
Parm->CurrentLen -= len;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(DISABLE);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingAddInStart
|
||||
*
|
||||
* @brief 向缓冲区开始处添加数据
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingAddInStart( RingMemParm_t *Parm, uint8_t *pData, uint32_t len )
|
||||
{
|
||||
uint32_t i,edgelen;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(ENABLE);
|
||||
}
|
||||
|
||||
if( len > Parm->RemanentLen )
|
||||
return !SUCCESS;
|
||||
|
||||
edgelen = Parm->pRead - Parm->pData; //Calculate the length of the remaining to the boundary
|
||||
|
||||
if( len > edgelen )
|
||||
{
|
||||
for(i=0; i<edgelen; i++)
|
||||
{
|
||||
*Parm->pRead-- = *pData++;
|
||||
}
|
||||
Parm->pRead = Parm->pData + Parm->MaxLen;
|
||||
for(i=0; i<(len-edgelen); i++)
|
||||
{
|
||||
*Parm->pRead-- = *pData++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
*Parm->pRead-- = *pData++;
|
||||
}
|
||||
}
|
||||
|
||||
Parm->RemanentLen -= len;
|
||||
Parm->CurrentLen += len;
|
||||
|
||||
if(RingMemProtection)
|
||||
{
|
||||
RingMemProtection(DISABLE);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingCopyOneData
|
||||
*
|
||||
* @brief Back the first data on the basis of the first address
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t RingReturnSingleData( RingMemParm_t *Parm, uint32_t Num )
|
||||
{
|
||||
uint32_t edgelen;
|
||||
|
||||
if( Parm->RemanentLen < Parm->MaxLen )
|
||||
{
|
||||
edgelen = Parm->pEnd - Parm->pRead;
|
||||
if( Num >= edgelen )
|
||||
{
|
||||
return Parm->pData[Num - edgelen];
|
||||
}
|
||||
else
|
||||
{
|
||||
return Parm->pRead[Num];
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
@@ -0,0 +1,74 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "ch32v20x_it.h"
|
||||
#include "CONFIG.h"
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void LLE_IRQHandler(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 BB_IRQHandler
|
||||
*
|
||||
* @brief BB Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void BB_IRQHandler(void)
|
||||
{
|
||||
BB_IRQLibHandler();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn LLE_IRQHandler
|
||||
*
|
||||
* @brief LLE Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void LLE_IRQHandler(void)
|
||||
{
|
||||
LLE_IRQLibHandler();
|
||||
}
|
||||
@@ -0,0 +1,978 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v30x_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 "CONFIG.h"
|
||||
#include "peripheral.h"
|
||||
#include "RingMem.h"
|
||||
|
||||
/* Global define */
|
||||
/* OTH */
|
||||
#define pMySetupReqPakHD ((PUSB_SETUP_REQ)EP0_DatabufHD)
|
||||
#define RepDescSize 62
|
||||
|
||||
#if DEF_USBD_SPEED == DEF_USBD_SPEED_LOW
|
||||
#define RepDataLoadLen 8
|
||||
#else
|
||||
#define RepDataLoadLen 64
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Endpoint Buffer */
|
||||
__attribute__((aligned(4))) UINT8 EP0_DatabufHD[64]; //ep0(64)
|
||||
__attribute__((aligned(4))) UINT8 EP1_DatabufHD[64 + 64]; //ep1_out(64)+ep1_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP2_DatabufHD[64 + 64]; //ep2_out(64)+ep2_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP3_DatabufHD[64 + 64]; //ep3_out(64)+ep3_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP4_DatabufHD[64 + 64]; //ep4_out(64)+ep4_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP5_DatabufHD[64 + 64]; //ep5_out(64)+ep5_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP6_DatabufHD[64 + 64]; //ep6_out(64)+ep6_in(64)
|
||||
__attribute__((aligned(4))) UINT8 EP7_DatabufHD[64 + 64]; //ep7_out(64)+ep7_in(64)
|
||||
|
||||
PUINT8 pEP0_RAM_Addr; //ep0(64)
|
||||
PUINT8 pEP1_RAM_Addr; //ep1_out(64)+ep1_in(64)
|
||||
PUINT8 pEP2_RAM_Addr; //ep2_out(64)+ep2_in(64)
|
||||
PUINT8 pEP3_RAM_Addr; //ep3_out(64)+ep3_in(64)
|
||||
PUINT8 pEP4_RAM_Addr; //ep4_out(64)+ep4_in(64)
|
||||
PUINT8 pEP5_RAM_Addr; //ep5_out(64)+ep5_in(64)
|
||||
PUINT8 pEP6_RAM_Addr; //ep6_out(64)+ep6_in(64)
|
||||
PUINT8 pEP7_RAM_Addr; //ep7_out(64)+ep7_in(64)
|
||||
|
||||
const UINT8 *pDescr;
|
||||
volatile UINT8 USBHD_Dev_SetupReqCode = 0xFF; /* USB2.0 full-speed device setup package command */
|
||||
volatile UINT16 USBHD_Dev_SetupReqLen = 0x00; /* USB2.0 full-speed device setup package length */
|
||||
volatile UINT8 USBHD_Dev_SetupReqValueH = 0x00; /* USB2.0 full-speed device setup package value high byte */
|
||||
volatile UINT8 USBHD_Dev_Config = 0x00; /* USB2.0 full-speed device configuration value */
|
||||
volatile UINT8 USBHD_Dev_Address = 0x00; /* USB2.0 full-speed device address value */
|
||||
volatile UINT8 USBHD_Dev_SleepStatus = 0x00; /* USB2.0 full-speed device sleep state */
|
||||
volatile UINT8 USBHD_Dev_EnumStatus = 0x00; /* USB2.0 full-speed device enumeration status */
|
||||
volatile UINT8 USBHD_Dev_Endp0_Tog = 0x01; /* USB2.0 Full-speed device endpoint 0 sync flag*/
|
||||
volatile UINT8 USBHD_Dev_Speed = 0x01; /* USB2.0 Full-speed device speed */
|
||||
|
||||
volatile UINT16 USBHD_Endp1_Up_Flag = 0x00; /* USB2.0 full-speed device endpoint 1 data upload status: 0: free; 1: upload; */
|
||||
volatile UINT8 USBHD_Endp1_Down_Flag = 0x00; /* USB2.0 full-speed device endpoint 1 Pass successful logo */
|
||||
volatile UINT8 USBHD_Endp1_Down_Len = 0x00; /* USB2.0 full-speed device endpoint 1 download length */
|
||||
volatile BOOL USBHD_Endp1_T_Tog = 0; /* USB2.0 full speed device endpoint 1 sends tog bit flip */
|
||||
volatile BOOL USBHD_Endp1_R_Tog = 0;
|
||||
|
||||
volatile UINT16 USBHD_Endp2_Up_Flag = 0x00; /* USB2.0 full-speed device endpoint 2 Data upload status: 0: free; 1: upload; */
|
||||
volatile UINT16 USBHD_Endp2_Up_LoadPtr = 0x00; /* USB2.0 full-speed device endpoint 2 Data upload loading offset */
|
||||
volatile UINT8 USBHD_Endp2_Down_Flag = 0x00; /* USB2.0 full-speed device endpoint 2 download success flag */
|
||||
volatile BOOL USBHD_Endp2_T_Tog = 0; /* USB2.0 full speed device endpoint 2 sends tog bit flip */
|
||||
volatile BOOL USBHD_Endp2_R_Tog = 0;
|
||||
|
||||
volatile UINT32V Endp2_send_seq = 0x00;
|
||||
volatile UINT8 DevConfig;
|
||||
volatile UINT8 SetupReqCode;
|
||||
volatile UINT16 SetupReqLen;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Device Descriptor */
|
||||
const UINT8 MyDevDescrHD[] = {
|
||||
|
||||
0x12, 0x01, 0x10, 0x01, 0xFF, 0x00, 0x00, DEF_USBD_UEP0_SIZE,
|
||||
0x86, 0x1A, 0x23, 0x75, 0x63, 0x02, 0x00, 0x02,
|
||||
0x00, 0x01};
|
||||
|
||||
/* Configration Descriptor */
|
||||
const UINT8 MyCfgDescrHD[] =
|
||||
{
|
||||
0x09, 0x02, 0x27, 0x00, 0x01, 0x01, 0x00, 0x80, 0xf0, //Configure descriptor, interface descriptor, endpoint descriptor
|
||||
0x09, 0x04, 0x00, 0x00, 0x03, 0xff, 0x01, 0x02, 0x00,
|
||||
0x07, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, //Bulk upload endpoint
|
||||
0x07, 0x05, 0x02, 0x02, 0x20, 0x00, 0x00, //Bulk download endpoint
|
||||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x01};
|
||||
|
||||
/* Language Descriptor */
|
||||
const UINT8 MyLangDescrHD[] =
|
||||
{
|
||||
0x04, 0x03, 0x09, 0x04};
|
||||
|
||||
/* Manufactor Descriptor */
|
||||
const UINT8 MyManuInfoHD[] =
|
||||
{
|
||||
0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0};
|
||||
|
||||
/* Product Information */
|
||||
const UINT8 MyProdInfoHD[] =
|
||||
{
|
||||
0x0C, 0x03, 'C', 0, 'H', 0, '1', 0, '0', 0, 'x', 0};
|
||||
|
||||
/* Product descriptor */
|
||||
const uint8_t StrDesc[28] =
|
||||
{
|
||||
0x1C, 0x03, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00,
|
||||
0x32, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2D, 0x00,
|
||||
0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00,
|
||||
0x61, 0x00, 0x6C, 0x00};
|
||||
|
||||
const uint8_t Return1[2] = {0x31, 0x00};
|
||||
const uint8_t Return2[2] = {0xC3, 0x00};
|
||||
const uint8_t Return3[2] = {0x9F, 0xEE};
|
||||
|
||||
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->UEP4_1_MOD = USBHD_UEP4_RX_EN | USBHD_UEP4_TX_EN | USBHD_UEP1_RX_EN | USBHD_UEP1_TX_EN;
|
||||
USBOTG_FS->UEP2_3_MOD = USBHD_UEP2_RX_EN | USBHD_UEP2_TX_EN | USBHD_UEP3_RX_EN | USBHD_UEP3_TX_EN;
|
||||
USBOTG_FS->UEP5_6_MOD = USBHD_UEP5_RX_EN | USBHD_UEP5_TX_EN | USBHD_UEP6_RX_EN | USBHD_UEP6_TX_EN;
|
||||
USBOTG_FS->UEP7_MOD = USBHD_UEP7_RX_EN | USBHD_UEP7_TX_EN;
|
||||
|
||||
USBOTG_FS->UEP0_DMA = (UINT32)pEP0_RAM_Addr;
|
||||
USBOTG_FS->UEP1_DMA = (UINT32)pEP1_RAM_Addr;
|
||||
USBOTG_FS->UEP2_DMA = (UINT32)pEP2_RAM_Addr;
|
||||
USBOTG_FS->UEP3_DMA = (UINT32)pEP3_RAM_Addr;
|
||||
USBOTG_FS->UEP4_DMA = (UINT32)pEP4_RAM_Addr;
|
||||
USBOTG_FS->UEP5_DMA = (UINT32)pEP5_RAM_Addr;
|
||||
USBOTG_FS->UEP6_DMA = (UINT32)pEP6_RAM_Addr;
|
||||
USBOTG_FS->UEP7_DMA = (UINT32)pEP7_RAM_Addr;
|
||||
|
||||
USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP1_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP3_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP4_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP5_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP6_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP7_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP1_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP2_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP3_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP4_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP5_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP6_TX_LEN = RepDataLoadLen;
|
||||
USBOTG_FS->UEP7_TX_LEN = RepDataLoadLen;
|
||||
|
||||
USBOTG_FS->UEP1_TX_CTRL = USBHD_UEP_T_RES_ACK;
|
||||
USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_ACK | USBHD_UEP_AUTO_TOG;
|
||||
USBOTG_FS->UEP3_TX_CTRL = USBHD_UEP_T_RES_ACK | USBHD_UEP_AUTO_TOG;
|
||||
USBOTG_FS->UEP4_TX_CTRL = USBHD_UEP_T_RES_ACK | USBHD_UEP_AUTO_TOG;
|
||||
USBOTG_FS->UEP5_TX_CTRL = USBHD_UEP_T_RES_ACK | USBHD_UEP_AUTO_TOG;
|
||||
USBOTG_FS->UEP6_TX_CTRL = USBHD_UEP_T_RES_ACK | USBHD_UEP_AUTO_TOG;
|
||||
USBOTG_FS->UEP7_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->CFGR2 &= ~RCC_USBFS_CLK_SRC; //usbotg clock selection: 0 = systick, 1 = usb20_phy
|
||||
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)
|
||||
{
|
||||
/* Endpoint buffer initialization */
|
||||
pEP0_RAM_Addr = EP0_DatabufHD;
|
||||
pEP1_RAM_Addr = EP1_DatabufHD;
|
||||
pEP2_RAM_Addr = EP2_DatabufHD;
|
||||
pEP3_RAM_Addr = EP3_DatabufHD;
|
||||
pEP4_RAM_Addr = EP4_DatabufHD;
|
||||
pEP5_RAM_Addr = EP5_DatabufHD;
|
||||
pEP6_RAM_Addr = EP6_DatabufHD;
|
||||
pEP7_RAM_Addr = EP7_DatabufHD;
|
||||
/* Enable USB clock */
|
||||
USBOTG_RCC_Init();
|
||||
Delay_Us(100);
|
||||
/* USB device initialization */
|
||||
USBDeviceInit();
|
||||
/* Enable USB interrupt */
|
||||
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 package processing */
|
||||
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;
|
||||
/* Determine whether the current standard request or other requests */
|
||||
if((pSetupReqPakHD->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD)
|
||||
{
|
||||
/* Other requests, such as class requests, manufacturer requests, etc. */
|
||||
if(pSetupReqPakHD->bRequestType == 0xC0)
|
||||
{
|
||||
if(SetupReqCode == 0x5F)
|
||||
{
|
||||
pDescr = Return1;
|
||||
len = sizeof(Return1);
|
||||
}
|
||||
else if(SetupReqCode == 0x95)
|
||||
{
|
||||
if((pSetupReqPakHD->wValue) == 0x18)
|
||||
{
|
||||
pDescr = Return2;
|
||||
len = sizeof(Return2);
|
||||
}
|
||||
else if((pSetupReqPakHD->wValue) == 0x06)
|
||||
{
|
||||
pDescr = Return3;
|
||||
len = sizeof(Return3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Processing standard USB request package */
|
||||
switch(SetupReqCode)
|
||||
{
|
||||
case USB_GET_DESCRIPTOR:
|
||||
{
|
||||
switch(((pSetupReqPakHD->wValue) >> 8))
|
||||
{
|
||||
case USB_DESCR_TYP_DEVICE:
|
||||
/* Get the device descriptor */
|
||||
pDescr = MyDevDescrHD;
|
||||
len = MyDevDescrHD[0];
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_CONFIG:
|
||||
/* Get the configuration descriptor */
|
||||
pDescr = MyCfgDescrHD;
|
||||
len = MyCfgDescrHD[2];
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_STRING:
|
||||
/* Get the string descriptor */
|
||||
switch((pSetupReqPakHD->wValue) & 0xff)
|
||||
{
|
||||
case 0:
|
||||
/* Language string descriptor */
|
||||
pDescr = MyLangDescrHD;
|
||||
len = MyLangDescrHD[0];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* USB manufacturer string descriptor */
|
||||
pDescr = MyManuInfoHD;
|
||||
len = MyManuInfoHD[0];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* USB product string descriptor */
|
||||
pDescr = StrDesc;
|
||||
len = StrDesc[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_REPORT:
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_QUALIF:
|
||||
break;
|
||||
|
||||
case USB_DESCR_TYP_BOS:
|
||||
/* BOS descriptor */
|
||||
/* USB2.0 device does not support the BOS descriptor */
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
if(SetupReqLen > len)
|
||||
SetupReqLen = len;
|
||||
len = (SetupReqLen >= DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : SetupReqLen;
|
||||
memcpy(pEP0_DataBuf, pDescr, len);
|
||||
pDescr += len;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_SET_ADDRESS:
|
||||
/* Setting address */
|
||||
SetupReqLen = (pSetupReqPakHD->wValue) & 0xff;
|
||||
break;
|
||||
|
||||
case USB_GET_CONFIGURATION:
|
||||
/* Get the configuration value */
|
||||
pEP0_DataBuf[0] = DevConfig;
|
||||
if(SetupReqLen > 1)
|
||||
SetupReqLen = 1;
|
||||
break;
|
||||
|
||||
case USB_SET_CONFIGURATION:
|
||||
/* Set the configuration value */
|
||||
DevConfig = (pSetupReqPakHD->wValue) & 0xff;
|
||||
break;
|
||||
|
||||
case USB_CLEAR_FEATURE:
|
||||
/* Cleaer feature */
|
||||
if((pSetupReqPakHD->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP)
|
||||
{
|
||||
/* Clear endpoint */
|
||||
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:
|
||||
/* Set feature */
|
||||
if((pMySetupReqPakHD->bRequestType & 0x1F) == 0x00)
|
||||
{
|
||||
/* Setting device */
|
||||
if(pMySetupReqPakHD->wValue == 0x01)
|
||||
{
|
||||
if(MyCfgDescrHD[7] & 0x20)
|
||||
{
|
||||
/* Set wake-up enable flag */
|
||||
USBHD_Dev_SleepStatus = 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else if((pMySetupReqPakHD->bRequestType & 0x1F) == 0x02)
|
||||
{
|
||||
/* Set the endpoint */
|
||||
if(pMySetupReqPakHD->wValue == 0x00)
|
||||
{
|
||||
/* Set the specified endpoint stall */
|
||||
switch((pMySetupReqPakHD->wIndex) & 0xff)
|
||||
{
|
||||
case 0x82:
|
||||
/* Set endpoint 2 IN STALL */
|
||||
USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
|
||||
//USBHS->UEP2_CTRL = ( USBHS->UEP2_CTRL & ~USBHS_EP_T_RES_MASK ) | USBHS_EP_T_RES_STALL;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
/* Set endpoint 2 OUT Stall */
|
||||
USBOTG_FS->UEP2_RX_CTRL = (USBOTG_FS->UEP2_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
|
||||
//USBHS->UEP2_CTRL = ( USBHS->UEP2_CTRL & ~USBHS_EP_R_RES_MASK ) | USBHS_EP_R_RES_STALL;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
/* Set endpoint 1 IN STALL */
|
||||
USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
|
||||
//USBHS->UEP1_CTRL = ( USBHS->UEP1_CTRL & ~USBHS_EP_T_RES_MASK ) | USBHS_EP_T_RES_STALL;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
/* Set endpoint 1 OUT STALL */
|
||||
USBOTG_FS->UEP1_RX_CTRL = (USBOTG_FS->UEP1_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
|
||||
//USBHS->UEP1_CTRL = ( USBHS->UEP1_CTRL & ~USBHS_EP_R_RES_MASK ) | USBHS_EP_R_RES_STALL;
|
||||
break;
|
||||
|
||||
default:
|
||||
errflag = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errflag = 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_GET_INTERFACE:
|
||||
/* Obtain interface */
|
||||
pEP0_DataBuf[0] = 0x00;
|
||||
if(SetupReqLen > 1)
|
||||
SetupReqLen = 1;
|
||||
break;
|
||||
|
||||
case USB_SET_INTERFACE:
|
||||
/* Set interface */
|
||||
EP0_DatabufHD[0] = 0x00;
|
||||
if(USBHD_Dev_SetupReqLen > 1)
|
||||
{
|
||||
USBHD_Dev_SetupReqLen = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_GET_STATUS:
|
||||
/* Reply according to the actual state of the current endpoint */
|
||||
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 > DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : 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 >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : 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;
|
||||
/* Back to NCK by default */
|
||||
case USBHD_UIS_TOKEN_IN | 1:
|
||||
USBOTG_FS->UEP1_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
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;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 3:
|
||||
USBOTG_FS->UEP3_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 4:
|
||||
USBOTG_FS->UEP4_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 5:
|
||||
USBOTG_FS->UEP5_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 6:
|
||||
USBOTG_FS->UEP6_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_IN | 7:
|
||||
USBOTG_FS->UEP7_TX_CTRL ^= USBHD_UEP_T_TOG;
|
||||
USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_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 | 1:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP1_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
|
||||
DevEP1_OUT_Deal(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;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 3:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP3_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP3_OUT_Deal(len);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 4:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP4_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP4_OUT_Deal(len);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 5:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP5_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP5_OUT_Deal(len);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 6:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP6_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP6_OUT_Deal(len);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBHD_UIS_TOKEN_OUT | 7:
|
||||
if(USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK)
|
||||
{
|
||||
USBOTG_FS->UEP7_RX_CTRL ^= USBHD_UEP_R_TOG;
|
||||
len = USBOTG_FS->RX_LEN;
|
||||
DevEP7_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->UEP1_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP3_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP4_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP5_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP6_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
USBOTG_FS->UEP7_RX_CTRL = USBHD_UEP_R_RES_ACK;
|
||||
|
||||
USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP1_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP3_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP4_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP5_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP6_TX_CTRL = USBHD_UEP_T_RES_NAK;
|
||||
USBOTG_FS->UEP7_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 USBSendData
|
||||
*
|
||||
* @brief Send data to the host
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
uint8_t USBSendData(void)
|
||||
{
|
||||
if(USBOTG_FS->UEP2_TX_CTRL & USBHD_UEP_T_RES_MASK == USBHD_UEP_T_RES_ACK)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
if(RingMemBLE.CurrentLen > 32)
|
||||
{
|
||||
RingMemRead(&RingMemBLE, pEP2_IN_DataBuf, 32);
|
||||
DevEP2_IN_Deal(32);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t len = RingMemBLE.CurrentLen;
|
||||
RingMemRead(&RingMemBLE, pEP2_IN_DataBuf, len);
|
||||
DevEP2_IN_Deal(len);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP1_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint1 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP1_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP1_TX_LEN = l;
|
||||
USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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 DevEP3_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint3 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP3_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP3_TX_LEN = l;
|
||||
USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP4_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint4 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP4_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP4_TX_LEN = l;
|
||||
USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP5_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint5 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP5_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP5_TX_LEN = l;
|
||||
USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP6_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint6 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP6_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP6_TX_LEN = l;
|
||||
USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP7_IN_Deal
|
||||
*
|
||||
* @brief Device endpoint7 IN.
|
||||
*
|
||||
* @param l - IN length(<64B)
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP7_IN_Deal(UINT8 l)
|
||||
{
|
||||
USBOTG_FS->UEP7_TX_LEN = l;
|
||||
USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP1_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 1 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP1_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP2_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 2 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP2_OUT_Deal(UINT8 l)
|
||||
{
|
||||
if(RingMemWrite(&RingMemUSB, pEP2_OUT_DataBuf, l) != SUCCESS)
|
||||
{
|
||||
PRINT("RingMemBLE ERR \n");
|
||||
}
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PROCESS_USBDATA_EVT, 32);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP3_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 3 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP3_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP4_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 4 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP4_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP5_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 5 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP5_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP6_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 6 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP6_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevEP7_OUT_Deal
|
||||
*
|
||||
* @brief Deal device Endpoint 7 OUT.
|
||||
*
|
||||
* @param l - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void DevEP7_OUT_Deal(UINT8 l)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : RingMem.h
|
||||
* Author : Hikari
|
||||
* Version : V1.4
|
||||
* Date : 2019/12/20
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
#ifndef RINGMEM_H
|
||||
#define RINGMEM_H
|
||||
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS 0
|
||||
#endif
|
||||
#ifndef ENABLE
|
||||
#define ENABLE 1
|
||||
#endif
|
||||
#ifndef DISABLE
|
||||
#define DISABLE 0
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef int (*RingMemProtection_t)(uint8_t enable);
|
||||
|
||||
//Buffer structure
|
||||
typedef struct
|
||||
{
|
||||
uint8_t volatile *pData; //Buffer first address
|
||||
uint8_t volatile *pWrite; //Pointer
|
||||
uint8_t volatile *pRead; //Pointer
|
||||
uint8_t volatile *pEnd; //The last address of the buffer area
|
||||
uint32_t volatile RemanentLen; //Remaining space size
|
||||
uint32_t volatile CurrentLen; //Already used space
|
||||
uint32_t volatile MaxLen; //Total space size
|
||||
} RingMemParm_t;
|
||||
|
||||
/*********************************************************************
|
||||
* Global Variables
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
extern void RingMemInit(RingMemParm_t *Parm, uint8_t *StartAddr, uint32_t MaxLen, RingMemProtection_t Protection);
|
||||
|
||||
extern uint8_t RingMemWrite(RingMemParm_t *Parm, uint8_t *pData, uint32_t len);
|
||||
|
||||
extern uint8_t RingMemRead(RingMemParm_t *Parm, uint8_t *pData, uint32_t len);
|
||||
|
||||
extern uint8_t RingMemCopy(RingMemParm_t *Parm, uint8_t *pData, uint32_t len);
|
||||
|
||||
extern uint8_t RingMemDelete(RingMemParm_t *Parm, uint32_t len);
|
||||
|
||||
extern uint8_t RingAddInStart(RingMemParm_t *Parm, uint8_t *pData, uint32_t len);
|
||||
|
||||
extern uint8_t RingReturnSingleData(RingMemParm_t *Parm, uint32_t Num);
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* 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,18 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* 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,798 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbotg_device.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains all the functions prototypes for the
|
||||
* USBOTG firmware library.
|
||||
*********************************************************************************
|
||||
* 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 // usb otg control,会话电平使能
|
||||
#define USB_OTG_CR_VBUS 0x10 // usb otg control,VBUS电平使能
|
||||
#define USB_OTG_CR_OTG_EN 0x08 // usb otg control,OTG功能使能
|
||||
#define USB_OTG_CR_IDPU 0x04 // usb otg control,ID引脚上拉
|
||||
#define USB_OTG_CR_CHARGEVBUS 0x02 // usb otg control,VBUS充电
|
||||
#define USB_OTG_CR_DISCHARGEVBUS 0x01 // usb otg control,VBUS放电
|
||||
|
||||
#define USB_OTG_SR (USBOTG_FS->OTG_CR) // usb otg status
|
||||
#define USB_OTG_SR_VBUS_VLD 0x01 // usb otg status,A设备VBUS输入电平有效
|
||||
#define USB_OTG_SR_SESS_VLD 0x02 // usb otg status,会话有效电平有效标志
|
||||
#define USB_OTG_SR_SESS_END 0x04 // usb otg status,会话结束电平有效标志
|
||||
#define USB_OTG_SR_ID_DIG 0x08 // usb otg status,ID电平
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* USBHS PHY Clock Config (RCC_CFGR2) 使用USBHS PHY时钟的情况下,需要用到这些宏定义 */
|
||||
#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)
|
||||
#endif
|
||||
|
||||
/*使用sysclk时钟的情况下,需要用到这些宏定义 */
|
||||
#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)
|
||||
|
||||
/******************************************************************************/
|
||||
/* 设备速度相关宏定义 */
|
||||
#define DEF_USBD_SPEED_FULL 1
|
||||
#define DEF_USBD_SPEED_LOW 2
|
||||
|
||||
#define DEF_USBD_SPEED DEF_USBD_SPEED_FULL
|
||||
/******************************************************************************/
|
||||
/* 端点大小相关宏定义 */
|
||||
#if DEF_USBD_SPEED == DEF_USBD_SPEED_FULL
|
||||
#define DEF_USBD_UEP0_SIZE 64
|
||||
#define DEF_USBD_MAX_PACK_SIZE 64
|
||||
#define DEF_USBD_BLK_PACK_SIZE 64
|
||||
#define DEF_USBD_INT_PACK_SIZE 64
|
||||
#define DEF_USBD_SYC_PACK_SIZE 1023
|
||||
#elif DEF_USBD_SPEED == DEF_USBD_SPEED_LOW
|
||||
#define DEF_USBD_UEP0_SIZE 8
|
||||
#define DEF_USBD_MAX_PACK_SIZE 8
|
||||
#define DEF_USBD_BLK_PACK_SIZE 0
|
||||
#define DEF_USBD_INT_PACK_SIZE 8
|
||||
#define DEF_USBD_SYC_PACK_SIZE 0
|
||||
#endif
|
||||
|
||||
/* 端点大小定义 */
|
||||
#define DEF_USB_LS_EP_SIZE 8 /* 端点全速模式大小 */
|
||||
#define DEF_USB_FS_EP_SIZE 64 /* 端点全速模式大小 */
|
||||
|
||||
/******************************************************************************/
|
||||
/* 变量外扩 */
|
||||
extern PUINT8 pEP0_RAM_Addr; //ep0(64)
|
||||
extern PUINT8 pEP1_RAM_Addr; //ep1_out(64)+ep1_in(64)
|
||||
extern PUINT8 pEP2_RAM_Addr; //ep2_out(64)+ep2_in(64)
|
||||
extern PUINT8 pEP3_RAM_Addr; //ep3_out(64)+ep3_in(64)
|
||||
extern PUINT8 pEP4_RAM_Addr; //ep4_out(64)+ep4_in(64)
|
||||
extern PUINT8 pEP5_RAM_Addr; //ep5_out(64)+ep5_in(64)
|
||||
extern PUINT8 pEP6_RAM_Addr; //ep6_out(64)+ep6_in(64)
|
||||
extern PUINT8 pEP7_RAM_Addr; //ep7_out(64)+ep7_in(64)
|
||||
|
||||
extern volatile UINT16 USBHD_Endp1_Up_Flag; /* USB2.0高速设备端点1数据上传状态: 0:空闲; 1:正在上传; */
|
||||
extern volatile UINT8 USBHD_Endp1_Down_Flag; /* USB2.0高速设备端点1下传成功标志 */
|
||||
extern volatile UINT8 USBHD_Endp1_Down_Len; /* USB2.0高速设备端点1下传长度 */
|
||||
extern volatile BOOL USBHD_Endp1_T_Tog; /* USB2.0高速设备端点1发送tog位翻转 */
|
||||
extern volatile BOOL USBHD_Endp1_R_Tog;
|
||||
|
||||
extern volatile UINT16 USBHD_Endp2_Up_Flag; /* USB2.0高速设备端点2数据上传状态: 0:空闲; 1:正在上传; */
|
||||
extern volatile UINT16 USBHD_Endp2_Up_LoadPtr; /* USB2.0高速设备端点2数据上传装载偏移 */
|
||||
extern volatile UINT8 USBHD_Endp2_Down_Flag; /* USB2.0高速设备端点2下传成功标志 */
|
||||
|
||||
/******************************************************************************/
|
||||
/* DMA地址和缓冲区相关宏定义 */
|
||||
#define pSetupReqPakHD ((PUSB_SETUP_REQ)pEP0_RAM_Addr)
|
||||
#define pEP0_DataBuf (pEP0_RAM_Addr)
|
||||
#define pEP1_OUT_DataBuf (pEP1_RAM_Addr)
|
||||
#define pEP1_IN_DataBuf (pEP1_RAM_Addr+64)
|
||||
#define pEP2_OUT_DataBuf (pEP2_RAM_Addr)
|
||||
#define pEP2_IN_DataBuf (pEP2_RAM_Addr+64)
|
||||
#define pEP3_OUT_DataBuf (pEP3_RAM_Addr)
|
||||
#define pEP3_IN_DataBuf (pEP3_RAM_Addr+64)
|
||||
#define pEP4_OUT_DataBuf (pEP4_RAM_Addr)
|
||||
#define pEP4_IN_DataBuf (pEP4_RAM_Addr+64)
|
||||
#define pEP5_OUT_DataBuf (pEP5_RAM_Addr)
|
||||
#define pEP5_IN_DataBuf (pEP5_RAM_Addr+64)
|
||||
#define pEP6_OUT_DataBuf (pEP6_RAM_Addr)
|
||||
#define pEP6_IN_DataBuf (pEP6_RAM_Addr+64)
|
||||
#define pEP7_OUT_DataBuf (pEP7_RAM_Addr)
|
||||
#define pEP7_IN_DataBuf (pEP7_RAM_Addr+64)
|
||||
/******************************************************************************/
|
||||
/* 端点状态获取宏定义 */
|
||||
#define EP1_GetINSta() (R8_UEP1_CTRL&UEP_T_RES_NAK)
|
||||
#define EP2_GetINSta() (R8_UEP2_CTRL&UEP_T_RES_NAK)
|
||||
#define EP3_GetINSta() (R8_UEP3_CTRL&UEP_T_RES_NAK)
|
||||
#define EP4_GetINSta() (R8_UEP4_CTRL&UEP_T_RES_NAK)
|
||||
#define EP5_GetINSta() (R8_UEP5_CTRL&UEP_T_RES_NAK)
|
||||
#define EP6_GetINSta() (R8_UEP6_CTRL&UEP_T_RES_NAK)
|
||||
#define EP7_GetINSta() (R8_UEP7_CTRL&UEP_T_RES_NAK)
|
||||
|
||||
/******************************************************************************/
|
||||
/* 函数声明和外扩 */
|
||||
extern void DevEP1_OUT_Deal( UINT8 l );
|
||||
extern void DevEP2_OUT_Deal( UINT8 l );
|
||||
extern void DevEP3_OUT_Deal( UINT8 l );
|
||||
extern void DevEP4_OUT_Deal( UINT8 l );
|
||||
extern void DevEP5_OUT_Deal( UINT8 l );
|
||||
extern void DevEP6_OUT_Deal( UINT8 l );
|
||||
extern void DevEP7_OUT_Deal( UINT8 l );
|
||||
|
||||
extern void DevEP1_IN_Deal( UINT8 l );
|
||||
extern void DevEP2_IN_Deal( UINT8 l );
|
||||
extern void DevEP3_IN_Deal( UINT8 l );
|
||||
extern void DevEP4_IN_Deal( UINT8 l );
|
||||
extern void DevEP5_IN_Deal( UINT8 l );
|
||||
extern void DevEP6_IN_Deal( UINT8 l );
|
||||
extern void DevEP7_IN_Deal( UINT8 l );
|
||||
|
||||
extern void USBDeviceInit( void );
|
||||
extern void USBOTG_Init( void );
|
||||
|
||||
extern uint8_t USBSendData(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* 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 PERIPHERAL_H
|
||||
#define PERIPHERAL_H
|
||||
#include "RingMem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Peripheral Task Events
|
||||
#define SBP_START_DEVICE_EVT 0x0001
|
||||
#define SBP_PERIODIC_EVT 0x0002
|
||||
#define SBP_READ_RSSI_EVT 0x0004
|
||||
#define SBP_PARAM_UPDATE_EVT 0x0008
|
||||
#define SBP_PHY_UPDATE_EVT 0x0010
|
||||
#define SBP_PROCESS_USBDATA_EVT 0x0020
|
||||
#define SBP_PROCESS_BLEDATA_EVT 0x0040
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t connHandle; // Connection handle of current connection
|
||||
uint16_t connInterval;
|
||||
uint16_t connSlaveLatency;
|
||||
uint16_t connTimeout;
|
||||
} peripheralConnItem_t;
|
||||
|
||||
extern RingMemParm_t RingMemUSB;
|
||||
extern uint8_t RingMemUSBBuf[2048];
|
||||
extern RingMemParm_t RingMemBLE;
|
||||
extern uint8_t RingMemBLEBuf[2048];
|
||||
extern uint8_t Peripheral_TaskID;
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* Task Initialization for the BLE Application
|
||||
*/
|
||||
extern void Peripheral_Init(void);
|
||||
|
||||
/*
|
||||
* Task Event Processor for the BLE Application
|
||||
*/
|
||||
extern uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
uint8_t app_usb_notify(uint8_t *SendBuf, uint8_t l);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/06/16
|
||||
* 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 */
|
||||
@@ -0,0 +1,859 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/10
|
||||
* Description : Peripheral slave multi-connection application, initialize
|
||||
* broadcast connection parameters, then broadcast, after connecting
|
||||
* to the host, request to update connection parameters,
|
||||
* and transmit data through custom services.
|
||||
*********************************************************************************
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "CONFIG.h"
|
||||
#include "devinfoservice.h"
|
||||
#include "gattprofile.h"
|
||||
#include "peripheral.h"
|
||||
#include "ble_usb_service.h"
|
||||
#include "ch32v20x_usbotg_device.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// How often to perform periodic event
|
||||
#define SBP_PERIODIC_EVT_PERIOD 1600
|
||||
|
||||
// How often to perform read rssi event
|
||||
#define SBP_READ_RSSI_EVT_PERIOD 3200
|
||||
|
||||
// Parameter update delay
|
||||
#define SBP_PARAM_UPDATE_DELAY 6400
|
||||
|
||||
// PHY update delay
|
||||
#define SBP_PHY_UPDATE_DELAY 2400
|
||||
|
||||
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
|
||||
#define DEFAULT_ADVERTISING_INTERVAL 80
|
||||
|
||||
// Limited discoverable mode advertises for 30.72s, and then stops
|
||||
// General discoverable mode advertises indefinitely
|
||||
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
|
||||
|
||||
// Minimum connection interval (units of 1.25ms, 6=7.5ms)
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
|
||||
|
||||
// Maximum connection interval (units of 1.25ms, 100=125ms)
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 100
|
||||
|
||||
// Slave latency to use parameter update
|
||||
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
|
||||
|
||||
// Supervision timeout value (units of 10ms, 100=1s)
|
||||
#define DEFAULT_DESIRED_CONN_TIMEOUT 100
|
||||
|
||||
// Company Identifier: WCH
|
||||
#define WCH_COMPANY_ID 0x07D7
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
|
||||
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
static uint8_t scanRspData[] = {
|
||||
// complete name
|
||||
0x11, // length of this data
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
'c', 'h','3', '2', 'v', '2', '0', '8', ' ', 'b', 'l', 'e', ' ', 'u', 's', 'b',
|
||||
|
||||
// connection interval range
|
||||
0x05, // length of this data
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
|
||||
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
|
||||
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
|
||||
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
0 // 0dBm
|
||||
};
|
||||
|
||||
// GAP - Advertisement data (max size = 31 bytes, though this is
|
||||
// best kept short to conserve power while advertising)
|
||||
static uint8_t advertData[] = {
|
||||
// Flags; this sets the device to use limited discoverable
|
||||
// mode (advertises for 30 seconds at a time) instead of general
|
||||
// discoverable mode (advertises indefinitely)
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_FLAGS,
|
||||
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
|
||||
|
||||
// service UUID, to notify central devices what services are included
|
||||
// in this peripheral
|
||||
0x03, // length of this data
|
||||
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
|
||||
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
|
||||
HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
|
||||
|
||||
// GAP GATT Attributes
|
||||
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "ch32v208 ble usb";
|
||||
|
||||
// Connection item list
|
||||
static peripheralConnItem_t peripheralConnList;
|
||||
|
||||
static uint16_t peripheralMTU = ATT_MTU_SIZE;
|
||||
|
||||
RingMemParm_t RingMemUSB;
|
||||
uint8_t RingMemUSBBuf[2048];
|
||||
RingMemParm_t RingMemBLE;
|
||||
uint8_t RingMemBLEBuf[2048];
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
|
||||
static void performPeriodicTask(void);
|
||||
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len);
|
||||
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
|
||||
uint16_t connSlaveLatency, uint16_t connTimeout);
|
||||
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList);
|
||||
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi);
|
||||
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len);
|
||||
void ble_usb_ServiceEvt(uint16_t connection_handle, ble_usb_evt_t *p_evt);
|
||||
int RingMem_Protection(uint8_t enable);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
|
||||
// GAP Role Callbacks
|
||||
static gapRolesCBs_t Peripheral_PeripheralCBs = {
|
||||
peripheralStateNotificationCB, // Profile State Change Callbacks
|
||||
peripheralRssiCB, // When a valid RSSI is read from controller (not used by application)
|
||||
peripheralParamUpdateCB};
|
||||
|
||||
// Broadcast Callbacks
|
||||
static gapRolesBroadcasterCBs_t Broadcaster_BroadcasterCBs = {
|
||||
NULL, // Not used in peripheral role
|
||||
NULL // Receive scan request callback
|
||||
};
|
||||
|
||||
// GAP Bond Manager Callbacks
|
||||
static gapBondCBs_t Peripheral_BondMgrCBs = {
|
||||
NULL, // Passcode callback (not used by application)
|
||||
NULL // Pairing / Bonding state Callback (not used by application)
|
||||
};
|
||||
|
||||
// Simple GATT Profile Callbacks
|
||||
static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
|
||||
simpleProfileChangeCB // Characteristic value change callback
|
||||
};
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_Init
|
||||
*
|
||||
* @brief Initialization function for the Peripheral App Task.
|
||||
* This is called during initialization and should contain
|
||||
* any application specific initialization (ie. hardware
|
||||
* initialization/setup, table initialization, power up
|
||||
* notificaiton ... ).
|
||||
*
|
||||
* @param task_id - the ID assigned by TMOS. This ID should be
|
||||
* used to send messages and set timers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Peripheral_Init()
|
||||
{
|
||||
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
|
||||
|
||||
// Setup the GAP Peripheral Role Profile
|
||||
{
|
||||
uint8_t initial_advertising_enable = TRUE;
|
||||
uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
|
||||
uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
|
||||
}
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
|
||||
|
||||
{
|
||||
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
|
||||
|
||||
// Set advertising interval
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
|
||||
|
||||
// Enable scan req notify
|
||||
GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
|
||||
}
|
||||
|
||||
// Setup the GAP Bond Manager
|
||||
{
|
||||
uint32_t passkey = 0; // passkey "000000"
|
||||
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
|
||||
uint8_t mitm = TRUE;
|
||||
uint8_t bonding = TRUE;
|
||||
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
|
||||
}
|
||||
|
||||
// Initialize GATT attributes
|
||||
GGS_AddService(GATT_ALL_SERVICES); // GAP
|
||||
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
|
||||
DevInfo_AddService(); // Device Information Service
|
||||
SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
|
||||
ble_usb_add_service(ble_usb_ServiceEvt);
|
||||
|
||||
// Setup the SimpleProfile Characteristic Values
|
||||
{
|
||||
uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = {1};
|
||||
uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {2};
|
||||
uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {3};
|
||||
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {4};
|
||||
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};
|
||||
|
||||
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, SIMPLEPROFILE_CHAR1_LEN, charValue1);
|
||||
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, charValue2);
|
||||
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3);
|
||||
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
|
||||
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
|
||||
}
|
||||
|
||||
// Init Connection Item
|
||||
peripheralInitConnItem(&peripheralConnList);
|
||||
|
||||
// Register callback with SimpleGATTprofile
|
||||
SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);
|
||||
|
||||
// Register receive scan request callback
|
||||
GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);
|
||||
|
||||
// Setup a delayed profile startup
|
||||
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
|
||||
|
||||
RingMemInit(&RingMemUSB, RingMemUSBBuf, 2048, RingMem_Protection);
|
||||
RingMemInit(&RingMemBLE, RingMemBLEBuf, 2048, RingMem_Protection);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralInitConnItem
|
||||
*
|
||||
* @brief Init Connection Item
|
||||
*
|
||||
* @param peripheralConnList -
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
|
||||
{
|
||||
peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
|
||||
peripheralConnList->connInterval = 0;
|
||||
peripheralConnList->connSlaveLatency = 0;
|
||||
peripheralConnList->connTimeout = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessEvent
|
||||
*
|
||||
* @brief Peripheral Application Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed
|
||||
*/
|
||||
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
// VOID task_id; // TMOS required parameter that isn't used in this function
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
|
||||
{
|
||||
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if(events & SBP_START_DEVICE_EVT)
|
||||
{
|
||||
// Start the Device
|
||||
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
|
||||
return (events ^ SBP_START_DEVICE_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PERIODIC_EVT)
|
||||
{
|
||||
// Restart timer
|
||||
if(SBP_PERIODIC_EVT_PERIOD)
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
|
||||
}
|
||||
// Perform periodic application task
|
||||
performPeriodicTask();
|
||||
return (events ^ SBP_PERIODIC_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PARAM_UPDATE_EVT)
|
||||
{
|
||||
// Send connect param update request
|
||||
GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,
|
||||
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_SLAVE_LATENCY,
|
||||
DEFAULT_DESIRED_CONN_TIMEOUT,
|
||||
Peripheral_TaskID);
|
||||
|
||||
return (events ^ SBP_PARAM_UPDATE_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PHY_UPDATE_EVT)
|
||||
{
|
||||
// start phy update
|
||||
PRINT("PHY Update %x...\n", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0, GAP_PHY_BIT_LE_2M,
|
||||
GAP_PHY_BIT_LE_2M, 0));
|
||||
|
||||
return (events ^ SBP_PHY_UPDATE_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_READ_RSSI_EVT)
|
||||
{
|
||||
GAPRole_ReadRssiCmd(peripheralConnList.connHandle);
|
||||
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
|
||||
return (events ^ SBP_READ_RSSI_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PROCESS_USBDATA_EVT)
|
||||
{
|
||||
while(RingMemUSB.CurrentLen)
|
||||
{
|
||||
uint8_t buf[peripheralMTU - 3];
|
||||
if(RingMemUSB.CurrentLen > peripheralMTU - 3)
|
||||
{
|
||||
RingMemCopy(&RingMemUSB, buf, peripheralMTU - 3);
|
||||
if(app_usb_notify(buf, peripheralMTU - 3))
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PROCESS_USBDATA_EVT, 80);
|
||||
break;
|
||||
}
|
||||
RingMemDelete(&RingMemUSB, peripheralMTU - 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
RingMemCopy(&RingMemUSB, buf, RingMemUSB.CurrentLen);
|
||||
if(app_usb_notify(buf, RingMemUSB.CurrentLen))
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PROCESS_USBDATA_EVT, 80);
|
||||
break;
|
||||
}
|
||||
RingMemDelete(&RingMemUSB, RingMemUSB.CurrentLen);
|
||||
}
|
||||
}
|
||||
return (events ^ SBP_PROCESS_USBDATA_EVT);
|
||||
}
|
||||
|
||||
if(events & SBP_PROCESS_BLEDATA_EVT)
|
||||
{
|
||||
if(RingMemBLE.CurrentLen)
|
||||
{
|
||||
USBSendData();
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PROCESS_BLEDATA_EVT, 5);
|
||||
}
|
||||
return (events ^ SBP_PROCESS_BLEDATA_EVT);
|
||||
}
|
||||
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessGAPMsg
|
||||
*
|
||||
* @brief Process an incoming task message.
|
||||
*
|
||||
* @param pMsg - message to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_ProcessGAPMsg(gapRoleEvent_t *pEvent)
|
||||
{
|
||||
switch(pEvent->gap.opcode)
|
||||
{
|
||||
case GAP_SCAN_REQUEST_EVENT:
|
||||
{
|
||||
PRINT("Receive scan req from %x %x %x %x %x %x ..\n", pEvent->scanReqEvt.scannerAddr[0],
|
||||
pEvent->scanReqEvt.scannerAddr[1], pEvent->scanReqEvt.scannerAddr[2], pEvent->scanReqEvt.scannerAddr[3],
|
||||
pEvent->scanReqEvt.scannerAddr[4], pEvent->scanReqEvt.scannerAddr[5]);
|
||||
break;
|
||||
}
|
||||
|
||||
case GAP_PHY_UPDATE_EVENT:
|
||||
{
|
||||
PRINT("Phy update Rx:%x Tx:%x ..\n", pEvent->linkPhyUpdate.connRxPHYS, pEvent->linkPhyUpdate.connTxPHYS);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessTMOSMsg
|
||||
*
|
||||
* @brief Process an incoming task message.
|
||||
*
|
||||
* @param pMsg - message to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
|
||||
{
|
||||
switch(pMsg->event)
|
||||
{
|
||||
case GAP_MSG_EVENT:
|
||||
{
|
||||
Peripheral_ProcessGAPMsg((gapRoleEvent_t *)pMsg);
|
||||
break;
|
||||
}
|
||||
|
||||
case GATT_MSG_EVENT:
|
||||
{
|
||||
gattMsgEvent_t *pMsgEvent;
|
||||
|
||||
pMsgEvent = (gattMsgEvent_t *)pMsg;
|
||||
if(pMsgEvent->method == ATT_MTU_UPDATED_EVENT)
|
||||
{
|
||||
peripheralMTU = pMsgEvent->msg.exchangeMTUReq.clientRxMTU;
|
||||
PRINT("mtu exchange: %d\n", pMsgEvent->msg.exchangeMTUReq.clientRxMTU);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_LinkEstablished
|
||||
*
|
||||
* @brief Process link established.
|
||||
*
|
||||
* @param pEvent - event to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_LinkEstablished(gapRoleEvent_t *pEvent)
|
||||
{
|
||||
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
|
||||
|
||||
// See if already connected
|
||||
if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
|
||||
{
|
||||
GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle);
|
||||
PRINT("Connection max...\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
peripheralConnList.connHandle = event->connectionHandle;
|
||||
peripheralConnList.connInterval = event->connInterval;
|
||||
peripheralConnList.connSlaveLatency = event->connLatency;
|
||||
peripheralConnList.connTimeout = event->connTimeout;
|
||||
peripheralMTU = ATT_MTU_SIZE;
|
||||
|
||||
// Set timer for periodic event
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
|
||||
|
||||
// Set timer for param update event
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);
|
||||
|
||||
// Start read rssi
|
||||
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
|
||||
|
||||
PRINT("Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_LinkTerminated
|
||||
*
|
||||
* @brief Process link terminated.
|
||||
*
|
||||
* @param pEvent - event to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_LinkTerminated(gapRoleEvent_t *pEvent)
|
||||
{
|
||||
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pEvent;
|
||||
|
||||
if(event->connectionHandle == peripheralConnList.connHandle)
|
||||
{
|
||||
peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
|
||||
peripheralConnList.connInterval = 0;
|
||||
peripheralConnList.connSlaveLatency = 0;
|
||||
peripheralConnList.connTimeout = 0;
|
||||
tmos_stop_task(Peripheral_TaskID, SBP_PERIODIC_EVT);
|
||||
tmos_stop_task(Peripheral_TaskID, SBP_READ_RSSI_EVT);
|
||||
|
||||
// Restart advertising
|
||||
{
|
||||
uint8_t advertising_enable = TRUE;
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT("ERR..\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralRssiCB
|
||||
*
|
||||
* @brief RSSI callback.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param rssi - RSSI
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi)
|
||||
{
|
||||
PRINT("RSSI -%d dB Conn %x \n", -rssi, connHandle);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralParamUpdateCB
|
||||
*
|
||||
* @brief Parameter update complete callback
|
||||
*
|
||||
* @param connHandle - connect handle
|
||||
* connInterval - connect interval
|
||||
* connSlaveLatency - connect slave latency
|
||||
* connTimeout - connect timeout
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
|
||||
uint16_t connSlaveLatency, uint16_t connTimeout)
|
||||
{
|
||||
if(connHandle == peripheralConnList.connHandle)
|
||||
{
|
||||
peripheralConnList.connInterval = connInterval;
|
||||
peripheralConnList.connSlaveLatency = connSlaveLatency;
|
||||
peripheralConnList.connTimeout = connTimeout;
|
||||
|
||||
PRINT("Update %x - Int %x \n", connHandle, connInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT("ERR..\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralStateNotificationCB
|
||||
*
|
||||
* @brief Notification from the profile of a state change.
|
||||
*
|
||||
* @param newState - new state
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
|
||||
{
|
||||
switch(newState & GAPROLE_STATE_ADV_MASK)
|
||||
{
|
||||
case GAPROLE_STARTED:
|
||||
PRINT("Initialized..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_ADVERTISING:
|
||||
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
|
||||
{
|
||||
Peripheral_LinkTerminated(pEvent);
|
||||
PRINT("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
|
||||
PRINT("Advertising..\n");
|
||||
}
|
||||
else if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
|
||||
{
|
||||
PRINT("Advertising..\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED:
|
||||
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
|
||||
{
|
||||
Peripheral_LinkEstablished(pEvent);
|
||||
PRINT("Connected..\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED_ADV:
|
||||
if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
|
||||
{
|
||||
PRINT("Connected Advertising..\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_WAITING:
|
||||
if(pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
|
||||
{
|
||||
PRINT("Waiting for advertising..\n");
|
||||
}
|
||||
else if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
|
||||
{
|
||||
Peripheral_LinkTerminated(pEvent);
|
||||
PRINT("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
|
||||
}
|
||||
else if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
|
||||
{
|
||||
if(pEvent->gap.hdr.status != SUCCESS)
|
||||
{
|
||||
PRINT("Waiting for advertising..\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT("Error..\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT("Error..%x\n", pEvent->gap.opcode);
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_ERROR:
|
||||
PRINT("Error..\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn performPeriodicTask
|
||||
*
|
||||
* @brief Perform a periodic application task. This function gets
|
||||
* called every five seconds as a result of the SBP_PERIODIC_EVT
|
||||
* TMOS event. In this example, the value of the third
|
||||
* characteristic in the SimpleGATTProfile service is retrieved
|
||||
* from the profile, and then copied into the value of the
|
||||
* the fourth characteristic.
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void performPeriodicTask(void)
|
||||
{
|
||||
uint8_t notiData[SIMPLEPROFILE_CHAR4_LEN] = {0x88};
|
||||
peripheralChar4Notify(notiData, SIMPLEPROFILE_CHAR4_LEN);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralChar4Notify
|
||||
*
|
||||
* @brief Prepare and send simpleProfileChar4 notification
|
||||
*
|
||||
* @param pValue - data to notify
|
||||
* len - length of data
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len)
|
||||
{
|
||||
attHandleValueNoti_t noti;
|
||||
if(len > (peripheralMTU - 3))
|
||||
{
|
||||
PRINT("Too large noti\n");
|
||||
return;
|
||||
}
|
||||
noti.len = len;
|
||||
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
|
||||
if(noti.pValue)
|
||||
{
|
||||
tmos_memcpy(noti.pValue, pValue, noti.len);
|
||||
if(simpleProfile_Notify(peripheralConnList.connHandle, ¬i) != SUCCESS)
|
||||
{
|
||||
GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfileChangeCB
|
||||
*
|
||||
* @brief Callback from SimpleBLEProfile indicating a value change
|
||||
*
|
||||
* @param paramID - parameter ID of the value that was changed.
|
||||
* pValue - pointer to data that was changed
|
||||
* len - length of data
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
|
||||
{
|
||||
switch(paramID)
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1:
|
||||
{
|
||||
uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
|
||||
tmos_memcpy(newValue, pValue, len);
|
||||
PRINT("profile ChangeCB CHAR1.. \n");
|
||||
break;
|
||||
}
|
||||
|
||||
case SIMPLEPROFILE_CHAR3:
|
||||
{
|
||||
uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
|
||||
tmos_memcpy(newValue, pValue, len);
|
||||
PRINT("profile ChangeCB CHAR3..\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// should not reach here!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_usb_ServiceEvt
|
||||
*
|
||||
* @brief ble usb service callback handler
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void ble_usb_ServiceEvt(uint16_t connection_handle, ble_usb_evt_t *p_evt)
|
||||
{
|
||||
switch(p_evt->type)
|
||||
{
|
||||
case BLE_USB_EVT_TX_NOTI_DISABLED:
|
||||
PRINT("%02x:bleusb_EVT_TX_NOTI_DISABLED\r\n", connection_handle);
|
||||
break;
|
||||
case BLE_USB_EVT_TX_NOTI_ENABLED:
|
||||
PRINT("%02x:bleusb_EVT_TX_NOTI_ENABLED\r\n", connection_handle);
|
||||
break;
|
||||
case BLE_USB_EVT_BLE_DATA_RECIEVED:
|
||||
PRINT("BLE RX DATA len:%d\r\n", p_evt->data.length);
|
||||
|
||||
if(RingMemWrite(&RingMemBLE, (uint8_t *)p_evt->data.p_data, p_evt->data.length) != SUCCESS)
|
||||
{
|
||||
PRINT("RingMemBLE ERR \n");
|
||||
}
|
||||
tmos_set_event(Peripheral_TaskID, SBP_PROCESS_BLEDATA_EVT);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn app_usb_notify
|
||||
*
|
||||
* @brief app usb service callback handler
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
uint8_t app_usb_notify(uint8_t *SendBuf, uint8_t l)
|
||||
{
|
||||
uint8_t result = FAILURE;
|
||||
|
||||
static attHandleValueNoti_t noti;
|
||||
|
||||
if (l > (peripheralMTU - 3)) {
|
||||
PRINT("usb notify too long, current MTU: %d\n", peripheralMTU);
|
||||
return bleInvalidMtuSize;
|
||||
}
|
||||
noti.len = l;
|
||||
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
|
||||
if(noti.pValue != NULL)
|
||||
{
|
||||
tmos_memcpy(noti.pValue, SendBuf, noti.len);
|
||||
result = ble_usb_notify(peripheralConnList.connHandle, ¬i, 0);
|
||||
if(result != SUCCESS)
|
||||
{
|
||||
GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn RingMem_Protection
|
||||
*
|
||||
* @brief Protect RingMem
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
int RingMem_Protection(uint8_t enable)
|
||||
{
|
||||
if(enable)
|
||||
{
|
||||
__disable_irq();
|
||||
}
|
||||
else
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
@@ -0,0 +1,69 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2020/08/06
|
||||
* Description : Peripheral slave application main function and task system initialization
|
||||
*********************************************************************************
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "CONFIG.h"
|
||||
#include "HAL.h"
|
||||
#include "gattprofile.h"
|
||||
#include "peripheral.h"
|
||||
#include "ch32v20x_usbotg_device.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Main_Circulation
|
||||
*
|
||||
* @brief Main loop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__((section(".highcode")))
|
||||
__attribute__((noinline))
|
||||
void Main_Circulation(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
TMOS_SystemProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main function
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
Delay_Init();
|
||||
#ifdef DEBUG
|
||||
USART_Printf_Init( 115200 );
|
||||
#endif
|
||||
PRINT("%s\n", VER_LIB);
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
GAPRole_PeripheralInit();
|
||||
Peripheral_Init();
|
||||
USBOTG_Init( );
|
||||
Main_Circulation();
|
||||
}
|
||||
|
||||
/******************************** endfile @ main ******************************/
|
||||
@@ -0,0 +1,989 @@
|
||||
/********************************** (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_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
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_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( 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_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#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_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(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_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(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_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(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_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(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_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(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_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(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
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user