Moved firmware to subfoler firmware
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_cdc.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_CDC_H
|
||||
#define __USB_CDC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup usbd_cdc
|
||||
* @brief This file is the Header file for usbd_cdc.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup usbd_cdc_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define CDC_IN_EP 0x81U /* EP1 for data IN */
|
||||
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
|
||||
|
||||
#ifndef CDC_HS_BINTERVAL
|
||||
#define CDC_HS_BINTERVAL 0x10U
|
||||
#endif /* CDC_HS_BINTERVAL */
|
||||
|
||||
#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_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
|
||||
#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_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
|
||||
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
|
||||
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* 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
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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);
|
||||
|
||||
} USBD_CDC_ItfTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits 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;
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CDC;
|
||||
#define USBD_CDC_CLASS &USBD_CDC
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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,
|
||||
uint16_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);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CDC_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,945 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc.c
|
||||
* @author MCD Application Team
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CDC
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CDC_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CDC_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CDC_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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);
|
||||
|
||||
/* 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 uint8_t USBD_CDC_CfgHSDesc[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:no of returned bytes */
|
||||
0x00,
|
||||
0x02, /* bNumInterfaces: 2 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
0x32, /* MaxPower 0 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 endpoints 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: 1 */
|
||||
|
||||
/*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_HS_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_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
|
||||
0x00 /* bInterval: ignore for Bulk transfer */
|
||||
} ;
|
||||
|
||||
|
||||
/* USB CDC device Configuration Descriptor */
|
||||
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[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:no of returned bytes */
|
||||
0x00,
|
||||
0x02, /* bNumInterfaces: 2 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
0xC0, /* bmAttributes: self powered */
|
||||
0x32, /* MaxPower 0 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 endpoints 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: 1 */
|
||||
|
||||
/*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),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*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),
|
||||
0x00 /* bInterval: ignore for Bulk transfer */
|
||||
} ;
|
||||
|
||||
__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuation Descriptor size */
|
||||
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
|
||||
USB_CDC_CONFIG_DESC_SIZ,
|
||||
0x00,
|
||||
0x02, /* bNumInterfaces: 2 interfaces */
|
||||
0x01, /* bConfigurationValue: */
|
||||
0x04, /* iConfiguration: */
|
||||
0xC0, /* bmAttributes: */
|
||||
0x32, /* MaxPower 100 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 endpoints 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: 1 */
|
||||
|
||||
/*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 */
|
||||
0x40, /* wMaxPacketSize: */
|
||||
0x00,
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/*Endpoint IN Descriptor*/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
0x40, /* wMaxPacketSize: */
|
||||
0x00,
|
||||
0x00 /* bInterval */
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CDC_Private_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)
|
||||
{
|
||||
uint8_t ret = 0U;
|
||||
USBD_CDC_HandleTypeDef *hcdc;
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Open EP IN */
|
||||
USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_HS_IN_PACKET_SIZE);
|
||||
|
||||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
|
||||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open EP IN */
|
||||
USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_IN_PACKET_SIZE);
|
||||
|
||||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
|
||||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
|
||||
}
|
||||
/* Open Command IN EP */
|
||||
USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
|
||||
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
|
||||
|
||||
pdev->pClassData = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
|
||||
|
||||
if (pdev->pClassData == NULL)
|
||||
{
|
||||
ret = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
|
||||
|
||||
/* Init physical Interface components */
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
|
||||
|
||||
/* Init Xfer states */
|
||||
hcdc->TxState = 0U;
|
||||
hcdc->RxState = 0U;
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
uint8_t ret = 0U;
|
||||
|
||||
/* Close EP IN */
|
||||
USBD_LL_CloseEP(pdev, CDC_IN_EP);
|
||||
pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP OUT */
|
||||
USBD_LL_CloseEP(pdev, CDC_OUT_EP);
|
||||
pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close Command IN EP */
|
||||
USBD_LL_CloseEP(pdev, CDC_CMD_EP);
|
||||
pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
|
||||
|
||||
/* DeInit physical Interface components */
|
||||
if (pdev->pClassData != NULL)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
|
||||
USBD_free(pdev->pClassData);
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassData;
|
||||
uint8_t ifalt = 0U;
|
||||
uint16_t status_info = 0U;
|
||||
uint8_t ret = USBD_OK;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS :
|
||||
if (req->wLength)
|
||||
{
|
||||
if (req->bmRequest & 0x80U)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
|
||||
(uint8_t *)(void *)hcdc->data,
|
||||
req->wLength);
|
||||
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcdc->CmdOpCode = req->bRequest;
|
||||
hcdc->CmdLength = (uint8_t)req->wLength;
|
||||
|
||||
USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
|
||||
(uint8_t *)(void *)req, 0U);
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
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;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return 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 = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
|
||||
PCD_HandleTypeDef *hpcd = pdev->pData;
|
||||
|
||||
if (pdev->pClassData != NULL)
|
||||
{
|
||||
if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
|
||||
{
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[epnum].total_length = 0U;
|
||||
|
||||
/* Send ZLP */
|
||||
USBD_LL_Transmit(pdev, epnum, NULL, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcdc->TxState = 0U;
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassData;
|
||||
|
||||
/* 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 */
|
||||
if (pdev->pClassData != NULL)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassData;
|
||||
|
||||
if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
|
||||
(uint8_t *)(void *)hcdc->data,
|
||||
(uint16_t)hcdc->CmdLength);
|
||||
hcdc->CmdOpCode = 0xFFU;
|
||||
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetFSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_CDC_CfgFSDesc);
|
||||
return USBD_CDC_CfgFSDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetHSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_CDC_CfgHSDesc);
|
||||
return USBD_CDC_CfgHSDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = sizeof(USBD_CDC_OtherSpeedCfgDesc);
|
||||
return USBD_CDC_OtherSpeedCfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
|
||||
{
|
||||
*length = 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)
|
||||
{
|
||||
uint8_t ret = USBD_FAIL;
|
||||
|
||||
if (fops != NULL)
|
||||
{
|
||||
pdev->pUserData = fops;
|
||||
ret = USBD_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_SetTxBuffer
|
||||
* @param pdev: device instance
|
||||
* @param pbuff: Tx Buffer
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuff,
|
||||
uint16_t length)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
|
||||
|
||||
hcdc->TxBuffer = pbuff;
|
||||
hcdc->TxLength = length;
|
||||
|
||||
return 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->pClassData;
|
||||
|
||||
hcdc->RxBuffer = pbuff;
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_TransmitPacket
|
||||
* Transmit packet on IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
|
||||
|
||||
if (pdev->pClassData != NULL)
|
||||
{
|
||||
if (hcdc->TxState == 0U)
|
||||
{
|
||||
/* Tx Transfer in progress */
|
||||
hcdc->TxState = 1U;
|
||||
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
|
||||
|
||||
/* Transmit next packet */
|
||||
USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
|
||||
(uint16_t)hcdc->TxLength);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBD_BUSY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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->pClassData;
|
||||
|
||||
/* Suspend or Resume USB Out process */
|
||||
if (pdev->pClassData != NULL)
|
||||
{
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
USBD_LL_PrepareReceive(pdev,
|
||||
CDC_OUT_EP,
|
||||
hcdc->RxBuffer,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
USBD_LL_PrepareReceive(pdev,
|
||||
CDC_OUT_EP,
|
||||
hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBD_FAIL;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_core.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for usbd_core.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CORE_H
|
||||
#define __USBD_CORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_conf.h"
|
||||
#include "usbd_def.h"
|
||||
#include "usbd_ioreq.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE
|
||||
* @brief This file is the Header file for usbd_core.c file
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef USBD_DEBUG_LEVEL
|
||||
#define USBD_DEBUG_LEVEL 0U
|
||||
#endif /* USBD_DEBUG_LEVEL */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
#define USBD_SOF USBD_LL_SOF
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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);
|
||||
|
||||
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);
|
||||
uint8_t USBD_LL_IsStallEP(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,
|
||||
uint16_t size);
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr,
|
||||
uint8_t *pbuf,
|
||||
uint16_t size);
|
||||
|
||||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||
void USBD_LL_Delay(uint32_t Delay);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CORE_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_req.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the usbd_req.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_REQUEST_H
|
||||
#define __USB_REQUEST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_REQ
|
||||
* @brief header file for the usbd_req.c file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_REQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_REQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_REQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,348 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_def.h
|
||||
* @author MCD Application Team
|
||||
* @brief General defines for the usb device library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DEF_H
|
||||
#define __USBD_DEF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_DEF
|
||||
* @brief general defines for the usb device library file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_DEF_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0U
|
||||
#endif /* NULL */
|
||||
|
||||
#ifndef USBD_MAX_NUM_INTERFACES
|
||||
#define USBD_MAX_NUM_INTERFACES 1U
|
||||
#endif /* USBD_MAX_NUM_CONFIGURATION */
|
||||
|
||||
#ifndef USBD_MAX_NUM_CONFIGURATION
|
||||
#define USBD_MAX_NUM_CONFIGURATION 1U
|
||||
#endif /* USBD_MAX_NUM_CONFIGURATION */
|
||||
|
||||
#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_SUPPORT_USER_STRING_DESC
|
||||
#define USBD_SUPPORT_USER_STRING_DESC 0U
|
||||
#endif /* USBD_SUPPORT_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_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_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
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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;
|
||||
|
||||
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_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_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_LPM_ENABLED == 1U)
|
||||
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
|
||||
#endif
|
||||
} USBD_DescriptorsTypeDef;
|
||||
|
||||
/* USB Device handle structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t is_used;
|
||||
uint32_t total_length;
|
||||
uint32_t rem_length;
|
||||
uint32_t maxpacket;
|
||||
} 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];
|
||||
uint32_t ep0_state;
|
||||
uint32_t ep0_data_len;
|
||||
uint8_t dev_state;
|
||||
uint8_t dev_old_state;
|
||||
uint8_t dev_address;
|
||||
uint8_t dev_connection_status;
|
||||
uint8_t dev_test_mode;
|
||||
uint32_t dev_remote_wakeup;
|
||||
|
||||
USBD_SetupReqTypedef request;
|
||||
USBD_DescriptorsTypeDef *pDesc;
|
||||
USBD_ClassTypeDef *pClass;
|
||||
void *pClassData;
|
||||
void *pUserData;
|
||||
void *pData;
|
||||
} USBD_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_DEF_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
|
||||
(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U))
|
||||
|
||||
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU))
|
||||
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif /* __packed */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/* In HS mode and when the DMA is used, all variables and data structures dealing
|
||||
with the DMA during the transaction process should be 4-bytes aligned */
|
||||
|
||||
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END __attribute__ ((aligned (4U)))
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#else
|
||||
#ifndef __ALIGN_END
|
||||
#define __ALIGN_END
|
||||
#endif /* __ALIGN_END */
|
||||
#ifndef __ALIGN_BEGIN
|
||||
#if defined (__CC_ARM) /* ARM Compiler */
|
||||
#define __ALIGN_BEGIN __align(4U)
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define __ALIGN_BEGIN
|
||||
#endif /* __CC_ARM */
|
||||
#endif /* __ALIGN_BEGIN */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_DEF_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_DEF_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DEF_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ioreq.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the usbd_ioreq.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_IOREQ_H
|
||||
#define __USBD_IOREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_IOREQ
|
||||
* @brief header file for the usbd_ioreq.c file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_IOREQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_IOREQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf,
|
||||
uint16_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf,
|
||||
uint16_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf,
|
||||
uint16_t len);
|
||||
|
||||
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuf,
|
||||
uint16_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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,611 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_core.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides all the USBD core functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Private_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)
|
||||
{
|
||||
/* Check whether the USB Host handle is valid */
|
||||
if (pdev == NULL)
|
||||
{
|
||||
#if (USBD_DEBUG_LEVEL > 1U)
|
||||
USBD_ErrLog("Invalid Device handle");
|
||||
#endif
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
/* Unlink previous class*/
|
||||
if (pdev->pClass != NULL)
|
||||
{
|
||||
pdev->pClass = 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 */
|
||||
USBD_LL_Init(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_DeInit
|
||||
* Re-Initialize th device library
|
||||
* @param pdev: device instance
|
||||
* @retval status: status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Set Default State */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
|
||||
/* Free Class Resources */
|
||||
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
|
||||
/* Stop the low level driver */
|
||||
USBD_LL_Stop(pdev);
|
||||
|
||||
/* Initialize low level driver */
|
||||
USBD_LL_DeInit(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
USBD_StatusTypeDef status = USBD_OK;
|
||||
if (pclass != NULL)
|
||||
{
|
||||
/* link the class to the USB Device handle */
|
||||
pdev->pClass = pclass;
|
||||
status = USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (USBD_DEBUG_LEVEL > 1U)
|
||||
USBD_ErrLog("Invalid Class handle");
|
||||
#endif
|
||||
status = USBD_FAIL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
USBD_LL_Start(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_Stop
|
||||
* Stop the USB Device Core.
|
||||
* @param pdev: Device Handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Free Class Resources */
|
||||
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
|
||||
/* Stop the low level driver */
|
||||
USBD_LL_Stop(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_RunTestMode
|
||||
* Launch test mode process
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_FAIL;
|
||||
|
||||
if (pdev->pClass != NULL)
|
||||
{
|
||||
/* Set configuration and Start the Class*/
|
||||
if (pdev->pClass->Init(pdev, cfgidx) == 0U)
|
||||
{
|
||||
ret = USBD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* Clear configuration and De-initialize the Class process*/
|
||||
pdev->pClass->DeInit(pdev, cfgidx);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_SetupStage
|
||||
* Handle the setup stage
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
|
||||
{
|
||||
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:
|
||||
USBD_StdDevReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_INTERFACE:
|
||||
USBD_StdItfReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||
USBD_StdEPReq(pdev, &pdev->request);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
|
||||
break;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_DataOutStage
|
||||
* Handle data OUT stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum, uint8_t *pdata)
|
||||
{
|
||||
USBD_EndpointTypeDef *pep;
|
||||
|
||||
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;
|
||||
|
||||
USBD_CtlContinueRx(pdev, pdata,
|
||||
(uint16_t)MIN(pep->rem_length, pep->maxpacket));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pdev->pClass->EP0_RxReady != NULL) &&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->EP0_RxReady(pdev);
|
||||
}
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
|
||||
{
|
||||
/*
|
||||
* STATUS PHASE completed, update ep0_state to idle
|
||||
*/
|
||||
pdev->ep0_state = USBD_EP0_IDLE;
|
||||
USBD_LL_StallEP(pdev, 0U);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((pdev->pClass->DataOut != NULL) &&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->DataOut(pdev, epnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* should never be in this condition */
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_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;
|
||||
|
||||
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;
|
||||
|
||||
USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length);
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* last packet is MPS multiple, so send ZLP packet */
|
||||
if ((pep->total_length % pep->maxpacket == 0U) &&
|
||||
(pep->total_length >= pep->maxpacket) &&
|
||||
(pep->total_length < pdev->ep0_data_len))
|
||||
{
|
||||
USBD_CtlContinueSendData(pdev, NULL, 0U);
|
||||
pdev->ep0_data_len = 0U;
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pdev->pClass->EP0_TxSent != NULL) &&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->EP0_TxSent(pdev);
|
||||
}
|
||||
USBD_LL_StallEP(pdev, 0x80U);
|
||||
USBD_CtlReceiveStatus(pdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
|
||||
(pdev->ep0_state == USBD_EP0_IDLE))
|
||||
{
|
||||
USBD_LL_StallEP(pdev, 0x80U);
|
||||
}
|
||||
}
|
||||
|
||||
if (pdev->dev_test_mode == 1U)
|
||||
{
|
||||
USBD_RunTestMode(pdev);
|
||||
pdev->dev_test_mode = 0U;
|
||||
}
|
||||
}
|
||||
else if ((pdev->pClass->DataIn != NULL) &&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->DataIn(pdev, epnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* should never be in this condition */
|
||||
return USBD_FAIL;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_Reset
|
||||
* Handle Reset event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Open EP0 OUT */
|
||||
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 */
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (pdev->pClassData)
|
||||
{
|
||||
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_LL_Reset
|
||||
* 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_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_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_SOF
|
||||
* Handle SOF event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
if (pdev->pClass->SOF != NULL)
|
||||
{
|
||||
pdev->pClass->SOF(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_IsoINIncomplete
|
||||
* Handle iso in incomplete event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
/* Prevent unused arguments compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_IsoOUTIncomplete
|
||||
* Handle iso out incomplete event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum)
|
||||
{
|
||||
/* Prevent unused arguments compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_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_DevDisconnected
|
||||
* Handle device disconnection event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Free Class Resources */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -0,0 +1,918 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_req.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the standard USB requests following chapter 9.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ctlreq.h"
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ
|
||||
* @brief USB standard requests module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_REQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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 void 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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_REQ_Private_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:
|
||||
pdev->pClass->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:
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
|
||||
|
||||
if ((req->wLength == 0U) && (ret == USBD_OK))
|
||||
{
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
break;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
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:
|
||||
pdev->pClass->Setup(pdev, req);
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
/* Check if it is a class request */
|
||||
if ((req->bmRequest & 0x60U) == 0x20U)
|
||||
{
|
||||
ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_SET_FEATURE:
|
||||
switch (pdev->dev_state)
|
||||
{
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
|
||||
{
|
||||
USBD_LL_StallEP(pdev, ep_addr);
|
||||
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))
|
||||
{
|
||||
USBD_LL_StallEP(pdev, ep_addr);
|
||||
}
|
||||
}
|
||||
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))
|
||||
{
|
||||
USBD_LL_StallEP(pdev, ep_addr);
|
||||
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)
|
||||
{
|
||||
USBD_LL_ClearStallEP(pdev, ep_addr);
|
||||
}
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
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;
|
||||
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&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))
|
||||
{
|
||||
pep->status = 0x0001U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pep->status = 0x0000U;
|
||||
}
|
||||
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&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)
|
||||
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
|
||||
case USB_DESC_TYPE_DEVICE:
|
||||
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_CONFIGURATION:
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pbuf = pdev->pClass->GetHSConfigDescriptor(&len);
|
||||
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
pbuf = pdev->pClass->GetFSConfigDescriptor(&len);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
||||
if (pdev->pClass->GetUsrStrDescriptor != NULL)
|
||||
{
|
||||
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_DEVICE_QUALIFIER:
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((len != 0U) && (req->wLength != 0U))
|
||||
{
|
||||
len = MIN(len, req->wLength);
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
}
|
||||
|
||||
if (req->wLength == 0U)
|
||||
{
|
||||
(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;
|
||||
USBD_LL_SetUSBAddress(pdev, dev_addr);
|
||||
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 void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
static uint8_t cfgidx;
|
||||
|
||||
cfgidx = (uint8_t)(req->wValue);
|
||||
|
||||
if (cfgidx > USBD_MAX_NUM_CONFIGURATION)
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pdev->dev_state)
|
||||
{
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if (cfgidx)
|
||||
{
|
||||
pdev->dev_config = cfgidx;
|
||||
pdev->dev_state = USBD_STATE_CONFIGURED;
|
||||
if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
return;
|
||||
}
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (cfgidx == 0U)
|
||||
{
|
||||
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||
pdev->dev_config = cfgidx;
|
||||
USBD_ClrClassConfig(pdev, cfgidx);
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
else if (cfgidx != pdev->dev_config)
|
||||
{
|
||||
/* Clear old configuration */
|
||||
USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
|
||||
|
||||
/* set new configuration */
|
||||
pdev->dev_config = cfgidx;
|
||||
if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
return;
|
||||
}
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
USBD_ClrClassConfig(pdev, cfgidx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_default_config, 1U);
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&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
|
||||
|
||||
if (pdev->dev_remote_wakeup)
|
||||
{
|
||||
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
|
||||
}
|
||||
|
||||
USBD_CtlSendData(pdev, (uint8_t *)(void *)&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;
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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;
|
||||
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)
|
||||
{
|
||||
req->bmRequest = *(uint8_t *)(pdata);
|
||||
req->bRequest = *(uint8_t *)(pdata + 1U);
|
||||
req->wValue = SWAPBYTE(pdata + 2U);
|
||||
req->wIndex = SWAPBYTE(pdata + 4U);
|
||||
req->wLength = SWAPBYTE(pdata + 6U);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
USBD_LL_StallEP(pdev, 0x80U);
|
||||
USBD_LL_StallEP(pdev, 0U);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
if (desc != NULL)
|
||||
{
|
||||
*len = (uint16_t)USBD_GetLen(desc) * 2U + 2U;
|
||||
unicode[idx++] = *(uint8_t *)(void *)len;
|
||||
unicode[idx++] = USB_DESC_TYPE_STRING;
|
||||
|
||||
while (*desc != '\0')
|
||||
{
|
||||
unicode[idx++] = *desc++;
|
||||
unicode[idx++] = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
while (*buf != '\0')
|
||||
{
|
||||
len++;
|
||||
buf++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ioreq.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the IO requests APIs for control endpoints.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ
|
||||
* @brief control I/O requests module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_IOREQ_Private_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, uint16_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 */
|
||||
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, uint16_t len)
|
||||
{
|
||||
/* Start the next transfer */
|
||||
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, uint16_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 */
|
||||
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, uint16_t len)
|
||||
{
|
||||
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 */
|
||||
USBD_LL_Transmit(pdev, 0x00U, NULL, 0U);
|
||||
|
||||
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 */
|
||||
USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
2
firmware/Middlewares/ST/desktop.ini
Normal file
2
firmware/Middlewares/ST/desktop.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
2
firmware/Middlewares/Third_Party/FatFs/desktop.ini
vendored
Normal file
2
firmware/Middlewares/Third_Party/FatFs/desktop.ini
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
2
firmware/Middlewares/Third_Party/FatFs/src/desktop.ini
vendored
Normal file
2
firmware/Middlewares/Third_Party/FatFs/src/desktop.ini
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
180
firmware/Middlewares/Third_Party/FatFs/src/diskio.c
vendored
Normal file
180
firmware/Middlewares/Third_Party/FatFs/src/diskio.c
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
||||
/* */
|
||||
/* Portions COPYRIGHT 2017 STMicroelectronics */
|
||||
/* Portions Copyright (C) 2014, ChaN, all right reserved */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* If a working storage control module is available, it should be */
|
||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||
/* This is an example of glue functions to attach various exsisting */
|
||||
/* storage control modules to the FatFs module with a defined API. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file diskio.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.4.1
|
||||
* @date 14-February-2017
|
||||
* @brief FatFs low level disk I/O module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission.
|
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or
|
||||
* microprocessor devices manufactured by or for STMicroelectronics.
|
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
|
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "diskio.h"
|
||||
#include "ff_gen_drv.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
extern Disk_drvTypeDef disk;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Gets Disk Status
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @retval DSTATUS: Operation status
|
||||
*/
|
||||
DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat;
|
||||
|
||||
stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
|
||||
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 = RES_OK;
|
||||
|
||||
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 = 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 = 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 = 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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
80
firmware/Middlewares/Third_Party/FatFs/src/diskio.h
vendored
Normal file
80
firmware/Middlewares/Third_Party/FatFs/src/diskio.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2014 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _USE_WRITE 1 /* 1: Enable disk_write function */
|
||||
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control 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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
4793
firmware/Middlewares/Third_Party/FatFs/src/ff.c
vendored
Normal file
4793
firmware/Middlewares/Third_Party/FatFs/src/ff.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
366
firmware/Middlewares/Third_Party/FatFs/src/ff.h
vendored
Normal file
366
firmware/Middlewares/Third_Party/FatFs/src/ff.h
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a free software that opened under license policy of
|
||||
/ following conditions.
|
||||
/
|
||||
/ Copyright (C) 2015, ChaN, all right reserved.
|
||||
/
|
||||
/ 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 _FATFS
|
||||
#define _FATFS 32020 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#if _FATFS != _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 */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#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
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
}win;
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (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) */
|
||||
#if _MAX_SS != _MIN_SS
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD volbase; /* Volume start sector */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !_FS_TINY
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* File data read/write buffer */
|
||||
}buf;
|
||||
#endif
|
||||
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
BYTE flag; /* Status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
|
||||
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
|
||||
DWORD dsect; /* 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 file open) */
|
||||
#endif
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
#if !_FS_TINY
|
||||
union{
|
||||
UINT d32[_MAX_SS/4]; /* Force 32bits alignement */
|
||||
BYTE d8[_MAX_SS]; /* File data read/write buffer */
|
||||
}buf;
|
||||
#endif
|
||||
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
|
||||
WORD id; /* Owner file system mount ID (**do not change order**) */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _FS_LOCK
|
||||
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#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 parameter error */
|
||||
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_SHARE */
|
||||
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 a file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of a 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 the file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the 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_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the 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 */
|
||||
|
||||
FRESULT delete_node (TCHAR* path, UINT sz_buff,FILINFO* fno); /*If we need to delete dir*/
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 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 /* 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 control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek feature */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
151
firmware/Middlewares/Third_Party/FatFs/src/ff_gen_drv.c
vendored
Normal file
151
firmware/Middlewares/Third_Party/FatFs/src/ff_gen_drv.c
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ff_gen_drv.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.4.1
|
||||
* @date 14-February-2017
|
||||
* @brief FatFs generic low level driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2017 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission.
|
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or
|
||||
* microprocessor devices manufactured by or for STMicroelectronics.
|
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
|
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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 paramter must be equal to 0
|
||||
* @retval Returns 0 in case of success, otherwise 1.
|
||||
*/
|
||||
uint8_t FATFS_LinkDriverEx(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(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****/
|
||||
|
||||
107
firmware/Middlewares/Third_Party/FatFs/src/ff_gen_drv.h
vendored
Normal file
107
firmware/Middlewares/Third_Party/FatFs/src/ff_gen_drv.h
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ff_gen_drv.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.4.1
|
||||
* @date 14-February-2017
|
||||
* @brief Header for ff_gen_drv.c module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2017 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission.
|
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or
|
||||
* microprocessor devices manufactured by or for STMicroelectronics.
|
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
|
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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"
|
||||
|
||||
/* 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];
|
||||
Diskio_drvTypeDef *drv[_VOLUMES];
|
||||
uint8_t lun[_VOLUMES];
|
||||
__IO uint8_t nbr;
|
||||
|
||||
}Disk_drvTypeDef;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
uint8_t FATFS_LinkDriverEx(Diskio_drvTypeDef *drv, char *path, uint8_t lun);
|
||||
uint8_t FATFS_LinkDriver(Diskio_drvTypeDef *drv, char *path);
|
||||
uint8_t FATFS_UnLinkDriver(char *path);
|
||||
uint8_t FATFS_LinkDriverEx(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****/
|
||||
|
||||
33
firmware/Middlewares/Third_Party/FatFs/src/integer.h
vendored
Normal file
33
firmware/Middlewares/Third_Party/FatFs/src/integer.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _FF_INTEGER
|
||||
#define _FF_INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* 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 16 bit or 32 bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types MUST be 32 bit */
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
firmware/Middlewares/Third_Party/FatFs/src/option/desktop.ini
vendored
Normal file
2
firmware/Middlewares/Third_Party/FatFs/src/option/desktop.ini
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
119
firmware/Middlewares/Third_Party/FatFs/src/option/syscall.c
vendored
Normal file
119
firmware/Middlewares/Third_Party/FatFs/src/option/syscall.c
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs */
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdlib.h> /* ANSI memory controls */
|
||||
#include "../ff.h"
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*-----------------------------------------------------------------------
|
||||
Create a Synchronization Object
|
||||
------------------------------------------------------------------------
|
||||
This function is called in f_mount function to create a new
|
||||
synchronization object, such as semaphore and mutex. When a zero is
|
||||
returned, the f_mount function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* TRUE:Function succeeded, FALSE:Could not create due to any error */
|
||||
BYTE vol, /* Corresponding logical drive being processed */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
osSemaphoreDef(SEM);
|
||||
*sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
|
||||
ret = (*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj function. When a zero is
|
||||
/ returned, the f_mount function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* TRUE:Function succeeded, FALSE:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
osSemaphoreDelete (sobj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a zero is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(osSemaphoreWait(sobj, _FS_TIMEOUT) == osOK)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
osSemaphoreRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
167
firmware/Middlewares/Third_Party/FatFs/src/user_diskio.c
vendored
Normal file
167
firmware/Middlewares/Third_Party/FatFs/src/user_diskio.c
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user_diskio.c
|
||||
* @brief This file includes a diskio driver skeleton to be completed by the user.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifdef USE_OBSOLETE_USER_CODE_SECTION_0
|
||||
/*
|
||||
* Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
|
||||
* To be suppressed in the future.
|
||||
* Kept to ensure backward compatibility with previous CubeMx versions when
|
||||
* migrating projects.
|
||||
* User code previously added there should be copied in the new user sections before
|
||||
* the section contents can be deleted.
|
||||
*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
/* USER CODE END 0 */
|
||||
#endif
|
||||
|
||||
/* USER CODE BEGIN DECL */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include "ff_gen_drv.h"
|
||||
#include "user_diskio_spi.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Disk status */
|
||||
static volatile DSTATUS Stat = STA_NOINIT;
|
||||
|
||||
/* USER CODE END DECL */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
DSTATUS USER_initialize (BYTE pdrv);
|
||||
DSTATUS USER_status (BYTE pdrv);
|
||||
DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
|
||||
#if _USE_WRITE == 1
|
||||
DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
|
||||
#endif /* _USE_WRITE == 1 */
|
||||
#if _USE_IOCTL == 1
|
||||
DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
|
||||
Diskio_drvTypeDef USER_Driver =
|
||||
{
|
||||
USER_initialize,
|
||||
USER_status,
|
||||
USER_read,
|
||||
#if _USE_WRITE
|
||||
USER_write,
|
||||
#endif /* _USE_WRITE == 1 */
|
||||
#if _USE_IOCTL == 1
|
||||
USER_ioctl,
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initializes a Drive
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @retval DSTATUS: Operation status
|
||||
*/
|
||||
DSTATUS USER_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
/* USER CODE BEGIN INIT */
|
||||
return USER_SPI_initialize(pdrv);
|
||||
/* USER CODE END INIT */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets Disk Status
|
||||
* @param pdrv: Physical drive number (0..)
|
||||
* @retval DSTATUS: Operation status
|
||||
*/
|
||||
DSTATUS USER_status (
|
||||
BYTE pdrv /* Physical drive number to identify the drive */
|
||||
)
|
||||
{
|
||||
/* USER CODE BEGIN STATUS */
|
||||
return USER_SPI_status(pdrv);
|
||||
/* USER CODE END STATUS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 USER_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 */
|
||||
)
|
||||
{
|
||||
/* USER CODE BEGIN READ */
|
||||
return USER_SPI_read(pdrv, buff, sector, count);
|
||||
/* USER CODE END READ */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 USER_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 */
|
||||
)
|
||||
{
|
||||
/* USER CODE BEGIN WRITE */
|
||||
/* USER CODE HERE */
|
||||
return USER_SPI_write(pdrv, buff, sector, count);
|
||||
/* USER CODE END WRITE */
|
||||
}
|
||||
#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 USER_ioctl (
|
||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
/* USER CODE BEGIN IOCTL */
|
||||
return USER_SPI_ioctl(pdrv, cmd, buff);
|
||||
/* USER CODE END IOCTL */
|
||||
}
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
47
firmware/Middlewares/Third_Party/FatFs/src/user_diskio.h
vendored
Normal file
47
firmware/Middlewares/Third_Party/FatFs/src/user_diskio.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user_diskio.h
|
||||
* @brief This file contains the common defines and functions prototypes for
|
||||
* the user_diskio driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USER_DISKIO_H
|
||||
#define __USER_DISKIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "user_diskio_spi.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern Diskio_drvTypeDef USER_Driver;
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USER_DISKIO_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
550
firmware/Middlewares/Third_Party/FatFs/src/user_diskio_spi.c
vendored
Normal file
550
firmware/Middlewares/Third_Party/FatFs/src/user_diskio_spi.c
vendored
Normal file
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user_diskio_spi.c
|
||||
* @brief This file contains the implementation of the user_diskio_spi FatFs
|
||||
* driver.
|
||||
******************************************************************************
|
||||
* Portions copyright (C) 2014, ChaN, all rights reserved.
|
||||
* Portions copyright (C) 2017, kiwih, all rights reserved.
|
||||
*
|
||||
* This software is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
* personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//This code was ported by kiwih from a copywrited (C) library written by ChaN
|
||||
//available at http://elm-chan.org/fsw/ff/ffsample.zip
|
||||
//(text at http://elm-chan.org/fsw/ff/00index_e.html)
|
||||
|
||||
//This file provides the FatFs driver functions and SPI code required to manage
|
||||
//an SPI-connected MMC or compatible SD card with FAT
|
||||
|
||||
//It is designed to be wrapped by a cubemx generated user_diskio.c file.
|
||||
|
||||
#include "stm32f1xx_hal.h" /* Provide the low-level HAL functions */
|
||||
#include "user_diskio_spi.h"
|
||||
|
||||
//Make sure you set #define SD_SPI_HANDLE as some hspix in main.h
|
||||
//Make sure you set #define SD_CS_GPIO_Port as some GPIO port in main.h
|
||||
//Make sure you set #define SD_CS_Pin as some GPIO pin in main.h
|
||||
extern SPI_HandleTypeDef SD_SPI_HANDLE;
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
//(Note that the _256 is used as a mask to clear the prescalar bits as it provides binary 111 in the correct position)
|
||||
#define FCLK_SLOW() { MODIFY_REG(SD_SPI_HANDLE.Instance->CR1, SPI_BAUDRATEPRESCALER_256, SPI_BAUDRATEPRESCALER_128); } /* Set SCLK = slow, approx 280 KBits/s*/
|
||||
#define FCLK_FAST() { MODIFY_REG(SD_SPI_HANDLE.Instance->CR1, SPI_BAUDRATEPRESCALER_256, SPI_BAUDRATEPRESCALER_16); } /* Set SCLK = fast, approx 4.5 MBits/s */
|
||||
|
||||
#define CS_HIGH() {HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_SET);}
|
||||
#define CS_LOW() {HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET);}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* MMC/SD command */
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND (MMC) */
|
||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
|
||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (24) /* WRITE_BLOCK */
|
||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
||||
#define CMD38 (38) /* ERASE */
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
#define CMD58 (58) /* READ_OCR */
|
||||
|
||||
/* MMC card type flags (MMC_GET_TYPE) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Physical drive status */
|
||||
|
||||
|
||||
static
|
||||
BYTE CardType; /* Card type flags */
|
||||
|
||||
uint32_t spiTimerTickStart;
|
||||
uint32_t spiTimerTickDelay;
|
||||
|
||||
void SPI_Timer_On(uint32_t waitTicks) {
|
||||
spiTimerTickStart = HAL_GetTick();
|
||||
spiTimerTickDelay = waitTicks;
|
||||
}
|
||||
|
||||
uint8_t SPI_Timer_Status() {
|
||||
return ((HAL_GetTick() - spiTimerTickStart) < spiTimerTickDelay);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SPI controls (Platform dependent) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
/* Exchange a byte */
|
||||
static
|
||||
BYTE xchg_spi (
|
||||
BYTE dat /* Data to send */
|
||||
)
|
||||
{
|
||||
BYTE rxDat;
|
||||
HAL_SPI_TransmitReceive(&SD_SPI_HANDLE, &dat, &rxDat, 1, 50);
|
||||
return rxDat;
|
||||
}
|
||||
|
||||
|
||||
/* Receive multiple byte */
|
||||
static
|
||||
void rcvr_spi_multi (
|
||||
BYTE *buff, /* Pointer to data buffer */
|
||||
UINT btr /* Number of bytes to receive (even number) */
|
||||
)
|
||||
{
|
||||
for(UINT i=0; i<btr; i++) {
|
||||
*(buff+i) = xchg_spi(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if _USE_WRITE
|
||||
/* Send multiple byte */
|
||||
static
|
||||
void xmit_spi_multi (
|
||||
const BYTE *buff, /* Pointer to the data */
|
||||
UINT btx /* Number of bytes to send (even number) */
|
||||
)
|
||||
{
|
||||
for(UINT i=0; i<btx; i++) {
|
||||
xchg_spi(*(buff+i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for card ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int wait_ready ( /* 1:Ready, 0:Timeout */
|
||||
UINT wt /* Timeout [ms] */
|
||||
)
|
||||
{
|
||||
BYTE d;
|
||||
//wait_ready needs its own timer, unfortunately, so it can't use the
|
||||
//spi_timer functions
|
||||
uint32_t waitSpiTimerTickStart;
|
||||
uint32_t waitSpiTimerTickDelay;
|
||||
|
||||
waitSpiTimerTickStart = HAL_GetTick();
|
||||
waitSpiTimerTickDelay = (uint32_t)wt;
|
||||
do {
|
||||
d = xchg_spi(0xFF);
|
||||
/* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
|
||||
} while (d != 0xFF && ((HAL_GetTick() - waitSpiTimerTickStart) < waitSpiTimerTickDelay)); /* Wait for card goes ready or timeout */
|
||||
|
||||
return (d == 0xFF) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Despiselect card and release SPI */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
void despiselect (void)
|
||||
{
|
||||
CS_HIGH(); /* Set CS# high */
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Select card and wait for ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int spiselect (void) /* 1:OK, 0:Timeout */
|
||||
{
|
||||
CS_LOW(); /* Set CS# low */
|
||||
xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
|
||||
if (wait_ready(500)) return 1; /* Wait for card ready */
|
||||
|
||||
despiselect();
|
||||
return 0; /* Timeout */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a data packet from the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int rcvr_datablock ( /* 1:OK, 0:Error */
|
||||
BYTE *buff, /* Data buffer */
|
||||
UINT btr /* Data block length (byte) */
|
||||
)
|
||||
{
|
||||
BYTE token;
|
||||
|
||||
|
||||
SPI_Timer_On(200);
|
||||
do { /* Wait for DataStart token in timeout of 200ms */
|
||||
token = xchg_spi(0xFF);
|
||||
/* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
|
||||
} while ((token == 0xFF) && SPI_Timer_Status());
|
||||
if(token != 0xFE) return 0; /* Function fails if invalid DataStart token or timeout */
|
||||
|
||||
rcvr_spi_multi(buff, btr); /* Store trailing data to the buffer */
|
||||
xchg_spi(0xFF); xchg_spi(0xFF); /* Discard CRC */
|
||||
|
||||
return 1; /* Function succeeded */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a data packet to the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
static
|
||||
int xmit_datablock ( /* 1:OK, 0:Failed */
|
||||
const BYTE *buff, /* Ponter to 512 byte data to be sent */
|
||||
BYTE token /* Token */
|
||||
)
|
||||
{
|
||||
BYTE resp;
|
||||
|
||||
|
||||
if (!wait_ready(500)) return 0; /* Wait for card ready */
|
||||
|
||||
xchg_spi(token); /* Send token */
|
||||
if (token != 0xFD) { /* Send data if token is other than StopTran */
|
||||
xmit_spi_multi(buff, 512); /* Data */
|
||||
xchg_spi(0xFF); xchg_spi(0xFF); /* Dummy CRC */
|
||||
|
||||
resp = xchg_spi(0xFF); /* Receive data resp */
|
||||
if ((resp & 0x1F) != 0x05) return 0; /* Function fails if the data packet was not accepted */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to the MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE send_cmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
|
||||
BYTE cmd, /* Command index */
|
||||
DWORD arg /* Argument */
|
||||
)
|
||||
{
|
||||
BYTE n, res;
|
||||
|
||||
|
||||
if (cmd & 0x80) { /* Send a CMD55 prior to ACMD<n> */
|
||||
cmd &= 0x7F;
|
||||
res = send_cmd(CMD55, 0);
|
||||
if (res > 1) return res;
|
||||
}
|
||||
|
||||
/* Select the card and wait for ready except to stop multiple block read */
|
||||
if (cmd != CMD12) {
|
||||
despiselect();
|
||||
if (!spiselect()) return 0xFF;
|
||||
}
|
||||
|
||||
/* Send command packet */
|
||||
xchg_spi(0x40 | cmd); /* Start + command index */
|
||||
xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
|
||||
xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
|
||||
xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
|
||||
xchg_spi((BYTE)arg); /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
|
||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
|
||||
xchg_spi(n);
|
||||
|
||||
/* Receive command resp */
|
||||
if (cmd == CMD12) xchg_spi(0xFF); /* Diacard following one byte when CMD12 */
|
||||
n = 10; /* Wait for response (10 bytes max) */
|
||||
do {
|
||||
res = xchg_spi(0xFF);
|
||||
} while ((res & 0x80) && --n);
|
||||
|
||||
return res; /* Return received response */
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public FatFs Functions (wrapped in user_diskio.c)
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
//The following functions are defined as inline because they aren't the functions that
|
||||
//are passed to FatFs - they are wrapped by autogenerated (non-inline) cubemx template
|
||||
//code.
|
||||
//If you do not wish to use cubemx, remove the "inline" from these functions here
|
||||
//and in the associated .h
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize disk drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
inline DSTATUS USER_SPI_initialize (
|
||||
BYTE drv /* Physical drive number (0) */
|
||||
)
|
||||
{
|
||||
BYTE n, cmd, ty, ocr[4];
|
||||
|
||||
if (drv != 0) return STA_NOINIT; /* Supports only drive 0 */
|
||||
//assume SPI already init init_spi(); /* Initialize SPI */
|
||||
|
||||
if (Stat & STA_NODISK) return Stat; /* Is card existing in the soket? */
|
||||
|
||||
FCLK_SLOW();
|
||||
for (n = 10; n; n--) xchg_spi(0xFF); /* Send 80 dummy clocks */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Put the card SPI/Idle state */
|
||||
SPI_Timer_On(1000); /* Initialization timeout = 1 sec */
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); /* Get 32 bit return value of R7 resp */
|
||||
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* Is the card supports vcc of 2.7-3.6V? */
|
||||
while (SPI_Timer_Status() && send_cmd(ACMD41, 1UL << 30)) ; /* Wait for end of initialization with ACMD41(HCS) */
|
||||
if (SPI_Timer_Status() && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
|
||||
ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* Card id SDv2 */
|
||||
}
|
||||
}
|
||||
} else { /* Not SDv2 card */
|
||||
if (send_cmd(ACMD41, 0) <= 1) { /* SDv1 or MMC? */
|
||||
ty = CT_SD1; cmd = ACMD41; /* SDv1 (ACMD41(0)) */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* MMCv3 (CMD1(0)) */
|
||||
}
|
||||
while (SPI_Timer_Status() && send_cmd(cmd, 0)) ; /* Wait for end of initialization */
|
||||
if (!SPI_Timer_Status() || send_cmd(CMD16, 512) != 0) /* Set block length: 512 */
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
CardType = ty; /* Card type */
|
||||
despiselect();
|
||||
|
||||
if (ty) { /* OK */
|
||||
FCLK_FAST(); /* Set fast clock */
|
||||
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT flag */
|
||||
} else { /* Failed */
|
||||
Stat = STA_NOINIT;
|
||||
}
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get disk status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
inline DSTATUS USER_SPI_status (
|
||||
BYTE drv /* Physical drive number (0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT; /* Supports only drive 0 */
|
||||
|
||||
return Stat; /* Return disk status */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
inline DRESULT USER_SPI_read (
|
||||
BYTE drv, /* Physical drive number (0) */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
UINT count /* Number of sectors to read (1..128) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ot BA conversion (byte addressing cards) */
|
||||
|
||||
if (count == 1) { /* Single sector read */
|
||||
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
|
||||
&& rcvr_datablock(buff, 512)) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
else { /* Multiple sector read */
|
||||
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!rcvr_datablock(buff, 512)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
}
|
||||
despiselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK; /* Return result */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_WRITE
|
||||
inline DRESULT USER_SPI_write (
|
||||
BYTE drv, /* Physical drive number (0) */
|
||||
const BYTE *buff, /* Ponter to the data to write */
|
||||
DWORD sector, /* Start sector number (LBA) */
|
||||
UINT count /* Number of sectors to write (1..128) */
|
||||
)
|
||||
{
|
||||
if (drv || !count) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */
|
||||
if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */
|
||||
|
||||
if (count == 1) { /* Single sector write */
|
||||
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
|
||||
&& xmit_datablock(buff, 0xFE)) {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
else { /* Multiple sector write */
|
||||
if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */
|
||||
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!xmit_datablock(buff, 0xFC)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (!xmit_datablock(0, 0xFD)) count = 1; /* STOP_TRAN token */
|
||||
}
|
||||
}
|
||||
despiselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK; /* Return result */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous drive controls other than data read/write */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#if _USE_IOCTL
|
||||
inline DRESULT USER_SPI_ioctl (
|
||||
BYTE drv, /* Physical drive number (0) */
|
||||
BYTE cmd, /* Control command code */
|
||||
void *buff /* Pointer to the conrtol data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
BYTE n, csd[16];
|
||||
DWORD *dp, st, ed, csize;
|
||||
|
||||
|
||||
if (drv) return RES_PARERR; /* Check parameter */
|
||||
if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check if drive is ready */
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC : /* Wait for end of internal write process of the drive */
|
||||
if (spiselect()) res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get drive capacity in unit of sector (DWORD) */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
|
||||
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
|
||||
*(DWORD*)buff = csize << 10;
|
||||
} else { /* SDC ver 1.XX or MMC ver 3 */
|
||||
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
|
||||
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
|
||||
*(DWORD*)buff = csize << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
if (CardType & CT_SD2) { /* SDC ver 2.00 */
|
||||
if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
|
||||
xchg_spi(0xFF);
|
||||
if (rcvr_datablock(csd, 16)) { /* Read partial block */
|
||||
for (n = 64 - 16; n; n--) xchg_spi(0xFF); /* Purge trailing data */
|
||||
*(DWORD*)buff = 16UL << (csd[10] >> 4);
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
|
||||
if (CardType & CT_SD1) { /* SDC ver 1.XX */
|
||||
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
|
||||
} else { /* MMC */
|
||||
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_TRIM : /* Erase a block of sectors (used when _USE_ERASE == 1) */
|
||||
if (!(CardType & CT_SDC)) break; /* Check if the card is SDC */
|
||||
if (USER_SPI_ioctl(drv, MMC_GET_CSD, csd)) break; /* Get CSD */
|
||||
if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; /* Check if sector erase can be applied to the card */
|
||||
dp = buff; st = dp[0]; ed = dp[1]; /* Load sector block */
|
||||
if (!(CardType & CT_BLOCK)) {
|
||||
st *= 512; ed *= 512;
|
||||
}
|
||||
if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { /* Erase sector block */
|
||||
res = RES_OK; /* FatFs does not check result of this command */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
}
|
||||
|
||||
despiselect();
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
38
firmware/Middlewares/Third_Party/FatFs/src/user_diskio_spi.h
vendored
Normal file
38
firmware/Middlewares/Third_Party/FatFs/src/user_diskio_spi.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user_diskio_spi.h
|
||||
* @brief This file contains the common defines and functions prototypes for
|
||||
* the user_diskio_spi driver implementation
|
||||
******************************************************************************
|
||||
* Portions copyright (C) 2014, ChaN, all rights reserved.
|
||||
* Portions copyright (C) 2017, kiwih, all rights reserved.
|
||||
*
|
||||
* This software is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
* personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _USER_DISKIO_SPI_H
|
||||
#define _USER_DISKIO_SPI_H
|
||||
|
||||
#include "integer.h" //from FatFs middleware library
|
||||
#include "diskio.h" //from FatFs middleware library
|
||||
#include "ff_gen_drv.h" //from FatFs middleware library
|
||||
|
||||
//we define these as inline because we don't want them to be actual function calls (they get "called" from the cubemx autogenerated user_diskio file)
|
||||
//we define them as extern because they are defined in a separate .c file to user_diskio.c (which #includes this .h file)
|
||||
|
||||
extern DSTATUS USER_SPI_initialize (BYTE pdrv);
|
||||
extern DSTATUS USER_SPI_status (BYTE pdrv);
|
||||
extern DRESULT USER_SPI_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
|
||||
#if _USE_WRITE == 1
|
||||
extern DRESULT USER_SPI_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
|
||||
#endif /* _USE_WRITE == 1 */
|
||||
#if _USE_IOCTL == 1
|
||||
extern DRESULT USER_SPI_ioctl (BYTE pdrv, BYTE cmd, void *buff);
|
||||
#endif /* _USE_IOCTL == 1 */
|
||||
|
||||
#endif
|
||||
2
firmware/Middlewares/Third_Party/desktop.ini
vendored
Normal file
2
firmware/Middlewares/Third_Party/desktop.ini
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
2
firmware/Middlewares/desktop.ini
Normal file
2
firmware/Middlewares/desktop.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Program Files\Google\Drive File Stream\54.0.3.0\GoogleDriveFS.exe,23
|
||||
Reference in New Issue
Block a user