first submission
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,908 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_mtp_ptp.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/09/01
|
||||
* 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 __APP_MTP_PTP_H
|
||||
#define __APP_MTP_PTP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Macro Definition */
|
||||
|
||||
/* Common Buffer Size */
|
||||
#define DEF_COM_BUF_LEN ( 8192 + 12 )
|
||||
|
||||
/* PTP V1.0 Operation Code */
|
||||
#define PTP_OC_Undefined 0x1000
|
||||
#define PTP_OC_GetDeviceInfo 0x1001
|
||||
#define PTP_OC_OpenSession 0x1002
|
||||
#define PTP_OC_CloseSession 0x1003
|
||||
#define PTP_OC_GetStorageIDs 0x1004
|
||||
#define PTP_OC_GetStorageInfo 0x1005
|
||||
#define PTP_OC_GetNumObjects 0x1006
|
||||
#define PTP_OC_GetObjectHandles 0x1007
|
||||
#define PTP_OC_GetObjectInfo 0x1008
|
||||
#define PTP_OC_GetObject 0x1009
|
||||
#define PTP_OC_GetThumb 0x100A
|
||||
#define PTP_OC_DeleteObject 0x100B
|
||||
#define PTP_OC_SendObjectInfo 0x100C
|
||||
#define PTP_OC_SendObject 0x100D
|
||||
#define PTP_OC_InitiateCapture 0x100E
|
||||
#define PTP_OC_FormatStore 0x100F
|
||||
#define PTP_OC_ResetDevice 0x1010
|
||||
#define PTP_OC_SelfTest 0x1011
|
||||
#define PTP_OC_SetObjectProtection 0x1012
|
||||
#define PTP_OC_PowerDown 0x1013
|
||||
#define PTP_OC_GetDevicePropDesc 0x1014
|
||||
#define PTP_OC_GetDevicePropValue 0x1015
|
||||
#define PTP_OC_SetDevicePropValue 0x1016
|
||||
#define PTP_OC_ResetDevicePropValue 0x1017
|
||||
#define PTP_OC_TerminateOpenCapture 0x1018
|
||||
#define PTP_OC_MoveObject 0x1019
|
||||
#define PTP_OC_CopyObject 0x101A
|
||||
#define PTP_OC_GetPartialObject 0x101B
|
||||
#define PTP_OC_InitiateOpenCapture 0x101C
|
||||
|
||||
/* PTP v1.1 operation codes */
|
||||
#define PTP_OC_StartEnumHandles 0x101D
|
||||
#define PTP_OC_EnumHandles 0x101E
|
||||
#define PTP_OC_StopEnumHandles 0x101F
|
||||
#define PTP_OC_GetVendorExtensionMaps 0x1020
|
||||
#define PTP_OC_GetVendorDeviceInfo 0x1021
|
||||
#define PTP_OC_GetResizedImageObject 0x1022
|
||||
#define PTP_OC_GetFilesystemManifest 0x1023
|
||||
#define PTP_OC_GetStreamInfo 0x1024
|
||||
#define PTP_OC_GetStream 0x1025
|
||||
|
||||
/* Microsoft / MTP extension codes */
|
||||
#define PTP_OC_GetObjectPropsSupported 0x9801
|
||||
#define PTP_OC_GetObjectPropDesc 0x9802
|
||||
#define PTP_OC_GetObjectPropValue 0x9803
|
||||
#define PTP_OC_SetObjectPropValue 0x9804
|
||||
#define PTP_OC_GetObjPropList 0x9805
|
||||
#define PTP_OC_SetObjPropList 0x9806
|
||||
#define PTP_OC_GetInterdependendPropdesc 0x9807
|
||||
#define PTP_OC_SendObjectPropList 0x9808
|
||||
#define PTP_OC_GetObjectReferences 0x9810
|
||||
#define PTP_OC_SetObjectReferences 0x9811
|
||||
#define PTP_OC_UpdateDeviceFirmware 0x9812
|
||||
#define PTP_OC_Skip 0x9820
|
||||
|
||||
/* PTP V1.0 Response Code */
|
||||
#define PTP_RC_Undefined 0x2000
|
||||
#define PTP_RC_OK 0x2001
|
||||
#define PTP_RC_GeneralError 0x2002
|
||||
#define PTP_RC_SessionNotOpen 0x2003
|
||||
#define PTP_RC_InvalidTransactionID 0x2004
|
||||
#define PTP_RC_OperationNotSupported 0x2005
|
||||
#define PTP_RC_ParameterNotSupported 0x2006
|
||||
#define PTP_RC_IncompleteTransfer 0x2007
|
||||
#define PTP_RC_InvalidStorageId 0x2008
|
||||
#define PTP_RC_InvalidObjectHandle 0x2009
|
||||
#define PTP_RC_DevicePropNotSupported 0x200A
|
||||
#define PTP_RC_InvalidObjectFormatCode 0x200B
|
||||
#define PTP_RC_StoreFull 0x200C
|
||||
#define PTP_RC_ObjectWriteProtected 0x200D
|
||||
#define PTP_RC_StoreReadOnly 0x200E
|
||||
#define PTP_RC_AccessDenied 0x200F
|
||||
#define PTP_RC_NoThumbnailPresent 0x2010
|
||||
#define PTP_RC_SelfTestFailed 0x2011
|
||||
#define PTP_RC_PartialDeletion 0x2012
|
||||
#define PTP_RC_StoreNotAvailable 0x2013
|
||||
#define PTP_RC_SpecificationByFormatUnsupported 0x2014
|
||||
#define PTP_RC_NoValidObjectInfo 0x2015
|
||||
#define PTP_RC_InvalidCodeFormat 0x2016
|
||||
#define PTP_RC_UnknownVendorCode 0x2017
|
||||
#define PTP_RC_CaptureAlreadyTerminated 0x2018
|
||||
#define PTP_RC_DeviceBusy 0x2019
|
||||
#define PTP_RC_InvalidParentObject 0x201A
|
||||
#define PTP_RC_InvalidDevicePropFormat 0x201B
|
||||
#define PTP_RC_InvalidDevicePropValue 0x201C
|
||||
#define PTP_RC_InvalidParameter 0x201D
|
||||
#define PTP_RC_SessionAlreadyOpened 0x201E
|
||||
#define PTP_RC_TransactionCanceled 0x201F
|
||||
#define PTP_RC_SpecificationOfDestinationUnsupported 0x2020
|
||||
|
||||
/* PTP V1.1 Response Code */
|
||||
#define PTP_RC_InvalidEnumHandle 0x2021
|
||||
#define PTP_RC_NoStreamEnabled 0x2022
|
||||
#define PTP_RC_InvalidDataSet 0x2023
|
||||
|
||||
/* USB Container Type */
|
||||
#define PTP_USB_CONTAINER_UNDEFINED 0x0000
|
||||
#define PTP_USB_CONTAINER_COMMAND 0x0001
|
||||
#define PTP_USB_CONTAINER_DATA 0x0002
|
||||
#define PTP_USB_CONTAINER_RESPONSE 0x0003
|
||||
#define PTP_USB_CONTAINER_EVENT 0x0004
|
||||
|
||||
/* PTP/IP Definition */
|
||||
#define PTPIP_INIT_COMMAND_REQUEST 1
|
||||
#define PTPIP_INIT_COMMAND_ACK 2
|
||||
#define PTPIP_INIT_EVENT_REQUEST 3
|
||||
#define PTPIP_INIT_EVENT_ACK 4
|
||||
#define PTPIP_INIT_FAIL 5
|
||||
#define PTPIP_CMD_REQUEST 6
|
||||
#define PTPIP_CMD_RESPONSE 7
|
||||
#define PTPIP_EVENT 8
|
||||
#define PTPIP_START_DATA_PACKET 9
|
||||
#define PTPIP_DATA_PACKET 10
|
||||
#define PTPIP_CANCEL_TRANSACTION 11
|
||||
#define PTPIP_END_DATA_PACKET 12
|
||||
#define PTPIP_PING 13
|
||||
#define PTPIP_PONG 14
|
||||
|
||||
/* Transaction Data Phase Description */
|
||||
#define PTP_DP_NODATA 0x0000
|
||||
#define PTP_DP_SENDDATA 0x0001
|
||||
#define PTP_DP_GETDATA 0x0002
|
||||
#define PTP_DP_DATA_MASK 0x00FF
|
||||
|
||||
/* PTP General */
|
||||
#define PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE 1024
|
||||
#define PTP_USB_BULK_HS_MAX_PACKET_LEN_READ 1024
|
||||
#define PTP_USB_BULK_HDR_LEN ( ( 2 * sizeof( uint32_t ) ) + ( 2 * sizeof( uint16_t ) ) )
|
||||
#define PTP_USB_BULK_PAYLOAD_LEN_WRITE ( PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE - PTP_USB_BULK_HDR_LEN )
|
||||
#define PTP_USB_BULK_PAYLOAD_LEN_READ ( PTP_USB_BULK_HS_MAX_PACKET_LEN_READ - PTP_USB_BULK_HDR_LEN )
|
||||
#define PTP_USB_BULK_REQ_LEN ( PTP_USB_BULK_HDR_LEN + ( 5 * sizeof( uint32_t ) ) )
|
||||
#define PTP_USB_BULK_REQ_RESP_MAX_LEN 63
|
||||
|
||||
/* DeviceInfo Data Offset */
|
||||
#define PTP_di_StandardVersion 0
|
||||
#define PTP_di_VendorExtensionID 2
|
||||
#define PTP_di_VendorExtensionVersion 6
|
||||
#define PTP_di_VendorExtensionDesc 8
|
||||
#define PTP_di_FunctionalMode 8
|
||||
#define PTP_di_OperationsSupported 10
|
||||
|
||||
/* Max Info Items Size */
|
||||
#define PTP_SUPPORTED_OPERATIONS_NBR 100
|
||||
#define PTP_SUPPORTED_EVENTS_NBR 100
|
||||
#define PTP_SUPPORTED_PROPRIETIES_NBR 100
|
||||
#define PTP_CAPTURE_FORMATS_NBR 100
|
||||
#define PTP_IMAGE_FORMATS_NBR 100
|
||||
#define PTP_MAX_STR_SIZE 514
|
||||
|
||||
/* Max Storage Units */
|
||||
#define PTP_MAX_STORAGE_UNITS_NBR 5
|
||||
|
||||
/* Storage Information */
|
||||
#define PTP_si_StorageType 0
|
||||
#define PTP_si_FilesystemType 2
|
||||
#define PTP_si_AccessCapability 4
|
||||
#define PTP_si_MaxCapability 6
|
||||
#define PTP_si_FreeSpaceInBytes 14
|
||||
#define PTP_si_FreeSpaceInImages 22
|
||||
#define PTP_si_StorageDescription 26
|
||||
|
||||
/* PTP Storage Type */
|
||||
#define PTP_ST_Undefined 0x0000
|
||||
#define PTP_ST_FixedROM 0x0001
|
||||
#define PTP_ST_RemovableROM 0x0002
|
||||
#define PTP_ST_FixedRAM 0x0003
|
||||
#define PTP_ST_RemovableRAM 0x0004
|
||||
|
||||
/* PTP File System Type */
|
||||
#define PTP_FST_Undefined 0x0000
|
||||
#define PTP_FST_GenericFlat 0x0001
|
||||
#define PTP_FST_GenericHierarchical 0x0002
|
||||
#define PTP_FST_DCF 0x0003
|
||||
|
||||
/* PTP Storage Information Access Capability */
|
||||
#define PTP_AC_ReadWrite 0x0000
|
||||
#define PTP_AC_ReadOnly 0x0001
|
||||
#define PTP_AC_ReadOnly_with_Object_Deletion 0x0002
|
||||
|
||||
/* Ancillary Format */
|
||||
#define PTP_OFC_Undefined 0x3000
|
||||
#define PTP_OFC_Defined 0x3800
|
||||
#define PTP_OFC_Association 0x3001
|
||||
#define PTP_OFC_Script 0x3002
|
||||
#define PTP_OFC_Executable 0x3003
|
||||
#define PTP_OFC_Text 0x3004
|
||||
#define PTP_OFC_HTML 0x3005
|
||||
#define PTP_OFC_DPOF 0x3006
|
||||
#define PTP_OFC_AIFF 0x3007
|
||||
#define PTP_OFC_WAV 0x3008
|
||||
#define PTP_OFC_MP3 0x3009
|
||||
#define PTP_OFC_AVI 0x300A
|
||||
#define PTP_OFC_MPEG 0x300B
|
||||
#define PTP_OFC_ASF 0x300C
|
||||
#define PTP_OFC_QT 0x300D
|
||||
|
||||
/* Image Format */
|
||||
#define PTP_OFC_EXIF_JPEG 0x3801
|
||||
#define PTP_OFC_TIFF_EP 0x3802
|
||||
#define PTP_OFC_FlashPix 0x3803
|
||||
#define PTP_OFC_BMP 0x3804
|
||||
#define PTP_OFC_CIFF 0x3805
|
||||
#define PTP_OFC_Undefined_0x3806 0x3806
|
||||
#define PTP_OFC_GIF 0x3807
|
||||
#define PTP_OFC_JFIF 0x3808
|
||||
#define PTP_OFC_PCD 0x3809
|
||||
#define PTP_OFC_PICT 0x380A
|
||||
#define PTP_OFC_PNG 0x380B
|
||||
#define PTP_OFC_Undefined_0x380C 0x380C
|
||||
#define PTP_OFC_TIFF 0x380D
|
||||
#define PTP_OFC_TIFF_IT 0x380E
|
||||
#define PTP_OFC_JP2 0x380F
|
||||
#define PTP_OFC_JPX 0x3810
|
||||
|
||||
/* PTP V1.1 DNG new */
|
||||
#define PTP_OFC_DNG 0x3811
|
||||
|
||||
/* MTP Extension */
|
||||
#define PTP_OFC_MTP_MediaCard 0xb211
|
||||
#define PTP_OFC_MTP_MediaCardGroup 0xb212
|
||||
#define PTP_OFC_MTP_Encounter 0xb213
|
||||
#define PTP_OFC_MTP_EncounterBox 0xb214
|
||||
#define PTP_OFC_MTP_M4A 0xb215
|
||||
#define PTP_OFC_MTP_ZUNEUNDEFINED 0xb217
|
||||
#define PTP_OFC_MTP_Firmware 0xb802
|
||||
#define PTP_OFC_MTP_WindowsImageFormat 0xb881
|
||||
#define PTP_OFC_MTP_UndefinedAudio 0xb900
|
||||
#define PTP_OFC_MTP_WMA 0xb901
|
||||
#define PTP_OFC_MTP_OGG 0xb902
|
||||
#define PTP_OFC_MTP_AAC 0xb903
|
||||
#define PTP_OFC_MTP_AudibleCod 0xb904
|
||||
#define PTP_OFC_MTP_FLAC 0xb906
|
||||
#define PTP_OFC_MTP_SamsungPlaylist 0xb909
|
||||
#define PTP_OFC_MTP_UndefinedVideo 0xb980
|
||||
#define PTP_OFC_MTP_WMV 0xb981
|
||||
#define PTP_OFC_MTP_MP4 0xb982
|
||||
#define PTP_OFC_MTP_MP2 0xb983
|
||||
#define PTP_OFC_MTP_3GP 0xb984
|
||||
#define PTP_OFC_MTP_UndefinedCollection 0xba00
|
||||
#define PTP_OFC_MTP_AbstractMultimediaAlbum 0xba01
|
||||
#define PTP_OFC_MTP_AbstractImageAlbum 0xba02
|
||||
#define PTP_OFC_MTP_AbstractAudioAlbum 0xba03
|
||||
#define PTP_OFC_MTP_AbstractVideoAlbum 0xba04
|
||||
#define PTP_OFC_MTP_AbstractAudioVideoPlaylist 0xba05
|
||||
#define PTP_OFC_MTP_AbstractContactGroup 0xba06
|
||||
#define PTP_OFC_MTP_AbstractMessageFolder 0xba07
|
||||
#define PTP_OFC_MTP_AbstractChapteredProduction 0xba08
|
||||
#define PTP_OFC_MTP_AbstractAudioPlaylist 0xba09
|
||||
#define PTP_OFC_MTP_AbstractVideoPlaylist 0xba0a
|
||||
#define PTP_OFC_MTP_AbstractMediacast 0xba0b
|
||||
#define PTP_OFC_MTP_WPLPlaylist 0xba10
|
||||
#define PTP_OFC_MTP_M3UPlaylist 0xba11
|
||||
#define PTP_OFC_MTP_MPLPlaylist 0xba12
|
||||
#define PTP_OFC_MTP_ASXPlaylist 0xba13
|
||||
#define PTP_OFC_MTP_PLSPlaylist 0xba14
|
||||
#define PTP_OFC_MTP_UndefinedDocument 0xba80
|
||||
#define PTP_OFC_MTP_AbstractDocument 0xba81
|
||||
#define PTP_OFC_MTP_XMLDocument 0xba82
|
||||
#define PTP_OFC_MTP_MSWordDocument 0xba83
|
||||
#define PTP_OFC_MTP_MHTCompiledHTMLDocument 0xba84
|
||||
#define PTP_OFC_MTP_MSExcelSpreadsheetXLS 0xba85
|
||||
#define PTP_OFC_MTP_MSPowerpointPresentationPPT 0xba86
|
||||
#define PTP_OFC_MTP_UndefinedMessage 0xbb00
|
||||
#define PTP_OFC_MTP_AbstractMessage 0xbb01
|
||||
#define PTP_OFC_MTP_UndefinedContact 0xbb80
|
||||
#define PTP_OFC_MTP_AbstractContact 0xbb81
|
||||
#define PTP_OFC_MTP_vCard2 0xbb82
|
||||
#define PTP_OFC_MTP_vCard3 0xbb83
|
||||
#define PTP_OFC_MTP_UndefinedCalendarItem 0xbe00
|
||||
#define PTP_OFC_MTP_AbstractCalendarItem 0xbe01
|
||||
#define PTP_OFC_MTP_vCalendar1 0xbe02
|
||||
#define PTP_OFC_MTP_vCalendar2 0xbe03
|
||||
#define PTP_OFC_MTP_UndefinedWindowsExecutable 0xbe80
|
||||
#define PTP_OFC_MTP_MediaCast 0xbe81
|
||||
#define PTP_OFC_MTP_Section 0xbe82
|
||||
|
||||
/* MTP Specific Object Property */
|
||||
#define PTP_OPC_StorageID 0xDC01
|
||||
#define PTP_OPC_ObjectFormat 0xDC02
|
||||
#define PTP_OPC_ProtectionStatus 0xDC03
|
||||
#define PTP_OPC_ObjectSize 0xDC04
|
||||
#define PTP_OPC_AssociationType 0xDC05
|
||||
#define PTP_OPC_AssociationDesc 0xDC06
|
||||
#define PTP_OPC_ObjectFileName 0xDC07
|
||||
#define PTP_OPC_DateCreated 0xDC08
|
||||
#define PTP_OPC_DateModified 0xDC09
|
||||
#define PTP_OPC_Keywords 0xDC0A
|
||||
#define PTP_OPC_ParentObject 0xDC0B
|
||||
#define PTP_OPC_AllowedFolderContents 0xDC0C
|
||||
#define PTP_OPC_Hidden 0xDC0D
|
||||
#define PTP_OPC_SystemObject 0xDC0E
|
||||
#define PTP_OPC_PersistantUniqueObjectIdentifier 0xDC41
|
||||
#define PTP_OPC_SyncID 0xDC42
|
||||
#define PTP_OPC_PropertyBag 0xDC43
|
||||
#define PTP_OPC_Name 0xDC44
|
||||
#define PTP_OPC_CreatedBy 0xDC45
|
||||
#define PTP_OPC_Artist 0xDC46
|
||||
#define PTP_OPC_DateAuthored 0xDC47
|
||||
#define PTP_OPC_Description 0xDC48
|
||||
#define PTP_OPC_URLReference 0xDC49
|
||||
#define PTP_OPC_LanguageLocale 0xDC4A
|
||||
#define PTP_OPC_CopyrightInformation 0xDC4B
|
||||
#define PTP_OPC_Source 0xDC4C
|
||||
#define PTP_OPC_OriginLocation 0xDC4D
|
||||
#define PTP_OPC_DateAdded 0xDC4E
|
||||
#define PTP_OPC_NonConsumable 0xDC4F
|
||||
#define PTP_OPC_CorruptOrUnplayable 0xDC50
|
||||
#define PTP_OPC_ProducerSerialNumber 0xDC51
|
||||
#define PTP_OPC_RepresentativeSampleFormat 0xDC81
|
||||
#define PTP_OPC_RepresentativeSampleSize 0xDC82
|
||||
#define PTP_OPC_RepresentativeSampleHeight 0xDC83
|
||||
#define PTP_OPC_RepresentativeSampleWidth 0xDC84
|
||||
#define PTP_OPC_RepresentativeSampleDuration 0xDC85
|
||||
#define PTP_OPC_RepresentativeSampleData 0xDC86
|
||||
#define PTP_OPC_Width 0xDC87
|
||||
#define PTP_OPC_Height 0xDC88
|
||||
#define PTP_OPC_Duration 0xDC89
|
||||
#define PTP_OPC_Rating 0xDC8A
|
||||
#define PTP_OPC_Track 0xDC8B
|
||||
#define PTP_OPC_Genre 0xDC8C
|
||||
#define PTP_OPC_Credits 0xDC8D
|
||||
#define PTP_OPC_Lyrics 0xDC8E
|
||||
#define PTP_OPC_SubscriptionContentID 0xDC8F
|
||||
#define PTP_OPC_ProducedBy 0xDC90
|
||||
#define PTP_OPC_UseCount 0xDC91
|
||||
#define PTP_OPC_SkipCount 0xDC92
|
||||
#define PTP_OPC_LastAccessed 0xDC93
|
||||
#define PTP_OPC_ParentalRating 0xDC94
|
||||
#define PTP_OPC_MetaGenre 0xDC95
|
||||
#define PTP_OPC_Composer 0xDC96
|
||||
#define PTP_OPC_EffectiveRating 0xDC97
|
||||
#define PTP_OPC_Subtitle 0xDC98
|
||||
#define PTP_OPC_OriginalReleaseDate 0xDC99
|
||||
#define PTP_OPC_AlbumName 0xDC9A
|
||||
#define PTP_OPC_AlbumArtist 0xDC9B
|
||||
#define PTP_OPC_Mood 0xDC9C
|
||||
#define PTP_OPC_DRMStatus 0xDC9D
|
||||
#define PTP_OPC_SubDescription 0xDC9E
|
||||
#define PTP_OPC_IsCropped 0xDCD1
|
||||
#define PTP_OPC_IsColorCorrected 0xDCD2
|
||||
#define PTP_OPC_ImageBitDepth 0xDCD3
|
||||
#define PTP_OPC_Fnumber 0xDCD4
|
||||
#define PTP_OPC_ExposureTime 0xDCD5
|
||||
#define PTP_OPC_ExposureIndex 0xDCD6
|
||||
#define PTP_OPC_DisplayName 0xDCE0
|
||||
#define PTP_OPC_BodyText 0xDCE1
|
||||
#define PTP_OPC_Subject 0xDCE2
|
||||
#define PTP_OPC_Priority 0xDCE3
|
||||
#define PTP_OPC_GivenName 0xDD00
|
||||
#define PTP_OPC_MiddleNames 0xDD01
|
||||
#define PTP_OPC_FamilyName 0xDD02
|
||||
#define PTP_OPC_Prefix 0xDD03
|
||||
#define PTP_OPC_Suffix 0xDD04
|
||||
#define PTP_OPC_PhoneticGivenName 0xDD05
|
||||
#define PTP_OPC_PhoneticFamilyName 0xDD06
|
||||
#define PTP_OPC_EmailPrimary 0xDD07
|
||||
#define PTP_OPC_EmailPersonal1 0xDD08
|
||||
#define PTP_OPC_EmailPersonal2 0xDD09
|
||||
#define PTP_OPC_EmailBusiness1 0xDD0A
|
||||
#define PTP_OPC_EmailBusiness2 0xDD0B
|
||||
#define PTP_OPC_EmailOthers 0xDD0C
|
||||
#define PTP_OPC_PhoneNumberPrimary 0xDD0D
|
||||
#define PTP_OPC_PhoneNumberPersonal 0xDD0E
|
||||
#define PTP_OPC_PhoneNumberPersonal2 0xDD0F
|
||||
#define PTP_OPC_PhoneNumberBusiness 0xDD10
|
||||
#define PTP_OPC_PhoneNumberBusiness2 0xDD11
|
||||
#define PTP_OPC_PhoneNumberMobile 0xDD12
|
||||
#define PTP_OPC_PhoneNumberMobile2 0xDD13
|
||||
#define PTP_OPC_FaxNumberPrimary 0xDD14
|
||||
#define PTP_OPC_FaxNumberPersonal 0xDD15
|
||||
#define PTP_OPC_FaxNumberBusiness 0xDD16
|
||||
#define PTP_OPC_PagerNumber 0xDD17
|
||||
#define PTP_OPC_PhoneNumberOthers 0xDD18
|
||||
#define PTP_OPC_PrimaryWebAddress 0xDD19
|
||||
#define PTP_OPC_PersonalWebAddress 0xDD1A
|
||||
#define PTP_OPC_BusinessWebAddress 0xDD1B
|
||||
#define PTP_OPC_InstantMessengerAddress 0xDD1C
|
||||
#define PTP_OPC_InstantMessengerAddress2 0xDD1D
|
||||
#define PTP_OPC_InstantMessengerAddress3 0xDD1E
|
||||
#define PTP_OPC_PostalAddressPersonalFull 0xDD1F
|
||||
#define PTP_OPC_PostalAddressPersonalFullLine1 0xDD20
|
||||
#define PTP_OPC_PostalAddressPersonalFullLine2 0xDD21
|
||||
#define PTP_OPC_PostalAddressPersonalFullCity 0xDD22
|
||||
#define PTP_OPC_PostalAddressPersonalFullRegion 0xDD23
|
||||
#define PTP_OPC_PostalAddressPersonalFullPostalCode 0xDD24
|
||||
#define PTP_OPC_PostalAddressPersonalFullCountry 0xDD25
|
||||
#define PTP_OPC_PostalAddressBusinessFull 0xDD26
|
||||
#define PTP_OPC_PostalAddressBusinessLine1 0xDD27
|
||||
#define PTP_OPC_PostalAddressBusinessLine2 0xDD28
|
||||
#define PTP_OPC_PostalAddressBusinessCity 0xDD29
|
||||
#define PTP_OPC_PostalAddressBusinessRegion 0xDD2A
|
||||
#define PTP_OPC_PostalAddressBusinessPostalCode 0xDD2B
|
||||
#define PTP_OPC_PostalAddressBusinessCountry 0xDD2C
|
||||
#define PTP_OPC_PostalAddressOtherFull 0xDD2D
|
||||
#define PTP_OPC_PostalAddressOtherLine1 0xDD2E
|
||||
#define PTP_OPC_PostalAddressOtherLine2 0xDD2F
|
||||
#define PTP_OPC_PostalAddressOtherCity 0xDD30
|
||||
#define PTP_OPC_PostalAddressOtherRegion 0xDD31
|
||||
#define PTP_OPC_PostalAddressOtherPostalCode 0xDD32
|
||||
#define PTP_OPC_PostalAddressOtherCountry 0xDD33
|
||||
#define PTP_OPC_OrganizationName 0xDD34
|
||||
#define PTP_OPC_PhoneticOrganizationName 0xDD35
|
||||
#define PTP_OPC_Role 0xDD36
|
||||
#define PTP_OPC_Birthdate 0xDD37
|
||||
#define PTP_OPC_MessageTo 0xDD40
|
||||
#define PTP_OPC_MessageCC 0xDD41
|
||||
#define PTP_OPC_MessageBCC 0xDD42
|
||||
#define PTP_OPC_MessageRead 0xDD43
|
||||
#define PTP_OPC_MessageReceivedTime 0xDD44
|
||||
#define PTP_OPC_MessageSender 0xDD45
|
||||
#define PTP_OPC_ActivityBeginTime 0xDD50
|
||||
#define PTP_OPC_ActivityEndTime 0xDD51
|
||||
#define PTP_OPC_ActivityLocation 0xDD52
|
||||
#define PTP_OPC_ActivityRequiredAttendees 0xDD54
|
||||
#define PTP_OPC_ActivityOptionalAttendees 0xDD55
|
||||
#define PTP_OPC_ActivityResources 0xDD56
|
||||
#define PTP_OPC_ActivityAccepted 0xDD57
|
||||
#define PTP_OPC_Owner 0xDD5D
|
||||
#define PTP_OPC_Editor 0xDD5E
|
||||
#define PTP_OPC_Webmaster 0xDD5F
|
||||
#define PTP_OPC_URLSource 0xDD60
|
||||
#define PTP_OPC_URLDestination 0xDD61
|
||||
#define PTP_OPC_TimeBookmark 0xDD62
|
||||
#define PTP_OPC_ObjectBookmark 0xDD63
|
||||
#define PTP_OPC_ByteBookmark 0xDD64
|
||||
#define PTP_OPC_LastBuildDate 0xDD70
|
||||
#define PTP_OPC_TimetoLive 0xDD71
|
||||
#define PTP_OPC_MediaGUID 0xDD72
|
||||
#define PTP_OPC_TotalBitRate 0xDE91
|
||||
#define PTP_OPC_BitRateType 0xDE92
|
||||
#define PTP_OPC_SampleRate 0xDE93
|
||||
#define PTP_OPC_NumberOfChannels 0xDE94
|
||||
#define PTP_OPC_AudioBitDepth 0xDE95
|
||||
#define PTP_OPC_ScanDepth 0xDE97
|
||||
#define PTP_OPC_AudioWAVECodec 0xDE99
|
||||
#define PTP_OPC_AudioBitRate 0xDE9A
|
||||
#define PTP_OPC_VideoFourCCCodec 0xDE9B
|
||||
#define PTP_OPC_VideoBitRate 0xDE9C
|
||||
#define PTP_OPC_FramesPerThousandSeconds 0xDE9D
|
||||
#define PTP_OPC_KeyFrameDistance 0xDE9E
|
||||
#define PTP_OPC_BufferSize 0xDE9F
|
||||
#define PTP_OPC_EncodingQuality 0xDEA0
|
||||
#define PTP_OPC_EncodingProfile 0xDEA1
|
||||
#define PTP_OPC_BuyFlag 0xD901
|
||||
|
||||
/* WiFi Provisioning MTP Extension Property Code */
|
||||
#define PTP_OPC_WirelessConfigurationFile 0xB104
|
||||
|
||||
/* PTP Association Type */
|
||||
#define PTP_AT_Undefined 0x0000
|
||||
#define PTP_AT_GenericFolder 0x0001
|
||||
#define PTP_AT_Album 0x0002
|
||||
#define PTP_AT_TimeSequence 0x0003
|
||||
#define PTP_AT_HorizontalPanoramic 0x0004
|
||||
#define PTP_AT_VerticalPanoramic 0x0005
|
||||
#define PTP_AT_2DPanoramic 0x0006
|
||||
#define PTP_AT_AncillaryData 0x0007
|
||||
|
||||
/* PTP Max Handle */
|
||||
#define PTP_MAX_HANDLER_NBR 0x0255
|
||||
|
||||
/* PTP Get Object Information */
|
||||
#define PTP_oi_StorageID 0
|
||||
#define PTP_oi_ObjectFormat 4
|
||||
#define PTP_oi_ProtectionStatus 6
|
||||
#define PTP_oi_ObjectCompressedSize 8
|
||||
#define PTP_oi_ThumbFormat 12
|
||||
#define PTP_oi_ThumbCompressedSize 14
|
||||
#define PTP_oi_ThumbPixWidth 18
|
||||
#define PTP_oi_ThumbPixHeight 22
|
||||
#define PTP_oi_ImagePixWidth 26
|
||||
#define PTP_oi_ImagePixHeight 30
|
||||
#define PTP_oi_ImageBitDepth 34
|
||||
#define PTP_oi_ParentObject 38
|
||||
#define PTP_oi_AssociationType 42
|
||||
#define PTP_oi_AssociationDesc 44
|
||||
#define PTP_oi_SequenceNumber 48
|
||||
#define PTP_oi_filenamelen 52
|
||||
#define PTP_oi_Filename 53
|
||||
|
||||
/* (MTP) Object Property Pack/Unpack */
|
||||
#define PTP_opd_ObjectPropertyCode 0
|
||||
#define PTP_opd_DataType 2
|
||||
#define PTP_opd_GetSet 4
|
||||
#define PTP_opd_FactoryDefaultValue 5
|
||||
|
||||
/* Device Property Form Flag */
|
||||
#define PTP_DPFF_None 0x00
|
||||
#define PTP_DPFF_Range 0x01
|
||||
#define PTP_DPFF_Enumeration 0x02
|
||||
|
||||
/* Object Property Code Used by MTP (First 3 are same as DPFF codes) */
|
||||
#define PTP_OPFF_None 0x00
|
||||
#define PTP_OPFF_Range 0x01
|
||||
#define PTP_OPFF_Enumeration 0x02
|
||||
#define PTP_OPFF_DateTime 0x03
|
||||
#define PTP_OPFF_FixedLengthArray 0x04
|
||||
#define PTP_OPFF_RegularExpression 0x05
|
||||
#define PTP_OPFF_ByteArray 0x06
|
||||
#define PTP_OPFF_LongString 0xFF
|
||||
|
||||
/* Device Property Pack/Unpack */
|
||||
#define PTP_dpd_DevicePropertyCode 0
|
||||
#define PTP_dpd_DataType 2
|
||||
#define PTP_dpd_GetSet 4
|
||||
#define PTP_dpd_FactoryDefaultValue 5
|
||||
|
||||
/* DataType Code */
|
||||
#define PTP_DTC_UNDEF 0x0000
|
||||
#define PTP_DTC_INT8 0x0001
|
||||
#define PTP_DTC_UINT8 0x0002
|
||||
#define PTP_DTC_INT16 0x0003
|
||||
#define PTP_DTC_UINT16 0x0004
|
||||
#define PTP_DTC_INT32 0x0005
|
||||
#define PTP_DTC_UINT32 0x0006
|
||||
#define PTP_DTC_INT64 0x0007
|
||||
#define PTP_DTC_UINT64 0x0008
|
||||
#define PTP_DTC_INT128 0x0009
|
||||
#define PTP_DTC_UINT128 0x000A
|
||||
#define PTP_DTC_ARRAY_MASK 0x4000
|
||||
#define PTP_DTC_AINT8 ( PTP_DTC_ARRAY_MASK | PTP_DTC_INT8 )
|
||||
#define PTP_DTC_AUINT8 ( PTP_DTC_ARRAY_MASK | PTP_DTC_UINT8 )
|
||||
#define PTP_DTC_AINT16 ( PTP_DTC_ARRAY_MASK | PTP_DTC_INT16 )
|
||||
#define PTP_DTC_AUINT16 ( PTP_DTC_ARRAY_MASK | PTP_DTC_UINT16 )
|
||||
#define PTP_DTC_AINT32 ( PTP_DTC_ARRAY_MASK | PTP_DTC_INT32 )
|
||||
#define PTP_DTC_AUINT32 ( PTP_DTC_ARRAY_MASK | PTP_DTC_UINT32 )
|
||||
#define PTP_DTC_AINT64 ( PTP_DTC_ARRAY_MASK | PTP_DTC_INT64 )
|
||||
#define PTP_DTC_AUINT64 ( PTP_DTC_ARRAY_MASK | PTP_DTC_UINT64 )
|
||||
#define PTP_DTC_AINT128 ( PTP_DTC_ARRAY_MASK | PTP_DTC_INT128 )
|
||||
#define PTP_DTC_AUINT128 ( PTP_DTC_ARRAY_MASK | PTP_DTC_UINT128 )
|
||||
#define PTP_DTC_STR 0xFFFF
|
||||
|
||||
/* PTP Event Code */
|
||||
#define PTP_EC_Undefined 0x4000
|
||||
#define PTP_EC_CancelTransaction 0x4001
|
||||
#define PTP_EC_ObjectAdded 0x4002
|
||||
#define PTP_EC_ObjectRemoved 0x4003
|
||||
#define PTP_EC_StoreAdded 0x4004
|
||||
#define PTP_EC_StoreRemoved 0x4005
|
||||
#define PTP_EC_DevicePropChanged 0x4006
|
||||
#define PTP_EC_ObjectInfoChanged 0x4007
|
||||
#define PTP_EC_DeviceInfoChanged 0x4008
|
||||
#define PTP_EC_RequestObjectTransfer 0x4009
|
||||
#define PTP_EC_StoreFull 0x400A
|
||||
#define PTP_EC_DeviceReset 0x400B
|
||||
#define PTP_EC_StorageInfoChanged 0x400C
|
||||
#define PTP_EC_CaptureComplete 0x400D
|
||||
#define PTP_EC_UnreportedStatus 0x400E
|
||||
|
||||
#define LE16( addr ) ( ( (uint16_t)( addr )[ 0 ] ) | \
|
||||
( (uint16_t)( ( (uint32_t)( addr )[ 1 ] ) << 8 ) ) )
|
||||
|
||||
#define LE24( addr ) ( ( (uint32_t)( addr )[ 0 ] ) | \
|
||||
( ( (uint32_t)( addr )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint32_t)( addr )[ 2 ] ) << 16 ) )
|
||||
|
||||
#define LE32( addr ) ( ( (uint32_t)( addr )[ 0 ] ) | \
|
||||
( ( (uint32_t)( addr )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint32_t)( addr )[ 2 ] ) << 16 ) | \
|
||||
( ( (uint32_t)( addr )[ 3 ] ) << 24 ) )
|
||||
|
||||
#define LE64( addr ) ( ( (uint64_t)( addr )[ 0 ] ) | \
|
||||
( ( (uint64_t)( addr )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint64_t)( addr )[ 2 ] ) << 16 ) | \
|
||||
( ( (uint64_t)( addr )[ 3 ] ) << 24 ) | \
|
||||
( ( (uint64_t)( addr )[ 4 ] ) << 32 ) | \
|
||||
( ( (uint64_t)( addr )[ 5 ] ) << 40 ) | \
|
||||
( ( (uint64_t)( addr )[ 6 ] ) << 48 ) | \
|
||||
( ( (uint64_t)( addr )[ 7 ] ) << 56 ) )
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Struct Definition */
|
||||
|
||||
/* PTP General Container */
|
||||
typedef struct _PTP_ContainerTypeDef
|
||||
{
|
||||
uint16_t Code;
|
||||
uint32_t SessionID;
|
||||
uint32_t Transaction_ID;
|
||||
uint32_t Param1;
|
||||
uint32_t Param2;
|
||||
uint32_t Param3;
|
||||
uint32_t Param4;
|
||||
uint32_t Param5;
|
||||
uint8_t Nparam;
|
||||
} PTP_ContainerTypeDef, *PPTP_ContainerTypeDef;
|
||||
|
||||
/* PTP Response Container */
|
||||
typedef struct _PTP_RespContainerTypeDef
|
||||
{
|
||||
uint32_t length;
|
||||
uint16_t type;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
uint32_t param4;
|
||||
uint32_t param5;
|
||||
} PTP_RespContainerTypeDef, *PPTP_RespContainerTypeDef;
|
||||
|
||||
/* PTP Operation Container */
|
||||
typedef struct _PTP_OpContainerTypeDef
|
||||
{
|
||||
uint32_t length;
|
||||
uint16_t type;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
uint32_t param4;
|
||||
uint32_t param5;
|
||||
} PTP_OpContainerTypeDef, *PPTP_OpContainerTypeDef;
|
||||
|
||||
/* PTP Data Container */
|
||||
typedef struct _PTP_DataContainerTypeDef
|
||||
{
|
||||
uint32_t length;
|
||||
uint16_t type;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
uint32_t param4;
|
||||
uint32_t param5;
|
||||
} params;
|
||||
|
||||
uint8_t data[ PTP_USB_BULK_PAYLOAD_LEN_READ ];
|
||||
} payload;
|
||||
} PTP_DataContainerTypeDef, *PPTP_DataContainerTypeDef;
|
||||
|
||||
/* PTP USB Asynchronous Event Interrupt Data Format */
|
||||
typedef struct _PTP_EventContainerTypeDef
|
||||
{
|
||||
uint32_t length;
|
||||
uint16_t type;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
} PTP_EventContainerTypeDef, *PPTP_EventContainerTypeDef;
|
||||
|
||||
/* PTP Transfer Control */
|
||||
typedef struct _PTP_HandleTypeDef
|
||||
{
|
||||
uint8_t *data_ptr;
|
||||
uint32_t data_length;
|
||||
uint32_t data_packet;
|
||||
uint32_t iteration;
|
||||
uint32_t data_packet_counter;
|
||||
uint8_t *object_ptr;
|
||||
} PTP_HandleTypeDef, *PPTP_HandleTypeDef;
|
||||
|
||||
/* PTP Device Information */
|
||||
typedef struct _PTP_DeviceInfoTypeDef
|
||||
{
|
||||
uint16_t StandardVersion;
|
||||
uint32_t VendorExtensionID;
|
||||
uint16_t VendorExtensionVersion;
|
||||
uint8_t VendorExtensionDesc[ PTP_MAX_STR_SIZE ];
|
||||
uint16_t FunctionalMode;
|
||||
uint32_t OperationsSupported_len;
|
||||
uint16_t OperationsSupported[ PTP_SUPPORTED_OPERATIONS_NBR ];
|
||||
uint32_t EventsSupported_len;
|
||||
uint16_t EventsSupported[ PTP_SUPPORTED_EVENTS_NBR ];
|
||||
uint32_t DevicePropertiesSupported_len;
|
||||
uint16_t DevicePropertiesSupported[ PTP_SUPPORTED_PROPRIETIES_NBR ];
|
||||
uint32_t CaptureFormats_len;
|
||||
uint16_t CaptureFormats[ PTP_CAPTURE_FORMATS_NBR ];
|
||||
uint32_t ImageFormats_len;
|
||||
uint16_t ImageFormats[ PTP_IMAGE_FORMATS_NBR ];
|
||||
uint8_t Manufacturer[ PTP_MAX_STR_SIZE ];
|
||||
uint8_t Model[ PTP_MAX_STR_SIZE ];
|
||||
uint8_t DeviceVersion[ PTP_MAX_STR_SIZE ];
|
||||
uint8_t SerialNumber[ PTP_MAX_STR_SIZE ];
|
||||
} PTP_DeviceInfoTypeDef, *PPTP_DeviceInfoTypeDef;
|
||||
|
||||
/* PTP StorageIDs */
|
||||
typedef struct _PTP_StorageIDsTypeDef
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t Storage[ PTP_MAX_STORAGE_UNITS_NBR ];
|
||||
} PTP_StorageIDsTypeDef, *PPTP_StorageIDsTypeDef;
|
||||
|
||||
/* PTP Storage Information */
|
||||
typedef struct __attribute__((packed)) _PTP_StorageInfoTypeDef
|
||||
{
|
||||
uint16_t StorageType;
|
||||
uint16_t FilesystemType;
|
||||
uint16_t AccessCapability;
|
||||
uint64_t MaxCapability;
|
||||
uint64_t FreeSpaceInBytes;
|
||||
uint32_t FreeSpaceInImages;
|
||||
uint8_t StorageDescription[ PTP_MAX_STR_SIZE ];
|
||||
uint8_t VolumeLabel[ PTP_MAX_STR_SIZE ];
|
||||
} PTP_StorageInfoTypeDef, *PPTP_StorageInfoTypeDef;
|
||||
|
||||
/* PTP Object Handle Type */
|
||||
typedef struct _PTP_ObjectHandlesTypeDef
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t Handler[PTP_MAX_HANDLER_NBR];
|
||||
} PTP_ObjectHandlesTypeDef, *PPTP_ObjectHandlesTypeDef;
|
||||
|
||||
/* PTP Object Information */
|
||||
typedef struct __attribute__((packed)) _PTP_ObjectInfoTypeDef
|
||||
{
|
||||
uint16_t ObjectFormat;
|
||||
uint16_t FileName_len;
|
||||
uint8_t Filename[ PTP_MAX_STR_SIZE ];
|
||||
uint16_t Data_Creat_len;
|
||||
uint8_t Data_Creat_Time[ 32 ];
|
||||
uint16_t Data_Modified_len;
|
||||
uint8_t Data_Modified_Time[ 32 ];
|
||||
uint64_t File_Size;
|
||||
} PTP_ObjectInfoTypeDef, *PPTP_ObjectInfoTypeDef;
|
||||
|
||||
/* Object Property */
|
||||
typedef union _PTP_PropertyValueTypeDef
|
||||
{
|
||||
char str[ PTP_MAX_STR_SIZE ];
|
||||
uint8_t u8;
|
||||
int8_t i8;
|
||||
uint16_t u16;
|
||||
int16_t i16;
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
uint64_t u64;
|
||||
int64_t i64;
|
||||
} PTP_PropertyValueTypeDef, *PPTP_PropertyValueTypeDef;
|
||||
|
||||
/* Property Describing Range Form */
|
||||
typedef struct _PTP_PropDescRangeFormTypeDef
|
||||
{
|
||||
PTP_PropertyValueTypeDef MinimumValue;
|
||||
PTP_PropertyValueTypeDef MaximumValue;
|
||||
PTP_PropertyValueTypeDef StepSize;
|
||||
} PTP_PropDescRangeFormTypeDef, *PPTP_PropDescRangeFormTypeDef;
|
||||
|
||||
/* Property Describing Dataset, Enum Form */
|
||||
typedef struct _PTP_PropDescEnumFormTypeDef
|
||||
{
|
||||
uint16_t NumberOfValues;
|
||||
PTP_PropertyValueTypeDef SupportedValue[ PTP_SUPPORTED_PROPRIETIES_NBR ];
|
||||
} PTP_PropDescEnumFormTypeDef, *PPTP_PropDescEnumFormTypeDef;
|
||||
|
||||
/* Object Property Describing */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ObjectPropertyCode;
|
||||
uint16_t DataType;
|
||||
uint8_t GetSet;
|
||||
PTP_PropertyValueTypeDef FactoryDefaultValue;
|
||||
uint32_t GroupCode;
|
||||
uint8_t FormFlag;
|
||||
union
|
||||
{
|
||||
PTP_PropDescEnumFormTypeDef Enum;
|
||||
PTP_PropDescRangeFormTypeDef Range;
|
||||
}FORM;
|
||||
} PTP_ObjectPropDescTypeDef;
|
||||
|
||||
/* Metadata Lists for MTP Operation */
|
||||
typedef struct _MTP_PropertiesTypeDef
|
||||
{
|
||||
uint16_t property;
|
||||
uint16_t datatype;
|
||||
uint32_t ObjectHandle;
|
||||
PTP_PropertyValueTypeDef propval;
|
||||
} MTP_PropertiesTypeDef, *PMTP_PropertiesTypeDef;
|
||||
|
||||
/* Device Property Describing Dataset (DevicePropDesc) */
|
||||
typedef struct _PTP_DevicePropDescTypdef
|
||||
{
|
||||
uint16_t DevicePropertyCode;
|
||||
uint16_t DataType;
|
||||
uint8_t GetSet;
|
||||
PTP_PropertyValueTypeDef FactoryDefaultValue;
|
||||
PTP_PropertyValueTypeDef CurrentValue;
|
||||
uint8_t FormFlag;
|
||||
union
|
||||
{
|
||||
PTP_PropDescEnumFormTypeDef Enum;
|
||||
PTP_PropDescRangeFormTypeDef Range;
|
||||
} FORM;
|
||||
} PTP_DevicePropDescTypdef, *PPTP_DevicePropDescTypdef;
|
||||
|
||||
/* Following Status */
|
||||
typedef enum
|
||||
{
|
||||
PTP_OK = 0,
|
||||
PTP_BUSY,
|
||||
PTP_FAIL,
|
||||
PTP_NOT_SUPPORTED,
|
||||
PTP_UNRECOVERED_ERROR,
|
||||
PTP_ERROR_SPEED_UNKNOWN,
|
||||
} USBH_StatusTypeDef;
|
||||
|
||||
/* MTP Parameters */
|
||||
typedef union _MTP_ParaTypeDef
|
||||
{
|
||||
struct handle
|
||||
{
|
||||
uint32_t Handle_num;
|
||||
uint32_t Handle_cur_num;
|
||||
uint32_t Handle_locate_num;
|
||||
uint32_t Handle_total_num;
|
||||
uint32_t flag;
|
||||
} mtp_handle;
|
||||
struct Data
|
||||
{
|
||||
uint32_t Handle_num;
|
||||
uint32_t Handle_locate;
|
||||
uint32_t Handle_maxlen;
|
||||
union Data1
|
||||
{
|
||||
struct Data2
|
||||
{
|
||||
uint32_t total_len;
|
||||
uint16_t type;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint8_t *check_data;
|
||||
} value_data;
|
||||
uint8_t *pdata;
|
||||
} data_str;
|
||||
} get_data;
|
||||
} MTP_ParaTypeDef, *PMTP_ParaTypeDef;
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Declaration */
|
||||
extern uint8_t DevDesc_Buf[ ];
|
||||
extern __attribute__ ((aligned(4))) uint8_t Com_Buf[ ];
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Function Declaration */
|
||||
extern void USBH_AnalyseType( uint8_t *pdev_buf, uint8_t *pcfg_buf, uint8_t *ptype );
|
||||
extern uint8_t USBH_EnumRootDevice( void );
|
||||
extern void IMAGE_AnalyzeCfgDesc( uint8_t index );
|
||||
extern uint8_t USBH_EnumImageDevice( uint8_t index );
|
||||
extern uint8_t MTP_SendData( uint8_t *pbuf, uint32_t len );
|
||||
extern uint8_t MTP_RecvData( uint8_t *pbuf, uint32_t *plen );
|
||||
extern void MTP_PTP_ParaInit( void );
|
||||
extern uint8_t USBH_PTP_SendRequest( void );
|
||||
extern uint8_t USBH_PTP_GetResponse( void );
|
||||
extern uint8_t USBH_PTP_OpenSession( uint32_t session );
|
||||
extern uint8_t USBH_PTP_GetDeviceInfo( void );
|
||||
extern uint8_t USBH_PTP_GetStorageIds( void );
|
||||
extern void PTP_GetString( uint8_t *str, uint8_t *data, uint32_t *len );
|
||||
extern uint8_t USBH_PTP_GetStorageInfo( uint32_t storage_id );
|
||||
extern uint8_t USBH_PTP_GetNumObjects( uint32_t storage_id, uint32_t objectformatcode, uint32_t objecthandle, uint32_t *numobs );
|
||||
extern void ObjectHandles_Process( uint8_t *pdata, uint32_t len );
|
||||
extern uint8_t USBH_MTP_GetObjectHandles( uint32_t storage_id, uint32_t objectformatcode, uint32_t objecthandle );
|
||||
extern uint8_t USBH_MTP_GetObjectInfo( uint32_t objecthandle );
|
||||
extern void PTP_GetDevicePropValue( uint8_t *data, uint32_t *offset, uint16_t datatype );
|
||||
extern uint32_t PTP_GetObjectPropList( uint8_t *data, uint32_t len, uint16_t propval );
|
||||
extern uint8_t USBH_MTP_GetObjectSize( uint32_t objecthandle );
|
||||
extern uint8_t USBH_PTP_GetPartialObject( void );
|
||||
extern void MTP_Init_Process( void );
|
||||
extern void USBH_MainDeal( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,675 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32f20x_usbfs_host.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/09/01
|
||||
* Description : USB full-speed port host operation 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.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "usb_host_config.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Definition */
|
||||
__attribute__((aligned(4))) uint8_t USBFS_RX_Buf[ USBFS_MAX_PACKET_SIZE ]; // IN, must even address
|
||||
__attribute__((aligned(4))) uint8_t USBFS_TX_Buf[ USBFS_MAX_PACKET_SIZE ]; // OUT, must even address
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFS_RCC_Init
|
||||
*
|
||||
* @brief Set USB port clock.
|
||||
* Note: If the SystemCoreClock is selected as the USB clock source,
|
||||
* only the frequency specified below can be used.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_RCC_Init( void )
|
||||
{
|
||||
if( SystemCoreClock == 144000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div3 );
|
||||
}
|
||||
else if( SystemCoreClock == 96000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div2 );
|
||||
}
|
||||
else if( SystemCoreClock == 48000000 )
|
||||
{
|
||||
RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div1 );
|
||||
}
|
||||
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_OTG_FS, ENABLE );
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn USBFS_Host_Init
|
||||
*
|
||||
* @brief Initialize USB port host configuration.
|
||||
*
|
||||
* @param sta - ENABLE or DISABLE
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFS_Host_Init( FunctionalState sta )
|
||||
{
|
||||
if( sta == ENABLE )
|
||||
{
|
||||
/* Reset USB module */
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
|
||||
Delay_Us( 10 );
|
||||
USBOTG_H_FS->BASE_CTRL = 0;
|
||||
|
||||
/* Initialize USB host configuration */
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_HOST_MODE | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
|
||||
USBOTG_H_FS->HOST_EP_MOD = USBFS_UH_EP_TX_EN | USBFS_UH_EP_RX_EN;
|
||||
USBOTG_H_FS->HOST_RX_DMA = (uint32_t)USBFS_RX_Buf;
|
||||
USBOTG_H_FS->HOST_TX_DMA = (uint32_t)USBFS_TX_Buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
|
||||
Delay_Us( 10 );
|
||||
USBOTG_H_FS->BASE_CTRL = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortStatus
|
||||
*
|
||||
* @brief Check the current status of the USB port in combination with
|
||||
* the saved status of the root device connected to this port.
|
||||
*
|
||||
* @para dev_sta: The saved status of the root device.
|
||||
*
|
||||
* @return The current status of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortStatus( uint8_t dev_sta )
|
||||
{
|
||||
if( USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT )// Check that there is a device connection or disconnection event on the port
|
||||
{
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT; // Clear flag
|
||||
if( USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH ) // Check that there is a device connection to the port
|
||||
{
|
||||
if( ( dev_sta == ROOT_DEV_DISCONNECT ) || ( ( dev_sta != ROOT_DEV_FAILED ) && ( USBFSH_CheckRootHubPortEnable( ) == 0x00 ) ) )
|
||||
{
|
||||
return ROOT_DEV_CONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROOT_DEV_FAILED;
|
||||
}
|
||||
}
|
||||
else // Check that there is no device connection to the port
|
||||
{
|
||||
return ROOT_DEV_DISCONNECT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROOT_DEV_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortEnable
|
||||
*
|
||||
* @brief Check the enable status of the USB port.
|
||||
* Note: This bit is automatically cleared when the device is disconnected.
|
||||
*
|
||||
* @return The current enable status of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortEnable( void )
|
||||
{
|
||||
return ( USBOTG_H_FS->HOST_CTRL & USBFS_UH_PORT_EN );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CheckRootHubPortSpeed
|
||||
*
|
||||
* @brief Check the speed of the USB port.
|
||||
*
|
||||
* @return The current speed of the port.
|
||||
*/
|
||||
uint8_t USBFSH_CheckRootHubPortSpeed( void )
|
||||
{
|
||||
return ( USBOTG_H_FS->MIS_ST & USBFS_UMS_DM_LEVEL? USB_LOW_SPEED: USB_FULL_SPEED );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetSelfAddr
|
||||
*
|
||||
* @brief Set the USB device address.
|
||||
*
|
||||
* @para addr: USB device address.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_SetSelfAddr( uint8_t addr )
|
||||
{
|
||||
USBOTG_H_FS->DEV_ADDR = ( USBOTG_H_FS->DEV_ADDR & USBFS_UDA_GP_BIT ) | ( addr & USBFS_USB_ADDR_MASK );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetSelfSpeed
|
||||
*
|
||||
* @brief Set USB speed.
|
||||
*
|
||||
* @para speed: USB speed.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_SetSelfSpeed( uint8_t speed )
|
||||
{
|
||||
if( speed == USB_FULL_SPEED )
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL &= ~USBFS_UC_LOW_SPEED;
|
||||
USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_LOW_SPEED;
|
||||
USBOTG_H_FS->HOST_SETUP &= ~USBFS_UH_PRE_PID_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_H_FS->BASE_CTRL |= USBFS_UC_LOW_SPEED;
|
||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_LOW_SPEED;
|
||||
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_PRE_PID_EN;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_ResetRootHubPort
|
||||
*
|
||||
* @brief Reset USB port.
|
||||
*
|
||||
* @para mod: Reset host port operating mode.
|
||||
* 0 -> reset and wait end
|
||||
* 1 -> begin reset
|
||||
* 2 -> end reset
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void USBFSH_ResetRootHubPort( uint8_t mode )
|
||||
{
|
||||
USBFSH_SetSelfAddr( 0x00 );
|
||||
USBFSH_SetSelfSpeed( USB_FULL_SPEED );
|
||||
|
||||
if( mode <= 1 )
|
||||
{
|
||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_BUS_RESET; // Start reset
|
||||
}
|
||||
if( mode == 0 )
|
||||
{
|
||||
Delay_Ms( DEF_BUS_RESET_TIME ); // Reset time from 10mS to 20mS
|
||||
}
|
||||
if( mode != 1 )
|
||||
{
|
||||
USBOTG_H_FS->HOST_CTRL &= ~USBFS_UH_BUS_RESET; // End reset
|
||||
}
|
||||
Delay_Ms( 2 );
|
||||
|
||||
if( USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT )
|
||||
{
|
||||
if( USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH )
|
||||
{
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_EnableRootHubPort
|
||||
*
|
||||
* @brief Enable USB host port.
|
||||
*
|
||||
* @para *pspeed: USB speed.
|
||||
*
|
||||
* @return Operation result of the enabled port.
|
||||
*/
|
||||
uint8_t USBFSH_EnableRootHubPort( uint8_t *pspeed )
|
||||
{
|
||||
if( USBOTG_H_FS->MIS_ST & USBFS_UMS_DEV_ATTACH )
|
||||
{
|
||||
if( USBFSH_CheckRootHubPortEnable( ) == 0x00 )
|
||||
{
|
||||
*pspeed = USBFSH_CheckRootHubPortSpeed( );
|
||||
if( *pspeed == USB_LOW_SPEED )
|
||||
{
|
||||
USBFSH_SetSelfSpeed( USB_LOW_SPEED );
|
||||
}
|
||||
}
|
||||
USBOTG_H_FS->HOST_CTRL |= USBFS_UH_PORT_EN;
|
||||
USBOTG_H_FS->HOST_SETUP |= USBFS_UH_SOF_EN;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERR_USB_DISCON;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_Transact
|
||||
*
|
||||
* @brief Perform USB transaction.
|
||||
*
|
||||
* @para endp_pid: Token PID.
|
||||
* endp_tog: Toggle
|
||||
* timeout: Timeout time.
|
||||
*
|
||||
* @return USB transfer result.
|
||||
*/
|
||||
uint8_t USBFSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint16_t timeout )
|
||||
{
|
||||
uint8_t r, trans_retry;
|
||||
uint16_t i;
|
||||
|
||||
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = endp_tog;
|
||||
trans_retry = 0;
|
||||
do
|
||||
{
|
||||
USBOTG_H_FS->HOST_EP_PID = endp_pid; // Specify token PID and endpoint number
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER; // Allow transfer
|
||||
for( i = DEF_WAIT_USB_TRANSFER_CNT; ( i != 0 ) && ( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 ); i-- )
|
||||
{
|
||||
Delay_Us( 1 ); // Delay for USB transfer
|
||||
}
|
||||
USBOTG_H_FS->HOST_EP_PID = 0x00; // Stop USB transfer
|
||||
if( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 )
|
||||
{
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
else // Complete transfer
|
||||
{
|
||||
if( USBOTG_H_FS->INT_ST & USBFS_UIS_TOG_OK )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
r = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK; // Response status of current USB transaction
|
||||
if( r == USB_PID_STALL )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
if( r == USB_PID_NAK )
|
||||
{
|
||||
if( timeout == 0 )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
if( timeout < 0xFFFF )
|
||||
{
|
||||
timeout--;
|
||||
}
|
||||
--trans_retry;
|
||||
}
|
||||
else switch ( endp_pid >> 4 )
|
||||
{
|
||||
case USB_PID_SETUP:
|
||||
case USB_PID_OUT:
|
||||
if( r )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
break;
|
||||
case USB_PID_IN:
|
||||
if( ( r == USB_PID_DATA0 ) || ( r == USB_PID_DATA1 ) )
|
||||
{
|
||||
;
|
||||
}
|
||||
else if( r )
|
||||
{
|
||||
return ( r | ERR_USB_TRANSFER );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
}
|
||||
Delay_Us( 20 );
|
||||
|
||||
if( USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT )
|
||||
{
|
||||
Delay_Us( 200 );
|
||||
|
||||
if( USBFSH_CheckRootHubPortEnable( ) == 0x00 )
|
||||
{
|
||||
return ERR_USB_DISCON; // USB device disconnect event
|
||||
}
|
||||
else
|
||||
{
|
||||
USBOTG_H_FS->INT_FG = USBFS_UIF_DETECT;
|
||||
}
|
||||
}
|
||||
}while( ++trans_retry < 10 );
|
||||
|
||||
return ERR_USB_TRANSFER; // Reply timeout
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_CtrlTransfer
|
||||
*
|
||||
* @brief USB host control transfer.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
* plen: Data length
|
||||
*
|
||||
* @return USB control transfer result.
|
||||
*/
|
||||
uint8_t USBFSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t rem_len, rx_len, rx_cnt, tx_cnt;
|
||||
|
||||
Delay_Us( 100 );
|
||||
if( plen )
|
||||
{
|
||||
*plen = 0;
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_LEN = sizeof( USB_SETUP_REQ );
|
||||
s = USBFSH_Transact( ( USB_PID_SETUP << 4 ) | 0x00, 0x00, DEF_CTRL_TRANS_TIMEOVER_CNT ); // SETUP stage
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = USBFS_UH_T_TOG | USBFS_UH_R_TOG; // Default DATA1
|
||||
rem_len = pUSBFS_SetupRequest->wLength;
|
||||
if( rem_len && pbuf )
|
||||
{
|
||||
if( pUSBFS_SetupRequest->bRequestType & USB_REQ_TYP_IN )
|
||||
{
|
||||
/* Receive data */
|
||||
while( rem_len )
|
||||
{
|
||||
Delay_Us( 100 );
|
||||
s = USBFSH_Transact( ( USB_PID_IN << 4 ) | 0x00, USBOTG_H_FS->HOST_RX_CTRL, DEF_CTRL_TRANS_TIMEOVER_CNT ); // IN
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBOTG_H_FS->HOST_RX_CTRL ^= USBFS_UH_R_TOG;
|
||||
|
||||
rx_len = ( USBOTG_H_FS->RX_LEN < rem_len )? USBOTG_H_FS->RX_LEN : rem_len;
|
||||
rem_len -= rx_len;
|
||||
if( plen )
|
||||
{
|
||||
*plen += rx_len; // The total length of the actual successful transmission and reception
|
||||
}
|
||||
for( rx_cnt = 0; rx_cnt != rx_len; rx_cnt++ )
|
||||
{
|
||||
*pbuf = USBFS_RX_Buf[ rx_cnt ];
|
||||
pbuf++;
|
||||
}
|
||||
|
||||
if( ( USBOTG_H_FS->RX_LEN == 0 ) || ( USBOTG_H_FS->RX_LEN & ( ep0_size - 1 ) ) )
|
||||
{
|
||||
break; // Short package
|
||||
}
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_LEN = 0; // Status stage is OUT
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send data */
|
||||
while( rem_len )
|
||||
{
|
||||
Delay_Us( 100 );
|
||||
USBOTG_H_FS->HOST_TX_LEN = ( rem_len >= ep0_size )? ep0_size : rem_len;
|
||||
for( tx_cnt = 0; tx_cnt != USBOTG_H_FS->HOST_TX_LEN; tx_cnt++ )
|
||||
{
|
||||
USBFS_TX_Buf[ tx_cnt ] = *pbuf;
|
||||
pbuf++;
|
||||
}
|
||||
s = USBFSH_Transact( USB_PID_OUT << 4 | 0x00, USBOTG_H_FS->HOST_TX_CTRL, DEF_CTRL_TRANS_TIMEOVER_CNT ); // OUT
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBOTG_H_FS->HOST_TX_CTRL ^= USBFS_UH_T_TOG;
|
||||
|
||||
rem_len -= USBOTG_H_FS->HOST_TX_LEN;
|
||||
if( plen )
|
||||
{
|
||||
*plen += USBOTG_H_FS->HOST_TX_LEN; // The total length of the actual successful transmission and reception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Delay_Us( 100 );
|
||||
s = USBFSH_Transact( ( USBOTG_H_FS->HOST_TX_LEN )? ( USB_PID_IN << 4 | 0x00 ) : ( USB_PID_OUT << 4 | 0x00 ), USBFS_UH_R_TOG | USBFS_UH_T_TOG, DEF_CTRL_TRANS_TIMEOVER_CNT ); // STATUS stage
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
if( USBOTG_H_FS->HOST_TX_LEN == 0 )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
if( USBOTG_H_FS->RX_LEN == 0 )
|
||||
{
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetDeviceDescr
|
||||
*
|
||||
* @brief Get the device descriptor of the USB device.
|
||||
*
|
||||
* @para pep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
*
|
||||
* @return The result of getting the device descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t len;
|
||||
|
||||
*pep0_size = DEFAULT_ENDP0_SIZE;
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetDevDesc, sizeof( USB_SETUP_REQ ) );
|
||||
s = USBFSH_CtrlTransfer( *pep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
*pep0_size = ( (PUSB_DEV_DESCR)pbuf )->bMaxPacketSize0;
|
||||
if( len < ( (PUSB_SETUP_REQ)SetupGetDevDesc )->wLength )
|
||||
{
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetConfigDescr
|
||||
*
|
||||
* @brief Get the configuration descriptor of the USB device.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* pbuf: Data buffer
|
||||
* buf_len: Data buffer length
|
||||
* pcfg_len: The length of the device configuration descriptor
|
||||
*
|
||||
* @return The result of getting the configuration descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) );
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, pcfg_len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
if( *pcfg_len < ( (PUSB_SETUP_REQ)SetupGetCfgDesc )->wLength )
|
||||
{
|
||||
return ERR_USB_BUF_OVER;
|
||||
}
|
||||
|
||||
*pcfg_len = ( (PUSB_CFG_DESCR)pbuf )->wTotalLength;
|
||||
if( *pcfg_len > buf_len )
|
||||
{
|
||||
*pcfg_len = buf_len;
|
||||
}
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wLength = *pcfg_len;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, pcfg_len );
|
||||
return s;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetStrDescr
|
||||
*
|
||||
* @brief Get the string descriptor of the USB device.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* str_num: Index of string descriptor
|
||||
* pbuf: Data buffer
|
||||
*
|
||||
* @return The result of getting the string descriptor.
|
||||
*/
|
||||
uint8_t USBFSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf )
|
||||
{
|
||||
uint8_t s;
|
||||
uint16_t len;
|
||||
|
||||
/* Get the string descriptor of the first 4 bytes */
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Get the complete string descriptor */
|
||||
len = pbuf[ 0 ];
|
||||
memcpy( pUSBFS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num;
|
||||
pUSBFS_SetupRequest->wLength = len;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, pbuf, &len );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetUsbAddress
|
||||
*
|
||||
* @brief Set USB device address.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* addr: Device address
|
||||
*
|
||||
* @return The result of setting device address.
|
||||
*/
|
||||
uint8_t USBFSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( pUSBFS_SetupRequest, SetupSetAddr, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = (uint16_t)addr;
|
||||
s = USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
if( s != ERR_SUCCESS )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
USBFSH_SetSelfAddr( addr );
|
||||
Delay_Ms( DEF_BUS_RESET_TIME >> 1 ); // Wait for the USB device to complete its operation.
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SetUsbConfig
|
||||
*
|
||||
* @brief Set USB configuration.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* cfg: Device configuration value
|
||||
*
|
||||
* @return The result of setting device configuration.
|
||||
*/
|
||||
uint8_t USBFSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val )
|
||||
{
|
||||
memcpy( pUSBFS_SetupRequest, SetupSetConfig, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wValue = (uint16_t)cfg_val;
|
||||
return USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_ClearEndpStall
|
||||
*
|
||||
* @brief Clear endpoint stall.
|
||||
*
|
||||
* @para ep0_size: Device endpoint 0 size
|
||||
* endp_num: Endpoint number.
|
||||
*
|
||||
* @return The result of clearing endpoint stall.
|
||||
*/
|
||||
uint8_t USBFSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num )
|
||||
{
|
||||
memcpy( pUSBFS_SetupRequest, SetupClearEndpStall, sizeof( USB_SETUP_REQ ) );
|
||||
pUSBFS_SetupRequest->wIndex = (uint16_t)endp_num;
|
||||
return USBFSH_CtrlTransfer( ep0_size, NULL, NULL );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_GetEndpData
|
||||
*
|
||||
* @brief Get data from USB device input endpoint.
|
||||
*
|
||||
* @para endp_num: Endpoint number
|
||||
* endp_tog: Endpoint toggle
|
||||
* pbuf: Data Buffer
|
||||
* plen: Data length
|
||||
*
|
||||
* @return The result of getting data.
|
||||
*/
|
||||
uint8_t USBFSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
s = USBFSH_Transact( ( USB_PID_IN << 4 ) | endp_num, *pendp_tog, 0 );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
*plen = USBOTG_H_FS->RX_LEN;
|
||||
memcpy( pbuf, USBFS_RX_Buf, *plen );
|
||||
|
||||
*pendp_tog ^= USBFS_UH_R_TOG;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn USBFSH_SendEndpData
|
||||
*
|
||||
* @brief Send data to the USB device output endpoint.
|
||||
*
|
||||
* @para endp_num: Endpoint number
|
||||
* endp_tog: Endpoint toggle
|
||||
* pbuf: Data Buffer
|
||||
* len: Data length
|
||||
*
|
||||
* @return The result of sending data.
|
||||
*/
|
||||
uint8_t USBFSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len )
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
memcpy( USBFS_TX_Buf, pbuf, len );
|
||||
USBOTG_H_FS->HOST_TX_LEN = len;
|
||||
s = USBFSH_Transact( ( USB_PID_OUT << 4 ) | endp_num, *pendp_tog, 0 );
|
||||
if( s == ERR_SUCCESS )
|
||||
{
|
||||
*pendp_tog ^= USBFS_UH_T_TOG;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usbfs_host.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : USBOTG full speed host 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 __CH32V20x_USBFS_HOST_H__
|
||||
#define __CH32V20x_USBFS_HOST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header File */
|
||||
#include "ch32v20x.h"
|
||||
#include "ch32v20x_usb.h"
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Macro Definition */
|
||||
|
||||
/* USB Setup Request */
|
||||
#define pUSBFS_SetupRequest ( (PUSB_SETUP_REQ)USBFS_TX_Buf )
|
||||
|
||||
/* USB Buffer Size */
|
||||
#ifndef USBFS_MAX_PACKET_SIZE
|
||||
#define USBFS_MAX_PACKET_SIZE 64
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Constant Definition */
|
||||
#ifndef DEF_USB_GEN_ENUM_CMD
|
||||
#define DEF_USB_GEN_ENUM_CMD
|
||||
/* Get Device Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetDevDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof( USB_DEV_DESCR ), 0x00
|
||||
};
|
||||
|
||||
/* Get Configuration Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetCfgDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00
|
||||
};
|
||||
|
||||
/* Get String Descriptor Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupGetStrDesc[ ] =
|
||||
{
|
||||
USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_STRING, 0x09, 0x04, 0x04, 0x00
|
||||
};
|
||||
|
||||
/* Set USB Address Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetAddr[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT, USB_SET_ADDRESS, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Set USB Configuration Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetConfig[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Clear Endpoint STALL Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupClearEndpStall[ ] =
|
||||
{
|
||||
USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Set Device Interface Command Packet */
|
||||
__attribute__((aligned(4))) static const uint8_t SetupSetInterface[ ] =
|
||||
{
|
||||
USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Variable Declaration */
|
||||
extern __attribute__((aligned(4))) uint8_t USBFS_RX_Buf[ ];
|
||||
extern __attribute__((aligned(4))) uint8_t USBFS_TX_Buf[ ];
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Function Declaration */
|
||||
extern void USBFS_RCC_Init( void );
|
||||
extern void USBFS_Host_Init( FunctionalState sta );
|
||||
extern uint8_t USBFSH_CheckRootHubPortStatus( uint8_t dev_sta );
|
||||
extern uint8_t USBFSH_CheckRootHubPortEnable( void );
|
||||
extern uint8_t USBFSH_CheckRootHubPortSpeed( void );
|
||||
extern void USBFSH_SetSelfAddr( uint8_t addr );
|
||||
extern void USBFSH_SetSelfSpeed( uint8_t speed );
|
||||
extern void USBFSH_ResetRootHubPort( uint8_t mode );
|
||||
extern uint8_t USBFSH_EnableRootHubPort( uint8_t *pspeed );
|
||||
extern uint8_t USBFSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint16_t timeout );
|
||||
extern uint8_t USBFSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen );
|
||||
extern uint8_t USBFSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf );
|
||||
extern uint8_t USBFSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len );
|
||||
extern uint8_t USBFSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf );
|
||||
extern uint8_t USBFSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr );
|
||||
extern uint8_t USBFSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val );
|
||||
extern uint8_t USBFSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num );
|
||||
extern uint8_t USBFSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen );
|
||||
extern uint8_t USBFSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : usb_host_config.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/08/29
|
||||
* 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 __USB_HOST_CONFIG_H
|
||||
#define __USB_HOST_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header File */
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
#include "ch32v20x_usb.h"
|
||||
#include "ch32v20x_usbfs_host.h"
|
||||
#include "app_mtp_ptp.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Debug Macro Definition */
|
||||
#define DEF_DEBUG_PRINTF 1
|
||||
#if ( DEF_DEBUG_PRINTF == 1 )
|
||||
#define DUG_PRINTF( format, arg... ) printf( format, ##arg )
|
||||
#else
|
||||
#define DUG_PRINTF( format, arg... ) do{ if( 0 )printf( format, ##arg ); }while( 0 );
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* USB Host Communication Related Macro Definition */
|
||||
|
||||
/* USB Host Port General Control */
|
||||
#define DEF_TOTAL_ROOT_HUB 1
|
||||
#define DEF_USBFS_PORT_EN 1
|
||||
#define DEF_USBFS_PORT_INDEX 0x00
|
||||
#define DEF_ONE_USB_SUP_DEV_TOTAL 1
|
||||
#define DEF_NEXT_HUB_PORT_NUM_MAX 4
|
||||
#define DEF_INTERFACE_NUM_MAX 4
|
||||
|
||||
/* USB Root Device Status */
|
||||
#define ROOT_DEV_DISCONNECT 0
|
||||
#define ROOT_DEV_CONNECTED 1
|
||||
#define ROOT_DEV_FAILED 2
|
||||
#define ROOT_DEV_SUCCESS 3
|
||||
|
||||
/* USB Device Address */
|
||||
#define USB_DEVICE_ADDR 0x02
|
||||
|
||||
/* USB Speed */
|
||||
#define USB_LOW_SPEED 0x00
|
||||
#define USB_FULL_SPEED 0x01
|
||||
#define USB_HIGH_SPEED 0x02
|
||||
#define USB_SPEED_CHECK_ERR 0xFF
|
||||
|
||||
/* Configuration Descriptor Type */
|
||||
#define DEF_DECR_CONFIG 0x02
|
||||
#define DEF_DECR_INTERFACE 0x04
|
||||
#define DEF_DECR_ENDPOINT 0x05
|
||||
#define DEF_DECR_HID 0x21
|
||||
|
||||
/* USB Communication Status Code */
|
||||
#define ERR_SUCCESS 0x00
|
||||
#define ERR_USB_CONNECT 0x15
|
||||
#define ERR_USB_DISCON 0x16
|
||||
#define ERR_USB_BUF_OVER 0x17
|
||||
#define ERR_USB_DISK_ERR 0x1F
|
||||
#define ERR_USB_TRANSFER 0x20
|
||||
#define ERR_USB_UNSUPPORT 0xFB
|
||||
#define ERR_USB_UNAVAILABLE 0xFC
|
||||
#define ERR_USB_UNKNOWN 0xFE
|
||||
|
||||
/* USB Device Enumeration Status Code */
|
||||
#define DEF_DEV_DESCR_GETFAIL 0x45
|
||||
#define DEF_DEV_ADDR_SETFAIL 0x46
|
||||
#define DEF_CFG_DESCR_GETFAIL 0x47
|
||||
#define DEF_REP_DESCR_GETFAIL 0x48
|
||||
#define DEF_DEV_TYPE_UNKNOWN 0xFF
|
||||
|
||||
/* USB Communication Time */
|
||||
#define DEF_BUS_RESET_TIME 11 // USB bus reset time
|
||||
#define DEF_RE_ATTACH_TIMEOUT 100 // Wait for the USB device to reconnect after reset, 100mS timeout
|
||||
#define DEF_WAIT_USB_TRANSFER_CNT 1000 // Wait for the USB transfer to complete
|
||||
#define DEF_CTRL_TRANS_TIMEOVER_CNT 200000/20 // Control transmission delay timing
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Struct Definition */
|
||||
/* Note: Please modify it according to your project. */
|
||||
|
||||
/* HUB Port Device */
|
||||
typedef struct _HUB_DEVICE
|
||||
{
|
||||
uint8_t bStatus;
|
||||
uint8_t bType;
|
||||
uint8_t bAddress;
|
||||
uint8_t bSpeed;
|
||||
uint8_t bEp0MaxPks;
|
||||
uint8_t DeviceIndex;
|
||||
}HUB_DEVICE, *PHUB_DEVICE;
|
||||
|
||||
/* Root HUB Device Structure */
|
||||
typedef struct _ROOT_HUB_DEVICE
|
||||
{
|
||||
uint8_t bStatus;
|
||||
uint8_t bType;
|
||||
uint8_t bAddress;
|
||||
uint8_t bSpeed;
|
||||
uint8_t bEp0MaxPks;
|
||||
uint8_t DeviceIndex;
|
||||
uint8_t bPortNum;
|
||||
HUB_DEVICE Device[ DEF_NEXT_HUB_PORT_NUM_MAX ];
|
||||
} ROOT_HUB_DEVICE, *PROOT_HUB_DEVICE;
|
||||
|
||||
/* USB Host Control Structure */
|
||||
typedef struct __HOST_CTL
|
||||
{
|
||||
uint8_t InterfaceNum;
|
||||
uint8_t ErrorCount;
|
||||
|
||||
struct interface
|
||||
{
|
||||
uint8_t Type;
|
||||
uint16_t HidDescLen;
|
||||
uint8_t HidReportID;
|
||||
uint8_t Full_KB_Flag;
|
||||
|
||||
uint8_t InEndpNum;
|
||||
uint8_t InEndpAddr[ 4 ];
|
||||
uint8_t InEndpType[ 4 ];
|
||||
uint16_t InEndpSize[ 4 ];
|
||||
uint8_t InEndpTog[ 4 ];
|
||||
uint8_t InEndpInterval[ 4 ];
|
||||
uint8_t InEndpTimeCount[ 4 ];
|
||||
|
||||
uint8_t OutEndpNum;
|
||||
uint8_t OutEndpAddr[ 4 ];
|
||||
uint8_t OutEndpType[ 4 ];
|
||||
uint16_t OutEndpSize[ 4 ];
|
||||
uint8_t OutEndpTog[ 4 ];
|
||||
|
||||
uint8_t IDFlag;
|
||||
uint8_t ReportID;
|
||||
|
||||
uint8_t LED_Usage_Min;
|
||||
uint8_t LED_Usage_Max;
|
||||
|
||||
uint8_t SetReport_Swi;
|
||||
uint8_t SetReport_Value;
|
||||
uint8_t SetReport_Flag;
|
||||
|
||||
}Interface[ DEF_INTERFACE_NUM_MAX ];
|
||||
} HOST_CTL, *PHOST_CTL;
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Struct Declaration */
|
||||
extern struct _ROOT_HUB_DEVICE RootHubDev;
|
||||
extern struct __HOST_CTL HostCtl[ ];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x_it.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
/*********************************************************************
|
||||
* @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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,540 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_usb.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef __CH32V20x_USB_H
|
||||
#define __CH32V20x_USB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header Files */
|
||||
#include "stdint.h"
|
||||
|
||||
/*******************************************************************************/
|
||||
/* USB Communication Related Macro Definition */
|
||||
|
||||
/* USB Endpoint0 Size */
|
||||
#ifndef DEFAULT_ENDP0_SIZE
|
||||
#define DEFAULT_ENDP0_SIZE 8
|
||||
#endif
|
||||
|
||||
/* USB PID */
|
||||
#ifndef USB_PID_SETUP
|
||||
#define USB_PID_NULL 0x00
|
||||
#define USB_PID_SOF 0x05
|
||||
#define USB_PID_SETUP 0x0D
|
||||
#define USB_PID_IN 0x09
|
||||
#define USB_PID_OUT 0x01
|
||||
#define USB_PID_NYET 0x06
|
||||
#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_DATA2 0x07
|
||||
#define USB_PID_MDATA 0x0F
|
||||
#define USB_PID_PRE 0x0C
|
||||
#define USB_PID_SPLIT 0x08
|
||||
#define USB_PID_PING 0x04
|
||||
#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
|
||||
|
||||
#define DEF_STRING_DESC_LANG 0x00
|
||||
#define DEF_STRING_DESC_MANU 0x01
|
||||
#define DEF_STRING_DESC_PROD 0x02
|
||||
#define DEF_STRING_DESC_SERN 0x03
|
||||
|
||||
/* 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
|
||||
#define USB_REQ_TYP_OUT 0x00
|
||||
#define USB_REQ_TYP_READ 0x80
|
||||
#define USB_REQ_TYP_WRITE 0x00
|
||||
#define USB_REQ_TYP_MASK 0x60
|
||||
#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
|
||||
#define USB_REQ_RECIP_DEVICE 0x00
|
||||
#define USB_REQ_RECIP_INTERF 0x01
|
||||
#define USB_REQ_RECIP_ENDP 0x02
|
||||
#define USB_REQ_RECIP_OTHER 0x03
|
||||
#define USB_REQ_FEAT_REMOTE_WAKEUP 0x01
|
||||
#define USB_REQ_FEAT_ENDP_HALT 0x00
|
||||
#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_IMAGE 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 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 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
|
||||
|
||||
/* USB UDisk */
|
||||
#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
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* USBFS Related Register Macro Definition */
|
||||
|
||||
/* R8_USB_CTRL */
|
||||
#define USBFS_UC_HOST_MODE 0x80
|
||||
#define USBFS_UC_LOW_SPEED 0x40
|
||||
#define USBFS_UC_DEV_PU_EN 0x20
|
||||
#define USBFS_UC_SYS_CTRL_MASK 0x30
|
||||
#define USBFS_UC_SYS_CTRL0 0x00
|
||||
#define USBFS_UC_SYS_CTRL1 0x10
|
||||
#define USBFS_UC_SYS_CTRL2 0x20
|
||||
#define USBFS_UC_SYS_CTRL3 0x30
|
||||
#define USBFS_UC_INT_BUSY 0x08
|
||||
#define USBFS_UC_RESET_SIE 0x04
|
||||
#define USBFS_UC_CLR_ALL 0x02
|
||||
#define USBFS_UC_DMA_EN 0x01
|
||||
|
||||
/* R8_USB_INT_EN */
|
||||
#define USBFS_UIE_DEV_SOF 0x80
|
||||
#define USBFS_UIE_DEV_NAK 0x40
|
||||
#define USBFS_UIE_FIFO_OV 0x10
|
||||
#define USBFS_UIE_HST_SOF 0x08
|
||||
#define USBFS_UIE_SUSPEND 0x04
|
||||
#define USBFS_UIE_TRANSFER 0x02
|
||||
#define USBFS_UIE_DETECT 0x01
|
||||
#define USBFS_UIE_BUS_RST 0x01
|
||||
|
||||
/* R8_USB_DEV_AD */
|
||||
#define USBFS_UDA_GP_BIT 0x80
|
||||
#define USBFS_USB_ADDR_MASK 0x7F
|
||||
|
||||
/* R8_USB_MIS_ST */
|
||||
#define USBFS_UMS_SOF_PRES 0x80
|
||||
#define USBFS_UMS_SOF_ACT 0x40
|
||||
#define USBFS_UMS_SIE_FREE 0x20
|
||||
#define USBFS_UMS_R_FIFO_RDY 0x10
|
||||
#define USBFS_UMS_BUS_RESET 0x08
|
||||
#define USBFS_UMS_SUSPEND 0x04
|
||||
#define USBFS_UMS_DM_LEVEL 0x02
|
||||
#define USBFS_UMS_DEV_ATTACH 0x01
|
||||
|
||||
/* R8_USB_INT_FG */
|
||||
#define USBFS_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
|
||||
#define USBFS_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define USBFS_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
|
||||
#define USBFS_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
|
||||
|
||||
/* R8_USB_INT_ST */
|
||||
#define USBFS_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
|
||||
#define USBFS_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define USBFS_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
|
||||
#define USBFS_UIS_TOKEN_OUT 0x00
|
||||
#define USBFS_UIS_TOKEN_SOF 0x10
|
||||
#define USBFS_UIS_TOKEN_IN 0x20
|
||||
#define USBFS_UIS_TOKEN_SETUP 0x30
|
||||
// bUIS_TOKEN1 & bUIS_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 USBFS_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
|
||||
#define USBFS_UIS_H_RES_MASK 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
|
||||
|
||||
/* R32_USB_OTG_CR */
|
||||
#define USBFS_CR_SESS_VTH 0x20
|
||||
#define USBFS_CR_VBUS_VTH 0x10
|
||||
#define USBFS_CR_OTG_EN 0x08
|
||||
#define USBFS_CR_IDPU 0x04
|
||||
#define USBFS_CR_CHARGE_VBUS 0x02
|
||||
#define USBFS_CR_DISCHAR_VBUS 0x01
|
||||
|
||||
/* R32_USB_OTG_SR */
|
||||
#define USBFS_SR_ID_DIG 0x08
|
||||
#define USBFS_SR_SESS_END 0x04
|
||||
#define USBFS_SR_SESS_VLD 0x02
|
||||
#define USBFS_SR_VBUS_VLD 0x01
|
||||
|
||||
/* R8_UDEV_CTRL */
|
||||
#define USBFS_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UD_GP_BIT 0x02 // general purpose bit
|
||||
#define USBFS_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
|
||||
|
||||
/* R8_UEP4_1_MOD */
|
||||
#define USBFS_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
|
||||
#define USBFS_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
|
||||
#define USBFS_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
|
||||
// bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
|
||||
// 0 0 x: disable endpoint and disable buffer
|
||||
// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
|
||||
// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
|
||||
// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
|
||||
// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
|
||||
// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
|
||||
#define USBFS_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
|
||||
#define USBFS_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
|
||||
// bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
|
||||
// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
|
||||
// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
|
||||
// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
|
||||
// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
|
||||
#define USBFS_UEP4_BUF_MOD 0x01
|
||||
|
||||
/* R8_UEP2_3_MOD */
|
||||
#define USBFS_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
|
||||
#define USBFS_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
|
||||
#define USBFS_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
|
||||
#define USBFS_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
|
||||
#define USBFS_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
|
||||
#define USBFS_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
|
||||
|
||||
/* R8_UEP5_6_MOD */
|
||||
#define USBFS_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
|
||||
#define USBFS_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
|
||||
#define USBFS_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
|
||||
#define USBFS_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
|
||||
#define USBFS_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
|
||||
#define USBFS_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
|
||||
|
||||
/* R8_UEP7_MOD */
|
||||
#define USBFS_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
|
||||
#define USBFS_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
|
||||
#define USBFS_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
|
||||
|
||||
/* R8_UEPn_TX_CTRL */
|
||||
#define USBFS_UEP_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
|
||||
#define USBFS_UEP_T_RES_ACK 0x00
|
||||
#define USBFS_UEP_T_RES_NONE 0x01
|
||||
#define USBFS_UEP_T_RES_NAK 0x02
|
||||
#define USBFS_UEP_T_RES_STALL 0x03
|
||||
// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
|
||||
// 00: DATA0 or DATA1 then expecting ACK (ready)
|
||||
// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: STALL (error)
|
||||
// host aux setup
|
||||
|
||||
/* R8_UEPn_RX_CTRL, n=0-7 */
|
||||
#define USBFS_UEP_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
|
||||
#define USBFS_UEP_R_RES_ACK 0x00
|
||||
#define USBFS_UEP_R_RES_NONE 0x01
|
||||
#define USBFS_UEP_R_RES_NAK 0x02
|
||||
#define USBFS_UEP_R_RES_STALL 0x03
|
||||
// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
|
||||
// 00: ACK (ready)
|
||||
// 01: no response, time out to host, for non-zero endpoint isochronous transactions
|
||||
// 10: NAK (busy)
|
||||
// 11: STALL (error)
|
||||
|
||||
/* R8_UHOST_CTRL */
|
||||
#define USBFS_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define USBFS_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define USBFS_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define USBFS_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
|
||||
#define USBFS_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
|
||||
#define USBFS_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
|
||||
|
||||
/* R32_UH_EP_MOD */
|
||||
#define USBFS_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
|
||||
#define USBFS_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
|
||||
// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
|
||||
// 0 x: disable endpoint and disable buffer
|
||||
// 1 0: 64 bytes buffer for transmittal (OUT endpoint)
|
||||
// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
|
||||
#define USBFS_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
|
||||
#define USBFS_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
|
||||
// bUH_EP_RX_EN & bUH_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
|
||||
|
||||
/* R16_UH_SETUP */
|
||||
#define USBFS_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub
|
||||
#define USBFS_UH_SOF_EN 0x0004 // USB host automatic SOF enable
|
||||
|
||||
/* R8_UH_EP_PID */
|
||||
#define USBFS_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer
|
||||
#define USBFS_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer
|
||||
|
||||
/* R8_UH_RX_CTRL */
|
||||
#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
|
||||
|
||||
/* R8_UH_TX_CTRL */
|
||||
#define USBFS_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define USBFS_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
|
||||
#define USBFS_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Struct Definition */
|
||||
|
||||
/* USB Setup Request */
|
||||
typedef struct __attribute__((packed)) _USB_SETUP_REQ
|
||||
{
|
||||
uint8_t bRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} USB_SETUP_REQ, *PUSB_SETUP_REQ;
|
||||
|
||||
/* USB Device Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_DEVICE_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
} USB_DEV_DESCR, *PUSB_DEV_DESCR;
|
||||
|
||||
/* USB Configuration Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_CONFIG_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t MaxPower;
|
||||
} USB_CFG_DESCR, *PUSB_CFG_DESCR;
|
||||
|
||||
/* USB Interface Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_INTERF_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
} USB_ITF_DESCR, *PUSB_ITF_DESCR;
|
||||
|
||||
/* USB Endpoint Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_ENDPOINT_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t wMaxPacketSizeL;
|
||||
uint8_t wMaxPacketSizeH;
|
||||
uint8_t bInterval;
|
||||
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
|
||||
|
||||
/* USB Configuration Descriptor Set */
|
||||
typedef struct __attribute__((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;
|
||||
|
||||
/* USB HUB Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_HUB_DESCR
|
||||
{
|
||||
uint8_t bDescLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bNbrPorts;
|
||||
uint8_t wHubCharacteristicsL;
|
||||
uint8_t wHubCharacteristicsH;
|
||||
uint8_t bPwrOn2PwrGood;
|
||||
uint8_t bHubContrCurrent;
|
||||
uint8_t DeviceRemovable;
|
||||
uint8_t PortPwrCtrlMask;
|
||||
} USB_HUB_DESCR, *PUSB_HUB_DESCR;
|
||||
|
||||
/* USB HID Descriptor */
|
||||
typedef struct __attribute__((packed)) _USB_HID_DESCR
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bDescriptorTypeX;
|
||||
uint8_t wDescriptorLengthL;
|
||||
uint8_t wDescriptorLengthH;
|
||||
} USB_HID_DESCR, *PUSB_HID_DESCR;
|
||||
|
||||
/* USB UDisk */
|
||||
typedef struct __attribute__((packed)) _UDISK_BOC_CBW
|
||||
{
|
||||
uint32_t mCBW_Sig;
|
||||
uint32_t mCBW_Tag;
|
||||
uint32_t mCBW_DataLen;
|
||||
uint8_t mCBW_Flag;
|
||||
uint8_t mCBW_LUN;
|
||||
uint8_t mCBW_CB_Len;
|
||||
uint8_t mCBW_CB_Buf[ 16 ];
|
||||
} UDISK_BOC_CBW, *PXUDISK_BOC_CBW;
|
||||
|
||||
/* USB UDisk */
|
||||
typedef struct __attribute__((packed)) _UDISK_BOC_CSW
|
||||
{
|
||||
uint32_t mCBW_Sig;
|
||||
uint32_t mCBW_Tag;
|
||||
uint32_t mCSW_Residue;
|
||||
uint8_t mCSW_Status;
|
||||
} UDISK_BOC_CSW, *PXUDISK_BOC_CSW;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CH32V20x_USB_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/09/01
|
||||
* Description : Main program body.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* @Note
|
||||
* This example demonstrates the enumeration process of a USB host to a device that
|
||||
* supports MTP and PTP protocols, and reads its files.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @Note
|
||||
* In addition, when the system frequency is selected as the USBFS clock source, only 144MHz/96MHz/48MHz
|
||||
* are supported.
|
||||
*/
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Header Files */
|
||||
#include "usb_host_config.h"
|
||||
|
||||
/*********************************************************************
|
||||
* @fn main
|
||||
*
|
||||
* @brief Main program.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
int main( void )
|
||||
{
|
||||
/* Initialize system configuration */
|
||||
Delay_Init( );
|
||||
USART_Printf_Init( 115200 );
|
||||
DUG_PRINTF( "SystemClk:%d\r\n", SystemCoreClock );
|
||||
DUG_PRINTF( "USBFS HOST MTP Test\r\n" );
|
||||
|
||||
/* Initialize USBFS host */
|
||||
#if DEF_USBFS_PORT_EN
|
||||
DUG_PRINTF( "USBFS Host Init\r\n" );
|
||||
USBFS_RCC_Init( );
|
||||
USBFS_Host_Init( ENABLE );
|
||||
memset( &RootHubDev.bStatus, 0, sizeof( ROOT_HUB_DEVICE ) );
|
||||
memset( &HostCtl[ DEF_USBFS_PORT_INDEX * DEF_ONE_USB_SUP_DEV_TOTAL ].InterfaceNum, 0, DEF_ONE_USB_SUP_DEV_TOTAL * sizeof( HOST_CTL ) );
|
||||
#endif
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
USBH_MainDeal( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,986 @@
|
||||
/********************************** (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
|
||||
@@ -0,0 +1,32 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user