v1
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/*!
|
||||
* \file diskio.h
|
||||
*
|
||||
* \brief Target disk I/O implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "integer.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
||||
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC \
|
||||
0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM \
|
||||
4 /* Inform device that the data on the block of sectors is no longer used \
|
||||
(needed at _USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
DSTATUS disk_initialize(BYTE pdrv);
|
||||
DSTATUS disk_status(BYTE pdrv);
|
||||
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff);
|
||||
DWORD get_fattime(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* \file fatfs.h
|
||||
*
|
||||
* \brief Target FatFS implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __fatfs_H
|
||||
#define __fatfs_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "ff.h"
|
||||
#include "ff_gen_drv.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern char Path[4]; /* USER logical drive path */
|
||||
extern FATFS FatFS; /* File system object for USER logical drive */
|
||||
extern FIL File; /* File object for USER */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
void FATFS_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*__fatfs_H */
|
||||
@@ -0,0 +1,362 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FF_H
|
||||
#define _FF_H 68300 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FF_H != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
||||
#if _USE_LFN == 0
|
||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if _FS_EXFAT
|
||||
#if _USE_LFN == 0
|
||||
#error LFN must be enabled when enable exFAT
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* File system type (0:N/A) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if _MAX_SS != _MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _USE_LFN != 0
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if _FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH != 0
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if _FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (_FDID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if _FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
|
||||
#endif
|
||||
#if _FS_LOCK != 0
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} _FDID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if _USE_LFN != 0
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if _USE_LFN != 0
|
||||
TCHAR altname[13]; /* Alternative file name */
|
||||
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[13]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ff_gen_drv.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for ff_gen_drv.c module.
|
||||
*****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
**/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __FF_GEN_DRV_H
|
||||
#define __FF_GEN_DRV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Disk IO Driver structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
|
||||
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
|
||||
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
|
||||
#if _USE_WRITE == 1
|
||||
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
|
||||
#endif /* _USE_WRITE == 1 */
|
||||
#if _USE_IOCTL == 1
|
||||
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
|
||||
}Diskio_drvTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Global Disk IO Drivers structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t is_initialized[_VOLUMES];
|
||||
const Diskio_drvTypeDef *drv[_VOLUMES];
|
||||
uint8_t lun[_VOLUMES];
|
||||
volatile uint8_t nbr;
|
||||
|
||||
}Disk_drvTypeDef;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path);
|
||||
uint8_t FATFS_UnLinkDriver(char *path);
|
||||
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun);
|
||||
uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun);
|
||||
uint8_t FATFS_GetAttachedDriversNbr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FF_GEN_DRV_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 68300 /* Revision ID */
|
||||
|
||||
/*-----------------------------------------------------------------------------/
|
||||
/ Additional user header to be used
|
||||
/-----------------------------------------------------------------------------*/
|
||||
//#include "main.h"
|
||||
//#include "stm32f4xx_hal.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/-----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
#define _USE_FASTSEEK 1
|
||||
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
|
||||
|
||||
#define _USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
#define _USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
#define _USE_LABEL 1
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
/*-----------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/-----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 437//850
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
*/
|
||||
|
||||
#define _USE_LFN 0 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN switches the support of long file name (LFN).
|
||||
/
|
||||
/ 0: Disable support of LFN. _MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
||||
/ It should be set 255 to support full featured LFN operations.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree(), must be added to the project. */
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
|
||||
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
||||
/ This option also affects behavior of string I/O functions. */
|
||||
|
||||
#define _STRF_ENCODE 3
|
||||
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
|
||||
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/
|
||||
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||
|
||||
#define _FS_RPATH 0 /* 0 to 2 */
|
||||
/* This option configures support of relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
/* USER CODE BEGIN Volumes */
|
||||
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID switches string support of volume ID.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
/* USER CODE END Volumes */
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Multiple partition */
|
||||
/* This option switches support of multi-partition on a physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When multi-partition is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ function will be available. */
|
||||
#define _MIN_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
#define _MAX_SS 512//4096 /* 512, 1024, 2048 or 4096 */
|
||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
#define _USE_TRIM 0
|
||||
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
#define _FS_NOFSINFO 0 /* 0,1,2 or 3 */
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||
|
||||
#define _FS_EXFAT 0
|
||||
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards C89 compatibility. */
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 6
|
||||
#define _NORTC_MDAY 4
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||
|
||||
#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */
|
||||
/* The option _FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t NULL
|
||||
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* define the ff_malloc ff_free macros as standard malloc free */
|
||||
#if !defined(ff_malloc) && !defined(ff_free)
|
||||
#include <stdlib.h>
|
||||
#define ff_malloc malloc
|
||||
#define ff_free free
|
||||
#endif
|
||||
|
||||
#endif /* _FFCONF */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _FF_INTEGER
|
||||
#define _FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
||||
typedef unsigned long long QWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
/*!
|
||||
* \file diskio.c
|
||||
*
|
||||
* \brief Target disk I/O implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "diskio.h"
|
||||
#include "ff_gen_drv.h"
|
||||
#include "msc_flash.h"
|
||||
|
||||
#include "time_conv.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
#if defined(__GNUC__)
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEV_USB 0 /* Example: Map USB MSD to physical drive 0 */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
extern Disk_drvTypeDef disk;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/**
|
||||
* @brief Gets Disk Status
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @retval DSTATUS: Operation status
|
||||
*/
|
||||
DSTATUS disk_status(BYTE pdrv /* Physical drive number to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat = STA_NOINIT;
|
||||
|
||||
// stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
|
||||
if (FAT_FLASH_ID == Fat_Flash_ReadID()) {
|
||||
stat = RES_OK;
|
||||
} else {
|
||||
stat = STA_NOINIT;
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a Drive
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @retval DSTATUS: Operation status
|
||||
*/
|
||||
DSTATUS
|
||||
disk_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat = STA_NOINIT;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_USB: {
|
||||
if (true == Disk_Init())
|
||||
stat = RES_OK;
|
||||
} break;
|
||||
}
|
||||
|
||||
// if(disk.is_initialized[pdrv] == 0)
|
||||
// {
|
||||
// disk.is_initialized[pdrv] = 1;
|
||||
// stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
|
||||
// }
|
||||
return stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads Sector(s)
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @param *buff: Data buffer to store read data
|
||||
* @param sector: Sector address (LBA)
|
||||
* @param count: Number of sectors to read (1..128)
|
||||
* @retval DRESULT: Operation result
|
||||
*/
|
||||
DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
DRESULT res = RES_ERROR;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_USB: {
|
||||
if (Disk_UnitRead(sector, count, buff) == true) {
|
||||
res = RES_OK;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
// res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes Sector(s)
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @param *buff: Data to be written
|
||||
* @param sector: Sector address (LBA)
|
||||
* @param count: Number of sectors to write (1..128)
|
||||
* @retval DRESULT: Operation result
|
||||
*/
|
||||
#if _USE_WRITE == 1
|
||||
DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address in LBA */
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
DRESULT res = RES_ERROR;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_USB: {
|
||||
if (Disk_UnitWrite(sector, count, (uint8_t *)buff) == true) {
|
||||
res = RES_OK;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
// res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
|
||||
return res;
|
||||
}
|
||||
#endif /* _USE_WRITE == 1 */
|
||||
|
||||
/**
|
||||
* @brief I/O control operation
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @param cmd: Control code
|
||||
* @param *buff: Buffer to send/receive control data
|
||||
* @retval DRESULT: Operation result
|
||||
*/
|
||||
#if _USE_IOCTL == 1
|
||||
DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res = RES_PARERR;
|
||||
|
||||
switch (pdrv) {
|
||||
case DEV_USB: {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT: {
|
||||
*(DWORD *)buff = Disk_UnitCount();
|
||||
res = RES_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_SECTOR_SIZE: {
|
||||
*(DWORD *)buff = Disk_UnitSize();
|
||||
res = RES_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_BLOCK_SIZE: {
|
||||
*(DWORD *)buff = 1;
|
||||
res = RES_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
// res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
|
||||
return res;
|
||||
}
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
|
||||
/**
|
||||
* @brief Gets Time from RTC
|
||||
* @param None
|
||||
* @retval Time in DWORD
|
||||
*/
|
||||
__weak DWORD get_fattime(void)
|
||||
{
|
||||
uint32_t fattime;
|
||||
// utc sec convert to utc date
|
||||
DateTime_t tmp_date = UTC_SecToDate(Utc_TotalSec);
|
||||
tmp_date = UTC_DateToZoneDate(TIME_ZONE, YEAR_BASE, tmp_date.year,
|
||||
tmp_date.month, tmp_date.day, tmp_date.hour,
|
||||
tmp_date.min, tmp_date.sec, tmp_date.week);
|
||||
fattime = ((YEAR_BASE + tmp_date.year - 1980) << 25) |
|
||||
(tmp_date.month << 21) | (tmp_date.day << 16) |
|
||||
(tmp_date.hour << 11) | (tmp_date.min << 5) | (tmp_date.sec >> 1);
|
||||
|
||||
return fattime;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,91 @@
|
||||
/*!
|
||||
* \file fatfs.c
|
||||
*
|
||||
* \brief Target FatFS implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "fatfs.h"
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
char Path[4]; /* Logical drive path */
|
||||
FATFS FatFS; /* File system object for Logical drive */
|
||||
FIL File; /* File object */
|
||||
DIR Dir;
|
||||
uint8_t buffer[_MAX_SS];
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief FatFS Initalization
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void FATFS_Init(void)
|
||||
{
|
||||
FRESULT res;
|
||||
|
||||
SPI_InitCfg_t spi_cfg = {0};
|
||||
|
||||
spi_cfg.Mode = SPI_MODE_MASTER;
|
||||
spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT;
|
||||
spi_cfg.Direction = SSI_CTRL0_TMOD_WR;
|
||||
spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW;
|
||||
spi_cfg.CLKPhase = SPI_CPHA_LEAD;
|
||||
spi_cfg.FirstBit = SPI_FirstBit_MSB;
|
||||
|
||||
xc_spi_init(XC_SPI0, &spi_cfg);
|
||||
xc_spi_flash_wake_up(XC_SPI0);
|
||||
|
||||
DEBUG("FatFS Init\r\n");
|
||||
res = f_mount(&FatFS, "0:", 1);
|
||||
DEBUG("Mount FRESULT: %d\r\n", res);
|
||||
|
||||
res = f_opendir(&Dir, "0:");
|
||||
DEBUG("Read Dir: %d\r\n", res);
|
||||
|
||||
if (FR_NO_FILESYSTEM == res) {
|
||||
res = f_mkfs("0:", FM_FAT, _MAX_SS, buffer, sizeof(buffer));
|
||||
DEBUG("Format FRESULT: %d\r\n", res);
|
||||
|
||||
res = f_unmount("0:");
|
||||
DEBUG("Umount FRESULT: %d\r\n", res);
|
||||
|
||||
// res = f_setlabel( "XinChip" );
|
||||
// DEBUG("Set label: %d\r\n", res);
|
||||
|
||||
res = f_mount(&FatFS, "0:", 1);
|
||||
DEBUG("Remount FRESULT: %d\r\n", res);
|
||||
|
||||
res = f_unmount("0:");
|
||||
DEBUG("Umount FRESULT: %d\r\n", res);
|
||||
} else {
|
||||
res = f_unmount("0:");
|
||||
DEBUG("Umount FRESULT: %d\r\n", res);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ff_gen_drv.c
|
||||
* @author MCD Application Team
|
||||
* @brief FatFs generic low level driver.
|
||||
*****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
**/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "ff_gen_drv.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
Disk_drvTypeDef disk = {{0}, {0}, {0}, 0};
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Links a compatible diskio driver/lun id and increments the number of
|
||||
active
|
||||
* linked drivers.
|
||||
* @note The number of linked drivers (volumes) is up to 10 due to FatFs
|
||||
limits.
|
||||
* @param drv: pointer to the disk IO Driver structure
|
||||
* @param path: pointer to the logical drive path
|
||||
* @param lun : only used for USB Key Disk to add multi-lun management
|
||||
else the parameter must be equal to 0
|
||||
* @retval Returns 0 in case of success, otherwise 1.
|
||||
*/
|
||||
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path,
|
||||
uint8_t lun)
|
||||
{
|
||||
uint8_t ret = 1;
|
||||
uint8_t DiskNum = 0;
|
||||
|
||||
if (disk.nbr < _VOLUMES) {
|
||||
disk.is_initialized[disk.nbr] = 0;
|
||||
disk.drv[disk.nbr] = drv;
|
||||
disk.lun[disk.nbr] = lun;
|
||||
DiskNum = disk.nbr++;
|
||||
path[0] = DiskNum + '0';
|
||||
path[1] = ':';
|
||||
path[2] = '/';
|
||||
path[3] = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Links a compatible diskio driver and increments the number of active
|
||||
* linked drivers.
|
||||
* @note The number of linked drivers (volumes) is up to 10 due to FatFs
|
||||
* limits
|
||||
* @param drv: pointer to the disk IO Driver structure
|
||||
* @param path: pointer to the logical drive path
|
||||
* @retval Returns 0 in case of success, otherwise 1.
|
||||
*/
|
||||
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path)
|
||||
{
|
||||
return FATFS_LinkDriverEx(drv, path, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlinks a diskio driver and decrements the number of active linked
|
||||
* drivers.
|
||||
* @param path: pointer to the logical drive path
|
||||
* @param lun : not used
|
||||
* @retval Returns 0 in case of success, otherwise 1.
|
||||
*/
|
||||
uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun)
|
||||
{
|
||||
uint8_t DiskNum = 0;
|
||||
uint8_t ret = 1;
|
||||
|
||||
if (disk.nbr >= 1) {
|
||||
DiskNum = path[0] - '0';
|
||||
if (disk.drv[DiskNum] != 0) {
|
||||
disk.drv[DiskNum] = 0;
|
||||
disk.lun[DiskNum] = 0;
|
||||
disk.nbr--;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlinks a diskio driver and decrements the number of active linked
|
||||
* drivers.
|
||||
* @param path: pointer to the logical drive path
|
||||
* @retval Returns 0 in case of success, otherwise 1.
|
||||
*/
|
||||
uint8_t FATFS_UnLinkDriver(char *path) { return FATFS_UnLinkDriverEx(path, 0); }
|
||||
|
||||
/**
|
||||
* @brief Gets number of linked drivers to the FatFs module.
|
||||
* @param None
|
||||
* @retval Number of attached drivers.
|
||||
*/
|
||||
uint8_t FATFS_GetAttachedDriversNbr(void) { return disk.nbr; }
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,75 @@
|
||||
/*!
|
||||
* \file usb_device.c
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usb_device.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Device Core handle declaration. */
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief This function handles USB On The Go FS global interrupt.
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
|
||||
|
||||
/**
|
||||
* @brief Init USB device Library, add supported class and start the library
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_DEVICE_Init(void)
|
||||
{
|
||||
/* Init Device Library, add supported class and start the library. */
|
||||
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
|
||||
USBD_UsrLog("__USB_INIT_FAIL__\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
|
||||
USBD_UsrLog("__USB_CLASS_FAIL__\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) !=
|
||||
USBD_OK) {
|
||||
USBD_UsrLog("__USB_CDC_FAIL__\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
|
||||
USBD_UsrLog("__USB_START_FAIL__\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* \file usb_device.h
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DEVICE_H
|
||||
#define __USB_DEVICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void USB_DEVICE_Init( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DEVICE_H */
|
||||
@@ -0,0 +1,322 @@
|
||||
/*!
|
||||
* \file usbd_cdc_if.c
|
||||
*
|
||||
* \brief Usb device for Virtual Com Port.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
|
||||
* @brief Public variables.
|
||||
* @{
|
||||
*/
|
||||
uint8_t Next_ep = 0;
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** Received data over USB are stored in this buffer */
|
||||
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
|
||||
uint16_t UserRxBufferLen = 0;
|
||||
|
||||
/** Data to send over USB CDC are stored in this buffer */
|
||||
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
|
||||
uint8_t UserReTx = false;
|
||||
|
||||
uint8_t TempBuffer[APP_TX_DATA_SIZE / 2];
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes
|
||||
* USBD_CDC_IF_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int8_t CDC_Init_FS(void);
|
||||
static int8_t CDC_DeInit_FS(void);
|
||||
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length);
|
||||
static int8_t CDC_Receive_FS(uint8_t *pbuf, uint32_t *Len);
|
||||
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = {CDC_Init_FS, CDC_DeInit_FS,
|
||||
CDC_Control_FS, CDC_Receive_FS,
|
||||
CDC_TransmitCplt_FS};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initializes the CDC media low layer over the FS USB IP
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_Init_FS(void)
|
||||
{
|
||||
/* Set Application Buffers */
|
||||
memset(TempBuffer, 0, sizeof(TempBuffer));
|
||||
UserRxBufferLen = 0;
|
||||
// USB_FlushTxFifo(hpcd_USB_OTG_FS.Instance, 0x10U);
|
||||
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
|
||||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the CDC media low layer
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_DeInit_FS(void) { return (USBD_OK); }
|
||||
|
||||
/**
|
||||
* @brief Manage the CDC class requests
|
||||
* @param cmd: Command code
|
||||
* @param pbuf: Buffer containing command data (request parameters)
|
||||
* @param length: Number of data to be sent (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else
|
||||
* USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CDC_SEND_ENCAPSULATED_COMMAND:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_GET_ENCAPSULATED_RESPONSE:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_SET_COMM_FEATURE:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_GET_COMM_FEATURE:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_CLEAR_COMM_FEATURE:
|
||||
|
||||
break;
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Line Coding Structure */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Offset | Field | Size | Value | Description */
|
||||
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per
|
||||
* second*/
|
||||
/* 4 | bCharFormat | 1 | Number | Stop bits */
|
||||
/* 0 - 1 Stop bit */
|
||||
/* 1 - 1.5 Stop bits */
|
||||
/* 2 - 2 Stop bits */
|
||||
/* 5 | bParityType | 1 | Number | Parity */
|
||||
/* 0 - None */
|
||||
/* 1 - Odd */
|
||||
/* 2 - Even */
|
||||
/* 3 - Mark */
|
||||
/* 4 - Space */
|
||||
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
|
||||
/*******************************************************************************/
|
||||
case CDC_SET_LINE_CODING:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_GET_LINE_CODING:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_SET_CONTROL_LINE_STATE:
|
||||
|
||||
break;
|
||||
|
||||
case CDC_SEND_BREAK:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Data received over USB OUT endpoint are sent over CDC interface
|
||||
* through this function.
|
||||
*
|
||||
* @note
|
||||
* This function will issue a NAK packet on any OUT packet received on
|
||||
* USB endpoint until exiting this function. If you exit this function
|
||||
* before transfer is complete on CDC interface (ie. using DMA
|
||||
* controller) it will result in receiving more data while previous ones are
|
||||
* still not sent.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else
|
||||
* USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len)
|
||||
{
|
||||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
|
||||
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||
// Receive Timer Refresh
|
||||
// TIMER_SetUs(XC_TIMER0, CDC_RECV_TIMEOUT_MS);
|
||||
// TIMER_Start_IT(XC_TIMER0);
|
||||
// DEBUG("len %d\n", *Len);
|
||||
//// Delay_Ms(10);
|
||||
// if(*Len != 0)
|
||||
// {
|
||||
// if(UserRxBufferLen < (APP_TX_DATA_SIZE/2))
|
||||
// {
|
||||
// ring_buffer_queue_arr(&CDC_Rx, Buf, *Len);
|
||||
// UserRxBufferLen += *Len;
|
||||
// }
|
||||
// }
|
||||
// DEBUG("u_len %d\n", UserRxBufferLen);
|
||||
CDC_Transmit_FS(UserRxBufferFS, *Len, CDC_IN_EP);
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_Transmit_FS
|
||||
* Data to send over USB IN endpoint are sent over CDC interface
|
||||
* through this function.
|
||||
* @note
|
||||
*
|
||||
*
|
||||
* @param Buf: Buffer of data to be sent
|
||||
* @param Len: Number of data to be sent (in bytes)
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
|
||||
*/
|
||||
uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len, uint8_t epnum)
|
||||
{
|
||||
uint8_t result = USBD_OK;
|
||||
|
||||
// DEBUG("cdc_epnum: %d\n", epnum);
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)hUsbDeviceFS.pClassData;
|
||||
if (hcdc->TxState != 0) {
|
||||
// DEBUG("bsy: %d\n", hcdc->TxState);
|
||||
return USBD_BUSY;
|
||||
}
|
||||
// DEBUG("tx_len %d\r", Len);
|
||||
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
|
||||
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
|
||||
|
||||
// uint8_t packetSendCnt = Len / 64;
|
||||
// uint8_t packetSendRem = Len % 64;
|
||||
//
|
||||
// for(uint8_t i=0; i<packetSendCnt; i++)
|
||||
// {
|
||||
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[i * 64], 64);
|
||||
// result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
|
||||
// while(hcdc->TxState != 0);
|
||||
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, NULL, 0);
|
||||
// result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
|
||||
// while(hcdc->TxState != 0);
|
||||
// }
|
||||
//
|
||||
// if(packetSendRem != 0)
|
||||
// {
|
||||
// DEBUG("SendRem\r");
|
||||
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[Len - packetSendRem],
|
||||
// packetSendRem); result = USBD_CDC_TransmitPacket(&hUsbDeviceFS,
|
||||
// epnum);
|
||||
// }
|
||||
// while(hcdc->TxState != 0);
|
||||
// memset(TempBuffer, 0, sizeof(TempBuffer));
|
||||
// UserRxBufferLen = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_TransmitCplt_FS
|
||||
* Data transmitted callback
|
||||
*
|
||||
* @note
|
||||
* This function is IN transfer complete callback used to inform user
|
||||
* that the submitted Data is successfully sent over USB.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else
|
||||
* USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
|
||||
{
|
||||
uint8_t result = USBD_OK;
|
||||
// static uint8_t offset = 0;
|
||||
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
UNUSED(epnum);
|
||||
|
||||
// if(UserReTx == true)
|
||||
// {
|
||||
// UserRxBufferLen -= CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
// offset++;
|
||||
// if(UserRxBufferLen > CDC_DATA_FS_MAX_PACKET_SIZE)
|
||||
// CDC_Transmit_FS(TempBuffer+offset*CDC_DATA_FS_MAX_PACKET_SIZE,
|
||||
// CDC_DATA_FS_MAX_PACKET_SIZE, CDC_IN_EP);
|
||||
// else
|
||||
// {
|
||||
|
||||
// UserReTx = false;
|
||||
// CDC_Transmit_FS(TempBuffer+offset*CDC_DATA_FS_MAX_PACKET_SIZE,
|
||||
// UserRxBufferLen, CDC_IN_EP);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(UserRxBufferLen <= CDC_DATA_FS_MAX_PACKET_SIZE)
|
||||
// {
|
||||
// offset = 0;
|
||||
// memset(TempBuffer, 0, sizeof(TempBuffer));
|
||||
// UserRxBufferLen = 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*!
|
||||
* \file usbd_cdc_if.h
|
||||
*
|
||||
* \brief Header for usbd_cdc_if.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CDC_IF_H
|
||||
#define __USBD_CDC_IF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_cdc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------——----------------------------------------*/
|
||||
/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
|
||||
* @brief Defines.
|
||||
* @{
|
||||
*/
|
||||
/* Define size for the receive and transmit buffer over CDC */
|
||||
#define APP_RX_DATA_SIZE 1024
|
||||
#define APP_TX_DATA_SIZE 1024
|
||||
|
||||
#define CDC_RECV_TIMEOUT_MS 5000U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** CDC Interface callback. */
|
||||
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
||||
extern uint8_t Next_ep;
|
||||
//extern tHandler_callback CDC_Recv_Timer_Cbk[4];
|
||||
extern uint16_t UserRxBufferLen;
|
||||
extern uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
|
||||
extern uint8_t UserTxEnable;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t epnum);
|
||||
|
||||
void CDC_Receive_Timeout(uint16_t val);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CDC_IF_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
/*!
|
||||
* \file usbd_desc.c
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
|
||||
* @brief Private defines.
|
||||
* @{
|
||||
*/
|
||||
#define USBD_VID 0x0483
|
||||
#define USBD_LANGID_STRING 0x0409
|
||||
#define USBD_MANUFACTURER_STRING "XinChip"
|
||||
#define USBD_PID_FS 22336
|
||||
#define USBD_PRODUCT_STRING_FS "XinChip Virtual ComPort"
|
||||
#define USBD_CONFIGURATION_STRING_FS "CDC Config"
|
||||
#define USBD_INTERFACE_STRING_FS "CDC Interface"
|
||||
|
||||
#define USB_SIZ_BOS_DESC 0x0C
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototypes
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
static void Get_SerialNum(void);
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
|
||||
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration for FS.
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
|
||||
USBD_FS_LangIDStrDescriptor,
|
||||
USBD_FS_ManufacturerStrDescriptor,
|
||||
USBD_FS_ProductStrDescriptor,
|
||||
USBD_FS_SerialStrDescriptor,
|
||||
USBD_FS_ConfigStrDescriptor,
|
||||
USBD_FS_InterfaceStrDescriptor
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
,
|
||||
USBD_FS_USR_BOSDescriptor
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/** USB standard device descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /*bLength */
|
||||
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
0x01,
|
||||
/*bcdUSB */ /* changed to USB version 2.01
|
||||
in order to support LPM L1 suspend
|
||||
resume test of USBCV3.0*/
|
||||
#else
|
||||
0x00, /*bcdUSB */
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
0x02,
|
||||
DEV_CLASS, /*bDeviceClass*/
|
||||
DEV_SUB_CLASS, /*bDeviceSubClass*/
|
||||
DEV_PROTOCOL, /*bDeviceProtocol*/
|
||||
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
|
||||
LOBYTE(USBD_VID), /*idVendor*/
|
||||
HIBYTE(USBD_VID), /*idVendor*/
|
||||
LOBYTE(USBD_PID_FS), /*idProduct*/
|
||||
HIBYTE(USBD_PID_FS), /*idProduct*/
|
||||
0x00, /*bcdDevice rel. 2.00*/
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
|
||||
USBD_IDX_PRODUCT_STR, /*Index of product string*/
|
||||
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
|
||||
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
|
||||
};
|
||||
|
||||
/* USB_DeviceDescriptor */
|
||||
/** BOS descriptor. */
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
|
||||
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
|
||||
/* device capability*/
|
||||
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
|
||||
0x0, 0x0, 0x0};
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
|
||||
/** USB lang identifier descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING)};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/* Internal string descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
#if defined(__ICCARM__) /*!< IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
|
||||
USB_SIZ_STRING_SERIAL,
|
||||
USB_DESC_TYPE_STRING,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Return the device descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_DeviceDesc);
|
||||
return USBD_FS_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the LangID string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the product string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the manufacturer string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the serial number string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = USB_SIZ_STRING_SERIAL;
|
||||
|
||||
/* Update the serial number string descriptor with the data from the unique
|
||||
* ID */
|
||||
Get_SerialNum();
|
||||
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
|
||||
|
||||
/* USER CODE END USBD_FS_SerialStrDescriptor */
|
||||
return (uint8_t *)USBD_StringSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the configuration string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the interface string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
/**
|
||||
* @brief Return the BOS descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_BOSDesc);
|
||||
return (uint8_t *)USBD_FS_BOSDesc;
|
||||
}
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/**
|
||||
* @brief Create the serial number string descriptor
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void Get_SerialNum(void)
|
||||
{
|
||||
uint32_t deviceserial0, deviceserial1, deviceserial2;
|
||||
|
||||
deviceserial0 = DEVICE_ID1;
|
||||
deviceserial1 = DEVICE_ID2;
|
||||
deviceserial2 = DEVICE_ID3;
|
||||
|
||||
deviceserial0 += deviceserial2;
|
||||
|
||||
if (deviceserial0 != 0) {
|
||||
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
|
||||
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert Hex 32Bits value into char
|
||||
* @param value: value to convert
|
||||
* @param pbuf: pointer to the buffer
|
||||
* @param len: buffer length
|
||||
* @retval None
|
||||
*/
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
if (((value >> 28)) < 0xA) {
|
||||
pbuf[2 * idx] = (value >> 28) + '0';
|
||||
} else {
|
||||
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
|
||||
}
|
||||
|
||||
value = value << 4;
|
||||
|
||||
pbuf[2 * idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,76 @@
|
||||
/*!
|
||||
* \file usbd_desc.h
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DESC__C
|
||||
#define __USBD_DESC__C
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
|
||||
* @brief Constants.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define DEV_CLASS 0x02
|
||||
#define DEV_SUB_CLASS 0x02
|
||||
#define DEV_PROTOCOL 0x00
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1B0000
|
||||
#define DEVICE_ID3 0x0914
|
||||
|
||||
#define USB_SIZ_STRING_SERIAL 0x1A
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** Descriptor for the Usb device. */
|
||||
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DESC__C */
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/*!
|
||||
* \file usb_device.c
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usb_device.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
#define CURSOR_STEP 2U
|
||||
#define CURSOR_WIDTH 200U
|
||||
#elif ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
|
||||
#define KEY_CAPS_DATA 0x39
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Device Core handle declaration. */
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief This function handles USB On The Go FS global interrupt.
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
|
||||
|
||||
/**
|
||||
* @brief Init USB device Library, add supported class and start the library
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_DEVICE_Init(void)
|
||||
{
|
||||
/* Init Device Library, add supported class and start the library. */
|
||||
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
/**
|
||||
* @brief Mouse get pointer datas
|
||||
* @param uint8_t *pbuf
|
||||
* @retval void
|
||||
*/
|
||||
void GetPointerData(uint8_t *pbuf)
|
||||
{
|
||||
static int32_t move_cnt = 0;
|
||||
static uint8_t step_x_y = 0;
|
||||
static int8_t x = 0, y = 0;
|
||||
static uint16_t cnt = 0;
|
||||
|
||||
move_cnt++;
|
||||
if (move_cnt > CURSOR_WIDTH) {
|
||||
step_x_y++;
|
||||
step_x_y = step_x_y % 4;
|
||||
move_cnt = 0;
|
||||
}
|
||||
switch (step_x_y) {
|
||||
case 0: {
|
||||
y = 0;
|
||||
x = CURSOR_STEP;
|
||||
|
||||
} break;
|
||||
|
||||
case 1: {
|
||||
x = 0;
|
||||
y = CURSOR_STEP;
|
||||
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
|
||||
y = 0;
|
||||
x = (int8_t)(-CURSOR_STEP);
|
||||
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
x = 0;
|
||||
y = (int8_t)(-CURSOR_STEP);
|
||||
|
||||
} break;
|
||||
}
|
||||
cnt++;
|
||||
pbuf[0] = 0; // 1;
|
||||
if (cnt > 1000) {
|
||||
pbuf[0] = 16; // 17;
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
pbuf[1] = x;
|
||||
pbuf[2] = y;
|
||||
pbuf[3] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Usb mouse test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Mouse_Test_SendReport(void)
|
||||
{
|
||||
uint8_t buff[4] = {0};
|
||||
|
||||
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
|
||||
/**
|
||||
* @brief Usb Keyboard test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Keyboard_Test_SendReport(eKeyState key_sta)
|
||||
{
|
||||
uint8_t buff[HID_EPIN_SIZE] = {0};
|
||||
|
||||
if (key_sta == KEY_PRESS) {
|
||||
buff[2] = KEY_CAPS_DATA;
|
||||
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
|
||||
} else if (key_sta == KEY_RELEASE) {
|
||||
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
|
||||
} else if (key_sta == KEY_HOLD_PRESS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HID_CLASS_MODE == HID_CUSTOM)
|
||||
/**
|
||||
* @brief Usb custom hid test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Custom_Test_SendReport(void)
|
||||
{
|
||||
uint8_t usb_tx_data[64] = {0};
|
||||
// usb_tx_data[0] = 0x01;
|
||||
for (uint8_t i = 0; i < 64; i++)
|
||||
usb_tx_data[i] = i;
|
||||
|
||||
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, usb_tx_data, 64);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/*!
|
||||
* \file usb_device.h
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DEVICE_H__
|
||||
#define __USB_DEVICE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
typedef enum {
|
||||
KEY_RELEASE = 0,
|
||||
KEY_PRESS,
|
||||
KEY_HOLD_PRESS
|
||||
} eKeyState;
|
||||
|
||||
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void USB_DEVICE_Init( void );
|
||||
|
||||
void USB_Mouse_Test_SendReport( void );
|
||||
void USB_Keyboard_Test_SendReport(eKeyState key_sta);
|
||||
void USB_Custom_Test_SendReport( void );
|
||||
|
||||
void GetPointerData(uint8_t *pbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DEVICE_H__ */
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
/*!
|
||||
* \file usbd_desc.c
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
|
||||
* @brief Private defines.
|
||||
* @{
|
||||
*/
|
||||
#define USBD_VID VID_VAL
|
||||
#define USBD_LANGID_STRING LANG_ID_STR
|
||||
#define USBD_MANUFACTURER_STRING "XinChip"
|
||||
#define USBD_PID_FS PID_FS_VAL
|
||||
#define USBD_PRODUCT_STRING_FS \
|
||||
"XinChip Custom Human interface" //"XinChip Human interface"
|
||||
#define USBD_CONFIGURATION_STRING_FS "Custom HID Config" //"HID Config"
|
||||
#define USBD_INTERFACE_STRING_FS "Custom HID Interface" //"HID Interface"
|
||||
|
||||
#define USB_SIZ_BOS_DESC 0x0C
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototypes
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
static void Get_SerialNum(void);
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
|
||||
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration for FS.
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
|
||||
USBD_FS_LangIDStrDescriptor,
|
||||
USBD_FS_ManufacturerStrDescriptor,
|
||||
USBD_FS_ProductStrDescriptor,
|
||||
USBD_FS_SerialStrDescriptor,
|
||||
USBD_FS_ConfigStrDescriptor,
|
||||
USBD_FS_InterfaceStrDescriptor
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
,
|
||||
USBD_FS_USR_BOSDescriptor
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/** USB standard device descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /*bLength */
|
||||
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
0x01,
|
||||
/*bcdUSB */ /* changed to USB version 2.01
|
||||
in order to support LPM L1 suspend
|
||||
resume test of USBCV3.0*/
|
||||
#else
|
||||
0x00, /*bcdUSB */
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
0x02,
|
||||
DEV_CLASS, /*bDeviceClass*/
|
||||
DEV_SUB_CLASS, /*bDeviceSubClass*/
|
||||
DEV_PROTOCOL, /*bDeviceProtocol*/
|
||||
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
|
||||
LOBYTE(USBD_VID), /*idVendor*/
|
||||
HIBYTE(USBD_VID), /*idVendor*/
|
||||
LOBYTE(USBD_PID_FS), /*idProduct*/
|
||||
HIBYTE(USBD_PID_FS), /*idProduct*/
|
||||
0x00, /*bcdDevice rel. 2.00*/
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
|
||||
USBD_IDX_PRODUCT_STR, /*Index of product string*/
|
||||
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
|
||||
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
|
||||
};
|
||||
|
||||
/* USB_DeviceDescriptor */
|
||||
/** BOS descriptor. */
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
|
||||
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
|
||||
/* device capability*/
|
||||
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
|
||||
0x0, 0x0, 0x0};
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
|
||||
/** USB lang identifier descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING)};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/* Internal string descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
#if defined(__ICCARM__) /*!< IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
|
||||
USB_SIZ_STRING_SERIAL,
|
||||
USB_DESC_TYPE_STRING,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Return the device descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_FS_DeviceDesc);
|
||||
return USBD_FS_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the LangID string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the product string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the manufacturer string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the serial number string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = USB_SIZ_STRING_SERIAL;
|
||||
|
||||
/* Update the serial number string descriptor with the data from the unique
|
||||
* ID */
|
||||
Get_SerialNum();
|
||||
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
|
||||
|
||||
/* USER CODE END USBD_FS_SerialStrDescriptor */
|
||||
return (uint8_t *)USBD_StringSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the configuration string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == USBD_SPEED_HIGH) {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the interface string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
/**
|
||||
* @brief Return the BOS descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_BOSDesc);
|
||||
return (uint8_t *)USBD_FS_BOSDesc;
|
||||
}
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/**
|
||||
* @brief Create the serial number string descriptor
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void Get_SerialNum(void)
|
||||
{
|
||||
uint32_t deviceserial0, deviceserial1, deviceserial2;
|
||||
|
||||
deviceserial0 = DEVICE_ID1;
|
||||
deviceserial1 = DEVICE_ID2;
|
||||
deviceserial2 = DEVICE_ID3;
|
||||
|
||||
deviceserial0 += deviceserial2;
|
||||
|
||||
if (deviceserial0 != 0) {
|
||||
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
|
||||
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert Hex 32Bits value into char
|
||||
* @param value: value to convert
|
||||
* @param pbuf: pointer to the buffer
|
||||
* @param len: buffer length
|
||||
* @retval None
|
||||
*/
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
if (((value >> 28)) < 0xA) {
|
||||
pbuf[2 * idx] = (value >> 28) + '0';
|
||||
} else {
|
||||
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
|
||||
}
|
||||
|
||||
value = value << 4;
|
||||
|
||||
pbuf[2 * idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
* \file usbd_desc.h
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DESC__C__
|
||||
#define __USBD_DESC__C__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
|
||||
* @brief Constants.
|
||||
* @{
|
||||
*/
|
||||
#if (HID_CLASS_MODE == HID_MOUSE)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17799
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1D0000
|
||||
#define DEVICE_ID3 0x1122
|
||||
#elif (HID_CLASS_MODE == HID_KEYBOARD)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17780
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1F0000
|
||||
#define DEVICE_ID3 0x1123
|
||||
#elif (HID_CLASS_MODE == HID_CUSTOM)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17781
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1F0000
|
||||
#define DEVICE_ID3 0x1124
|
||||
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
|
||||
#define VID_VAL 1156
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22353
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1E0000
|
||||
#define DEVICE_ID3 0x1123
|
||||
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM))
|
||||
#define VID_VAL 1156
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22354
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x200000
|
||||
#define DEVICE_ID3 0x1215
|
||||
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
|
||||
#define VID_VAL 1157
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22355
|
||||
|
||||
#define DEVICE_ID1 0x20230000
|
||||
#define DEVICE_ID2 0x210000
|
||||
#define DEVICE_ID3 0x0228
|
||||
#endif
|
||||
|
||||
#define DEV_CLASS 0x00
|
||||
#define DEV_SUB_CLASS 0x00
|
||||
#define DEV_PROTOCOL 0x00
|
||||
|
||||
#define USB_SIZ_STRING_SERIAL 0x1A
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** Descriptor for the Usb device. */
|
||||
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DESC__C__ */
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*!
|
||||
* \file usb_device.c
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usb_device.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_hid.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define CURSOR_STEP 2U
|
||||
#define CURSOR_WIDTH 200U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Device Core handle declaration. */
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief This function handles USB On The Go FS global interrupt.
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
|
||||
|
||||
/**
|
||||
* @brief Init USB device Library, add supported class and start the library
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_DEVICE_Init(void)
|
||||
{
|
||||
/* Init Device Library, add supported class and start the library. */
|
||||
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
/**
|
||||
* @brief Mouse get pointer datas
|
||||
* @param uint8_t *pbuf
|
||||
* @retval void
|
||||
*/
|
||||
void GetPointerData(uint8_t *pbuf)
|
||||
{
|
||||
static int32_t move_cnt = 0;
|
||||
static uint8_t step_x_y = 0;
|
||||
static int8_t x = 0, y = 0;
|
||||
static uint16_t cnt = 0;
|
||||
|
||||
move_cnt++;
|
||||
if (move_cnt > CURSOR_WIDTH) {
|
||||
step_x_y++;
|
||||
step_x_y = step_x_y % 4;
|
||||
move_cnt = 0;
|
||||
}
|
||||
switch (step_x_y) {
|
||||
case 0: {
|
||||
y = 0;
|
||||
x = CURSOR_STEP;
|
||||
|
||||
} break;
|
||||
|
||||
case 1: {
|
||||
x = 0;
|
||||
y = CURSOR_STEP;
|
||||
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
|
||||
y = 0;
|
||||
x = (int8_t)(-CURSOR_STEP);
|
||||
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
x = 0;
|
||||
y = (int8_t)(-CURSOR_STEP);
|
||||
|
||||
} break;
|
||||
}
|
||||
cnt++;
|
||||
if (cnt > 1000) {
|
||||
if (pbuf[0] != 16)
|
||||
pbuf[0] = 16;
|
||||
else
|
||||
pbuf[0] = 0;
|
||||
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
pbuf[1] = x;
|
||||
pbuf[2] = y;
|
||||
pbuf[3] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Usb mouse test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Mouse_Test_SendReport(void)
|
||||
{
|
||||
uint8_t buff[4] = {0};
|
||||
#if (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
|
||||
USBD_Mouse_HID_SendReport(&hUsbDeviceFS, buff, HID_EP2IN_SIZE);
|
||||
#elif (HID_CLASS_MODE == (HID_CUSTOM | HID_MOUSE))
|
||||
USBD_Mouse_HID_SendReport(&hUsbDeviceFS, buff, HID_EPIN_SIZE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
|
||||
#define CUSTOM_SR_LEN 64U
|
||||
/**
|
||||
* @brief Usb custom hid test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Custom_Test_SendReport(void)
|
||||
{
|
||||
uint8_t usb_tx_data[CUSTOM_SR_LEN] = {0};
|
||||
for (uint8_t i = 0; i < CUSTOM_SR_LEN; i++)
|
||||
usb_tx_data[i] = i;
|
||||
USBD_Custom_HID_SendReport(&hUsbDeviceFS, usb_tx_data, CUSTOM_SR_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
/**
|
||||
* @brief Usb custom1 hid test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Custom1_Test_SendReport(void)
|
||||
{
|
||||
uint8_t usb_tx_data[64] = {0};
|
||||
usb_tx_data[0] = 0x81;
|
||||
for (uint8_t i = 1; i < 64; i++)
|
||||
usb_tx_data[i] = i;
|
||||
USBD_Custom1_HID_SendReport(&hUsbDeviceFS, usb_tx_data, 64);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Usb custom2 hid test send report
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Custom2_Test_SendReport(void)
|
||||
{
|
||||
uint8_t usb_tx_data[64] = {0};
|
||||
usb_tx_data[0] = 0x82;
|
||||
for (uint8_t i = 1; i < 64; i++)
|
||||
usb_tx_data[i] = i;
|
||||
USBD_Custom2_HID_SendReport(&hUsbDeviceFS, usb_tx_data, 64);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/*!
|
||||
* \file usb_device.h
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DEVICE_H__
|
||||
#define __USB_DEVICE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void USB_DEVICE_Init( void );
|
||||
uint8_t USB_Dev_State_Judge(uint8_t * rtc_cnt);
|
||||
void USB_Mouse_Test_SendReport( void );
|
||||
void USB_Custom_Test_SendReport( void );
|
||||
|
||||
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
void USB_Custom1_Test_SendReport( void );
|
||||
void USB_Custom2_Test_SendReport( void );
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DEVICE_H__ */
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
/*!
|
||||
* \file usbd_desc.c
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
|
||||
* @brief Private defines.
|
||||
* @{
|
||||
*/
|
||||
#define USBD_VID VID_VAL
|
||||
#define USBD_LANGID_STRING LANG_ID_STR
|
||||
#define USBD_MANUFACTURER_STRING "XinChip"
|
||||
#define USBD_PID_FS PID_FS_VAL
|
||||
#define USBD_PRODUCT_STRING_FS "XinChip Human interface"
|
||||
#define USBD_CONFIGURATION_STRING_FS "HID Config"
|
||||
#define USBD_INTERFACE_STRING_FS "HID Interface"
|
||||
|
||||
#define USB_SIZ_BOS_DESC 0x0C
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototypes
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
static void Get_SerialNum(void);
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
|
||||
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration for FS.
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
|
||||
USBD_FS_LangIDStrDescriptor,
|
||||
USBD_FS_ManufacturerStrDescriptor,
|
||||
USBD_FS_ProductStrDescriptor,
|
||||
USBD_FS_SerialStrDescriptor,
|
||||
USBD_FS_ConfigStrDescriptor,
|
||||
USBD_FS_InterfaceStrDescriptor
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
,
|
||||
USBD_FS_USR_BOSDescriptor
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/** USB standard device descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /*bLength */
|
||||
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
0x01,
|
||||
/*bcdUSB */ /* changed to USB version 2.01
|
||||
in order to support LPM L1 suspend
|
||||
resume test of USBCV3.0*/
|
||||
#else
|
||||
0x00, /*bcdUSB */
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
0x02,
|
||||
DEV_CLASS, /*bDeviceClass*/
|
||||
DEV_SUB_CLASS, /*bDeviceSubClass*/
|
||||
DEV_PROTOCOL, /*bDeviceProtocol*/
|
||||
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
|
||||
LOBYTE(USBD_VID), /*idVendor*/
|
||||
HIBYTE(USBD_VID), /*idVendor*/
|
||||
LOBYTE(USBD_PID_FS), /*idProduct*/
|
||||
HIBYTE(USBD_PID_FS), /*idProduct*/
|
||||
0x00, /*bcdDevice rel. 2.00*/
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
|
||||
USBD_IDX_PRODUCT_STR, /*Index of product string*/
|
||||
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
|
||||
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
|
||||
};
|
||||
|
||||
/* USB_DeviceDescriptor */
|
||||
/** BOS descriptor. */
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
|
||||
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
|
||||
/* device capability*/
|
||||
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
|
||||
0x0, 0x0, 0x0};
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
|
||||
/** USB lang identifier descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING)};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/* Internal string descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
#if defined(__ICCARM__) /*!< IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
|
||||
USB_SIZ_STRING_SERIAL,
|
||||
USB_DESC_TYPE_STRING,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Return the device descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_FS_DeviceDesc);
|
||||
return USBD_FS_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the LangID string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the product string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the manufacturer string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the serial number string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = USB_SIZ_STRING_SERIAL;
|
||||
|
||||
/* Update the serial number string descriptor with the data from the unique
|
||||
* ID */
|
||||
Get_SerialNum();
|
||||
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
|
||||
|
||||
/* USER CODE END USBD_FS_SerialStrDescriptor */
|
||||
return (uint8_t *)USBD_StringSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the configuration string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == USBD_SPEED_HIGH) {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the interface string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
/**
|
||||
* @brief Return the BOS descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_BOSDesc);
|
||||
return (uint8_t *)USBD_FS_BOSDesc;
|
||||
}
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/**
|
||||
* @brief Create the serial number string descriptor
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void Get_SerialNum(void)
|
||||
{
|
||||
uint32_t deviceserial0, deviceserial1, deviceserial2;
|
||||
|
||||
deviceserial0 = DEVICE_ID1;
|
||||
deviceserial1 = DEVICE_ID2;
|
||||
deviceserial2 = DEVICE_ID3;
|
||||
|
||||
deviceserial0 += deviceserial2;
|
||||
|
||||
if (deviceserial0 != 0) {
|
||||
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
|
||||
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert Hex 32Bits value into char
|
||||
* @param value: value to convert
|
||||
* @param pbuf: pointer to the buffer
|
||||
* @param len: buffer length
|
||||
* @retval None
|
||||
*/
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
if (((value >> 28)) < 0xA) {
|
||||
pbuf[2 * idx] = (value >> 28) + '0';
|
||||
} else {
|
||||
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
|
||||
}
|
||||
|
||||
value = value << 4;
|
||||
|
||||
pbuf[2 * idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,128 @@
|
||||
/*!
|
||||
* \file usbd_desc.h
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DESC__C__
|
||||
#define __USBD_DESC__C__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
|
||||
* @brief Constants.
|
||||
* @{
|
||||
*/
|
||||
#if (HID_CLASS_MODE == HID_MOUSE)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17799
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1D0000
|
||||
#define DEVICE_ID3 0x1122
|
||||
#elif (HID_CLASS_MODE == HID_KEYBOARD)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17780
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1F0000
|
||||
#define DEVICE_ID3 0x1123
|
||||
#elif (HID_CLASS_MODE == HID_CUSTOM)
|
||||
#define VID_VAL 1155
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 17781
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1F0000
|
||||
#define DEVICE_ID3 0x1124
|
||||
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
|
||||
#define VID_VAL 1156
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22353
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x1E0000
|
||||
#define DEVICE_ID3 0x1123
|
||||
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM))
|
||||
#define VID_VAL 1156
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22354
|
||||
|
||||
#define DEVICE_ID1 0x20220000
|
||||
#define DEVICE_ID2 0x200000
|
||||
#define DEVICE_ID3 0x1215
|
||||
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
|
||||
#define VID_VAL 1157
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22355
|
||||
|
||||
#define DEVICE_ID1 0x20230000
|
||||
#define DEVICE_ID2 0x210000
|
||||
#define DEVICE_ID3 0x0228
|
||||
#elif (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
#define VID_VAL 1158
|
||||
#define LANG_ID_STR 1033
|
||||
#define PID_FS_VAL 22356
|
||||
|
||||
#define DEVICE_ID1 0x20230000
|
||||
#define DEVICE_ID2 0x210000
|
||||
#define DEVICE_ID3 0x0816
|
||||
#endif
|
||||
|
||||
#define DEV_CLASS 0x00
|
||||
#define DEV_SUB_CLASS 0x00
|
||||
#define DEV_PROTOCOL 0x00
|
||||
|
||||
#define USB_SIZ_STRING_SERIAL 0x1A
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** Descriptor for the Usb device. */
|
||||
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DESC__C__ */
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*!
|
||||
* \file msc_flash.c
|
||||
*
|
||||
* \brief Target fatfs flash implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "msc_flash.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
uint8_t spim_init = false;
|
||||
|
||||
#define FLASH_SECTOR_ALIGN(address) \
|
||||
((uint32_t)(address) & ~(FAT_FLASH_SECTOR_SIZE - 1))
|
||||
#define FLASH_SECTOR_OFFSET(address) \
|
||||
((uint32_t)(address) & (FAT_FLASH_SECTOR_SIZE - 1))
|
||||
|
||||
static uint8_t dataBuffer[FAT_FLASH_SECTOR_SIZE] = {0};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/**
|
||||
* @brief FatFs flash read id
|
||||
* @param void
|
||||
* @retval uint32_t - id
|
||||
*/
|
||||
uint32_t Fat_Flash_ReadID(void)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
DEBUG("id\r");
|
||||
if (XR_OK == spi_flash_rdid(XC_SPI0, (uint8_t *)&id)) {
|
||||
DEBUG("read id :0x%08x\r\n", id);
|
||||
return id;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash chip erase
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_ChipErase(void)
|
||||
{
|
||||
uint32_t offset_cnt =
|
||||
(FAT_FLASH_END_ADDR - FAT_FLASH_START_ADDR + 1) / FAT_FLASH_SECTOR_SIZE;
|
||||
|
||||
for (uint32_t i = 0; i < offset_cnt; i++) {
|
||||
if (XR_OK !=
|
||||
xc_spi_flash_erase_sector(XC_SPI0, FAT_FLASH_START_ADDR +
|
||||
i * FAT_FLASH_SECTOR_SIZE))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash sector erase
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_SectorErase(uint32_t address)
|
||||
{
|
||||
if (XR_OK == xc_spi_flash_erase_sector(XC_SPI0, address))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash write data
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_WriteData(uint32_t address, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
uint16_t writeLen, pageOff;
|
||||
|
||||
while (length > 0) {
|
||||
pageOff = FLASH_PAGE_SIZE - (address % FLASH_PAGE_SIZE);
|
||||
writeLen = length > pageOff ? pageOff : length;
|
||||
|
||||
if (XR_OK == spi_write_bytes(XC_SPI0, address, buffer, writeLen)) {
|
||||
length -= writeLen;
|
||||
address += writeLen;
|
||||
buffer += writeLen;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash read data
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_ReadData(uint32_t address, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
if (XR_OK == spi_flash_read(XC_SPI0, address, buffer, length))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash data are write in units of 512 bytes
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_Write_512B(uint32_t address, uint8_t count, uint8_t *data)
|
||||
{
|
||||
uint32_t sectorAddress;
|
||||
uint32_t sectorOffset;
|
||||
|
||||
address += FAT_FLASH_START_ADDR;
|
||||
if (address >= FAT_FLASH_END_ADDR)
|
||||
return false;
|
||||
|
||||
// count *= 2;
|
||||
while (count > 0) {
|
||||
sectorAddress = FLASH_SECTOR_ALIGN(address);
|
||||
sectorOffset = FLASH_SECTOR_OFFSET(address);
|
||||
|
||||
Fat_Flash_ReadData(sectorAddress, dataBuffer, FAT_FLASH_SECTOR_SIZE);
|
||||
Fat_Flash_SectorErase(address);
|
||||
|
||||
while (count > 0) {
|
||||
memcpy(dataBuffer + sectorOffset, data, DISK_UNIT_SIZE);
|
||||
data += DISK_UNIT_SIZE;
|
||||
address += DISK_UNIT_SIZE;
|
||||
count -= 1;
|
||||
sectorOffset += DISK_UNIT_SIZE;
|
||||
|
||||
if ((sectorOffset & (FAT_FLASH_SECTOR_SIZE - 1)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false == Fat_Flash_WriteData(sectorAddress, dataBuffer,
|
||||
FAT_FLASH_SECTOR_SIZE))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FatFs flash data are read in units of 512 bytes
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Fat_Flash_Read_512B(uint32_t address, uint8_t count, uint8_t *data)
|
||||
{
|
||||
address += FAT_FLASH_START_ADDR;
|
||||
if (address >= FAT_FLASH_END_ADDR)
|
||||
return false;
|
||||
|
||||
// count *= 2;
|
||||
while (count--) {
|
||||
if (true == Fat_Flash_ReadData(address, data, (DISK_UNIT_SIZE))) {
|
||||
data += (DISK_UNIT_SIZE);
|
||||
address += (DISK_UNIT_SIZE);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*----------------------------- Disk Map -----------------------------------*/
|
||||
/**
|
||||
* @brief Disk init
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Disk_Init(void)
|
||||
{
|
||||
if (spim_init == false) {
|
||||
SPI_Flash_Init();
|
||||
spim_init = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disk erase
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Disk_Erase(void)
|
||||
{
|
||||
if (true == Fat_Flash_ChipErase())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disk unit size
|
||||
* @param void
|
||||
* @retval uint16_t - size
|
||||
*/
|
||||
uint16_t Disk_UnitSize(void) { return DISK_UNIT_SIZE; }
|
||||
|
||||
/**
|
||||
* @brief Disk unit count
|
||||
* @param void
|
||||
* @retval uint32_t - count
|
||||
*/
|
||||
uint32_t Disk_UnitCount(void)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
count = (FAT_FLASH_END_ADDR - FAT_FLASH_START_ADDR + 1) /
|
||||
FAT_FLASH_PAGE_SIZE / 2;
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disk unit data read
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Disk_UnitRead(uint32_t unitAddr, uint16_t unitCount, uint8_t *data)
|
||||
{
|
||||
if (true == Fat_Flash_Read_512B(unitAddr * 512, unitCount, data))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disk unit data write
|
||||
* @param void
|
||||
* @retval bool - true or false
|
||||
*/
|
||||
bool Disk_UnitWrite(uint32_t unitAddr, uint16_t unitCount, uint8_t *data)
|
||||
{
|
||||
if (true == Fat_Flash_Write_512B(unitAddr * 512, unitCount, data))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -0,0 +1,72 @@
|
||||
/*!
|
||||
* \file msc_flash.h
|
||||
*
|
||||
* \brief Target msc flash implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MSC_FLASH_H__
|
||||
#define __MSC_FLASH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xc6xxx_hal_spi.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define FAT_FLASH_ID 0x12408500 //0x00136085
|
||||
|
||||
#define FAT_FLASH_PAGE_SIZE 256U
|
||||
#define FAT_FLASH_SECTOR_SIZE 4096u
|
||||
|
||||
#define FAT_FLASH_START_ADDR 0x20000 //0x40000
|
||||
#define FAT_FLASH_END_ADDR 0x40000 //0x7FFFF
|
||||
|
||||
#define DISK_UNIT_SIZE 512U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
uint32_t Fat_Flash_ReadID( void );
|
||||
bool Disk_Init( void );
|
||||
bool Disk_Erase( void );
|
||||
uint16_t Disk_UnitSize( void );
|
||||
uint32_t Disk_UnitCount( void );
|
||||
bool Disk_UnitRead( uint32_t unitAddr, uint16_t unitCount, uint8_t *data );
|
||||
bool Disk_UnitWrite( uint32_t unitAddr, uint16_t unitCount, uint8_t *data );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*!
|
||||
* \file usb_device.c
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usb_device.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usbd_storage_if.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Device Core handle declaration. */
|
||||
USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief This function handles USB On The Go FS global interrupt.
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
|
||||
|
||||
/**
|
||||
* @brief Init USB device Library, add supported class and start the library
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void USB_DEVICE_Init(void)
|
||||
{
|
||||
/* Init Device Library, add supported class and start the library. */
|
||||
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_MSC_RegisterStorage(&hUsbDeviceFS,
|
||||
&USBD_Storage_Interface_fops_FS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* \file usb_device.h
|
||||
*
|
||||
* \brief Target usb device implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DEVICE_H__
|
||||
#define __USB_DEVICE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void USB_DEVICE_Init( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DEVICE_H__ */
|
||||
@@ -0,0 +1,358 @@
|
||||
/*!
|
||||
* \file usbd_desc.c
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
|
||||
* @brief Private defines.
|
||||
* @{
|
||||
*/
|
||||
#define USBD_VID 0x0483 // 1155
|
||||
#define USBD_LANGID_STRING 0x0409 // 1033
|
||||
#define USBD_MANUFACTURER_STRING "XinChip" //"XinChip"
|
||||
#define USBD_PID_FS 22314 // 17788
|
||||
#define USBD_PRODUCT_STRING_FS "XinChip Mass Storage" //"XinChip Mass Storage"
|
||||
#define USBD_CONFIGURATION_STRING_FS "MSC Config"
|
||||
#define USBD_INTERFACE_STRING_FS "MSC Interface"
|
||||
|
||||
#define USB_SIZ_BOS_DESC 0x0C
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototypes
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
static void Get_SerialNum(void);
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
|
||||
|
||||
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||
* USBD_DESC_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration for FS.
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length);
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
|
||||
USBD_FS_LangIDStrDescriptor,
|
||||
USBD_FS_ManufacturerStrDescriptor,
|
||||
USBD_FS_ProductStrDescriptor,
|
||||
USBD_FS_SerialStrDescriptor,
|
||||
USBD_FS_ConfigStrDescriptor,
|
||||
USBD_FS_InterfaceStrDescriptor
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
,
|
||||
USBD_FS_USR_BOSDescriptor
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/** USB standard device descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
|
||||
0x12, /*bLength */
|
||||
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
0x01,
|
||||
/*bcdUSB */ /* changed to USB version 2.01
|
||||
in order to support LPM L1 suspend
|
||||
resume test of USBCV3.0*/
|
||||
#else
|
||||
0x00, /*bcdUSB */
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
0x02,
|
||||
0x00, /*bDeviceClass*/
|
||||
0x00, /*bDeviceSubClass*/
|
||||
0x00, /*bDeviceProtocol*/
|
||||
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
|
||||
LOBYTE(USBD_VID), /*idVendor*/
|
||||
HIBYTE(USBD_VID), /*idVendor*/
|
||||
LOBYTE(USBD_PID_FS), /*idProduct*/
|
||||
HIBYTE(USBD_PID_FS), /*idProduct*/
|
||||
0x00, /*bcdDevice rel. 2.00*/
|
||||
0x02,
|
||||
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
|
||||
USBD_IDX_PRODUCT_STR, /*Index of product string*/
|
||||
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
|
||||
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
|
||||
};
|
||||
|
||||
/* USB_DeviceDescriptor */
|
||||
/** BOS descriptor. */
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
|
||||
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
|
||||
/* device capability*/
|
||||
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
|
||||
0x0, 0x0, 0x0};
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
|
||||
* @brief Private variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
|
||||
/** USB lang identifier descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
|
||||
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
|
||||
HIBYTE(USBD_LANGID_STRING)};
|
||||
|
||||
#if defined(__ICCARM__) /* IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif /* defined ( __ICCARM__ ) */
|
||||
/* Internal string descriptor. */
|
||||
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||
|
||||
#if defined(__ICCARM__) /*!< IAR Compiler */
|
||||
#pragma data_alignment = 4
|
||||
#endif
|
||||
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
|
||||
USB_SIZ_STRING_SERIAL,
|
||||
USB_DESC_TYPE_STRING,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Return the device descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_DeviceDesc);
|
||||
return USBD_FS_DeviceDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the LangID string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_LangIDDesc);
|
||||
return USBD_LangIDDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the product string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the manufacturer string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the serial number string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
UNUSED(speed);
|
||||
*length = USB_SIZ_STRING_SERIAL;
|
||||
|
||||
/* Update the serial number string descriptor with the data from the unique
|
||||
* ID */
|
||||
Get_SerialNum();
|
||||
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
|
||||
|
||||
/* USER CODE END USBD_FS_SerialStrDescriptor */
|
||||
return (uint8_t *)USBD_StringSerial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the configuration string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
if (speed == USBD_SPEED_HIGH) {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the interface string descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
|
||||
uint16_t *length)
|
||||
{
|
||||
if (speed == 0) {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
} else {
|
||||
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
|
||||
length);
|
||||
}
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
/**
|
||||
* @brief Return the BOS descriptor
|
||||
* @param speed : Current device speed
|
||||
* @param length : Pointer to data length variable
|
||||
* @retval Pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
|
||||
{
|
||||
INFO("\n");
|
||||
UNUSED(speed);
|
||||
*length = sizeof(USBD_FS_BOSDesc);
|
||||
return (uint8_t *)USBD_FS_BOSDesc;
|
||||
}
|
||||
#endif /* (USBD_LPM_ENABLED == 1) */
|
||||
|
||||
/**
|
||||
* @brief Create the serial number string descriptor
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void Get_SerialNum(void)
|
||||
{
|
||||
uint32_t deviceserial0, deviceserial1; //, deviceserial2;
|
||||
|
||||
// deviceserial0 = *(uint32_t *) DEVICE_ID1;
|
||||
// deviceserial1 = *(uint32_t *) DEVICE_ID2;
|
||||
// deviceserial2 = *(uint32_t *) DEVICE_ID3;
|
||||
|
||||
deviceserial0 = 0x20220902; // 5177440; //0;//5177402;
|
||||
deviceserial1 = 0x1A0000; // 1395675155; //0x001A0000;
|
||||
// deviceserial2 = //540488500; //0;
|
||||
|
||||
// deviceserial0 += deviceserial2;
|
||||
|
||||
if (deviceserial0 != 0) {
|
||||
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
|
||||
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert Hex 32Bits value into char
|
||||
* @param value: value to convert
|
||||
* @param pbuf: pointer to the buffer
|
||||
* @param len: buffer length
|
||||
* @retval None
|
||||
*/
|
||||
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
if (((value >> 28)) < 0xA) {
|
||||
pbuf[2 * idx] = (value >> 28) + '0';
|
||||
} else {
|
||||
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
|
||||
}
|
||||
|
||||
value = value << 4;
|
||||
|
||||
pbuf[2 * idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*!
|
||||
* \file usbd_desc.h
|
||||
*
|
||||
* \brief Target the USB device descriptors implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DESC__C__
|
||||
#define __USBD_DESC__C__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
|
||||
* @brief Constants.
|
||||
* @{
|
||||
*/
|
||||
#define DEVICE_ID1 (UID_BASE)
|
||||
#define DEVICE_ID2 (UID_BASE + 0x4)
|
||||
#define DEVICE_ID3 (UID_BASE + 0x8)
|
||||
|
||||
#define USB_SIZ_STRING_SERIAL 0x1A
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** Descriptor for the Usb device. */
|
||||
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DESC__C__ */
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
/*!
|
||||
* \file usbd_storage_if.c
|
||||
*
|
||||
* \brief Memory management layer.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_storage_if.h"
|
||||
#include "msc_flash.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/** @defgroup USBD_STORAGE_Private_Defines
|
||||
* @brief Private defines.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define STORAGE_LUN_NBR 1
|
||||
#define STORAGE_BLK_NBR 0x48
|
||||
#define STORAGE_BLK_SIZ 0x200
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Consts
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
/* USER CODE BEGIN INQUIRY_DATA_FS */
|
||||
/** USB Mass storage Standard Inquiry Data. */
|
||||
const int8_t STORAGE_Inquirydata_FS[] = {
|
||||
/* 36 */
|
||||
|
||||
/* LUN 0 */
|
||||
0x00, 0x80, 0x02, 0x02, (STANDARD_INQUIRY_DATA_LEN - 5),
|
||||
0x00, 0x00, 0x00, 'X', 'i',
|
||||
'n', 'C', 'h', 'i', 'p',
|
||||
' ', /* Manufacturer : 8 bytes */
|
||||
'P', 'r', 'o', 'd', 'u',
|
||||
'c', 't', ' ', /* Product : 16 Bytes */
|
||||
' ', ' ', ' ', ' ', ' ',
|
||||
' ', ' ', ' ', '0', '.',
|
||||
'0', '1' /* Version : 4 Bytes */
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_STORAGE_Exported_Variables
|
||||
* @brief Public variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_STORAGE_Private_FunctionPrototypes
|
||||
* @brief Private functions declaration.
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int8_t STORAGE_Init_FS(uint8_t lun);
|
||||
static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num,
|
||||
uint16_t *block_size);
|
||||
static int8_t STORAGE_IsReady_FS(uint8_t lun);
|
||||
static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
|
||||
static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
|
||||
uint16_t blk_len);
|
||||
static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
|
||||
uint16_t blk_len);
|
||||
static int8_t STORAGE_GetMaxLun_FS(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
USBD_StorageTypeDef USBD_Storage_Interface_fops_FS = {
|
||||
STORAGE_Init_FS, STORAGE_GetCapacity_FS,
|
||||
STORAGE_IsReady_FS, STORAGE_IsWriteProtected_FS,
|
||||
STORAGE_Read_FS, STORAGE_Write_FS,
|
||||
STORAGE_GetMaxLun_FS, (int8_t *)STORAGE_Inquirydata_FS};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initializes the storage unit (medium) over USB FS IP
|
||||
* @param lun: Logical unit number.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_Init_FS(uint8_t lun)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the medium capacity.
|
||||
* @param lun: Logical unit number.
|
||||
* @param block_num: Number of total block number.
|
||||
* @param block_size: Block size.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num,
|
||||
uint16_t *block_size)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
#if STORAGE_NO_FLASH
|
||||
// STORAGE_BLK_NBR;
|
||||
// STORAGE_BLK_SIZ;
|
||||
*block_num = STORAGE_BLK_NBR;
|
||||
*block_size = STORAGE_BLK_SIZ;
|
||||
|
||||
#else
|
||||
*block_num = Disk_UnitCount();
|
||||
*block_size = Disk_UnitSize();
|
||||
#endif
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the medium is ready.
|
||||
* @param lun: Logical unit number.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_IsReady_FS(uint8_t lun)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether the medium is write protected.
|
||||
* @param lun: Logical unit number.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads data from the medium.
|
||||
* @param lun: Logical unit number.
|
||||
* @param buf: data buffer.
|
||||
* @param blk_addr: Logical block address.
|
||||
* @param blk_len: Blocks number.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
|
||||
uint16_t blk_len)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
#if STORAGE_NO_FLASH
|
||||
UNUSED(buf);
|
||||
UNUSED(blk_addr);
|
||||
UNUSED(blk_len);
|
||||
// memcpy(buf, temp + (blk_addr * STORAGE_BLK_SIZ), blk_len *
|
||||
// STORAGE_BLK_SIZ);
|
||||
|
||||
#else
|
||||
Disk_UnitRead(blk_addr, blk_len, buf);
|
||||
|
||||
#endif
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data into the medium.
|
||||
* @param lun: Logical unit number.
|
||||
* @param buf: data buffer.
|
||||
* @param blk_addr: Logical block address.
|
||||
* @param blk_len: Blocks number.
|
||||
* @retval USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
|
||||
uint16_t blk_len)
|
||||
{
|
||||
UNUSED(lun);
|
||||
|
||||
#if STORAGE_NO_FLASH
|
||||
UNUSED(buf);
|
||||
UNUSED(blk_addr);
|
||||
UNUSED(blk_len);
|
||||
// memcpy(temp + (blk_addr * STORAGE_BLK_SIZ), buf, blk_len *
|
||||
// STORAGE_BLK_SIZ);
|
||||
|
||||
#else
|
||||
Disk_UnitWrite(blk_addr, blk_len, buf);
|
||||
|
||||
#endif
|
||||
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the Max Supported LUNs.
|
||||
* @param None
|
||||
* @retval Lun(s) number.
|
||||
*/
|
||||
int8_t STORAGE_GetMaxLun_FS(void) { return (STORAGE_LUN_NBR - 1); }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,73 @@
|
||||
/*!
|
||||
* \file usbd_storage_if.h
|
||||
*
|
||||
* \brief Header for usbd_storage_if.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_STORAGE_IF_H__
|
||||
#define __USBD_STORAGE_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_msc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_STORAGE_Exported_Defines USBD_STORAGE_Exported_Defines
|
||||
* @brief Defines.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define STORAGE_NO_FLASH 0U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_STORAGE_Exported_Variables USBD_STORAGE_Exported_Variables
|
||||
* @brief Public variables.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** STORAGE Interface callback. */
|
||||
extern USBD_StorageTypeDef USBD_Storage_Interface_fops_FS;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_STORAGE_IF_H__ */
|
||||
|
||||
@@ -0,0 +1,766 @@
|
||||
/*!
|
||||
* \file usbd_cdc.c
|
||||
*
|
||||
* \brief This file provides the high layer firmware functions to manage the
|
||||
* following functionalities of the USB CDC Class:
|
||||
* - Initialization and Configuration of high and low layer
|
||||
* - Enumeration as CDC Device (and enumeration for each implemented
|
||||
* memory interface)
|
||||
* - OUT/IN data transfer
|
||||
* - Command IN transfer (class requests management)
|
||||
* - Error management
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* CDC Class Driver Description
|
||||
* ===================================================================
|
||||
* This driver manages the "Universal Serial Bus Class Definitions for
|
||||
* Communications Devices Revision 1.2 November 16, 2007" and the sub-protocol
|
||||
* specification of "Universal Serial Bus Communications Class Subclass
|
||||
* Specification for PSTN Devices Revision 1.2 February 9, 2007" This driver
|
||||
* implements the following aspects of the specification:
|
||||
* - Device descriptor management
|
||||
* - Configuration descriptor management
|
||||
* - Enumeration as CDC device with 2 data endpoints (IN and OUT)
|
||||
* and 1 command endpoint (IN)
|
||||
* - Requests management (as described in section 6.2 in
|
||||
* specification)
|
||||
* - Abstract Control Model compliant
|
||||
* - Union Functional collection (using 1 IN endpoint for control)
|
||||
* - Data interface class
|
||||
*
|
||||
* These aspects may be enriched or modified for a specific user
|
||||
* application.
|
||||
*
|
||||
* This driver doesn't implement the following aspects of the
|
||||
* specification (but it is possible to manage these features with some
|
||||
* modifications on this driver):
|
||||
* - Any class-specific aspect relative to communication classes
|
||||
* should be managed by user application.
|
||||
* - All communication classes other than PSTN are not managed
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CDC_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
|
||||
|
||||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t
|
||||
USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CDC_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* CDC interface class callbacks structure */
|
||||
USBD_ClassTypeDef USBD_CDC = {
|
||||
USBD_CDC_Init,
|
||||
USBD_CDC_DeInit,
|
||||
USBD_CDC_Setup,
|
||||
NULL, /* EP0_TxSent */
|
||||
USBD_CDC_EP0_RxReady,
|
||||
USBD_CDC_DataIn,
|
||||
USBD_CDC_DataOut,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_CDC_GetHSCfgDesc,
|
||||
USBD_CDC_GetFSCfgDesc,
|
||||
USBD_CDC_GetOtherSpeedCfgDesc,
|
||||
USBD_CDC_GetDeviceQualifierDescriptor,
|
||||
};
|
||||
|
||||
/* USB CDC device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t
|
||||
USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = {
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength */
|
||||
0x00, 0x02, /* bNumInterfaces: 2 interfaces */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor
|
||||
describing the configuration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
/* Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoint used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Header Functional Descriptor */
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
|
||||
/* Call Management Functional Descriptor */
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
0x01, /* bDataInterface */
|
||||
|
||||
/* ACM Functional Descriptor */
|
||||
0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x02, /* bmCapabilities */
|
||||
|
||||
/* Union Functional Descriptor */
|
||||
0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
0x00, /* bMasterInterface: Communication class interface */
|
||||
0x01, /* bSlaveInterface0: Data Class Interface */
|
||||
|
||||
/* Endpoint 2 Descriptor */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */
|
||||
HIBYTE(CDC_CMD_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Data class interface descriptor */
|
||||
0x09, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||
0x01, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: Two endpoints used */
|
||||
0x0A, /* bInterfaceClass: CDC */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint OUT Descriptor */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
|
||||
|
||||
/* Endpoint IN Descriptor */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static uint8_t CDCInEpAdd = CDC_IN_EP;
|
||||
static uint8_t CDCOutEpAdd = CDC_OUT_EP;
|
||||
static uint8_t CDCCmdEpAdd = CDC_CMD_EP;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief USBD_CDC_Init
|
||||
* Initialize the CDC interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
USBD_CDC_HandleTypeDef *hcdc;
|
||||
|
||||
hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
|
||||
|
||||
if (hcdc == NULL) {
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef));
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_IN_PACKET_SIZE);
|
||||
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
|
||||
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Set bInterval for CMD Endpoint */
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL;
|
||||
|
||||
/* Open Command IN EP */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR,
|
||||
CDC_CMD_PACKET_SIZE);
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
hcdc->RxBuffer = NULL;
|
||||
|
||||
/* Init physical Interface components */
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
|
||||
|
||||
/* Init Xfer states */
|
||||
hcdc->TxState = 0U;
|
||||
hcdc->RxState = 0U;
|
||||
|
||||
if (hcdc->RxBuffer == NULL) {
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_Init
|
||||
* DeInitialize the CDC layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
/* Close EP IN */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCInEpAdd);
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP OUT */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCOutEpAdd);
|
||||
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close Command IN EP */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd);
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* DeInit physical Interface components */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL) {
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_Setup
|
||||
* Handle the CDC specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t len;
|
||||
uint8_t ifalt = 0U;
|
||||
uint16_t status_info = 0U;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
if (hcdc == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
if (req->wLength != 0U) {
|
||||
if ((req->bmRequest & 0x80U) != 0U) {
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->Control(req->bRequest, (uint8_t *)hcdc->data,
|
||||
req->wLength);
|
||||
|
||||
len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
|
||||
} else {
|
||||
hcdc->CmdOpCode = req->bRequest;
|
||||
hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE);
|
||||
|
||||
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data,
|
||||
hcdc->CmdLength);
|
||||
}
|
||||
} else {
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->Control(req->bRequest, (uint8_t *)req, 0U);
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
(void)USBD_CtlSendData(pdev, &ifalt, 1U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (pdev->dev_state != USBD_STATE_CONFIGURED) {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_DataIn
|
||||
* Data sent on non-control IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc;
|
||||
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
|
||||
((pdev->ep_in[epnum & 0xFU].total_length %
|
||||
hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) {
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[epnum & 0xFU].total_length = 0U;
|
||||
|
||||
/* Send ZLP */
|
||||
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
|
||||
} else {
|
||||
hcdc->TxState = 0U;
|
||||
|
||||
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->TransmitCplt != NULL) {
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_DataOut
|
||||
* Data received on non-control Out endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
/* Get the received data length */
|
||||
hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
|
||||
|
||||
/* USB data will be immediately processed, this allow next USB traffic being
|
||||
NAKed till the end of the application Xfer */
|
||||
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->Receive(hcdc->RxBuffer, &hcdc->RxLength);
|
||||
|
||||
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &hcdc->RxBuffer[0]);
|
||||
|
||||
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_EP0_RxReady
|
||||
* Handle EP0 Rx Ready event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hcdc == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if ((pdev->pUserData[pdev->classId] != NULL) &&
|
||||
(hcdc->CmdOpCode != 0xFFU)) {
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
|
||||
->Control(hcdc->CmdOpCode, (uint8_t *)hcdc->data,
|
||||
(uint16_t)hcdc->CmdLength);
|
||||
hcdc->CmdOpCode = 0xFFU;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetFSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpCmdDesc =
|
||||
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc =
|
||||
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
if (pEpCmdDesc != NULL) {
|
||||
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL) {
|
||||
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpInDesc != NULL) {
|
||||
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetHSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
// USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc,
|
||||
// CDC_CMD_EP); USBD_EpDescTypeDef *pEpOutDesc =
|
||||
// USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); USBD_EpDescTypeDef
|
||||
// *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
// if (pEpCmdDesc != NULL)
|
||||
// {
|
||||
// pEpCmdDesc->bInterval = CDC_HS_BINTERVAL;
|
||||
// }
|
||||
|
||||
// if (pEpOutDesc != NULL)
|
||||
// {
|
||||
// pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
|
||||
// }
|
||||
|
||||
// if (pEpInDesc != NULL)
|
||||
// {
|
||||
// pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
|
||||
// }
|
||||
|
||||
// *length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetOtherSpeedCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpCmdDesc =
|
||||
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc =
|
||||
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
if (pEpCmdDesc != NULL) {
|
||||
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL) {
|
||||
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpInDesc != NULL) {
|
||||
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetDeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
|
||||
|
||||
return USBD_CDC_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_RegisterInterface
|
||||
* @param pdev: device instance
|
||||
* @param fops: CD Interface callback
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_ItfTypeDef *fops)
|
||||
{
|
||||
if (fops == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_SetTxBuffer
|
||||
* @param pdev: device instance
|
||||
* @param pbuff: Tx Buffer
|
||||
* @param length: Tx Buffer length
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
if (hcdc == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc->TxBuffer = pbuff;
|
||||
hcdc->TxLength = length;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_SetRxBuffer
|
||||
* @param pdev: device instance
|
||||
* @param pbuff: Rx Buffer
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hcdc == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc->RxBuffer = pbuff;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_TransmitPacket
|
||||
* Transmit packet on IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
extern volatile uint32_t epnum_change;
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_StatusTypeDef ret = USBD_BUSY;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (hcdc->TxState == 0U) {
|
||||
|
||||
/* Tx Transfer in progress */
|
||||
hcdc->TxState = 1U;
|
||||
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[epnum & 0xFU].total_length = hcdc->TxLength;
|
||||
epnum_change = (epnum & 0xFU);
|
||||
|
||||
/* Transmit next packet */
|
||||
(void)USBD_LL_Transmit(pdev, epnum, hcdc->TxBuffer, hcdc->TxLength);
|
||||
|
||||
// /* Update the packet total length */
|
||||
// pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength;
|
||||
// /* Transmit next packet */
|
||||
// (void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer,
|
||||
// hcdc->TxLength);
|
||||
|
||||
ret = USBD_OK;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_ReceivePacket
|
||||
* prepare OUT Endpoint for reception
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc =
|
||||
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*!
|
||||
* \file usbd_cdc.h
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_CDC_H
|
||||
#define __USB_CDC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup usbd_cdc_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef CDC_IN_EP
|
||||
#define CDC_IN_EP 0x81U /* EP1 for data IN */
|
||||
#endif /* CDC_IN_EP */
|
||||
#ifndef CDC_OUT_EP
|
||||
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#endif /* CDC_OUT_EP */
|
||||
#ifndef CDC_CMD_EP
|
||||
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
|
||||
#endif /* CDC_CMD_EP */
|
||||
|
||||
#ifndef CDC_FS_BINTERVAL
|
||||
#define CDC_FS_BINTERVAL 0x10U
|
||||
#endif /* CDC_FS_BINTERVAL */
|
||||
|
||||
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
|
||||
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
|
||||
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
|
||||
|
||||
#define USB_CDC_CONFIG_DESC_SIZ 67U
|
||||
|
||||
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
|
||||
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
|
||||
|
||||
#define CDC_REQ_MAX_DATA_SIZE 0x7U
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* CDC definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
|
||||
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
|
||||
#define CDC_SET_COMM_FEATURE 0x02U
|
||||
#define CDC_GET_COMM_FEATURE 0x03U
|
||||
#define CDC_CLEAR_COMM_FEATURE 0x04U
|
||||
#define CDC_SET_LINE_CODING 0x20U
|
||||
#define CDC_GET_LINE_CODING 0x21U
|
||||
#define CDC_SET_CONTROL_LINE_STATE 0x22U
|
||||
#define CDC_SEND_BREAK 0x23U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t bitrate;
|
||||
uint8_t format;
|
||||
uint8_t paritytype;
|
||||
uint8_t datatype;
|
||||
} USBD_CDC_LineCodingTypeDef;
|
||||
|
||||
typedef struct _USBD_CDC_Itf
|
||||
{
|
||||
int8_t (* Init)(void);
|
||||
int8_t (* DeInit)(void);
|
||||
int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
|
||||
int8_t (* Receive)(uint8_t *Buf, uint32_t *Len);
|
||||
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
|
||||
} USBD_CDC_ItfTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[CDC_DATA_FS_MAX_PACKET_SIZE * 2U]; /* Force 32-bit alignment */
|
||||
uint8_t CmdOpCode;
|
||||
uint8_t CmdLength;
|
||||
uint8_t *RxBuffer;
|
||||
uint8_t *TxBuffer;
|
||||
uint32_t RxLength;
|
||||
uint32_t TxLength;
|
||||
|
||||
__IO uint32_t TxState;
|
||||
__IO uint32_t RxState;
|
||||
} USBD_CDC_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CDC;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_ItfTypeDef *fops);
|
||||
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length);
|
||||
|
||||
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
|
||||
|
||||
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CDC_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,264 @@
|
||||
/*!
|
||||
* \file usbd_hid.h
|
||||
*
|
||||
* \brief This file provides the HID core functions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_HID_H
|
||||
#define __USB_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_HID_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#if (HID_CLASS_MODE == HID_MOUSE) /* HID_MOUSE */
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x04U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 34U
|
||||
#elif (HID_CLASS_MODE == HID_KEYBOARD) /* HID_KEYBOARD */
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x08U
|
||||
|
||||
#define HID_EPOUT_ADDR 0x01U
|
||||
#define HID_EPOUT_SIZE 0x01U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 41U
|
||||
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
|
||||
#elif (HID_CLASS_MODE == HID_CUSTOM) /* HID_CUSTOM */
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x40U
|
||||
|
||||
#define HID_EPOUT_ADDR 0x01U
|
||||
#define HID_EPOUT_SIZE 0x40U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 41U
|
||||
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 0x40U
|
||||
|
||||
#elif ((HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM)) || \
|
||||
(HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM)))/* (HID_MOUSE | HID_CUSTOM) */
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x04U
|
||||
#endif
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x08U
|
||||
|
||||
#define HID_EPOUT_ADDR 0x01U
|
||||
#define HID_EPOUT_SIZE 0x01U
|
||||
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
|
||||
#endif
|
||||
|
||||
#define CUSTOM_HID_EPIN_ADDR 0x82U
|
||||
#define CUSTOM_HID_EPIN_SIZE 0x40U
|
||||
|
||||
#define CUSTOM_HID_EPOUT_ADDR 0x02U
|
||||
#define CUSTOM_HID_EPOUT_SIZE 0x40U
|
||||
|
||||
#define CUSTOM_HID_FS_BINTERVAL 0x5U
|
||||
|
||||
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x40U
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
#define USB_HID_CONFIG_DESC_SIZ 66U
|
||||
#endif
|
||||
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
|
||||
#define USB_HID_CONFIG_DESC_SIZ 73U
|
||||
#endif
|
||||
|
||||
|
||||
#define HID_DATAIN_EPNUM (HID_EPIN_ADDR & 0x0FU)
|
||||
#define CUSTOM_HID_DATAIN_EPNUM (CUSTOM_HID_EPIN_ADDR & 0x0FU)
|
||||
|
||||
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
|
||||
|
||||
#define HID_EP1IN_ADDR 0x81U
|
||||
#define HID_EP1IN_SIZE 0x08U
|
||||
|
||||
#define HID_EP1OUT_ADDR 0x01U
|
||||
#define HID_EP1OUT_SIZE 0x01U
|
||||
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
|
||||
|
||||
#define HID_EP2IN_ADDR 0x82U
|
||||
#define HID_EP2IN_SIZE 0x04U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 66U
|
||||
|
||||
#define HID_DATAIN_EPNUM_1 (HID_EP1IN_ADDR & 0x0FU)
|
||||
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define USB_HID_DESC_SIZ 9U
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74U
|
||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63U
|
||||
#define USBD_CUSTOM_REPORT_DESC_SIZE 34U//43U //39U//34U
|
||||
|
||||
#define HID_DESCRIPTOR_TYPE 0x21U
|
||||
#define HID_REPORT_DESC 0x22U
|
||||
|
||||
#ifndef HID_HS_BINTERVAL
|
||||
#define HID_HS_BINTERVAL 0x07U
|
||||
#endif /* HID_HS_BINTERVAL */
|
||||
|
||||
#ifndef HID_FS_BINTERVAL
|
||||
#if ((HID_CLASS_MODE== HID_MOUSE) || \
|
||||
(HID_CLASS_MODE == HID_KEYBOARD))
|
||||
#define HID_FS_BINTERVAL 0x01U
|
||||
#else
|
||||
#define HID_FS_BINTERVAL 0x01U
|
||||
#endif
|
||||
#endif /* HID_FS_BINTERVAL */
|
||||
|
||||
#define HID_REQ_SET_PROTOCOL 0x0BU
|
||||
#define HID_REQ_GET_PROTOCOL 0x03U
|
||||
|
||||
#define HID_REQ_SET_IDLE 0x0AU
|
||||
#define HID_REQ_GET_IDLE 0x02U
|
||||
|
||||
#define HID_REQ_SET_REPORT 0x09U
|
||||
#define HID_REQ_GET_REPORT 0x01U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HID_IDLE = 0,
|
||||
HID_BUSY,
|
||||
} HID_StateTypeDef;
|
||||
|
||||
#if (HID_CLASS_MODE == HID_MOUSE)
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
HID_StateTypeDef state;
|
||||
} USBD_HID_HandleTypeDef;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Report_buf[USBD_HID_OUTREPORT_BUF_SIZE];
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
uint32_t IsReportAvailable;
|
||||
HID_StateTypeDef state;
|
||||
} USBD_HID_HandleTypeDef;
|
||||
#endif
|
||||
|
||||
|
||||
//#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
|
||||
///** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
// * @{
|
||||
// */
|
||||
//typedef enum
|
||||
//{
|
||||
// CUSTOM_HID_IDLE = 0U,
|
||||
// CUSTOM_HID_BUSY,
|
||||
//} CUSTOM_HID_StateTypeDef;
|
||||
|
||||
//typedef struct
|
||||
//{
|
||||
// uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
|
||||
// uint32_t Protocol;
|
||||
// uint32_t IdleState;
|
||||
// uint32_t AltSetting;
|
||||
// uint32_t IsReportAvailable;
|
||||
// CUSTOM_HID_StateTypeDef state;
|
||||
//} USBD_CUSTOM_HID_HandleTypeDef;
|
||||
//#endif
|
||||
|
||||
/*
|
||||
* HID Class specification version 1.1
|
||||
* 6.2.1 HID Descriptor
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bHIDDescriptorType;
|
||||
uint16_t wItemLength;
|
||||
} __PACKED USBD_HIDDescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern USBD_ClassTypeDef USBD_HID;
|
||||
#if (HID_CLASS_MODE == HID_KEYBOARD)
|
||||
extern uint8_t Report_buff[1];
|
||||
#endif
|
||||
|
||||
extern uint8_t DataOut_Finished;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *report, uint16_t len);
|
||||
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_HID_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,275 @@
|
||||
/*!
|
||||
* \file usbd_hid.h
|
||||
*
|
||||
* \brief This file provides the HID core functions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_HID_H
|
||||
#define __USB_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_HID_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
|
||||
|
||||
#define HID_EP1IN_ADDR 0x81U
|
||||
#define HID_EP1IN_SIZE 0x08U
|
||||
|
||||
#define HID_EP1OUT_ADDR 0x01U
|
||||
#define HID_EP1OUT_SIZE 0x01U
|
||||
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
|
||||
|
||||
#define HID_EP2IN_ADDR 0x82U
|
||||
#define HID_EP2IN_SIZE 0x04U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 66U
|
||||
|
||||
#define HID_DATAIN_EPNUM_1 (HID_EP1IN_ADDR & 0x0FU)
|
||||
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
|
||||
|
||||
#endif
|
||||
|
||||
#if (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x04U
|
||||
|
||||
#define CUSTOM_HID_EPIN_ADDR 0x82U
|
||||
#define CUSTOM_HID_EPIN_SIZE 0x40U
|
||||
|
||||
#define CUSTOM_HID_EPOUT_ADDR 0x02U
|
||||
#define CUSTOM_HID_EPOUT_SIZE 0x40U
|
||||
|
||||
#define CUSTOM_HID_FS_BINTERVAL 0x5U
|
||||
|
||||
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x40U
|
||||
|
||||
#define HID_DATAIN_EPNUM (HID_EPIN_ADDR & 0x0FU)
|
||||
#define CUSTOM_HID_DATAIN_EPNUM (CUSTOM_HID_EPIN_ADDR & 0x0FU)
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 66U
|
||||
#endif
|
||||
|
||||
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#define HID_EPIN_SIZE 0x40U
|
||||
|
||||
#define HID_EPOUT_ADDR 0x01U
|
||||
#define HID_EPOUT_SIZE 0x40U
|
||||
|
||||
#define HID_EP2IN_ADDR 0x82U
|
||||
#define HID_EP2IN_SIZE 0x40U
|
||||
|
||||
#define HID_EP2OUT_ADDR 0x02U
|
||||
#define HID_EP2OUT_SIZE 0x40U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 73U
|
||||
//#define USB_HID_DOUBLE_CUSTOM_CONFIG_DESC_SIZ 82U
|
||||
#define USBD_HID_OUTREPORT_BUF_SIZE 0x40U
|
||||
|
||||
#define HID_DATAIN_EPNUM_1 (HID_EPIN_ADDR & 0x0FU)
|
||||
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
|
||||
#endif
|
||||
|
||||
|
||||
#define USB_HID_DESC_SIZ 9U
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74U
|
||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63U
|
||||
#define USBD_CUSTOM_REPORT_DESC_SIZE 34U
|
||||
|
||||
#define HID_DESCRIPTOR_TYPE 0x21U
|
||||
#define HID_REPORT_DESC 0x22U
|
||||
|
||||
#ifndef HID_HS_BINTERVAL
|
||||
#define HID_HS_BINTERVAL 0x07U
|
||||
#endif /* HID_HS_BINTERVAL */
|
||||
|
||||
#ifndef HID_FS_BINTERVAL
|
||||
#define HID_FS_BINTERVAL 0x01U
|
||||
#endif /* HID_FS_BINTERVAL */
|
||||
|
||||
#ifndef HID_FS_K_BINTERVAL
|
||||
#define HID_FS_K_BINTERVAL 0x0AU
|
||||
#endif /* HID_FS_BINTERVAL */
|
||||
|
||||
#ifndef HID_FS_M_BINTERVAL
|
||||
#define HID_FS_M_BINTERVAL 0x01U
|
||||
#endif /* HID_FS_BINTERVAL */
|
||||
|
||||
#define HID_REQ_SET_PROTOCOL 0x0BU
|
||||
#define HID_REQ_GET_PROTOCOL 0x03U
|
||||
|
||||
#define HID_REQ_SET_IDLE 0x0AU
|
||||
#define HID_REQ_GET_IDLE 0x02U
|
||||
|
||||
#define HID_REQ_SET_REPORT 0x09U
|
||||
#define HID_REQ_GET_REPORT 0x01U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HID_IDLE = 0,
|
||||
HID_BUSY,
|
||||
} HID_StateTypeDef;
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
HID_StateTypeDef state;
|
||||
} USBD_HID_HandleTypeDef;
|
||||
#endif
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CUSTOM_HID_IDLE = 0U,
|
||||
CUSTOM_HID_BUSY,
|
||||
} CUSTOM_HID_StateTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
uint32_t IsReportAvailable;
|
||||
CUSTOM_HID_StateTypeDef state;
|
||||
} USBD_CUSTOM_HID_HandleTypeDef;
|
||||
#endif
|
||||
|
||||
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Report_buf[USBD_HID_OUTREPORT_BUF_SIZE];
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
uint32_t IsReportAvailable;
|
||||
HID_StateTypeDef state;
|
||||
} USBD_HID_HandleTypeDef;
|
||||
#endif
|
||||
|
||||
|
||||
//#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
|
||||
///** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
// * @{
|
||||
// */
|
||||
//typedef enum
|
||||
//{
|
||||
// CUSTOM_HID_IDLE = 0U,
|
||||
// CUSTOM_HID_BUSY,
|
||||
//} CUSTOM_HID_StateTypeDef;
|
||||
|
||||
//typedef struct
|
||||
//{
|
||||
// uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
|
||||
// uint32_t Protocol;
|
||||
// uint32_t IdleState;
|
||||
// uint32_t AltSetting;
|
||||
// uint32_t IsReportAvailable;
|
||||
// CUSTOM_HID_StateTypeDef state;
|
||||
//} USBD_CUSTOM_HID_HandleTypeDef;
|
||||
//#endif
|
||||
|
||||
/*
|
||||
* HID Class specification version 1.1
|
||||
* 6.2.1 HID Descriptor
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bHIDDescriptorType;
|
||||
uint16_t wItemLength;
|
||||
} __PACKED USBD_HIDDescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern USBD_ClassTypeDef USBD_HID;
|
||||
|
||||
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
|
||||
extern uint8_t Report_buff[1];
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#if (HID_CLASS_MODE == (HID_MOUSE | HID_KEYBOARD))
|
||||
uint8_t USBD_Mouse_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
uint8_t USBD_Keyboard_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
|
||||
uint8_t USBD_Mouse_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
uint8_t USBD_Custom_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
#elif (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
|
||||
uint8_t USBD_Custom1_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
uint8_t USBD_Custom2_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
#endif
|
||||
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_HID_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,493 @@
|
||||
/*!
|
||||
* \file usbd_msc.c
|
||||
*
|
||||
* \brief This file provides all the MSC core functions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* MSC Class Description
|
||||
* ===================================================================
|
||||
* This module manages the MSC class V1.0 following the "Universal
|
||||
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT)
|
||||
Version 1.0
|
||||
* Sep. 31, 1999".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Bulk-Only Transport protocol
|
||||
* - Subclass : SCSI transparent command set (ref. SCSI Primary
|
||||
Commands - 3 (SPC-3))
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_msc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup MSC_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
|
||||
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length);
|
||||
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length);
|
||||
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup MSC_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_ClassTypeDef USBD_MSC = {
|
||||
USBD_MSC_Init,
|
||||
USBD_MSC_DeInit,
|
||||
USBD_MSC_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/
|
||||
USBD_MSC_DataIn,
|
||||
USBD_MSC_DataOut,
|
||||
NULL, /*SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_MSC_GetHSCfgDesc,
|
||||
USBD_MSC_GetFSCfgDesc,
|
||||
USBD_MSC_GetOtherSpeedCfgDesc,
|
||||
USBD_MSC_GetDeviceQualifierDescriptor,
|
||||
};
|
||||
|
||||
/* USB Mass storage device Configuration Descriptor */
|
||||
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
|
||||
__ALIGN_BEGIN static uint8_t
|
||||
USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = {
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_MSC_CONFIG_DESC_SIZ,
|
||||
|
||||
0x00, 0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x04, /* iConfiguration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/******************** Mass Storage interface ********************/
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x08, /* bInterfaceClass: MSC Class */
|
||||
0x06, /* bInterfaceSubClass : SCSI transparent*/
|
||||
0x50, /* nInterfaceProtocol */
|
||||
0x05, /* iInterface: */
|
||||
/******************** Mass Storage Endpoints ********************/
|
||||
0x07, /* Endpoint descriptor length = 7 */
|
||||
0x05, /* Endpoint descriptor type */
|
||||
MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */
|
||||
0x02, /* Bulk endpoint type */
|
||||
LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET),
|
||||
0x00, /* Polling interval in milliseconds */
|
||||
|
||||
0x07, /* Endpoint descriptor length = 7 */
|
||||
0x05, /* Endpoint descriptor type */
|
||||
MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */
|
||||
0x02, /* Bulk endpoint type */
|
||||
LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET),
|
||||
0x00 /* Polling interval in milliseconds */
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t
|
||||
USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
MSC_MAX_FS_PACKET,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
uint8_t MSCInEpAdd = MSC_EPIN_ADDR;
|
||||
uint8_t MSCOutEpAdd = MSC_EPOUT_ADDR;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief USBD_MSC_Init
|
||||
* Initialize the mass storage configuration
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: configuration index
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc;
|
||||
|
||||
hmsc = (USBD_MSC_BOT_HandleTypeDef *)USBD_malloc(
|
||||
sizeof(USBD_MSC_BOT_HandleTypeDef));
|
||||
|
||||
if (hmsc == NULL) {
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hmsc;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH) {
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK,
|
||||
MSC_MAX_HS_PACKET);
|
||||
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK,
|
||||
MSC_MAX_HS_PACKET);
|
||||
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
|
||||
} else {
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK,
|
||||
MSC_MAX_FS_PACKET);
|
||||
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK,
|
||||
MSC_MAX_FS_PACKET);
|
||||
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
|
||||
}
|
||||
|
||||
/* Init the BOT layer */
|
||||
MSC_BOT_Init(pdev);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_DeInit
|
||||
* DeInitialize the mass storage configuration
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: configuration index
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
/* Close MSC EPs */
|
||||
(void)USBD_LL_CloseEP(pdev, MSCOutEpAdd);
|
||||
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP IN */
|
||||
(void)USBD_LL_CloseEP(pdev, MSCInEpAdd);
|
||||
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Free MSC Class Resources */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL) {
|
||||
/* De-Init the BOT layer */
|
||||
MSC_BOT_DeInit(pdev);
|
||||
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_MSC_Setup
|
||||
* Handle the MSC specific requests
|
||||
* @param pdev: device instance
|
||||
* @param req: USB request
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint16_t status_info = 0U;
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
/* Class request */
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
switch (req->bRequest) {
|
||||
case BOT_GET_MAX_LUN:
|
||||
if ((req->wValue == 0U) && (req->wLength == 1U) &&
|
||||
((req->bmRequest & 0x80U) == 0x80U)) {
|
||||
hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)
|
||||
pdev->pUserData[pdev->classId])
|
||||
->GetMaxLun();
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_RESET:
|
||||
if ((req->wValue == 0U) && (req->wLength == 0U) &&
|
||||
((req->bmRequest & 0x80U) != 0x80U)) {
|
||||
MSC_BOT_Reset(pdev);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* Interface & Endpoint request */
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
hmsc->interface = (uint8_t)(req->wValue);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (req->wValue == USB_FEATURE_EP_HALT) {
|
||||
/* Flush the FIFO */
|
||||
(void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
|
||||
|
||||
/* Handle BOT error */
|
||||
MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_DataIn
|
||||
* handle data IN Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
MSC_BOT_DataIn(pdev, epnum);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_DataOut
|
||||
* handle data OUT Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
MSC_BOT_DataOut(pdev, epnum);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_GetHSCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL) {
|
||||
pEpInDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL) {
|
||||
pEpOutDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
|
||||
return USBD_MSC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_GetFSCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL) {
|
||||
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL) {
|
||||
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
|
||||
return USBD_MSC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_GetOtherSpeedCfgDesc
|
||||
* return other speed configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc =
|
||||
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL) {
|
||||
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL) {
|
||||
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
|
||||
return USBD_MSC_CfgDesc;
|
||||
}
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_MSC_DeviceQualifierDesc);
|
||||
|
||||
return USBD_MSC_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_MSC_RegisterStorage
|
||||
* @param fops: storage callback
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
|
||||
USBD_StorageTypeDef *fops)
|
||||
{
|
||||
if (fops == NULL) {
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,134 @@
|
||||
/*!
|
||||
* \file usbd_msc.h
|
||||
*
|
||||
* \brief Header for the usbd_msc.c file
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_H
|
||||
#define __USBD_MSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_msc_bot.h"
|
||||
#include "usbd_msc_scsi.h"
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_BOT_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/* MSC Class Config */
|
||||
#ifndef MSC_MEDIA_PACKET
|
||||
#define MSC_MEDIA_PACKET 512U
|
||||
#endif /* MSC_MEDIA_PACKET */
|
||||
|
||||
#define MSC_MAX_FS_PACKET 0x40U
|
||||
#define MSC_MAX_HS_PACKET 0x200U
|
||||
|
||||
#define BOT_GET_MAX_LUN 0xFE
|
||||
#define BOT_RESET 0xFF
|
||||
#define USB_MSC_CONFIG_DESC_SIZ 32
|
||||
|
||||
#ifndef MSC_EPIN_ADDR
|
||||
#define MSC_EPIN_ADDR 0x81U
|
||||
#endif /* MSC_EPIN_ADDR */
|
||||
|
||||
#ifndef MSC_EPOUT_ADDR
|
||||
#define MSC_EPOUT_ADDR 0x01U
|
||||
#endif /* MSC_EPOUT_ADDR */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USB_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
typedef struct _USBD_STORAGE
|
||||
{
|
||||
int8_t (* Init)(uint8_t lun);
|
||||
int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
|
||||
int8_t (* IsReady)(uint8_t lun);
|
||||
int8_t (* IsWriteProtected)(uint8_t lun);
|
||||
int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
|
||||
int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
|
||||
int8_t (* GetMaxLun)(void);
|
||||
int8_t *pInquiry;
|
||||
|
||||
} USBD_StorageTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t max_lun;
|
||||
uint32_t interface;
|
||||
uint8_t bot_state;
|
||||
uint8_t bot_status;
|
||||
uint32_t bot_data_length;
|
||||
uint8_t bot_data[MSC_MEDIA_PACKET];
|
||||
USBD_MSC_BOT_CBWTypeDef cbw;
|
||||
USBD_MSC_BOT_CSWTypeDef csw;
|
||||
|
||||
USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH];
|
||||
uint8_t scsi_sense_head;
|
||||
uint8_t scsi_sense_tail;
|
||||
uint8_t scsi_medium_state;
|
||||
|
||||
uint16_t scsi_blk_size;
|
||||
uint32_t scsi_blk_nbr;
|
||||
|
||||
uint32_t scsi_blk_addr;
|
||||
uint32_t scsi_blk_len;
|
||||
} USBD_MSC_BOT_HandleTypeDef;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* Structure for MSC process */
|
||||
extern USBD_ClassTypeDef USBD_MSC;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
|
||||
USBD_StorageTypeDef *fops);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_H */
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
/*!
|
||||
* \file usbd_msc_bot.c
|
||||
*
|
||||
* \brief This file provides all the BOT protocol core functions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_msc_bot.h"
|
||||
#include "usbd_ioreq.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usbd_msc_scsi.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern uint8_t MSCInEpAdd;
|
||||
extern uint8_t MSCOutEpAdd;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup MSC_BOT_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
|
||||
uint32_t len);
|
||||
static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev);
|
||||
static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief MSC_BOT_Init
|
||||
* Initialize the BOT Process
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hmsc->bot_state = USBD_BOT_IDLE;
|
||||
hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
|
||||
|
||||
hmsc->scsi_sense_tail = 0U;
|
||||
hmsc->scsi_sense_head = 0U;
|
||||
hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
|
||||
|
||||
((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Init(0U);
|
||||
|
||||
(void)USBD_LL_FlushEP(pdev, MSCOutEpAdd);
|
||||
(void)USBD_LL_FlushEP(pdev, MSCInEpAdd);
|
||||
|
||||
/* Prepare EP to Receive First BOT Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
|
||||
USBD_BOT_CBW_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_Reset
|
||||
* Reset the BOT Machine
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hmsc->bot_state = USBD_BOT_IDLE;
|
||||
hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
|
||||
|
||||
(void)USBD_LL_ClearStallEP(pdev, MSCInEpAdd);
|
||||
(void)USBD_LL_ClearStallEP(pdev, MSCOutEpAdd);
|
||||
|
||||
/* Prepare EP to Receive First BOT Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
|
||||
USBD_BOT_CBW_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_DeInit
|
||||
* DeInitialize the BOT Machine
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc != NULL) {
|
||||
hmsc->bot_state = USBD_BOT_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_DataIn
|
||||
* Handle BOT IN data stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(epnum);
|
||||
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hmsc->bot_state) {
|
||||
case USBD_BOT_DATA_IN:
|
||||
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_BOT_SEND_DATA:
|
||||
case USBD_BOT_LAST_DATA_IN:
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief MSC_BOT_DataOut
|
||||
* Process MSC OUT data
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(epnum);
|
||||
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hmsc->bot_state) {
|
||||
case USBD_BOT_IDLE:
|
||||
MSC_BOT_CBW_Decode(pdev);
|
||||
break;
|
||||
|
||||
case USBD_BOT_DATA_OUT:
|
||||
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_CBW_Decode
|
||||
* Decode the CBW command and set the BOT state machine accordingly
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hmsc->csw.dTag = hmsc->cbw.dTag;
|
||||
hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
|
||||
|
||||
if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) ||
|
||||
(hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
|
||||
(hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) ||
|
||||
(hmsc->cbw.bCBLength > 16U)) {
|
||||
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
|
||||
|
||||
hmsc->bot_status = USBD_BOT_STATUS_ERROR;
|
||||
MSC_BOT_Abort(pdev);
|
||||
} else {
|
||||
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
|
||||
// if (hmsc->bot_state == USBD_BOT_NO_DATA)
|
||||
// {
|
||||
// MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
|
||||
// }
|
||||
// else
|
||||
{
|
||||
MSC_BOT_Abort(pdev);
|
||||
}
|
||||
}
|
||||
/* Burst xfer handled internally */
|
||||
else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
|
||||
(hmsc->bot_state != USBD_BOT_DATA_OUT) &&
|
||||
(hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) {
|
||||
if (hmsc->bot_data_length > 0U) {
|
||||
MSC_BOT_SendData(pdev, hmsc->bot_data, hmsc->bot_data_length);
|
||||
} else if (hmsc->bot_data_length == 0U) {
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
|
||||
} else {
|
||||
MSC_BOT_Abort(pdev);
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_SendData
|
||||
* Send the requested data
|
||||
* @param pdev: device instance
|
||||
* @param buf: pointer to data buffer
|
||||
* @param len: Data Length
|
||||
* @retval None
|
||||
*/
|
||||
static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
|
||||
uint32_t len)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
uint32_t length;
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
length = MIN(hmsc->cbw.dDataLength, len);
|
||||
|
||||
hmsc->csw.dDataResidue -= len;
|
||||
hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
|
||||
hmsc->bot_state = USBD_BOT_SEND_DATA;
|
||||
|
||||
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, pbuf, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_SendCSW
|
||||
* Send the Command Status Wrapper
|
||||
* @param pdev: device instance
|
||||
* @param status : CSW status
|
||||
* @retval None
|
||||
*/
|
||||
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
|
||||
hmsc->csw.bStatus = CSW_Status;
|
||||
hmsc->bot_state = USBD_BOT_IDLE;
|
||||
|
||||
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, (uint8_t *)&hmsc->csw,
|
||||
USBD_BOT_CSW_LENGTH);
|
||||
|
||||
/* Prepare EP to Receive next Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
|
||||
USBD_BOT_CBW_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_Abort
|
||||
* Abort the current transfer
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((hmsc->cbw.bmFlags == 0U) && (hmsc->cbw.dDataLength != 0U) &&
|
||||
(hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) {
|
||||
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
|
||||
}
|
||||
|
||||
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
|
||||
|
||||
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
|
||||
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
|
||||
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MSC_BOT_CplClrFeature
|
||||
* Complete the clear feature request
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc =
|
||||
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hmsc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
|
||||
{
|
||||
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
|
||||
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
|
||||
} else if (((epnum & 0x80U) == 0x80U) &&
|
||||
(hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) {
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,138 @@
|
||||
/*!
|
||||
* \file usbd_msc_bot.h
|
||||
*
|
||||
* \brief Header for the usbd_msc_bot.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_BOT_H
|
||||
#define __USBD_MSC_BOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define USBD_BOT_IDLE 0U /* Idle state */
|
||||
#define USBD_BOT_DATA_OUT 1U /* Data Out state */
|
||||
#define USBD_BOT_DATA_IN 2U /* Data In state */
|
||||
#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */
|
||||
#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */
|
||||
#define USBD_BOT_NO_DATA 5U /* No data Stage */
|
||||
|
||||
#define USBD_BOT_CBW_SIGNATURE 0x43425355U
|
||||
#define USBD_BOT_CSW_SIGNATURE 0x53425355U
|
||||
#define USBD_BOT_CBW_LENGTH 31U
|
||||
#define USBD_BOT_CSW_LENGTH 13U
|
||||
#define USBD_BOT_MAX_DATA 256U
|
||||
|
||||
/* CSW Status Definitions */
|
||||
#define USBD_CSW_CMD_PASSED 0x00U
|
||||
#define USBD_CSW_CMD_FAILED 0x01U
|
||||
#define USBD_CSW_PHASE_ERROR 0x02U
|
||||
|
||||
/* BOT Status */
|
||||
#define USBD_BOT_STATUS_NORMAL 0U
|
||||
#define USBD_BOT_STATUS_RECOVERY 1U
|
||||
#define USBD_BOT_STATUS_ERROR 2U
|
||||
|
||||
|
||||
#define USBD_DIR_IN 0U
|
||||
#define USBD_DIR_OUT 1U
|
||||
#define USBD_BOTH_DIR 2U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup MSC_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataLength;
|
||||
uint8_t bmFlags;
|
||||
uint8_t bLUN;
|
||||
uint8_t bCBLength;
|
||||
uint8_t CB[16];
|
||||
uint8_t ReservedForAlign;
|
||||
} USBD_MSC_BOT_CBWTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataResidue;
|
||||
uint8_t bStatus;
|
||||
uint8_t ReservedForAlign[3];
|
||||
} USBD_MSC_BOT_CSWTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
|
||||
* @{
|
||||
*/
|
||||
void MSC_BOT_Init(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
|
||||
void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
|
||||
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev,
|
||||
uint8_t CSW_Status);
|
||||
|
||||
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_BOT_H */
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*!
|
||||
* \file usbd_msc_data.c
|
||||
*
|
||||
* \brief This file provides all the vital inquiry pages and sense data.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_msc_data.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* USB Mass storage Page 0 Inquiry Data */
|
||||
uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] = {
|
||||
0x00, 0x00, 0x00, (LENGTH_INQUIRY_PAGE00 - 4U),
|
||||
0x00, 0x80
|
||||
// 0x83 //alex revise
|
||||
};
|
||||
|
||||
/* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
|
||||
uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = {
|
||||
0x00, 0x80, 0x00, LENGTH_INQUIRY_PAGE80,
|
||||
0x20, /* Put Product Serial number */
|
||||
0x20, 0x20, 0x20};
|
||||
|
||||
/* USB Mass storage sense 6 Data */
|
||||
uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {
|
||||
0x22, 0x00, 0x00, 0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/* USB Mass storage sense 10 Data */
|
||||
uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = {
|
||||
0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* \file usbd_msc_data.h
|
||||
*
|
||||
* \brief Header for the usbd_msc_data.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_DATA_H
|
||||
#define __USBD_MSC_DATA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USB_INFO_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define MODE_SENSE6_LEN 0x17U
|
||||
#define MODE_SENSE10_LEN 0x1BU
|
||||
#define LENGTH_INQUIRY_PAGE00 0x06U //0x07U//0x06U alex revise
|
||||
#define LENGTH_INQUIRY_PAGE80 0x08U
|
||||
#define LENGTH_FORMAT_CAPACITIES 0x14U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_INFO_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
|
||||
extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
|
||||
extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
|
||||
extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_DATA_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,163 @@
|
||||
/*!
|
||||
* \file usbd_msc_scsi.h
|
||||
*
|
||||
* \brief Header for the usbd_msc_scsi.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_SCSI_H
|
||||
#define __USBD_MSC_SCSI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SENSE_LIST_DEEPTH 4U
|
||||
|
||||
/* SCSI Commands */
|
||||
#define SCSI_FORMAT_UNIT 0x04U
|
||||
#define SCSI_INQUIRY 0x12U
|
||||
#define SCSI_MODE_SELECT6 0x15U
|
||||
#define SCSI_MODE_SELECT10 0x55U
|
||||
#define SCSI_MODE_SENSE6 0x1AU
|
||||
#define SCSI_MODE_SENSE10 0x5AU
|
||||
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU
|
||||
#define SCSI_READ6 0x08U
|
||||
#define SCSI_READ10 0x28U
|
||||
#define SCSI_READ12 0xA8U
|
||||
#define SCSI_READ16 0x88U
|
||||
|
||||
#define SCSI_READ_CAPACITY10 0x25U
|
||||
#define SCSI_READ_CAPACITY16 0x9EU
|
||||
|
||||
#define SCSI_REQUEST_SENSE 0x03U
|
||||
#define SCSI_START_STOP_UNIT 0x1BU
|
||||
#define SCSI_TEST_UNIT_READY 0x00U
|
||||
#define SCSI_WRITE6 0x0AU
|
||||
#define SCSI_WRITE10 0x2AU
|
||||
#define SCSI_WRITE12 0xAAU
|
||||
#define SCSI_WRITE16 0x8AU
|
||||
|
||||
#define SCSI_VERIFY10 0x2FU
|
||||
#define SCSI_VERIFY12 0xAFU
|
||||
#define SCSI_VERIFY16 0x8FU
|
||||
|
||||
#define SCSI_SEND_DIAGNOSTIC 0x1DU
|
||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23U
|
||||
|
||||
#define NO_SENSE 0U
|
||||
#define RECOVERED_ERROR 1U
|
||||
#define NOT_READY 2U
|
||||
#define MEDIUM_ERROR 3U
|
||||
#define HARDWARE_ERROR 4U
|
||||
#define ILLEGAL_REQUEST 5U
|
||||
#define UNIT_ATTENTION 6U
|
||||
#define DATA_PROTECT 7U
|
||||
#define BLANK_CHECK 8U
|
||||
#define VENDOR_SPECIFIC 9U
|
||||
#define COPY_ABORTED 10U
|
||||
#define ABORTED_COMMAND 11U
|
||||
#define VOLUME_OVERFLOW 13U
|
||||
#define MISCOMPARE 14U
|
||||
|
||||
|
||||
#define INVALID_CDB 0x20U
|
||||
#define INVALID_FIELED_IN_COMMAND 0x24U
|
||||
#define PARAMETER_LIST_LENGTH_ERROR 0x1AU
|
||||
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U
|
||||
#define ADDRESS_OUT_OF_RANGE 0x21U
|
||||
#define MEDIUM_NOT_PRESENT 0x3AU
|
||||
#define MEDIUM_HAVE_CHANGED 0x28U
|
||||
#define WRITE_PROTECTED 0x27U
|
||||
#define UNRECOVERED_READ_ERROR 0x11U
|
||||
#define WRITE_FAULT 0x03U
|
||||
|
||||
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU
|
||||
#define READ_CAPACITY10_DATA_LEN 0x08U
|
||||
#define REQUEST_SENSE_DATA_LEN 0x12U
|
||||
#define STANDARD_INQUIRY_DATA_LEN 0x24U
|
||||
#define BLKVFY 0x04U
|
||||
|
||||
#define SCSI_MEDIUM_UNLOCKED 0x00U
|
||||
#define SCSI_MEDIUM_LOCKED 0x01U
|
||||
#define SCSI_MEDIUM_EJECTED 0x02U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_SCSI_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _SENSE_ITEM
|
||||
{
|
||||
uint8_t Skey;
|
||||
union
|
||||
{
|
||||
struct _ASCs
|
||||
{
|
||||
uint8_t ASC;
|
||||
uint8_t ASCQ;
|
||||
} b;
|
||||
uint8_t ASC;
|
||||
uint8_t *pData;
|
||||
} w;
|
||||
} USBD_SCSI_SenseTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd);
|
||||
|
||||
void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
|
||||
uint8_t ASC);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_SCSI_H */
|
||||
|
||||
@@ -0,0 +1,732 @@
|
||||
/*!
|
||||
* \file usbd_core.c
|
||||
*
|
||||
* \brief This file provides all the USBD core functions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief USBD_Init
|
||||
* Initializes the device stack and load the class driver
|
||||
* @param pdev: device instance
|
||||
* @param pdesc: Descriptor structure address
|
||||
* @param id: Low level core index
|
||||
* @retval None
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
|
||||
USBD_DescriptorsTypeDef *pdesc, uint8_t id)
|
||||
{
|
||||
USBD_StatusTypeDef ret;
|
||||
|
||||
/* Check whether the USB Host handle is valid */
|
||||
if (pdev == NULL) {
|
||||
#if (USBD_DEBUG_LEVEL > 1U)
|
||||
USBD_ErrLog("Invalid Device handle");
|
||||
#endif /* (USBD_DEBUG_LEVEL > 1U) */
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
/* Unlink previous class*/
|
||||
pdev->pClass[0] = NULL;
|
||||
pdev->pUserData[0] = NULL;
|
||||
|
||||
pdev->pConfDesc = NULL;
|
||||
|
||||
/* Assign USBD Descriptors */
|
||||
if (pdesc != NULL) {
|
||||
pdev->pDesc = pdesc;
|
||||
}
|
||||
|
||||
/* Set Device initial State */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
pdev->id = id;
|
||||
|
||||
/* Initialize low level driver */
|
||||
ret = USBD_LL_Init(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_DeInit
|
||||
* Re-Initialize the device library
|
||||
* @param pdev: device instance
|
||||
* @retval status: status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_StatusTypeDef ret;
|
||||
|
||||
/* Disconnect the USB Device */
|
||||
(void)USBD_LL_Stop(pdev);
|
||||
|
||||
/* Set Default State */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
|
||||
/* Free Class Resources */
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
}
|
||||
|
||||
pdev->pUserData[0] = NULL;
|
||||
|
||||
/* Free Device descriptors resources */
|
||||
pdev->pDesc = NULL;
|
||||
pdev->pConfDesc = NULL;
|
||||
|
||||
/* DeInitialize low level driver */
|
||||
ret = USBD_LL_DeInit(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_RegisterClass
|
||||
* Link class driver to Device Core.
|
||||
* @param pDevice : Device Handle
|
||||
* @param pclass: Class handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev,
|
||||
USBD_ClassTypeDef *pclass)
|
||||
{
|
||||
uint16_t len = 0U;
|
||||
|
||||
if (pclass == NULL) {
|
||||
#if (USBD_DEBUG_LEVEL > 1U)
|
||||
USBD_ErrLog("Invalid Class handle");
|
||||
#endif /* (USBD_DEBUG_LEVEL > 1U) */
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
/* link the class to the USB Device handle */
|
||||
pdev->pClass[0] = pclass;
|
||||
|
||||
/* Get Device Configuration Descriptor */
|
||||
if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL) {
|
||||
pdev->pConfDesc =
|
||||
(void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);
|
||||
}
|
||||
|
||||
/* Increment the NumClasses */
|
||||
pdev->NumClasses++;
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_Start
|
||||
* Start the USB Device Core.
|
||||
* @param pdev: Device Handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Start the low level driver */
|
||||
return USBD_LL_Start(pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_Stop
|
||||
* Stop the USB Device Core.
|
||||
* @param pdev: Device Handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Disconnect USB Device */
|
||||
(void)USBD_LL_Stop(pdev);
|
||||
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
(void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_RunTestMode
|
||||
* Launch test mode process
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
#ifdef USBD_HS_TESTMODE_ENABLE
|
||||
USBD_StatusTypeDef ret;
|
||||
|
||||
/* Run USB HS test mode */
|
||||
ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
#endif /* USBD_HS_TESTMODE_ENABLE */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_SetClassConfig
|
||||
* Configure device and start the interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: configuration index
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
/* Set configuration and Start the Class */
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_ClrClassConfig
|
||||
* Clear current configuration
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: configuration index
|
||||
* @retval status: USBD_StatusTypeDef
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
/* Clear configuration and De-initialize the Class process */
|
||||
if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U) {
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_SetupStage
|
||||
* Handle the setup stage
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
|
||||
{
|
||||
USBD_StatusTypeDef ret;
|
||||
|
||||
USBD_ParseSetupRequest(&pdev->request, psetup);
|
||||
|
||||
pdev->ep0_state = USBD_EP0_SETUP;
|
||||
|
||||
pdev->ep0_data_len = pdev->request.wLength;
|
||||
|
||||
switch (pdev->request.bmRequest & 0x1FU) {
|
||||
case USB_REQ_RECIPIENT_DEVICE:
|
||||
ret = USBD_StdDevReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_INTERFACE:
|
||||
ret = USBD_StdItfReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
ret = USBD_StdEPReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_DataOutStage
|
||||
* Handle data OUT stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @param pdata: data pointer
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
|
||||
uint8_t *pdata)
|
||||
{
|
||||
USBD_EndpointTypeDef *pep;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint8_t idx;
|
||||
|
||||
if (epnum == 0U) {
|
||||
pep = &pdev->ep_out[0];
|
||||
|
||||
if (pdev->ep0_state == USBD_EP0_DATA_OUT) {
|
||||
if (pep->rem_length > pep->maxpacket) {
|
||||
pep->rem_length -= pep->maxpacket;
|
||||
|
||||
(void)USBD_CtlContinueRx(pdev, pdata,
|
||||
MIN(pep->rem_length, pep->maxpacket));
|
||||
} else {
|
||||
// alex revise
|
||||
/* Find the class ID relative to the current request */
|
||||
switch (pdev->request.bmRequest & 0x1FU) {
|
||||
case USB_REQ_RECIPIENT_DEVICE:
|
||||
/* Device requests must be managed by the first instantiated
|
||||
class (or duplicated by all classes for simplicity) */
|
||||
idx = 0U;
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_INTERFACE:
|
||||
idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Back to the first class in case of doubt */
|
||||
idx = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx < USBD_MAX_SUPPORTED_CLASS) {
|
||||
/* Setup the class ID and route the request to the relative
|
||||
* class function */
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[idx]->EP0_RxReady != NULL) {
|
||||
pdev->classId = idx;
|
||||
pdev->pClass[idx]->EP0_RxReady(pdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
|
||||
{
|
||||
/*
|
||||
* STATUS PHASE completed, update ep0_state to idle
|
||||
*/
|
||||
pdev->ep0_state = USBD_EP0_IDLE;
|
||||
(void)USBD_LL_StallEP(pdev, 0U);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* Get the class index relative to this interface */
|
||||
idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));
|
||||
|
||||
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
|
||||
/* Call the class data out function to manage the request */
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[idx]->DataOut != NULL) {
|
||||
pdev->classId = idx;
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev,
|
||||
epnum);
|
||||
}
|
||||
}
|
||||
if (ret != USBD_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_DataInStage
|
||||
* Handle data in stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
|
||||
uint8_t *pdata)
|
||||
{
|
||||
USBD_EndpointTypeDef *pep;
|
||||
USBD_StatusTypeDef ret;
|
||||
uint8_t idx;
|
||||
|
||||
if (epnum == 0U) {
|
||||
pep = &pdev->ep_in[0];
|
||||
|
||||
if (pdev->ep0_state == USBD_EP0_DATA_IN) {
|
||||
if (pep->rem_length > pep->maxpacket) {
|
||||
pep->rem_length -= pep->maxpacket;
|
||||
|
||||
(void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length);
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
// (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
|
||||
} else {
|
||||
/* last packet is MPS multiple, so send ZLP packet */
|
||||
if ((pep->total_length % pep->maxpacket == 0) &&
|
||||
(pep->total_length >= pep->maxpacket) &&
|
||||
(pep->total_length < pdev->ep0_data_len)) {
|
||||
(void)USBD_CtlContinueSendData(pdev, NULL, 0U);
|
||||
pdev->ep0_data_len = 0U;
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
// (void)USBD_LL_PrepareReceive(pdev, 0U, NULL,
|
||||
// 0U);
|
||||
} else {
|
||||
// if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
// {
|
||||
// if (pdev->pClass[0]->EP0_TxSent != NULL)
|
||||
// {
|
||||
// pdev->classId = 0U;
|
||||
// pdev->pClass[0]->EP0_TxSent(pdev);
|
||||
// }
|
||||
// }
|
||||
// (void)USBD_LL_StallEP(pdev, 0x80U);
|
||||
(void)USBD_CtlReceiveStatus(pdev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
|
||||
(pdev->ep0_state == USBD_EP0_IDLE))
|
||||
{
|
||||
(void)USBD_LL_StallEP(pdev, 0x80U);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pdev->dev_test_mode != 0U) {
|
||||
(void)USBD_RunTestMode(pdev);
|
||||
pdev->dev_test_mode = 0U;
|
||||
}
|
||||
} else {
|
||||
/* Get the class index relative to this interface */
|
||||
idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U));
|
||||
|
||||
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
|
||||
/* Call the class data out function to manage the request */
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[idx]->DataIn != NULL) {
|
||||
pdev->classId = idx;
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev,
|
||||
epnum);
|
||||
|
||||
if (ret != USBD_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_Reset
|
||||
* Handle Reset event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
/* Upon Reset call user call back */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
pdev->ep0_state = USBD_EP0_IDLE;
|
||||
pdev->dev_config = 0U;
|
||||
pdev->dev_remote_wakeup = 0U;
|
||||
pdev->dev_test_mode = 0U;
|
||||
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
if (pdev->pClass[0]->DeInit != NULL) {
|
||||
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) !=
|
||||
USBD_OK) {
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Open EP0 OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
|
||||
pdev->ep_out[0x00U & 0xFU].is_used = 1U;
|
||||
|
||||
pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
|
||||
/* Open EP0 IN */
|
||||
(void)USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
|
||||
pdev->ep_in[0x80U & 0xFU].is_used = 1U;
|
||||
|
||||
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_SetSpeed
|
||||
* Handle Reset event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
|
||||
USBD_SpeedTypeDef speed)
|
||||
{
|
||||
pdev->dev_speed = speed;
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_Suspend
|
||||
* Handle Suspend event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
pdev->dev_old_state = pdev->dev_state;
|
||||
pdev->dev_state = USBD_STATE_SUSPENDED;
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_Resume
|
||||
* Handle Resume event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
if (pdev->dev_state == USBD_STATE_SUSPENDED) {
|
||||
pdev->dev_state = pdev->dev_old_state;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_SOF
|
||||
* Handle SOF event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* The SOF event can be distributed for all classes that support it */
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
if (pdev->pClass[0]->SOF != NULL) {
|
||||
(void)pdev->pClass[0]->SOF(pdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_IsoINIncomplete
|
||||
* Handle iso in incomplete event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
if (pdev->pClass[pdev->classId] == NULL) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL) {
|
||||
(void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum);
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_IsoOUTIncomplete
|
||||
* Handle iso out incomplete event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
if (pdev->pClass[pdev->classId] == NULL) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL) {
|
||||
(void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum);
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_DevConnected
|
||||
* Handle device connection event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_DevDisconnected
|
||||
* Handle device disconnection event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
/* Free Class Resources */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
|
||||
if (pdev->pClass[0] != NULL) {
|
||||
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) {
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CoreFindIF
|
||||
* return the class index relative to the selected interface
|
||||
* @param pdev: device instance
|
||||
* @param index : selected interface number
|
||||
* @retval index of the class using the selected interface number. OxFF if no
|
||||
* class found.
|
||||
*/
|
||||
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
UNUSED(index);
|
||||
|
||||
return 0x00U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CoreFindEP
|
||||
* return the class index relative to the selected endpoint
|
||||
* @param pdev: device instance
|
||||
* @param index : selected endpoint number
|
||||
* @retval index of the class using the selected endpoint number. 0xFF if no
|
||||
* class found.
|
||||
*/
|
||||
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
UNUSED(index);
|
||||
|
||||
return 0x00U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetEpDesc
|
||||
* This function return the Endpoint descriptor
|
||||
* @param pdev: device instance
|
||||
* @param pConfDesc: pointer to Bos descriptor
|
||||
* @param EpAddr: endpoint address
|
||||
* @retval pointer to video endpoint descriptor
|
||||
*/
|
||||
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
|
||||
{
|
||||
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
|
||||
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
|
||||
USBD_EpDescTypeDef *pEpDesc = NULL;
|
||||
uint16_t ptr;
|
||||
|
||||
if (desc->wTotalLength > desc->bLength) {
|
||||
ptr = desc->bLength;
|
||||
|
||||
while (ptr < desc->wTotalLength) {
|
||||
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
|
||||
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) {
|
||||
|
||||
pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc;
|
||||
|
||||
if (pEpDesc->bEndpointAddress == EpAddr) {
|
||||
break;
|
||||
} else {
|
||||
pEpDesc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)pEpDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetNextDesc
|
||||
* This function return the next descriptor header
|
||||
* @param buf: Buffer where the descriptor is available
|
||||
* @param ptr: data pointer inside the descriptor
|
||||
* @retval next header
|
||||
*/
|
||||
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
|
||||
{
|
||||
USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf;
|
||||
|
||||
*ptr += pnext->bLength;
|
||||
pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength);
|
||||
|
||||
return (pnext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,130 @@
|
||||
/*!
|
||||
* \file usbd_core.h
|
||||
*
|
||||
* \brief Header file for usbd_core.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CORE_H
|
||||
#define __USBD_CORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_def.h"
|
||||
#include "usbd_ioreq.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
#define USBD_SOF USBD_LL_SOF
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id);
|
||||
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
|
||||
|
||||
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index);
|
||||
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index);
|
||||
|
||||
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup);
|
||||
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
|
||||
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed);
|
||||
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev);
|
||||
|
||||
/* USBD Low Level Driver */
|
||||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
|
||||
uint8_t ep_type, uint16_t ep_mps);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
|
||||
uint8_t *pbuf, uint32_t size);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
|
||||
uint8_t *pbuf, uint32_t size);
|
||||
|
||||
#ifdef USBD_HS_TESTMODE_ENABLE
|
||||
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode);
|
||||
#endif /* USBD_HS_TESTMODE_ENABLE */
|
||||
|
||||
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
|
||||
void USBD_LL_Delay(uint32_t Delay);
|
||||
|
||||
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr);
|
||||
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CORE_H */
|
||||
|
||||
@@ -0,0 +1,886 @@
|
||||
/*!
|
||||
* \file usbd_ctlreq.c
|
||||
*
|
||||
* \brief This file provides the standard USB requests following chapter 9.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_ctlreq.h"
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
// volatile uint32_t rec_type = 0;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup USBD_REQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static void USBD_SetAddress(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static void USBD_SetFeature(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
static uint8_t USBD_GetLen(uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief USBD_StdDevReq
|
||||
* Handle standard usb device requests
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
case USB_REQ_TYPE_VENDOR:
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass[pdev->classId]->Setup(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
USBD_GetDescriptor(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
USBD_SetAddress(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
ret = USBD_SetConfig(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_CONFIGURATION:
|
||||
USBD_GetConfig(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_STATUS:
|
||||
USBD_GetStatus(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_FEATURE:
|
||||
USBD_SetFeature(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
USBD_ClrFeature(pdev, req);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_StdItfReq
|
||||
* Handle standard usb interface requests
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint8_t idx;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
case USB_REQ_TYPE_VENDOR:
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_DEFAULT:
|
||||
case USBD_STATE_ADDRESSED:
|
||||
case USBD_STATE_CONFIGURED:
|
||||
|
||||
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) {
|
||||
/* Get the class index relative to this interface */
|
||||
idx = USBD_CoreFindIF(pdev, LOBYTE(req->wIndex));
|
||||
if (((uint8_t)idx != 0xFFU) &&
|
||||
(idx < USBD_MAX_SUPPORTED_CLASS)) {
|
||||
/* Call the class data out function to manage the request */
|
||||
if (pdev->pClass[idx]->Setup != NULL) {
|
||||
pdev->classId = idx;
|
||||
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(
|
||||
pdev, req));
|
||||
} else {
|
||||
/* should never reach this condition */
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
} else {
|
||||
/* No relative interface found */
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
|
||||
if ((req->wLength == 0U) && (ret == USBD_OK)) {
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_StdEPReq
|
||||
* Handle standard usb endpoint requests
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_EndpointTypeDef *pep;
|
||||
uint8_t ep_addr;
|
||||
uint8_t idx;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
ep_addr = LOBYTE(req->wIndex);
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
case USB_REQ_TYPE_VENDOR:
|
||||
/* Get the class index relative to this endpoint */
|
||||
idx = USBD_CoreFindEP(pdev, ep_addr);
|
||||
if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
|
||||
pdev->classId = idx;
|
||||
/* Call the class data out function to manage the request */
|
||||
if (pdev->pClass[idx]->Setup != NULL) {
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->Setup(pdev, req);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
case USB_REQ_SET_FEATURE:
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
|
||||
(void)USBD_LL_StallEP(pdev, ep_addr);
|
||||
(void)USBD_LL_StallEP(pdev, 0x80U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_EP_HALT) {
|
||||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U) &&
|
||||
(req->wLength == 0x00U)) {
|
||||
(void)USBD_LL_StallEP(pdev, ep_addr);
|
||||
}
|
||||
}
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
|
||||
(void)USBD_LL_StallEP(pdev, ep_addr);
|
||||
(void)USBD_LL_StallEP(pdev, 0x80U);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_EP_HALT) {
|
||||
if ((ep_addr & 0x7FU) != 0x00U) {
|
||||
(void)USBD_LL_ClearStallEP(pdev, ep_addr);
|
||||
}
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
|
||||
/* Get the class index relative to this interface */
|
||||
idx = USBD_CoreFindEP(pdev, ep_addr);
|
||||
if (((uint8_t)idx != 0xFFU) &&
|
||||
(idx < USBD_MAX_SUPPORTED_CLASS)) {
|
||||
pdev->classId = idx;
|
||||
/* Call the class data out function to manage the
|
||||
* request */
|
||||
if (pdev->pClass[idx]->Setup != NULL) {
|
||||
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(
|
||||
pdev, req));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_STATUS:
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
pep = ((ep_addr & 0x80U) == 0x80U)
|
||||
? &pdev->ep_in[ep_addr & 0x7FU]
|
||||
: &pdev->ep_out[ep_addr & 0x7FU];
|
||||
|
||||
pep->status = 0x0000U;
|
||||
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if ((ep_addr & 0x80U) == 0x80U) {
|
||||
if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) {
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) {
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pep = ((ep_addr & 0x80U) == 0x80U)
|
||||
? &pdev->ep_in[ep_addr & 0x7FU]
|
||||
: &pdev->ep_out[ep_addr & 0x7FU];
|
||||
|
||||
if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) {
|
||||
pep->status = 0x0000U;
|
||||
} else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) {
|
||||
pep->status = 0x0001U;
|
||||
} else {
|
||||
pep->status = 0x0000U;
|
||||
}
|
||||
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetDescriptor
|
||||
* Handle Get Descriptor requests
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
uint16_t len = 0U;
|
||||
uint8_t *pbuf = NULL;
|
||||
uint8_t err = 0U;
|
||||
|
||||
switch (req->wValue >> 8) {
|
||||
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U))
|
||||
case USB_DESC_TYPE_BOS:
|
||||
if (pdev->pDesc->GetBOSDescriptor != NULL) {
|
||||
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U) */
|
||||
case USB_DESC_TYPE_DEVICE:
|
||||
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_DEVICE;
|
||||
if ((req->wLength == 64) || (pdev->dev_state == USBD_STATE_DEFAULT)) {
|
||||
// len = 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_CONFIGURATION:
|
||||
// if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
// {
|
||||
// pbuf = (uint8_t
|
||||
// *)pdev->pClass[0]->GetHSConfigDescriptor(&len); pbuf[1] =
|
||||
// USB_DESC_TYPE_CONFIGURATION;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len);
|
||||
// rec_type = DESC_TYPE_CONFIGURATION;
|
||||
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_STRING:
|
||||
switch ((uint8_t)(req->wValue)) {
|
||||
case USBD_IDX_LANGID_STR:
|
||||
if (pdev->pDesc->GetLangIDStrDescriptor != NULL) {
|
||||
pbuf =
|
||||
pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_LANGID_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_IDX_MFC_STR:
|
||||
if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) {
|
||||
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(
|
||||
pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_MFC_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_IDX_PRODUCT_STR:
|
||||
if (pdev->pDesc->GetProductStrDescriptor != NULL) {
|
||||
pbuf =
|
||||
pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_PRODUCT_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_IDX_SERIAL_STR:
|
||||
if (pdev->pDesc->GetSerialStrDescriptor != NULL) {
|
||||
pbuf =
|
||||
pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_SERIAL_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_IDX_CONFIG_STR:
|
||||
if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) {
|
||||
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(
|
||||
pdev->dev_speed, &len);
|
||||
// rec_type = DESC_TYPE_CONFIG_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_IDX_INTERFACE_STR:
|
||||
if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) {
|
||||
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed,
|
||||
&len);
|
||||
// rec_type = DESC_TYPE_INTERFACE_STR;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
||||
pbuf = NULL;
|
||||
|
||||
for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) {
|
||||
if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL) {
|
||||
pdev->classId = idx;
|
||||
pbuf = pdev->pClass[idx]->GetUsrStrDescriptor(
|
||||
pdev, LOBYTE(req->wValue), &len);
|
||||
|
||||
if (pbuf == NULL) /* This means that no class recognized the
|
||||
string index */
|
||||
{
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
#if (USBD_CLASS_USER_STRING_DESC == 1U)
|
||||
if (pdev->pDesc->GetUserStrDescriptor != NULL) {
|
||||
pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed,
|
||||
(req->wValue), &len);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
#if ((USBD_CLASS_USER_STRING_DESC == 0U) && \
|
||||
(USBD_SUPPORT_USER_STRING_DESC == 0U))
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
#endif /* (USBD_CLASS_USER_STRING_DESC == 0U) && \
|
||||
(USBD_SUPPORT_USER_STRING_DESC == 0U) */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_DEVICE_QUALIFIER:
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH) {
|
||||
pbuf =
|
||||
(uint8_t *)pdev->pClass[0]->GetDeviceQualifierDescriptor(&len);
|
||||
// rec_type = DESC_TYPE_DEVICE_QUALIFIER;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH) {
|
||||
pbuf =
|
||||
(uint8_t *)pdev->pClass[0]->GetOtherSpeedConfigDescriptor(&len);
|
||||
// rec_type = DESC_TYPE_OTHER_SPEED_CONFIGURATION;
|
||||
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err != 0U) {
|
||||
// (void)USBD_CtlSendData(pdev, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->wLength != 0U) {
|
||||
if (len != 0U) {
|
||||
len = MIN(len, req->wLength);
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// USBD_CtlError(pdev, req);
|
||||
// }
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// (void)USBD_CtlSendStatus(pdev);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_SetAddress
|
||||
* Set device address
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
uint8_t dev_addr;
|
||||
|
||||
if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) {
|
||||
dev_addr = (uint8_t)(req->wValue) & 0x7FU;
|
||||
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
|
||||
USBD_CtlError(pdev, req);
|
||||
} else {
|
||||
pdev->dev_address = dev_addr;
|
||||
(void)USBD_LL_SetUSBAddress(pdev, dev_addr);
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
|
||||
if (dev_addr != 0U) {
|
||||
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||
} else {
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_SetConfig
|
||||
* Handle Set device configuration request
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
static uint8_t cfgidx;
|
||||
|
||||
cfgidx = (uint8_t)(req->wValue);
|
||||
|
||||
if (cfgidx > USBD_MAX_NUM_CONFIGURATION) {
|
||||
USBD_CtlError(pdev, req);
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if (cfgidx != 0U) {
|
||||
pdev->dev_config = cfgidx;
|
||||
|
||||
ret = USBD_SetClassConfig(pdev, cfgidx);
|
||||
|
||||
if (ret != USBD_OK) {
|
||||
USBD_CtlError(pdev, req);
|
||||
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||
} else {
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
pdev->dev_state = USBD_STATE_CONFIGURED;
|
||||
}
|
||||
} else {
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (cfgidx == 0U) {
|
||||
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||
pdev->dev_config = cfgidx;
|
||||
(void)USBD_ClrClassConfig(pdev, cfgidx);
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
} else if (cfgidx != pdev->dev_config) {
|
||||
/* Clear old configuration */
|
||||
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
|
||||
|
||||
/* set new configuration */
|
||||
pdev->dev_config = cfgidx;
|
||||
|
||||
ret = USBD_SetClassConfig(pdev, cfgidx);
|
||||
|
||||
if (ret != USBD_OK) {
|
||||
USBD_CtlError(pdev, req);
|
||||
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
|
||||
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||
} else {
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
} else {
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
(void)USBD_ClrClassConfig(pdev, cfgidx);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetConfig
|
||||
* Handle Get device configuration request
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
if (req->wLength != 1U) {
|
||||
USBD_CtlError(pdev, req);
|
||||
} else {
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_DEFAULT:
|
||||
case USBD_STATE_ADDRESSED:
|
||||
pdev->dev_default_config = 0U;
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config,
|
||||
1U);
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetStatus
|
||||
* Handle Get Status request
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_DEFAULT:
|
||||
case USBD_STATE_ADDRESSED:
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wLength != 0x2U) {
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
|
||||
#else
|
||||
pdev->dev_config_status = 0U;
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
|
||||
if (pdev->dev_remote_wakeup != 0U) {
|
||||
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
|
||||
}
|
||||
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_SetFeature
|
||||
* Handle Set device feature request
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) {
|
||||
pdev->dev_remote_wakeup = 1U;
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
} else if (req->wValue == USB_FEATURE_TEST_MODE) {
|
||||
pdev->dev_test_mode = req->wIndex >> 8;
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
} else {
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_ClrFeature
|
||||
* Handle clear device feature request
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval status
|
||||
*/
|
||||
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
switch (pdev->dev_state) {
|
||||
case USBD_STATE_DEFAULT:
|
||||
case USBD_STATE_ADDRESSED:
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) {
|
||||
pdev->dev_remote_wakeup = 0U;
|
||||
(void)USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_ParseSetupRequest
|
||||
* Copy buffer into setup structure
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
|
||||
{
|
||||
uint8_t *pbuff = pdata;
|
||||
|
||||
req->bmRequest = *(uint8_t *)(pbuff);
|
||||
|
||||
pbuff++;
|
||||
req->bRequest = *(uint8_t *)(pbuff);
|
||||
|
||||
pbuff++;
|
||||
req->wValue = SWAPBYTE(pbuff);
|
||||
|
||||
pbuff++;
|
||||
pbuff++;
|
||||
req->wIndex = SWAPBYTE(pbuff);
|
||||
|
||||
pbuff++;
|
||||
pbuff++;
|
||||
req->wLength = SWAPBYTE(pbuff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlError
|
||||
* Handle USB low level Error
|
||||
* @param pdev: device instance
|
||||
* @param req: usb request
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
UNUSED(req);
|
||||
|
||||
(void)USBD_LL_StallEP(pdev, 0x80U);
|
||||
(void)USBD_LL_StallEP(pdev, 0U);
|
||||
// alex revise
|
||||
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
|
||||
|
||||
// DEBUG("USBD_CtlError\r\n");
|
||||
// DEBUG("TODO: \r\n");
|
||||
// DEBUG("\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetString
|
||||
* Convert Ascii string into unicode one
|
||||
* @param desc : descriptor buffer
|
||||
* @param unicode : Formatted string buffer (unicode)
|
||||
* @param len : descriptor length
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
|
||||
{
|
||||
uint8_t idx = 0U;
|
||||
uint8_t *pdesc;
|
||||
|
||||
if (desc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pdesc = desc;
|
||||
*len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U;
|
||||
|
||||
unicode[idx] = *(uint8_t *)len;
|
||||
idx++;
|
||||
unicode[idx] = USB_DESC_TYPE_STRING;
|
||||
idx++;
|
||||
|
||||
while (*pdesc != (uint8_t)'\0') {
|
||||
unicode[idx] = *pdesc;
|
||||
pdesc++;
|
||||
idx++;
|
||||
|
||||
unicode[idx] = 0U;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetLen
|
||||
* return the string length
|
||||
* @param buf : pointer to the ascii string buffer
|
||||
* @retval string length
|
||||
*/
|
||||
static uint8_t USBD_GetLen(uint8_t *buf)
|
||||
{
|
||||
uint8_t len = 0U;
|
||||
uint8_t *pbuff = buf;
|
||||
|
||||
while (*pbuff != (uint8_t)'\0') {
|
||||
len++;
|
||||
pbuff++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,58 @@
|
||||
/*!
|
||||
* \file usbd_ctlreq.h
|
||||
*
|
||||
* \brief Header file for the usbd_req.c file
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_REQUEST_H
|
||||
#define __USB_REQUEST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
|
||||
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata);
|
||||
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_REQUEST_H */
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
/*!
|
||||
* \file usbd_def.h
|
||||
*
|
||||
* \brief General defines for the usb device library
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
#ifndef __USBD_DEF_H
|
||||
#define __USBD_DEF_H
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_hal_pcd_np.h"
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USB_DEF_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#if USB_HID
|
||||
#define HID_MOUSE 0x01
|
||||
#define HID_KEYBOARD 0x02
|
||||
#define HID_CUSTOM 0x04
|
||||
#define HID_DOUBLE_CUSTOM 0X08
|
||||
#endif
|
||||
|
||||
#if USB_SINGLE_DEVICE
|
||||
|
||||
//#define HID_CLASS_MODE HID_MOUSE
|
||||
|
||||
#elif USB_COMPOSITE_DEVICE
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0U
|
||||
#endif /* NULL */
|
||||
|
||||
#ifndef USBD_MAX_NUM_CONFIGURATION
|
||||
#define USBD_MAX_NUM_CONFIGURATION 1U
|
||||
#endif /* USBD_MAX_NUM_CONFIGURATION */
|
||||
|
||||
#ifndef USBD_MAX_SUPPORTED_CLASS
|
||||
#define USBD_MAX_SUPPORTED_CLASS 1U
|
||||
#endif /* USBD_MAX_SUPPORTED_CLASS */
|
||||
|
||||
#ifndef USBD_MAX_CLASS_ENDPOINTS
|
||||
#define USBD_MAX_CLASS_ENDPOINTS 5U
|
||||
#endif /* USBD_MAX_CLASS_ENDPOINTS */
|
||||
|
||||
#ifndef USBD_MAX_CLASS_INTERFACES
|
||||
#define USBD_MAX_CLASS_INTERFACES 5U
|
||||
#endif /* USBD_MAX_CLASS_INTERFACES */
|
||||
|
||||
#ifndef USBD_LPM_ENABLED
|
||||
#define USBD_LPM_ENABLED 0U
|
||||
#endif /* USBD_LPM_ENABLED */
|
||||
|
||||
#ifndef USBD_SELF_POWERED
|
||||
#define USBD_SELF_POWERED 1U
|
||||
#endif /*USBD_SELF_POWERED */
|
||||
|
||||
#ifndef USBD_MAX_POWER
|
||||
#define USBD_MAX_POWER 0x32U /* 100 mA */
|
||||
#endif /* USBD_MAX_POWER */
|
||||
|
||||
#ifndef USBD_SUPPORT_USER_STRING_DESC
|
||||
#define USBD_SUPPORT_USER_STRING_DESC 0U
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
#ifndef USBD_CLASS_USER_STRING_DESC
|
||||
#define USBD_CLASS_USER_STRING_DESC 0U
|
||||
#endif /* USBD_CLASS_USER_STRING_DESC */
|
||||
|
||||
#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU
|
||||
#define USB_LEN_DEV_DESC 0x12U
|
||||
#define USB_LEN_CFG_DESC 0x09U
|
||||
#define USB_LEN_IF_DESC 0x09U
|
||||
#define USB_LEN_EP_DESC 0x07U
|
||||
#define USB_LEN_OTG_DESC 0x03U
|
||||
#define USB_LEN_LANGID_STR_DESC 0x04U
|
||||
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U
|
||||
|
||||
#define USBD_IDX_LANGID_STR 0x00U
|
||||
#define USBD_IDX_MFC_STR 0x01U
|
||||
#define USBD_IDX_PRODUCT_STR 0x02U
|
||||
#define USBD_IDX_SERIAL_STR 0x03U
|
||||
#define USBD_IDX_CONFIG_STR 0x04U
|
||||
#define USBD_IDX_INTERFACE_STR 0x05U
|
||||
|
||||
#define USB_REQ_TYPE_STANDARD 0x00U
|
||||
#define USB_REQ_TYPE_CLASS 0x20U
|
||||
#define USB_REQ_TYPE_VENDOR 0x40U
|
||||
#define USB_REQ_TYPE_MASK 0x60U
|
||||
|
||||
#define USB_REQ_RECIPIENT_DEVICE 0x00U
|
||||
#define USB_REQ_RECIPIENT_INTERFACE 0x01U
|
||||
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U
|
||||
#define USB_REQ_RECIPIENT_MASK 0x03U
|
||||
|
||||
#define USB_REQ_GET_STATUS 0x00U
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01U
|
||||
#define USB_REQ_SET_FEATURE 0x03U
|
||||
#define USB_REQ_SET_ADDRESS 0x05U
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06U
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07U
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08U
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09U
|
||||
#define USB_REQ_GET_INTERFACE 0x0AU
|
||||
#define USB_REQ_SET_INTERFACE 0x0BU
|
||||
#define USB_REQ_SYNCH_FRAME 0x0CU
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 0x01U
|
||||
#define USB_DESC_TYPE_CONFIGURATION 0x02U
|
||||
#define USB_DESC_TYPE_STRING 0x03U
|
||||
#define USB_DESC_TYPE_INTERFACE 0x04U
|
||||
#define USB_DESC_TYPE_ENDPOINT 0x05U
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
|
||||
#define USB_DESC_TYPE_IAD 0x0BU
|
||||
#define USB_DESC_TYPE_BOS 0x0FU
|
||||
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 0x02U
|
||||
#define USB_CONFIG_SELF_POWERED 0x01U
|
||||
|
||||
#define USB_FEATURE_EP_HALT 0x00U
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 0x01U
|
||||
#define USB_FEATURE_TEST_MODE 0x02U
|
||||
|
||||
#define USB_DEVICE_CAPABITY_TYPE 0x10U
|
||||
|
||||
#define USB_CONF_DESC_SIZE 0x09U
|
||||
#define USB_IF_DESC_SIZE 0x09U
|
||||
#define USB_EP_DESC_SIZE 0x07U
|
||||
#define USB_IAD_DESC_SIZE 0x08U
|
||||
|
||||
#define USB_HS_MAX_PACKET_SIZE 512U
|
||||
#define USB_FS_MAX_PACKET_SIZE 64U
|
||||
#define USB_MAX_EP0_SIZE 64U
|
||||
|
||||
/* Device Status */
|
||||
#define USBD_STATE_DEFAULT 0x01U
|
||||
#define USBD_STATE_ADDRESSED 0x02U
|
||||
#define USBD_STATE_CONFIGURED 0x03U
|
||||
#define USBD_STATE_SUSPENDED 0x04U
|
||||
|
||||
|
||||
/* EP0 State */
|
||||
#define USBD_EP0_IDLE 0x00U
|
||||
#define USBD_EP0_SETUP 0x01U
|
||||
#define USBD_EP0_DATA_IN 0x02U
|
||||
#define USBD_EP0_DATA_OUT 0x03U
|
||||
#define USBD_EP0_STATUS_IN 0x04U
|
||||
#define USBD_EP0_STATUS_OUT 0x05U
|
||||
#define USBD_EP0_STALL 0x06U
|
||||
|
||||
#define USBD_EP_TYPE_CTRL 0x00U
|
||||
#define USBD_EP_TYPE_ISOC 0x01U
|
||||
#define USBD_EP_TYPE_BULK 0x02U
|
||||
#define USBD_EP_TYPE_INTR 0x03U
|
||||
|
||||
#ifndef LOBYTE
|
||||
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU))
|
||||
#endif /* LOBYTE */
|
||||
|
||||
#ifndef HIBYTE
|
||||
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
|
||||
#endif /* HIBYTE */
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif /* MAX */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
//typedef enum
|
||||
//{
|
||||
// RESET = 0U,
|
||||
// SET = !RESET
|
||||
//} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
F_DISABLE = 0U,
|
||||
F_ENABLE = !F_DISABLE
|
||||
} FunctionalState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SUCCESS = 0U,
|
||||
ERROR = !SUCCESS
|
||||
} ErrorStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DESC_TYPE_DEVICE = 1,
|
||||
DESC_TYPE_CONFIGURATION,
|
||||
DESC_TYPE_LANGID_STR,
|
||||
DESC_TYPE_MFC_STR,
|
||||
DESC_TYPE_PRODUCT_STR,
|
||||
DESC_TYPE_SERIAL_STR,
|
||||
DESC_TYPE_CONFIG_STR,
|
||||
DESC_TYPE_INTERFACE_STR,
|
||||
DESC_TYPE_DEVICE_QUALIFIER,
|
||||
DESC_TYPE_OTHER_SPEED_CONFIGURATION
|
||||
} eDescriptor_Idx;
|
||||
|
||||
/** @defgroup USBD_DEF_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef struct usb_setup_req
|
||||
{
|
||||
uint8_t bmRequest;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} USBD_SetupReqTypedef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
} __PACKED USBD_ConfigDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumDeviceCaps;
|
||||
} USBD_BosDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
} __PACKED USBD_EpDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubType;
|
||||
} USBD_DescHeaderTypeDef;
|
||||
|
||||
struct _USBD_HandleTypeDef;
|
||||
|
||||
typedef struct _Device_cb
|
||||
{
|
||||
uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
/* Control Endpoints*/
|
||||
uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev);
|
||||
uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev);
|
||||
/* Class Specific Endpoints*/
|
||||
uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev);
|
||||
uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
|
||||
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length);
|
||||
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length);
|
||||
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
|
||||
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length);
|
||||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
||||
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
} USBD_ClassTypeDef;
|
||||
|
||||
/* Following USB Device Speed */
|
||||
typedef enum
|
||||
{
|
||||
USBD_SPEED_HIGH = 0U,
|
||||
USBD_SPEED_FULL = 1U,
|
||||
USBD_SPEED_LOW = 2U,
|
||||
} USBD_SpeedTypeDef;
|
||||
|
||||
/* Following USB Device status */
|
||||
typedef enum
|
||||
{
|
||||
USBD_OK = 0U,
|
||||
USBD_BUSY,
|
||||
USBD_EMEM,
|
||||
USBD_FAIL,
|
||||
} USBD_StatusTypeDef;
|
||||
|
||||
/* USB Device descriptors structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#if (USBD_CLASS_USER_STRING_DESC == 1)
|
||||
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
|
||||
#endif /* USBD_CLASS_USER_STRING_DESC */
|
||||
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
|
||||
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */
|
||||
} USBD_DescriptorsTypeDef;
|
||||
|
||||
/* USB Device handle structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t total_length;
|
||||
uint32_t rem_length;
|
||||
uint32_t maxpacket;
|
||||
uint16_t is_used;
|
||||
uint16_t bInterval;
|
||||
} USBD_EndpointTypeDef;
|
||||
|
||||
/* USB Device handle structure */
|
||||
typedef struct _USBD_HandleTypeDef
|
||||
{
|
||||
uint8_t id;
|
||||
uint32_t dev_config;
|
||||
uint32_t dev_default_config;
|
||||
uint32_t dev_config_status;
|
||||
USBD_SpeedTypeDef dev_speed;
|
||||
USBD_EndpointTypeDef ep_in[16];
|
||||
USBD_EndpointTypeDef ep_out[16];
|
||||
__IO uint32_t ep0_state;
|
||||
uint32_t ep0_data_len;
|
||||
__IO uint8_t dev_state;
|
||||
__IO uint8_t dev_old_state;
|
||||
uint8_t dev_address;
|
||||
uint8_t dev_connection_status;
|
||||
uint8_t dev_test_mode;
|
||||
uint32_t dev_remote_wakeup;
|
||||
uint8_t ConfIdx;
|
||||
|
||||
USBD_SetupReqTypedef request;
|
||||
USBD_DescriptorsTypeDef *pDesc;
|
||||
USBD_ClassTypeDef *pClass[USBD_MAX_SUPPORTED_CLASS];
|
||||
void *pClassData;
|
||||
void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS];
|
||||
void *pUserData[USBD_MAX_SUPPORTED_CLASS];
|
||||
void *pData;
|
||||
void *pBosDesc;
|
||||
void *pConfDesc;
|
||||
uint32_t classId;
|
||||
uint32_t NumClasses;
|
||||
} USBD_HandleTypeDef;
|
||||
|
||||
/* USB Device endpoint direction */
|
||||
typedef enum
|
||||
{
|
||||
OUT = 0x00,
|
||||
IN = 0x80,
|
||||
} USBD_EPDirectionTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NETWORK_CONNECTION = 0x00,
|
||||
RESPONSE_AVAILABLE = 0x01,
|
||||
CONNECTION_SPEED_CHANGE = 0x2A
|
||||
} USBD_CDC_NotifCodeTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_DEF_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
|
||||
{
|
||||
uint16_t _SwapVal, _Byte1, _Byte2;
|
||||
uint8_t *_pbuff = addr;
|
||||
|
||||
_Byte1 = *(uint8_t *)_pbuff;
|
||||
_pbuff++;
|
||||
_Byte2 = *(uint8_t *)_pbuff;
|
||||
|
||||
_SwapVal = (_Byte2 << 8) | _Byte1;
|
||||
|
||||
return _SwapVal;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||
|
||||
|
||||
#endif /* __USBD_DEF_H */
|
||||
@@ -0,0 +1,172 @@
|
||||
/*!
|
||||
* \file usbd_ioreq.c
|
||||
*
|
||||
* \brief This file provides the IO requests APIs for control endpoints.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief USBD_CtlSendData
|
||||
* send data on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to data buffer
|
||||
* @param len: length of data to be sent
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
|
||||
uint32_t len)
|
||||
{
|
||||
/* Set EP0 State */
|
||||
pdev->ep0_state = USBD_EP0_DATA_IN;
|
||||
pdev->ep_in[0].total_length = len;
|
||||
|
||||
pdev->ep_in[0].rem_length = len;
|
||||
|
||||
/* Start the transfer */
|
||||
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlContinueSendData
|
||||
* continue sending data on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to data buffer
|
||||
* @param len: length of data to be sent
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf, uint32_t len)
|
||||
{
|
||||
/* Start the next transfer */
|
||||
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlPrepareRx
|
||||
* receive data on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to data buffer
|
||||
* @param len: length of data to be received
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
|
||||
uint32_t len)
|
||||
{
|
||||
/* Set EP0 State */
|
||||
pdev->ep0_state = USBD_EP0_DATA_OUT;
|
||||
pdev->ep_out[0].total_length = len;
|
||||
|
||||
pdev->ep_out[0].rem_length = len;
|
||||
|
||||
/* Start the transfer */
|
||||
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlContinueRx
|
||||
* continue receive data on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to data buffer
|
||||
* @param len: length of data to be received
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
|
||||
uint32_t len)
|
||||
{
|
||||
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlSendStatus
|
||||
* send zero lzngth packet on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Set EP0 State */
|
||||
pdev->ep0_state = USBD_EP0_STATUS_IN;
|
||||
|
||||
/* Start the transfer */
|
||||
(void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U);
|
||||
// alex revise
|
||||
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CtlReceiveStatus
|
||||
* receive zero lzngth packet on the ctl pipe
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Set EP0 State */
|
||||
pdev->ep0_state = USBD_EP0_STATUS_OUT;
|
||||
|
||||
/* Start the transfer */
|
||||
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
|
||||
|
||||
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_GetRxCount
|
||||
* returns the received data length
|
||||
* @param pdev: device instance
|
||||
* @param ep_addr: endpoint address
|
||||
* @retval Rx Data blength
|
||||
*/
|
||||
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return USBD_LL_GetRxDataSize(pdev, ep_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* \file usbd_ioreq.h
|
||||
*
|
||||
* \brief Header file for the usbd_ioreq.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_IOREQ_H
|
||||
#define __USBD_IOREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf, uint32_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf, uint32_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf, uint32_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf, uint32_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev);
|
||||
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_IOREQ_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,589 @@
|
||||
/*!
|
||||
* \file usbd_conf.c
|
||||
*
|
||||
* \brief This file implements the board support package for the USB device
|
||||
* library
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_def.h"
|
||||
#include "xc_hal_usb.h"
|
||||
#if USB_MSC
|
||||
#include "usbd_msc.h"
|
||||
#elif USB_HID
|
||||
#include "usbd_hid.h"
|
||||
#elif USB_CDC
|
||||
#include "usbd_cdc.h"
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototypes
|
||||
------------------------------------------------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state
|
||||
*/
|
||||
__disable_irq();
|
||||
|
||||
while (1) {
|
||||
}
|
||||
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
LL Driver Callbacks (PCD -> USB Device Library)
|
||||
*******************************************************************************/
|
||||
/* MSP Init */
|
||||
void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
|
||||
{
|
||||
USB_Phy_Init();
|
||||
USB_Phy_Enable();
|
||||
USB_Current_Ctrl(0);
|
||||
// NVIC_SetPriority(USB_IRQn, 0); // MSC mode do not SET!!!!
|
||||
USB_Phy_DP_Oprt(PULL_UP);
|
||||
|
||||
HAL_Delay(100); // for(int i = 0; i < 0x455000*2; i++);
|
||||
NVIC_EnableIRQ(USB_IRQn);
|
||||
}
|
||||
|
||||
/* MSP DeInit */
|
||||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle) { USB_Phy_Deinit(); }
|
||||
|
||||
/**
|
||||
* @brief Setup stage callback
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
USBD_LL_SetupStage((USBD_HandleTypeDef *)hpcd->pData,
|
||||
(uint8_t *)hpcd->Setup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Data Out stage callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @param epnum: Endpoint number
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||
{
|
||||
USBD_LL_DataOutStage((USBD_HandleTypeDef *)hpcd->pData, epnum,
|
||||
hpcd->OUT_ep[epnum].xfer_buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Data In stage callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @param epnum: Endpoint number
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||
{
|
||||
USBD_LL_DataInStage((USBD_HandleTypeDef *)hpcd->pData, epnum,
|
||||
hpcd->IN_ep[epnum].xfer_buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SOF callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
USBD_LL_SOF((USBD_HandleTypeDef *)hpcd->pData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
|
||||
|
||||
// if ( hpcd->Init.speed == PCD_SPEED_HIGH)
|
||||
// {
|
||||
// speed = USBD_SPEED_HIGH;
|
||||
// }
|
||||
if (hpcd->Init.speed == PCD_SPEED_FULL) {
|
||||
speed = USBD_SPEED_FULL;
|
||||
} else {
|
||||
Error_Handler();
|
||||
}
|
||||
/* Set Speed. */
|
||||
USBD_LL_SetSpeed((USBD_HandleTypeDef *)hpcd->pData, speed);
|
||||
|
||||
/* Reset Device. */
|
||||
USBD_LL_Reset((USBD_HandleTypeDef *)hpcd->pData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend callback.
|
||||
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't
|
||||
* support it)
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
/* Inform USB library that core enters in suspend Mode. */
|
||||
USBD_LL_Suspend((USBD_HandleTypeDef *)hpcd->pData);
|
||||
|
||||
__HAL_PCD_GATE_PHYCLOCK(hpcd);
|
||||
/* Enter in STOP mode. */
|
||||
/* USER CODE BEGIN 2 */
|
||||
if (hpcd->Init.low_power_enable) {
|
||||
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register.
|
||||
*/
|
||||
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk |
|
||||
SCB_SCR_SLEEPONEXIT_Msk));
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume callback.
|
||||
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't
|
||||
* support it)
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
/* USER CODE BEGIN 3 */
|
||||
|
||||
/* USER CODE END 3 */
|
||||
USBD_LL_Resume((USBD_HandleTypeDef *)hpcd->pData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISOOUTIncomplete callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @param epnum: Endpoint number
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||
{
|
||||
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ISOINIncomplete callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @param epnum: Endpoint number
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||
{
|
||||
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
USBD_LL_DevConnected((USBD_HandleTypeDef *)hpcd->pData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnect callback.
|
||||
* @param hpcd: PCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
|
||||
{
|
||||
USBD_LL_DevDisconnected((USBD_HandleTypeDef *)hpcd->pData);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
LL Driver Interface (USB Device Library --> PCD)
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Initializes the low level portion of the device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Init USB Ip. */
|
||||
if (pdev->id == DEVICE_FS) {
|
||||
/* Link the driver to the stack. */
|
||||
hpcd_USB_OTG_FS.pData = pdev;
|
||||
pdev->pData = &hpcd_USB_OTG_FS;
|
||||
|
||||
hpcd_USB_OTG_FS.Instance = XC_USB_OTG_FS;
|
||||
hpcd_USB_OTG_FS.Init.dev_endpoints = 4; // 4;
|
||||
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
|
||||
hpcd_USB_OTG_FS.Init.dma_enable = F_DISABLE;
|
||||
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
|
||||
hpcd_USB_OTG_FS.Init.Sof_enable = F_DISABLE;
|
||||
hpcd_USB_OTG_FS.Init.low_power_enable = F_DISABLE;
|
||||
hpcd_USB_OTG_FS.Init.lpm_enable = F_DISABLE;
|
||||
hpcd_USB_OTG_FS.Init.vbus_sensing_enable = F_DISABLE;
|
||||
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = F_DISABLE;
|
||||
if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x40);
|
||||
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40);
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-Initializes the low level portion of the device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_DeInit(pdev->pData);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the low level portion of the device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_Start(pdev->pData);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the low level portion of the device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_Stop(pdev->pData);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens an endpoint of the low level driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @param ep_type: Endpoint type
|
||||
* @param ep_mps: Endpoint max packet size
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
|
||||
uint8_t ep_type, uint16_t ep_mps)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes an endpoint of the low level driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns Stall condition.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval Stall (1: Yes, 0: No)
|
||||
*/
|
||||
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
|
||||
|
||||
if ((ep_addr & 0x80) == 0x80) {
|
||||
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
|
||||
} else {
|
||||
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assigns a USB address to the device.
|
||||
* @param pdev: Device handle
|
||||
* @param dev_addr: Device address
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev,
|
||||
uint8_t dev_addr)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmits data over an endpoint.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @param pbuf: Pointer to data to be sent
|
||||
* @param size: Data size
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
|
||||
uint8_t *pbuf, uint32_t size)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares an endpoint for reception.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @param pbuf: Pointer to data to be received
|
||||
* @param size: Data size
|
||||
* @retval USBD status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr, uint8_t *pbuf,
|
||||
uint32_t size)
|
||||
{
|
||||
HAL_StatusTypeDef hal_status = HAL_OK;
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
|
||||
|
||||
usb_status = USBD_Get_USB_Status(hal_status);
|
||||
|
||||
return usb_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the last transferred packet size.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint number
|
||||
* @retval Received Data Size
|
||||
*/
|
||||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef *)pdev->pData, ep_addr);
|
||||
}
|
||||
|
||||
#ifdef USBD_HS_TESTMODE_ENABLE
|
||||
/**
|
||||
* @brief Set High speed Test mode.
|
||||
* @param pdev: Device handle
|
||||
* @param testmode: test mode
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev,
|
||||
uint8_t testmode)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
UNUSED(testmode);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
#endif /* USBD_HS_TESTMODE_ENABLE */
|
||||
|
||||
/**
|
||||
* @brief Static single allocation.
|
||||
* @param size: Size of allocated memory
|
||||
* @retval None
|
||||
*/
|
||||
void *USBD_static_malloc(uint32_t size)
|
||||
{
|
||||
#if USB_MSC
|
||||
static uint32_t mem[(sizeof(USBD_MSC_BOT_HandleTypeDef) / 4) +
|
||||
1]; /* On 32-bit boundary */
|
||||
#elif USB_CDC
|
||||
static uint32_t
|
||||
mem[(sizeof(USBD_CDC_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
|
||||
#elif USB_HID
|
||||
static uint32_t
|
||||
mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
|
||||
#else
|
||||
static uint32_t mem[1];
|
||||
#endif
|
||||
return mem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dummy memory free
|
||||
* @param p: Pointer to allocated memory address
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_static_free(void *p) {}
|
||||
|
||||
/**
|
||||
* @brief Delays routine for the USB Device Library.
|
||||
* @param Delay: Delay in ms
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_LL_Delay(uint32_t Delay) { HAL_Delay(Delay); }
|
||||
|
||||
/**
|
||||
* @brief Returns the USB status depending on the HAL status:
|
||||
* @param hal_status: HAL status
|
||||
* @retval USB status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
|
||||
{
|
||||
USBD_StatusTypeDef usb_status = USBD_OK;
|
||||
|
||||
switch (hal_status) {
|
||||
case HAL_OK:
|
||||
usb_status = USBD_OK;
|
||||
break;
|
||||
case HAL_ERROR:
|
||||
usb_status = USBD_FAIL;
|
||||
break;
|
||||
case HAL_BUSY:
|
||||
usb_status = USBD_BUSY;
|
||||
break;
|
||||
case HAL_TIMEOUT:
|
||||
usb_status = USBD_FAIL;
|
||||
break;
|
||||
default:
|
||||
usb_status = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
return usb_status;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*!
|
||||
* \file usbd_conf.h
|
||||
*
|
||||
* \brief Header for usbd_conf.c file.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CONF__H
|
||||
#define __USBD_CONF__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usbd_def.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
|
||||
* @brief Defines for configuration of the Usb device.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*---------- -----------*/
|
||||
#if USB_SINGLE_DEVICE
|
||||
#define USBD_MAX_NUM_INTERFACES 1U
|
||||
#elif USB_COMPOSITE_DEVICE
|
||||
#define USBD_MAX_NUM_INTERFACES 2U
|
||||
#endif
|
||||
/*---------- -----------*/
|
||||
#define USBD_MAX_NUM_CONFIGURATION 1U
|
||||
/*---------- -----------*/
|
||||
#define USBD_MAX_STR_DESC_SIZ 512U
|
||||
/*---------- -----------*/
|
||||
#define USBD_DEBUG_LEVEL 0U
|
||||
/*---------- -----------*/
|
||||
#define USBD_LPM_ENABLED 0U
|
||||
/*---------- -----------*/
|
||||
#define USBD_SELF_POWERED 1U
|
||||
/*---------- -----------*/
|
||||
#define MSC_MEDIA_PACKET 512U
|
||||
|
||||
/****************************************/
|
||||
/* #define for FS and HS identification */
|
||||
#define DEVICE_FS 0
|
||||
//#define DEVICE_HS 1
|
||||
|
||||
/* Memory management macros make sure to use static memory allocation */
|
||||
/** Alias for memory allocation. */
|
||||
#define USBD_malloc (void *)USBD_static_malloc
|
||||
|
||||
/** Alias for memory release. */
|
||||
#define USBD_free USBD_static_free
|
||||
|
||||
/** Alias for memory set. */
|
||||
#define USBD_memset memset
|
||||
|
||||
/** Alias for memory copy. */
|
||||
#define USBD_memcpy memcpy
|
||||
|
||||
/** Alias for delay. */
|
||||
#define USBD_Delay HAL_Delay
|
||||
|
||||
/* DEBUG macros */
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 0)
|
||||
#define USBD_UsrLog(...) DEBUG(__VA_ARGS__);\
|
||||
DEBUG("\n");
|
||||
#else
|
||||
#define USBD_UsrLog(...)
|
||||
#endif /* (USBD_DEBUG_LEVEL > 0U) */
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 1)
|
||||
|
||||
#define USBD_ErrLog(...) DEBUG("ERROR: ") ;\
|
||||
DEBUG(__VA_ARGS__);\
|
||||
DEBUG("\n");
|
||||
#else
|
||||
#define USBD_ErrLog(...)
|
||||
#endif /* (USBD_DEBUG_LEVEL > 1U) */
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 2)
|
||||
#define USBD_DbgLog(...) DEBUG("DEBUG : ") ;\
|
||||
DEBUG(__VA_ARGS__);\
|
||||
DEBUG("\n");
|
||||
#else
|
||||
#define USBD_DbgLog(...)
|
||||
#endif /* (USBD_DEBUG_LEVEL > 2U) */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void *USBD_static_malloc(uint32_t size);
|
||||
void USBD_static_free(void *p);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CONF__H__ */
|
||||
@@ -0,0 +1,57 @@
|
||||
/*!
|
||||
* \file rtc.h
|
||||
*
|
||||
* \brief Target rtc implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RTC_H__
|
||||
#define __RTC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern volatile uint32_t Utc_TotalSec;
|
||||
// Test val
|
||||
extern uint8_t Sec_Flag;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
void rtc_sec_handler(void);
|
||||
void RTC_Config( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RTC_H__ */
|
||||
@@ -0,0 +1,86 @@
|
||||
/*!
|
||||
* \file time_conv.h
|
||||
*
|
||||
* \brief Target time convert implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TIME_CONV_H__
|
||||
#define __TIME_CONV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "rtc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
#define YEAR_BASE 2000U
|
||||
#define TIME_ZONE (8)
|
||||
|
||||
#define M_JAN 1U
|
||||
#define M_FEB 2U
|
||||
#define M_MAR 3U
|
||||
#define M_APR 4U
|
||||
#define M_MAY 5U
|
||||
#define M_JUN 6U
|
||||
#define M_JUL 7U
|
||||
#define M_AUG 8U
|
||||
#define M_SEP 9U
|
||||
#define M_OCT 10U
|
||||
#define M_NOV 11U
|
||||
#define M_DEC 12U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef struct tm Utc_Date_t;
|
||||
typedef struct
|
||||
{
|
||||
uint8_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint8_t hour;
|
||||
uint8_t min;
|
||||
uint8_t sec;
|
||||
uint8_t week;
|
||||
} DateTime_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
DateTime_t UTC_SecToDate( uint32_t utc_sec );
|
||||
DateTime_t UTC_DateToZoneDate(int8_t zone_num, uint16_t year_base, uint8_t u_year, uint8_t u_month,
|
||||
uint8_t u_day, uint8_t u_hour, uint8_t u_min, uint8_t u_sec, uint8_t u_week);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TIME_CONV_H__ */
|
||||
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
* \file rtc.c
|
||||
*
|
||||
* \brief Target rtc implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "rtc.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------
|
||||
-----------------------------------------*/
|
||||
#define MANUF_UTC_SEC 1680516516 // rtc start time
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Constant
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
volatile uint32_t Utc_TotalSec = MANUF_UTC_SEC;
|
||||
// Test val
|
||||
uint8_t Sec_Flag = false;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief RTC handler func
|
||||
* @param xinc_drv_rtc_int_type_t - type
|
||||
* @retval void
|
||||
*/
|
||||
uint8_t Sec_Callback(void)
|
||||
{
|
||||
Utc_TotalSec += 1;
|
||||
Sec_Flag = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RTC config func
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void RTC_Config(void)
|
||||
{
|
||||
// Initialize RTC instance
|
||||
RTC_InitTypeDef rtc_cfg = {0};
|
||||
NVIC_DisableIRQ(RTC_IRQn);
|
||||
|
||||
// rtc_cfg.Date.Sec = 0;
|
||||
// rtc_cfg.Date.Min = 0;
|
||||
// rtc_cfg.Date.Hour = 18;
|
||||
// rtc_cfg.Date.Day = 93;
|
||||
// rtc_cfg.Date.Week = 1;
|
||||
rtc_cfg.Date.Sec = 0;
|
||||
rtc_cfg.Date.Min = 45;
|
||||
rtc_cfg.Date.Hour = 19;
|
||||
rtc_cfg.Date.Day = 340;
|
||||
rtc_cfg.Date.Week = 2;
|
||||
|
||||
rtc_cfg.DateLimit.SecLimit = 60;
|
||||
rtc_cfg.DateLimit.MinLimit = 60;
|
||||
rtc_cfg.DateLimit.HourLimit = 24;
|
||||
|
||||
rtc_cfg.MatchTimeEnable = false;
|
||||
|
||||
rtc_cfg.SecIT_Enable = true;
|
||||
rtc_cfg.MinIT_Enable = false;
|
||||
rtc_cfg.HourIT_Enable = false;
|
||||
rtc_cfg.DayIT_Enable = false;
|
||||
|
||||
// Rtc enable
|
||||
RTC_Init(XC_RTC, &rtc_cfg);
|
||||
RTC_Start(XC_RTC);
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*!
|
||||
* \file time_conv.c
|
||||
*
|
||||
* \brief Target time convert implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "time_conv.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief UTC second convert to date and time.
|
||||
* @details
|
||||
* @param[in] uint32_t - utc_sec
|
||||
* @param[out] void
|
||||
* @retval DateTime_t
|
||||
* @retval void
|
||||
* @par identifier
|
||||
* reserve
|
||||
* @par other
|
||||
* void
|
||||
* @par change log
|
||||
* Alex created on 2022-09-09
|
||||
*/
|
||||
DateTime_t UTC_SecToDate(uint32_t utc_sec)
|
||||
{
|
||||
Utc_Date_t tmp;
|
||||
DateTime_t ret;
|
||||
|
||||
tmp = *localtime(&utc_sec);
|
||||
|
||||
ret.year = tmp.tm_year;
|
||||
ret.month = tmp.tm_mon;
|
||||
ret.day = tmp.tm_mday;
|
||||
ret.hour = tmp.tm_hour;
|
||||
ret.min = tmp.tm_min;
|
||||
ret.sec = tmp.tm_sec;
|
||||
ret.week = tmp.tm_wday;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert the date in the UTC time zone to the date in the
|
||||
* corresponding time zone.
|
||||
* @details
|
||||
* @param[in] int8_t - zone_num
|
||||
* uint16_t - year_base
|
||||
* uint8_t - u_year, u_month, u_day, u_hour, u_min, u_sec, u_week
|
||||
* @param[out] void
|
||||
* @retval DateTime_t
|
||||
* @retval void
|
||||
* @par identifier
|
||||
* reserve
|
||||
* @par other
|
||||
* void
|
||||
* @par change log
|
||||
* Alex created on 2022-09-09
|
||||
*/
|
||||
DateTime_t UTC_DateToZoneDate(int8_t zone_num, uint16_t year_base,
|
||||
uint8_t u_year, uint8_t u_month, uint8_t u_day,
|
||||
uint8_t u_hour, uint8_t u_min, uint8_t u_sec,
|
||||
uint8_t u_week)
|
||||
{
|
||||
DateTime_t zonedate;
|
||||
int t_year = 0;
|
||||
int lastday = 0; // last day of the month
|
||||
int lastmon_lastday = 0; // last day of last month
|
||||
int8_t t_hour = 0;
|
||||
|
||||
t_year = u_year - 100 + year_base;
|
||||
zonedate.month = u_month + 1;
|
||||
zonedate.day = u_day;
|
||||
zonedate.hour = u_hour;
|
||||
zonedate.min = u_min;
|
||||
zonedate.sec = u_sec;
|
||||
zonedate.week = u_week;
|
||||
|
||||
// Determine days by month
|
||||
if (M_JAN == zonedate.month || M_MAR == zonedate.month ||
|
||||
M_MAY == zonedate.month || M_JUL == zonedate.month ||
|
||||
M_AUG == zonedate.month || M_OCT == zonedate.month ||
|
||||
M_DEC == zonedate.month) {
|
||||
lastday = 31;
|
||||
if (M_MAR == zonedate.month) {
|
||||
// leap year determination
|
||||
if ((t_year % 400 == 0) || (t_year % 4 == 0 && t_year % 100 != 0))
|
||||
lastmon_lastday = 29;
|
||||
else
|
||||
lastmon_lastday = 28;
|
||||
}
|
||||
if (M_AUG == zonedate.month)
|
||||
lastmon_lastday = 31;
|
||||
} else if (M_APR == zonedate.month || M_JUN == zonedate.month ||
|
||||
M_SEP == zonedate.month || M_NOV == zonedate.month) {
|
||||
lastday = 30;
|
||||
lastmon_lastday = 31;
|
||||
} else {
|
||||
lastmon_lastday = 31;
|
||||
// leap year determination
|
||||
if ((t_year % 400 == 0) || (t_year % 4 == 0 && t_year % 100 != 0))
|
||||
lastday = 29;
|
||||
else
|
||||
lastday = 28;
|
||||
}
|
||||
|
||||
t_hour = (int8_t)zonedate.hour + zone_num;
|
||||
if (t_hour >= 24) {
|
||||
zonedate.hour = (uint8_t)t_hour - 24;
|
||||
zonedate.day += 1;
|
||||
if (zonedate.day > lastday) {
|
||||
zonedate.day -= lastday;
|
||||
zonedate.month += 1;
|
||||
if (zonedate.month > M_DEC) {
|
||||
zonedate.month -= M_DEC;
|
||||
t_year += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (zonedate.week < 6)
|
||||
zonedate.week += 1;
|
||||
else
|
||||
zonedate.week = 0;
|
||||
} else if (t_hour < 0) {
|
||||
zonedate.hour = (uint8_t)(t_hour + 24);
|
||||
zonedate.day -= 1;
|
||||
if (zonedate.day == 0) {
|
||||
zonedate.day = lastmon_lastday;
|
||||
zonedate.month -= 1;
|
||||
if (zonedate.month == 0) {
|
||||
zonedate.month = M_DEC;
|
||||
t_year -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((zonedate.week > 0) && (zonedate.week <= 6))
|
||||
zonedate.week -= 1;
|
||||
else
|
||||
zonedate.week = 6;
|
||||
} else
|
||||
zonedate.hour = t_hour;
|
||||
|
||||
zonedate.year = t_year - year_base;
|
||||
|
||||
return zonedate;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,573 @@
|
||||
/*!
|
||||
* \file xc_hal_ll_usb_np.h
|
||||
*
|
||||
* \brief USB Low Layer HAL module driver.(use non-periodic fifo)
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
#ifndef __XC_HAL_LL_USB_NP_H
|
||||
#define __XC_HAL_LL_USB_NP_H
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_usb_bitfields.h"
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
|
||||
#if defined (USB_OTG_FS)
|
||||
|
||||
/**
|
||||
* @brief USB Mode definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USB_DEVICE_MODE = 0,
|
||||
USB_HOST_MODE = 1,
|
||||
USB_DRD_MODE = 2
|
||||
} USB_OTG_ModeTypeDef;
|
||||
|
||||
/**
|
||||
* @brief URB States definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
URB_IDLE = 0,
|
||||
URB_DONE,
|
||||
URB_NOTREADY,
|
||||
URB_NYET,
|
||||
URB_ERROR,
|
||||
URB_STALL
|
||||
} USB_OTG_URBStateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Host channel States definition
|
||||
*/
|
||||
//typedef enum
|
||||
//{
|
||||
// HC_IDLE = 0,
|
||||
// HC_XFRC,
|
||||
// HC_HALTED,
|
||||
// HC_NAK,
|
||||
// HC_NYET,
|
||||
// HC_STALL,
|
||||
// HC_XACTERR,
|
||||
// HC_BBLERR,
|
||||
// HC_DATATGLERR
|
||||
//} USB_OTG_HCStateTypeDef;
|
||||
|
||||
/**
|
||||
* @brief USB Instance Initialization Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dev_endpoints; /*!< Device Endpoints number.
|
||||
This parameter depends on the used USB core.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint32_t Host_channels; /*!< Host Channels number.
|
||||
This parameter Depends on the used USB core.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint32_t speed; /*!< USB Core speed.
|
||||
This parameter can be any value of @ref PCD_Speed/HCD_Speed
|
||||
(HCD_SPEED_xxx, HCD_SPEED_xxx) */
|
||||
|
||||
uint32_t dma_enable; /*!< Enable or disable of the USB embedded DMA used only for OTG HS. */
|
||||
|
||||
uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */
|
||||
|
||||
uint32_t phy_itface; /*!< Select the used PHY interface.
|
||||
This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module */
|
||||
|
||||
uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
|
||||
|
||||
uint32_t low_power_enable; /*!< Enable or disable the low power mode. */
|
||||
|
||||
uint32_t lpm_enable; /*!< Enable or disable Link Power Management. */
|
||||
|
||||
uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
|
||||
|
||||
uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
|
||||
|
||||
uint32_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */
|
||||
|
||||
uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
|
||||
|
||||
} USB_OTG_CfgTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t num; /*!< Endpoint number
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint8_t is_in; /*!< Endpoint direction
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t is_stall; /*!< Endpoint stall condition
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t is_iso_incomplete; /*!< Endpoint isoc condition
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t type; /*!< Endpoint type
|
||||
This parameter can be any value of @ref USB_LL_EP_Type */
|
||||
|
||||
uint8_t data_pid_start; /*!< Initial data PID
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t even_odd_frame; /*!< IFrame parity
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint16_t tx_fifo_num; /*!< Transmission FIFO number
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint32_t maxpacket; /*!< Endpoint Max packet size
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
|
||||
|
||||
uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
|
||||
|
||||
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
|
||||
|
||||
uint32_t xfer_len; /*!< Current transfer length */
|
||||
|
||||
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
|
||||
} USB_OTG_EPTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t dev_addr; /*!< USB device address.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
|
||||
|
||||
uint8_t ch_num; /*!< Host channel number.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint8_t ep_num; /*!< Endpoint number.
|
||||
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
|
||||
|
||||
uint8_t ep_is_in; /*!< Endpoint direction
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t speed; /*!< USB Host Channel speed.
|
||||
This parameter can be any value of @ref HCD_Device_Speed:
|
||||
(HCD_DEVICE_SPEED_xxx) */
|
||||
|
||||
uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
|
||||
|
||||
uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */
|
||||
|
||||
uint8_t ep_type; /*!< Endpoint Type.
|
||||
This parameter can be any value of @ref USB_LL_EP_Type */
|
||||
|
||||
uint16_t max_packet; /*!< Endpoint Max packet size.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
|
||||
|
||||
uint8_t data_pid; /*!< Initial data PID.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
|
||||
|
||||
uint32_t XferSize; /*!< OTG Channel transfer size. */
|
||||
|
||||
uint32_t xfer_len; /*!< Current transfer length. */
|
||||
|
||||
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
|
||||
|
||||
uint8_t toggle_in; /*!< IN transfer current toggle flag.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint8_t toggle_out; /*!< OUT transfer current toggle flag
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
|
||||
|
||||
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
|
||||
|
||||
uint32_t ErrCnt; /*!< Host channel error count. */
|
||||
|
||||
USB_OTG_URBStateTypeDef urb_state; /*!< URB state.
|
||||
This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
|
||||
|
||||
// USB_OTG_HCStateTypeDef state; /*!< Host Channel state.
|
||||
// This parameter can be any value of @ref USB_OTG_HCStateTypeDef */
|
||||
} USB_OTG_HCTypeDef;
|
||||
|
||||
/* =========================================================================================================================== */
|
||||
/* ================ USB ================ */
|
||||
/* =========================================================================================================================== */
|
||||
/**
|
||||
* @brief USB_OTG_Core_Registers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register 000h */
|
||||
__IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register 004h */
|
||||
__IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register 008h */
|
||||
__IO uint32_t GUSBCFG; /*!< Core USB Configuration Register 00Ch */
|
||||
__IO uint32_t GRSTCTL; /*!< Core Reset Register 010h */
|
||||
__IO uint32_t GINTSTS; /*!< Core Interrupt Register 014h */
|
||||
__IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register 018h */
|
||||
__IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register 01Ch */
|
||||
__IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register 020h */
|
||||
__IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register 024h */
|
||||
__IO uint32_t GNPTXFSIZ; /*!< Non Periodic Tx FIFO Size Register 028h */
|
||||
__IO uint32_t GNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg 02Ch */
|
||||
uint32_t Reserved30[57]; /*!< Reserved 0x30-0x110 */
|
||||
} USB_OTG_GlobalTypeDef;
|
||||
|
||||
/**
|
||||
* @brief USB_OTG_device_Registers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t DCFG; /*!< dev Configuration Register 800h */
|
||||
__IO uint32_t DCTL; /*!< dev Control Register 804h */
|
||||
__IO uint32_t DSTS; /*!< dev Status Register (RO) 808h */
|
||||
uint32_t Reserved0C; /*!< Reserved 80Ch */
|
||||
__IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask 810h */
|
||||
__IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask 814h */
|
||||
__IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg 818h */
|
||||
__IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask 81Ch */
|
||||
__I uint32_t DTKNQR1; /*!< dev IN Token Seq Reg 1 820h */
|
||||
__I uint32_t DTKNQR2; /*!< dev IN Token Seq Reg 2 824h */
|
||||
__IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register 828h */
|
||||
__IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register 82Ch */
|
||||
__I uint32_t DTKNQR3; /*!< dev IN Token Seq Reg 3 830h */
|
||||
__I uint32_t DTKNQR4; /*!< dev IN Token Seq Reg 4 834h */
|
||||
} USB_OTG_DeviceTypeDef;
|
||||
|
||||
/**
|
||||
* @brief USB_OTG_IN_Endpoint-Specific_Register
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */
|
||||
uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h */
|
||||
__IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */
|
||||
uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch */
|
||||
__IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */
|
||||
uint32_t Reserved14; /*!< Reserved 900h + (ep_num * 20h) + 14h */
|
||||
__IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */
|
||||
uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */
|
||||
} USB_OTG_INEndpointTypeDef;
|
||||
|
||||
/**
|
||||
* @brief USB_OTG_OUT_Endpoint-Specific_Registers
|
||||
*/
|
||||
/**
|
||||
* @brief USB_OTG_OUT_Endpoint-Specific_Registers
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */
|
||||
uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h */
|
||||
__IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */
|
||||
uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch */
|
||||
__IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */
|
||||
uint32_t Reserved14[5]; /*!< Reserved B00h + (ep_num * 20h) + 14h - B00h + (ep_num * 20h) + 1Ch */
|
||||
} USB_OTG_OUTEndpointTypeDef;
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define XC_USB_FS_PERIPH_BASE 0x50010000UL
|
||||
#define XC_USB_OTG_FS ((USB_OTG_GlobalTypeDef *) XC_USB_FS_PERIPH_BASE)
|
||||
|
||||
/** @defgroup USB_OTG_CORE VERSION ID
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_CORE_ID_300A 0x4F54300AU
|
||||
#define USB_OTG_CORE_ID_310A 0x4F54310AU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_Core_Mode_ USB Core Mode
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_MODE_DEVICE 0U
|
||||
#define USB_OTG_MODE_HOST 1U
|
||||
#define USB_OTG_MODE_DRD 2U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL Device Speed
|
||||
* @{
|
||||
*/
|
||||
#define USBD_HS_SPEED 0U
|
||||
#define USBD_HSINFS_SPEED 1U
|
||||
#define USBH_HS_SPEED 0U
|
||||
#define USBD_FS_SPEED 2U
|
||||
#define USBH_FSLS_SPEED 1U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_SPEED_HIGH 0U
|
||||
#define USB_OTG_SPEED_HIGH_IN_FULL 1U
|
||||
#define USB_OTG_SPEED_FULL 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_ULPI_PHY 1U
|
||||
#define USB_OTG_EMBEDDED_PHY 2U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Turnaround_Timeout Turnaround Timeout Value
|
||||
* @{
|
||||
*/
|
||||
#ifndef USBD_HS_TRDT_VALUE
|
||||
#define USBD_HS_TRDT_VALUE 9U
|
||||
#endif /* USBD_HS_TRDT_VALUE */
|
||||
#ifndef USBD_FS_TRDT_VALUE
|
||||
#define USBD_FS_TRDT_VALUE 5U
|
||||
#define USBD_DEFAULT_TRDT_VALUE 9U
|
||||
#endif /* USBD_HS_TRDT_VALUE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_HS_MAX_PACKET_SIZE 512U
|
||||
#define USB_OTG_FS_MAX_PACKET_SIZE 64U
|
||||
#define USB_OTG_MAX_EP0_SIZE 64U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
|
||||
* @{
|
||||
*/
|
||||
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0U << 1)
|
||||
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1U << 1)
|
||||
#define DSTS_ENUMSPD_FS_PHY_48MHZ (3U << 1)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
|
||||
* @{
|
||||
*/
|
||||
#define DCFG_FRAME_INTERVAL_80 0U
|
||||
#define DCFG_FRAME_INTERVAL_85 1U
|
||||
#define DCFG_FRAME_INTERVAL_90 2U
|
||||
#define DCFG_FRAME_INTERVAL_95 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
|
||||
* @{
|
||||
*/
|
||||
#define EP_MPS_64 0U
|
||||
#define EP_MPS_32 1U
|
||||
#define EP_MPS_16 2U
|
||||
#define EP_MPS_8 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
|
||||
* @{
|
||||
*/
|
||||
#define EP_SPEED_LOW 0U
|
||||
#define EP_SPEED_FULL 1U
|
||||
#define EP_SPEED_HIGH 2U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
|
||||
* @{
|
||||
*/
|
||||
#define EP_TYPE_CTRL 0U
|
||||
#define EP_TYPE_ISOC 1U
|
||||
#define EP_TYPE_BULK 2U
|
||||
#define EP_TYPE_INTR 3U
|
||||
#define EP_TYPE_MSK 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
|
||||
* @{
|
||||
*/
|
||||
#define STS_GOUT_NAK 1U
|
||||
#define STS_DATA_UPDT 2U
|
||||
#define STS_XFER_COMP 3U
|
||||
#define STS_SETUP_COMP 4U
|
||||
#define STS_SETUP_UPDT 6U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
|
||||
* @{
|
||||
*/
|
||||
#define HCFG_30_60_MHZ 0U
|
||||
#define HCFG_48_MHZ 1U
|
||||
#define HCFG_6_MHZ 2U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
|
||||
* @{
|
||||
*/
|
||||
#define HPRT0_PRTSPD_HIGH_SPEED 0U
|
||||
#define HPRT0_PRTSPD_FULL_SPEED 1U
|
||||
#define HPRT0_PRTSPD_LOW_SPEED 2U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define HCCHAR_CTRL 0U
|
||||
#define HCCHAR_ISOC 1U
|
||||
#define HCCHAR_BULK 2U
|
||||
#define HCCHAR_INTR 3U
|
||||
|
||||
#define HC_PID_DATA0 0U
|
||||
#define HC_PID_DATA2 1U
|
||||
#define HC_PID_DATA1 2U
|
||||
#define HC_PID_SETUP 3U
|
||||
|
||||
#define GRXSTS_PKTSTS_IN 2U
|
||||
#define GRXSTS_PKTSTS_IN_XFER_COMP 3U
|
||||
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U
|
||||
#define GRXSTS_PKTSTS_CH_HALTED 7U
|
||||
|
||||
#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE)
|
||||
#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE)
|
||||
|
||||
#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE))
|
||||
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBx_BASE\
|
||||
+ USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
|
||||
|
||||
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE\
|
||||
+ USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
|
||||
|
||||
#define USBx_DFIFO(i) *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
|
||||
|
||||
#define USBx_HOST ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE))
|
||||
#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USBx_BASE\
|
||||
+ USB_OTG_HOST_CHANNEL_BASE\
|
||||
+ ((i) * USB_OTG_HOST_CHANNEL_SIZE)))
|
||||
|
||||
#define EP_ADDR_MSK 0xFU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
|
||||
* @{
|
||||
*/
|
||||
#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
|
||||
#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
|
||||
|
||||
#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
|
||||
#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
|
||||
HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
|
||||
HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, uint32_t hclk, uint8_t speed);
|
||||
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode);
|
||||
HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed);
|
||||
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num);
|
||||
HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma);
|
||||
HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma);
|
||||
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
|
||||
uint8_t ch_ep_num, uint16_t len, uint8_t dma);
|
||||
|
||||
void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
|
||||
HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_EPStopXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
|
||||
HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address);
|
||||
HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup);
|
||||
uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
|
||||
uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
|
||||
void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
|
||||
|
||||
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
|
||||
HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq);
|
||||
HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state);
|
||||
uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx);
|
||||
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
|
||||
uint8_t epnum, uint8_t dev_address, uint8_t speed,
|
||||
uint8_t ep_type, uint16_t mps);
|
||||
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx,
|
||||
USB_OTG_HCTypeDef *hc, uint8_t dma);
|
||||
|
||||
uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num);
|
||||
HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num);
|
||||
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
|
||||
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (USB_OTG_FS) */
|
||||
|
||||
#endif /* __XC_HAL_LL_USB_NP_H */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,686 @@
|
||||
/*!
|
||||
* \file xc_hal_pcd_np.h
|
||||
*
|
||||
* \brief PCD HAL module driver.(use non-periodic fifo)
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author MCD Application Team
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*/
|
||||
|
||||
#ifndef __XC_HAL_PCD_NP_H
|
||||
#define __XC_HAL_PCD_NP_H
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_hal_ll_usb_np.h"
|
||||
|
||||
|
||||
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief PCD State structure definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_PCD_STATE_RESET = 0x00,
|
||||
HAL_PCD_STATE_READY = 0x01,
|
||||
HAL_PCD_STATE_ERROR = 0x02,
|
||||
HAL_PCD_STATE_BUSY = 0x03,
|
||||
HAL_PCD_STATE_TIMEOUT = 0x04
|
||||
} PCD_StateTypeDef;
|
||||
|
||||
/* Device LPM suspend state */
|
||||
typedef enum
|
||||
{
|
||||
LPM_L0 = 0x00, /* on */
|
||||
LPM_L1 = 0x01, /* LPM L1 sleep */
|
||||
LPM_L2 = 0x02, /* suspend */
|
||||
LPM_L3 = 0x03, /* off */
|
||||
} PCD_LPM_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PCD_LPM_L0_ACTIVE = 0x00, /* on */
|
||||
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
|
||||
} PCD_LPM_MsgTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PCD_BCD_ERROR = 0xFF,
|
||||
PCD_BCD_CONTACT_DETECTION = 0xFE,
|
||||
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD,
|
||||
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC,
|
||||
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB,
|
||||
PCD_BCD_DISCOVERY_COMPLETED = 0x00,
|
||||
|
||||
} PCD_BCD_MsgTypeDef;
|
||||
|
||||
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
|
||||
typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
|
||||
typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
|
||||
typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
|
||||
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
|
||||
|
||||
/**
|
||||
* @brief PCD Handle Structure definition
|
||||
*/
|
||||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
|
||||
typedef struct __PCD_HandleTypeDef
|
||||
#else
|
||||
typedef struct
|
||||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
|
||||
{
|
||||
PCD_TypeDef *Instance; /*!< Register base address */
|
||||
PCD_InitTypeDef Init; /*!< PCD required parameters */
|
||||
__IO uint8_t USB_Address; /*!< USB Address */
|
||||
PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
|
||||
PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
|
||||
HAL_LockTypeDef Lock; /*!< PCD peripheral status */
|
||||
__IO PCD_StateTypeDef State; /*!< PCD communication state */
|
||||
__IO uint32_t ErrorCode; /*!< PCD Error code */
|
||||
uint32_t Setup[12]; /*!< Setup packet buffer */
|
||||
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */
|
||||
uint32_t BESL;
|
||||
uint32_t FrameNumber; /*!< Store Current Frame number */
|
||||
|
||||
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
void *pData; /*!< Pointer to upper stack Handler */
|
||||
|
||||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
|
||||
void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */
|
||||
void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */
|
||||
void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */
|
||||
void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */
|
||||
void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */
|
||||
void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */
|
||||
void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */
|
||||
|
||||
void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */
|
||||
void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */
|
||||
void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */
|
||||
void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */
|
||||
void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */
|
||||
void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */
|
||||
|
||||
void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */
|
||||
void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */
|
||||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
|
||||
} PCD_HandleTypeDef;
|
||||
|
||||
typedef struct {
|
||||
uint8_t IN_Lock;
|
||||
uint8_t OUT_Lock;
|
||||
} PCD_IN_OUT_Status;
|
||||
|
||||
extern PCD_IN_OUT_Status PCD_Sta;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup PCD_Speed PCD Speed
|
||||
* @{
|
||||
*/
|
||||
#define PCD_SPEED_HIGH USBD_HS_SPEED
|
||||
#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED
|
||||
#define PCD_SPEED_FULL USBD_FS_SPEED
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PCD_PHY_Module PCD PHY Module
|
||||
* @{
|
||||
*/
|
||||
#define PCD_PHY_ULPI 1U
|
||||
#define PCD_PHY_EMBEDDED 2U
|
||||
#define PCD_PHY_UTMI 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PCD_Error_Code_definition PCD Error Code definition
|
||||
* @brief PCD Error Code definition
|
||||
* @{
|
||||
*/
|
||||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
|
||||
#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */
|
||||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
|
||||
|
||||
/** @defgroup PCD_Exported_Macros PCD Exported Macros
|
||||
* @brief macros to handle interrupts and specific clock configurations
|
||||
* @{
|
||||
*/
|
||||
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
|
||||
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
|
||||
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
|
||||
|
||||
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \
|
||||
((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
|
||||
|
||||
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__))
|
||||
#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
|
||||
|
||||
#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \
|
||||
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
|
||||
|
||||
#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \
|
||||
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
|
||||
|
||||
#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \
|
||||
((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
|
||||
|
||||
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
|
||||
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
|
||||
do { \
|
||||
EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE); \
|
||||
EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE; \
|
||||
} while(0U)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
|
||||
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
|
||||
do { \
|
||||
EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
|
||||
EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
|
||||
} while(0U)
|
||||
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
|
||||
|
||||
|
||||
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
|
||||
* @{
|
||||
*/
|
||||
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
|
||||
#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */
|
||||
#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 20) /*!< USB HS EXTI Line WakeUp Interrupt */
|
||||
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
|
||||
#ifndef USB_OTG_DOEPINT_OTEPSPR
|
||||
#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_OTEPSPR */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_OTEPSPRM
|
||||
#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */
|
||||
|
||||
#ifndef USB_OTG_DOEPINT_NAK
|
||||
#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_NAK */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_NAKM
|
||||
#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_NAKM */
|
||||
|
||||
#ifndef USB_OTG_DOEPINT_STPKTRX
|
||||
#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_STPKTRX */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_NYETM
|
||||
#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_NYETM */
|
||||
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/* Initialization/de-initialization functions ********************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
|
||||
HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
|
||||
|
||||
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
|
||||
/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
|
||||
* @brief HAL USB OTG PCD Callback ID enumeration definition
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */
|
||||
HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */
|
||||
HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */
|
||||
HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */
|
||||
HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */
|
||||
HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */
|
||||
HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */
|
||||
|
||||
HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */
|
||||
HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */
|
||||
|
||||
} HAL_PCD_CallbackIDTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
|
||||
* @brief HAL USB OTG PCD Callback pointer definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */
|
||||
typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */
|
||||
typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */
|
||||
typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */
|
||||
typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */
|
||||
typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */
|
||||
typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
|
||||
HAL_PCD_CallbackIDTypeDef CallbackID,
|
||||
pPCD_CallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd,
|
||||
HAL_PCD_CallbackIDTypeDef CallbackID);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_DataOutStageCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_DataInStageCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_IsoOutIncpltCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_IsoInIncpltCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_BcdCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd,
|
||||
pPCD_LpmCallbackTypeDef pCallback);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd);
|
||||
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* I/O operation functions ***************************************************/
|
||||
/* Non-Blocking mode: Interrupt */
|
||||
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral Control functions **********************************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint16_t ep_mps, uint8_t ep_type);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint8_t *pBuf, uint32_t len);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint8_t *pBuf, uint32_t len);
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral State functions ************************************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
#if defined(USB_OTG_FS)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Typedef
|
||||
------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief PCD State structure definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_PCD_STATE_RESET = 0x00,
|
||||
HAL_PCD_STATE_READY = 0x01,
|
||||
HAL_PCD_STATE_ERROR = 0x02,
|
||||
HAL_PCD_STATE_BUSY = 0x03,
|
||||
HAL_PCD_STATE_TIMEOUT = 0x04
|
||||
} PCD_StateTypeDef;
|
||||
|
||||
/* Device LPM suspend state */
|
||||
typedef enum
|
||||
{
|
||||
LPM_L0 = 0x00, /* on */
|
||||
LPM_L1 = 0x01, /* LPM L1 sleep */
|
||||
LPM_L2 = 0x02, /* suspend */
|
||||
LPM_L3 = 0x03, /* off */
|
||||
} PCD_LPM_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PCD_LPM_L0_ACTIVE = 0x00, /* on */
|
||||
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
|
||||
} PCD_LPM_MsgTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PCD_BCD_ERROR = 0xFF,
|
||||
PCD_BCD_CONTACT_DETECTION = 0xFE,
|
||||
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD,
|
||||
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC,
|
||||
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB,
|
||||
PCD_BCD_DISCOVERY_COMPLETED = 0x00,
|
||||
|
||||
} PCD_BCD_MsgTypeDef;
|
||||
|
||||
typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
|
||||
typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
|
||||
typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
|
||||
|
||||
/**
|
||||
* @brief PCD Handle Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
PCD_TypeDef *Instance; /*!< Register base address */
|
||||
PCD_InitTypeDef Init; /*!< PCD required parameters */
|
||||
__IO uint8_t USB_Address; /*!< USB Address */
|
||||
PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
|
||||
PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
|
||||
HAL_LockTypeDef Lock; /*!< PCD peripheral status */
|
||||
__IO PCD_StateTypeDef State; /*!< PCD communication state */
|
||||
__IO uint32_t ErrorCode; /*!< PCD Error code */
|
||||
uint32_t Setup[12]; /*!< Setup packet buffer */
|
||||
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */
|
||||
uint32_t BESL;
|
||||
uint32_t FrameNumber; /*!< Store Current Frame number */
|
||||
|
||||
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
|
||||
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
|
||||
This parameter can be set to ENABLE or DISABLE */
|
||||
void *pData; /*!< Pointer to upper stack Handler */
|
||||
} PCD_HandleTypeDef;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/** @defgroup PCD_Speed PCD Speed
|
||||
* @{
|
||||
*/
|
||||
//#define PCD_SPEED_HIGH USBD_HS_SPEED
|
||||
//#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED
|
||||
#define PCD_SPEED_FULL USBD_FS_SPEED
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PCD_PHY_Module PCD PHY Module
|
||||
* @{
|
||||
*/
|
||||
#define PCD_PHY_ULPI 1U
|
||||
#define PCD_PHY_EMBEDDED 2U
|
||||
#define PCD_PHY_UTMI 3U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PCD_Exported_Macros PCD Exported Macros
|
||||
* @brief macros to handle interrupts and specific clock configurations
|
||||
* @{
|
||||
*/
|
||||
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
|
||||
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
|
||||
|
||||
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \
|
||||
((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
|
||||
|
||||
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__))
|
||||
#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
|
||||
|
||||
#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \
|
||||
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
|
||||
|
||||
#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \
|
||||
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
|
||||
|
||||
#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \
|
||||
((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
|
||||
|
||||
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (USB_OTG_HS_WAKEUP_EXTI_LINE)
|
||||
|
||||
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
|
||||
// do { \
|
||||
// EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE); \
|
||||
// EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE; \
|
||||
// } while(0U)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
|
||||
|
||||
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
|
||||
do { \
|
||||
EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
|
||||
EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
|
||||
} while(0U)
|
||||
|
||||
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
|
||||
* @{
|
||||
*/
|
||||
#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */
|
||||
//#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 20) /*!< USB HS EXTI Line WakeUp Interrupt */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifndef USB_OTG_DOEPINT_OTEPSPR
|
||||
#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_OTEPSPR */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_OTEPSPRM
|
||||
#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */
|
||||
|
||||
#ifndef USB_OTG_DOEPINT_NAK
|
||||
#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_NAK */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_NAKM
|
||||
#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_NAKM */
|
||||
|
||||
#ifndef USB_OTG_DOEPINT_STPKTRX
|
||||
#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */
|
||||
#endif /* defined USB_OTG_DOEPINT_STPKTRX */
|
||||
|
||||
#ifndef USB_OTG_DOEPMSK_NYETM
|
||||
#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */
|
||||
#endif /* defined USB_OTG_DOEPMSK_NYETM */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------------------------------------------------*/
|
||||
/* Initialization/de-initialization functions ********************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
|
||||
HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* I/O operation functions ***************************************************/
|
||||
/* Non-Blocking mode: Interrupt */
|
||||
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
|
||||
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
|
||||
|
||||
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral Control functions **********************************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint16_t ep_mps, uint8_t ep_type);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint8_t *pBuf, uint32_t len);
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
|
||||
uint8_t *pBuf, uint32_t len);
|
||||
|
||||
|
||||
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
|
||||
HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral State functions ************************************************/
|
||||
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (USB_OTG_FS) */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __XC_HAL_PCD_NP_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
/*!
|
||||
* \file xc_hal_usb.c
|
||||
*
|
||||
* \brief Target xinchip hal usb implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_hal_usb.h"
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define USB_RESET_ON( ) cpr_rf_reg1__usb_rstn_reg__setf(0)//CLEAR_BIT(XC_CPR->RF_REG1, (1 << 20))
|
||||
#define USB_RESET_OFF( ) cpr_rf_reg1__usb_rstn_reg__setf(1)//SET_BIT(XC_CPR->RF_REG1, (1 << 20))
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief usb phy dm operation
|
||||
* @param uint32_t - bit
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_DM_Oprt(uint32_t bit)
|
||||
{
|
||||
cpr_rf_reg5__usb_rwreg__setf(bit << 3);
|
||||
// if(bit == PULL_UP)
|
||||
// SET_BIT(XC_CPR->RF_REG5, (bit << 3));
|
||||
// else if(bit == PULL_DOWN)
|
||||
// CLEAR_BIT(XC_CPR->RF_REG5, (bit << 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy dp operation
|
||||
* @param uint32_t - bit
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_DP_Oprt(uint32_t bit)
|
||||
{
|
||||
cpr_rf_reg5__usb_rwreg__setf(bit << 2);
|
||||
// if(bit == PULL_UP)
|
||||
// SET_BIT(XC_CPR->RF_REG5, (bit << 2));
|
||||
// else if(bit == PULL_DOWN)
|
||||
// CLEAR_BIT(XC_CPR->RF_REG5, (bit << 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy enable
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_Enable( void )
|
||||
{
|
||||
cpr_rf_reg5__usb_rwreg__setf(0 << 4);
|
||||
// CLEAR_BIT(XC_CPR->RF_REG5, (1 << 4));
|
||||
// SET_BIT(XC_CPR->RF_REG5, (1 << 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy disable
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_Disable( void )
|
||||
{
|
||||
cpr_rf_reg5__usb_rwreg__setf(1 << 4);
|
||||
// SET_BIT(XC_CPR->RF_REG5, (1 << 4));
|
||||
}
|
||||
|
||||
#define readl(addr) (*(volatile unsigned int *) (addr))
|
||||
#define writel(addr, value) (*(volatile unsigned int *) (addr) = (value))
|
||||
|
||||
/**
|
||||
* @brief 32M OSC multiper bbpll to 96M
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void OSC32M_Multi_BBPLL_96M( void )
|
||||
{
|
||||
#if (XC6XX_5C != 1)
|
||||
if(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg( );
|
||||
rf_ana27__bbpll_16m_sel__setf(DISABLE);
|
||||
rf_ana27__bbpll_core_96m_en__setf(ENABLE);
|
||||
rf_ana26__bbpll_loopdiv__setf(0x06);
|
||||
rf_ana26__clk_bbpll_en__setf(ENABLE);
|
||||
rf_ana26__clk_bbpll_rstn__setf(ENABLE);
|
||||
rf_ana26__bbpll_en__setf(ENABLE);
|
||||
rf_ana26__bbpll_core_64m_en__setf(ENABLE);
|
||||
|
||||
// /* BT_CLK 时钟控制寄存器 */
|
||||
// XC_CPR->BT_CLK_CTL = (CPR_BT_CLK_CTL_BT_CLK_EN_ENABLE | (CPR_BT_CLK_CTL_BT_CLK_EN_Msk << 16));
|
||||
// /* BT_MODEM_CLK 时钟控制寄存器 */
|
||||
//// XC_CPR->BT_MODEM_CTL = (CPR_BT_MODEM_CLK_CTL_BT_MODEM_CLK_EN_ENABLE |
|
||||
//// (CPR_BT_MODEM_CLK_CTL_BT_MODEM_CLK_EN_Msk << 16));
|
||||
// /* 配置 BT_PCLK_EN 使能 */
|
||||
// XC_CPR->CTLAPBCLKEN_GRCTL |= (CPR_CTLAPBCLKEN_GRCTL_BT_PCLK_EN_ENABLE |
|
||||
// (CPR_CTLAPBCLKEN_GRCTL_BT_PCLK_EN_Msk << CPR_CTLAPBCLKEN_GRCTL_MASK_OFFSET));
|
||||
//
|
||||
// SET_BIT(XC_BT_RF->BT.rx_pm_reg_l, (1 << 14));
|
||||
// XC_CPR_AO->AON_CORERFLDO_EN = 0x1;
|
||||
|
||||
|
||||
// SET_BIT(XC_BT_RF->ana26_reg_l, (0xf << 12));
|
||||
// SET_BIT(XC_BT_RF->ana27_reg_l, 0x02); // ana27 div 2
|
||||
// SET_BIT(XC_BT_RF->ana26_reg_l, 0x06); // ana26 6*32 / 2 = 192M / 2 = 96M
|
||||
}
|
||||
#else
|
||||
uint32_t last_idx = xc_clock_hfclk_in_get()/1000000;
|
||||
// CLEAR_BIT(XC_CPR->RF_REG4, (uint32_t)0x1f);
|
||||
// SET_BIT(XC_CPR->RF_REG4, (uint32_t)0x11);
|
||||
|
||||
// CLEAR_BIT(XC_CPR->RF_REG3, (uint32_t)(0x07 | (0x1f<<8) | (0x3f<<14)));
|
||||
// SET_BIT(XC_CPR->RF_REG3, (uint32_t)((0x1 << 1) | (0x07<<8) | (0x08<<14)));
|
||||
|
||||
uint32_t val = XC_CPR->RF_REG4;
|
||||
XC_CPR->RF_REG4 = (val & 0xFFFFFFE0) | 0x11; // div2
|
||||
|
||||
val = XC_CPR->RF_REG3;
|
||||
//[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M]
|
||||
XC_CPR->RF_REG3 = (val & (~(uint32_t)(0x07 | (0x1f<<8) | (0x3f<<14)))) |
|
||||
(0x1 << 1) | (0x07<<8) | (0x08<<14);
|
||||
|
||||
m_clock_cb.hfclk_in = CLOCK_HFCLK_IN_96M;
|
||||
|
||||
uint32_t baudrate, uart_clk, div, mul, clk_ctl, adj_div;
|
||||
|
||||
uart_clk = xc_clock_hfclk_in_get();
|
||||
baudrate = XC_CPR->UART0_CLK_CTL;
|
||||
mul = (baudrate >> 16) & 0xFFFF;
|
||||
div = (baudrate & 0xFFFF);
|
||||
|
||||
adj_div = uart_clk / 1000000;
|
||||
clk_ctl = (mul << 16 ) | ( div * adj_div / last_idx);
|
||||
|
||||
XC_CPR->UART0_CLK_CTL = clk_ctl;
|
||||
|
||||
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
|
||||
SysTick_Config(xc_clock_hfclk_in_get() / 100);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb bbpll close
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_BBPLL_Close( void )
|
||||
{
|
||||
rf_ana26__bbpll_core_64m_en__setf(DISABLE);
|
||||
rf_ana26__bbpll_en__setf(DISABLE);
|
||||
rf_ana26__clk_bbpll_rstn__setf(DISABLE);
|
||||
rf_ana26__clk_bbpll_en__setf(DISABLE);
|
||||
rf_ana26__bbpll_loopdiv__setf(0x00);
|
||||
// CLEAR_BIT(XC_BT_RF->ana26_reg_l, (0xf << 12));
|
||||
// CLEAR_BIT(XC_BT_RF->ana26_reg_l, 0x06);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb pll enable
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_PLL_Enable( void )
|
||||
{
|
||||
OSC32M_Multi_BBPLL_96M( );
|
||||
|
||||
cpr_rf_reg1__usb_mclk_div__setf(1);
|
||||
cpr_rf_reg1__usb_hclk_en__setf(1);
|
||||
cpr_rf_reg1__usb_mclk_en__setf(1);
|
||||
cpr_rf_reg1__usb_utmi_clk_div__setf(1);
|
||||
cpr_rf_reg1__usb_utmi_clk_en__setf(1);
|
||||
|
||||
// WRITE_REG(XC_CPR->RF_REG1, (XC_CPR->RF_REG1 & 0xE0FFCFF0) | 0x11003001); // usb clk enable
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb pll disable
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_PLL_Disable( void )
|
||||
{
|
||||
USB_BBPLL_Close( );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy init
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_Init( void )
|
||||
{
|
||||
USB_PLL_Enable( );
|
||||
|
||||
USB_RESET_ON( );
|
||||
HAL_Delay(100);//for(int i = 0; i < 0x4550; i++);//HAL_Delay(100);
|
||||
USB_RESET_OFF( );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy deinit
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_Deinit( void )
|
||||
{
|
||||
cpr_rf_reg1__usb_utmi_clk_en__setf(0);
|
||||
cpr_rf_reg1__usb_utmi_clk_div__setf(0);
|
||||
cpr_rf_reg1__usb_hclk_en__setf(0);
|
||||
cpr_rf_reg1__usb_mclk_en__setf(0);
|
||||
// WRITE_REG(XC_CPR->RF_REG1, (XC_CPR->RF_REG1 & 0xE0FFCFF0) | (~0x00003000)); // usb clk disable
|
||||
USB_Phy_Disable( );
|
||||
NVIC_DisableIRQ(USB_IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb phy reset
|
||||
* @param void
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Phy_Reset( void )
|
||||
{
|
||||
USB_RESET_ON( );
|
||||
HAL_Delay(150); //for(int i = 0; i < 0x4550; i++);//HAL_Delay(100);
|
||||
USB_RESET_OFF( );
|
||||
HAL_Delay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief usb current control
|
||||
* @param uint8_t - val
|
||||
* @retval None
|
||||
*/
|
||||
void USB_Current_Ctrl( uint8_t val )
|
||||
{
|
||||
cpr_rf_reg5__usbphy_usb_ibc__setf(val);
|
||||
|
||||
// CLEAR_BIT(XC_CPR->RF_REG5, (3 << 21));
|
||||
|
||||
// SET_BIT(XC_CPR->RF_REG5, (val << 21));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* \file xc_hal_usb.h
|
||||
*
|
||||
* \brief The header of xc_hal_usb.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef __XC_HAL_USB_H_
|
||||
#define __XC_HAL_USB_H_
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
//#define SET_REG_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
//#define CLEAR_REG_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
//#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
//#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
//#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
//#define READ_REG(REG) ((REG))
|
||||
|
||||
#define PULL_UP 1U
|
||||
#define PULL_DOWN 0U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
------------------------------------------- -----------------------------------------*/
|
||||
void USB_Phy_DM_Oprt(uint32_t bit);
|
||||
void USB_Phy_DP_Oprt(uint32_t bit);
|
||||
void USB_Phy_Enable( void );
|
||||
void USB_Phy_Disable( void );
|
||||
void USB_PLL_Enable( void );
|
||||
void USB_PLL_Disable( void );
|
||||
void USB_Phy_Init( void );
|
||||
void USB_Phy_Deinit( void );
|
||||
void USB_Phy_Reset( void );
|
||||
void USB_Current_Ctrl( uint8_t val );
|
||||
|
||||
|
||||
#endif /* __XC_HAL_USB_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user