first commit
This commit is contained in:
+235
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Header file for the usbd_dfu.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DFU_H
|
||||
#define __USB_DFU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_DFU
|
||||
* @brief This file is the Header file for usbd_dfu.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_DFU_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_DFU_MAX_ITF_NUM))
|
||||
#define USB_DFU_DESC_SIZ 9
|
||||
|
||||
#define DFU_DESCRIPTOR_TYPE 0x21
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* DFU Requests DFU states */
|
||||
/**************************************************/
|
||||
#define APP_STATE_IDLE 0
|
||||
#define APP_STATE_DETACH 1
|
||||
#define DFU_STATE_IDLE 2
|
||||
#define DFU_STATE_DNLOAD_SYNC 3
|
||||
#define DFU_STATE_DNLOAD_BUSY 4
|
||||
#define DFU_STATE_DNLOAD_IDLE 5
|
||||
#define DFU_STATE_MANIFEST_SYNC 6
|
||||
#define DFU_STATE_MANIFEST 7
|
||||
#define DFU_STATE_MANIFEST_WAIT_RESET 8
|
||||
#define DFU_STATE_UPLOAD_IDLE 9
|
||||
#define DFU_STATE_ERROR 10
|
||||
|
||||
/**************************************************/
|
||||
/* DFU errors */
|
||||
/**************************************************/
|
||||
#define DFU_ERROR_NONE 0x00
|
||||
#define DFU_ERROR_TARGET 0x01
|
||||
#define DFU_ERROR_FILE 0x02
|
||||
#define DFU_ERROR_WRITE 0x03
|
||||
#define DFU_ERROR_ERASE 0x04
|
||||
#define DFU_ERROR_CHECK_ERASED 0x05
|
||||
#define DFU_ERROR_PROG 0x06
|
||||
#define DFU_ERROR_VERIFY 0x07
|
||||
#define DFU_ERROR_ADDRESS 0x08
|
||||
#define DFU_ERROR_NOTDONE 0x09
|
||||
#define DFU_ERROR_FIRMWARE 0x0A
|
||||
#define DFU_ERROR_VENDOR 0x0B
|
||||
#define DFU_ERROR_USB 0x0C
|
||||
#define DFU_ERROR_POR 0x0D
|
||||
#define DFU_ERROR_UNKNOWN 0x0E
|
||||
#define DFU_ERROR_STALLEDPKT 0x0F
|
||||
|
||||
/**************************************************/
|
||||
/* DFU Manifestation State */
|
||||
/**************************************************/
|
||||
#define DFU_MANIFEST_COMPLETE 0x00
|
||||
#define DFU_MANIFEST_IN_PROGRESS 0x01
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Special Commands with Download Request */
|
||||
/**************************************************/
|
||||
#define DFU_CMD_GETCOMMANDS 0x00
|
||||
#define DFU_CMD_SETADDRESSPOINTER 0x21
|
||||
#define DFU_CMD_ERASE 0x41
|
||||
|
||||
#define DFU_MEDIA_ERASE 0x00
|
||||
#define DFU_MEDIA_PROGRAM 0x01
|
||||
|
||||
/**************************************************/
|
||||
/* Other defines */
|
||||
/**************************************************/
|
||||
/* Bit Detach capable = bit 3 in bmAttributes field */
|
||||
#define DFU_DETACH_MASK (uint8_t)(1 << 4)
|
||||
#define DFU_STATUS_DEPTH (6)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DFU_DETACH = 0,
|
||||
DFU_DNLOAD ,
|
||||
DFU_UPLOAD,
|
||||
DFU_GETSTATUS,
|
||||
DFU_CLRSTATUS,
|
||||
DFU_GETSTATE,
|
||||
DFU_ABORT
|
||||
} DFU_RequestTypeDef;
|
||||
|
||||
typedef void (*pFunction)(void);
|
||||
|
||||
|
||||
/********** Descriptor of DFU interface 0 Alternate setting n ****************/
|
||||
#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
0x00, /* bInterfaceNumber: Number of Interface */ \
|
||||
(n), /* bAlternateSetting: Alternate setting */ \
|
||||
0x00, /* bNumEndpoints*/ \
|
||||
0xFE, /* bInterfaceClass: Application Specific Class Code */ \
|
||||
0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
|
||||
0x02, /* nInterfaceProtocol: DFU mode protocol */ \
|
||||
USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \
|
||||
|
||||
#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), /* XFERSIZEB0 */\
|
||||
((uint8_t)(size >> 8)) /* XFERSIZEB1 */
|
||||
|
||||
#define IS_PROTECTED_AREA(add) (uint8_t)(((add >= 0x08000000) && (add < (APP_DEFAULT_ADD)))? 1:0)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t d32[USBD_DFU_XFER_SIZE/4];
|
||||
uint8_t d8[USBD_DFU_XFER_SIZE];
|
||||
}buffer;
|
||||
|
||||
uint8_t dev_state;
|
||||
uint8_t dev_status[DFU_STATUS_DEPTH];
|
||||
uint8_t manif_state;
|
||||
|
||||
uint32_t wblock_num;
|
||||
uint32_t wlength;
|
||||
uint32_t data_ptr;
|
||||
__IO uint32_t alt_setting;
|
||||
|
||||
}
|
||||
USBD_DFU_HandleTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const uint8_t* pStrDesc;
|
||||
uint16_t (* Init) (void);
|
||||
uint16_t (* DeInit) (void);
|
||||
uint16_t (* Erase) (uint32_t Add);
|
||||
uint16_t (* Write) (uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint8_t* (* Read) (uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint16_t (* GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff);
|
||||
}
|
||||
USBD_DFU_MediaTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_DFU;
|
||||
#define USBD_DFU_CLASS &USBD_DFU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_DFU_RegisterMedia (USBD_HandleTypeDef *pdev,
|
||||
USBD_DFU_MediaTypeDef *fops);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DFU_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu_media_template.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief header file for the usbd_dfu_media_template.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DFU_MEDIA_TEMPLATE_H
|
||||
#define __USBD_DFU_MEDIA_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_dfu.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA
|
||||
* @brief header file for the usbd_dfu_media_template.c file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DFU_MEDIA_TEMPLATE_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+1107
File diff suppressed because it is too large
Load Diff
+139
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu_media_template.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Memory management layer
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_dfu_media_template.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Extern function prototypes ------------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
uint16_t MEM_If_Init(void);
|
||||
uint16_t MEM_If_Erase (uint32_t Add);
|
||||
uint16_t MEM_If_Write (uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint8_t *MEM_If_Read (uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint16_t MEM_If_DeInit(void);
|
||||
uint16_t MEM_If_GetStatus (uint32_t Add, uint8_t Cmd, uint8_t *buffer);
|
||||
|
||||
USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops =
|
||||
{
|
||||
(uint8_t *)"DFU MEDIA",
|
||||
MEM_If_Init,
|
||||
MEM_If_DeInit,
|
||||
MEM_If_Erase,
|
||||
MEM_If_Write,
|
||||
MEM_If_Read,
|
||||
MEM_If_GetStatus,
|
||||
|
||||
};
|
||||
/**
|
||||
* @brief MEM_If_Init
|
||||
* Memory initialization routine.
|
||||
* @param None
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_DeInit
|
||||
* Memory deinitialization routine.
|
||||
* @param None
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_DeInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Erase
|
||||
* Erase sector.
|
||||
* @param Add: Address of sector to be erased.
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Erase(uint32_t Add)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Write
|
||||
* Memory write routine.
|
||||
* @param Add: Address to be written to.
|
||||
* @param Len: Number of data to be written (in bytes).
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Read
|
||||
* Memory read routine.
|
||||
* @param Add: Address to be read from.
|
||||
* @param Len: Number of data to be read (in bytes).
|
||||
* @retval Pointer to the physical address where data should be read.
|
||||
*/
|
||||
uint8_t *MEM_If_Read (uint8_t *src, uint8_t *dest, uint32_t Len)
|
||||
{
|
||||
/* Return a valid address to avoid HardFault */
|
||||
return (uint8_t*)(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flash_If_GetStatus
|
||||
* Memory read routine.
|
||||
* @param Add: Address to be read from.
|
||||
* @param cmd: Number of data to be read (in bytes).
|
||||
* @retval Pointer to the physical address where data should be read.
|
||||
*/
|
||||
uint16_t MEM_If_GetStatus (uint32_t Add, uint8_t Cmd, uint8_t *buffer)
|
||||
{
|
||||
switch (Cmd)
|
||||
{
|
||||
case DFU_MEDIA_PROGRAM:
|
||||
|
||||
break;
|
||||
|
||||
case DFU_MEDIA_ERASE:
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Header file for the usbd_conf_template.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CONF_TEMPLATE_H
|
||||
#define __USBD_CONF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32fxxx.h" /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CONF
|
||||
* @brief USB device low level driver configuration file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CONF_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USBD_MAX_NUM_INTERFACES 1
|
||||
#define USBD_MAX_NUM_CONFIGURATION 1
|
||||
#define USBD_MAX_STR_DESC_SIZ 0x100
|
||||
#define USBD_SUPPORT_USER_STRING 0
|
||||
#define USBD_SELF_POWERED 1
|
||||
#define USBD_DEBUG_LEVEL 2
|
||||
|
||||
/* MSC Class Config */
|
||||
#define MSC_MEDIA_PACKET 8192
|
||||
|
||||
/* CDC Class Config */
|
||||
#define USBD_CDC_INTERVAL 2000
|
||||
|
||||
/* DFU Class Config */
|
||||
#define USBD_DFU_MAX_ITF_NUM 1
|
||||
#define USBD_DFU_XFERS_IZE 1024
|
||||
|
||||
/* AUDIO Class Config */
|
||||
#define USBD_AUDIO_FREQ 22100
|
||||
|
||||
/** @defgroup USBD_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Memory management macros */
|
||||
#define USBD_malloc malloc
|
||||
#define USBD_free free
|
||||
#define USBD_memset memset
|
||||
#define USBD_memcpy memcpy
|
||||
|
||||
/* DEBUG macros */
|
||||
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 0)
|
||||
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBD_UsrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 1)
|
||||
|
||||
#define USBD_ErrLog(...) printf("ERROR: ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBD_ErrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBD_DEBUG_LEVEL > 2)
|
||||
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBD_DbgLog(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CONF_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CONF_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CONF_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CONF_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CONF_TEMPLATE_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_core.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Header file for usbd_core.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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****/
|
||||
|
||||
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_req.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Header file for the usbd_req.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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****/
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_def.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief General defines for the usb device library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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 0
|
||||
#endif
|
||||
|
||||
|
||||
#define USB_LEN_DEV_QUALIFIER_DESC 0x0A
|
||||
#define USB_LEN_DEV_DESC 0x12
|
||||
#define USB_LEN_CFG_DESC 0x09
|
||||
#define USB_LEN_IF_DESC 0x09
|
||||
#define USB_LEN_EP_DESC 0x07
|
||||
#define USB_LEN_OTG_DESC 0x03
|
||||
#define USB_LEN_LANGID_STR_DESC 0x04
|
||||
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09
|
||||
|
||||
#define USBD_IDX_LANGID_STR 0x00
|
||||
#define USBD_IDX_MFC_STR 0x01
|
||||
#define USBD_IDX_PRODUCT_STR 0x02
|
||||
#define USBD_IDX_SERIAL_STR 0x03
|
||||
#define USBD_IDX_CONFIG_STR 0x04
|
||||
#define USBD_IDX_INTERFACE_STR 0x05
|
||||
|
||||
#define USB_REQ_TYPE_STANDARD 0x00
|
||||
#define USB_REQ_TYPE_CLASS 0x20
|
||||
#define USB_REQ_TYPE_VENDOR 0x40
|
||||
#define USB_REQ_TYPE_MASK 0x60
|
||||
|
||||
#define USB_REQ_RECIPIENT_DEVICE 0x00
|
||||
#define USB_REQ_RECIPIENT_INTERFACE 0x01
|
||||
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
|
||||
#define USB_REQ_RECIPIENT_MASK 0x03
|
||||
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
#define USB_DESC_TYPE_BOS 0x0F
|
||||
|
||||
#define USB_CONFIG_REMOTE_WAKEUP 2
|
||||
#define USB_CONFIG_SELF_POWERED 1
|
||||
|
||||
#define USB_FEATURE_EP_HALT 0
|
||||
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||
#define USB_FEATURE_TEST_MODE 2
|
||||
|
||||
#define USB_DEVICE_CAPABITY_TYPE 0x10
|
||||
|
||||
#define USB_HS_MAX_PACKET_SIZE 512
|
||||
#define USB_FS_MAX_PACKET_SIZE 64
|
||||
#define USB_MAX_EP0_SIZE 64
|
||||
|
||||
/* Device Status */
|
||||
#define USBD_STATE_DEFAULT 1
|
||||
#define USBD_STATE_ADDRESSED 2
|
||||
#define USBD_STATE_CONFIGURED 3
|
||||
#define USBD_STATE_SUSPENDED 4
|
||||
|
||||
|
||||
/* EP0 State */
|
||||
#define USBD_EP0_IDLE 0
|
||||
#define USBD_EP0_SETUP 1
|
||||
#define USBD_EP0_DATA_IN 2
|
||||
#define USBD_EP0_DATA_OUT 3
|
||||
#define USBD_EP0_STATUS_IN 4
|
||||
#define USBD_EP0_STATUS_OUT 5
|
||||
#define USBD_EP0_STALL 6
|
||||
|
||||
#define USBD_EP_TYPE_CTRL 0
|
||||
#define USBD_EP_TYPE_ISOC 1
|
||||
#define USBD_EP_TYPE_BULK 2
|
||||
#define USBD_EP_TYPE_INTR 3
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @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 == 1)
|
||||
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 = 0,
|
||||
USBD_SPEED_FULL = 1,
|
||||
USBD_SPEED_LOW = 2,
|
||||
}USBD_SpeedTypeDef;
|
||||
|
||||
/* Following USB Device status */
|
||||
typedef enum {
|
||||
USBD_OK = 0,
|
||||
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 == 1)
|
||||
uint8_t *(*GetBOSDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||
#endif
|
||||
} USBD_DescriptorsTypeDef;
|
||||
|
||||
/* USB Device handle structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t status;
|
||||
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[15];
|
||||
USBD_EndpointTypeDef ep_out[15];
|
||||
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)) + 1))) << 8))
|
||||
|
||||
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
|
||||
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
|
||||
#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__) /* GNU Compiler */
|
||||
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||
#define __ALIGN_BEGIN
|
||||
#else
|
||||
#define __ALIGN_END
|
||||
#if defined (__CC_ARM) /* ARM Compiler */
|
||||
#define __ALIGN_BEGIN __align(4)
|
||||
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||
#define __ALIGN_BEGIN
|
||||
#elif defined (__TASKING__) /* TASKING Compiler */
|
||||
#define __ALIGN_BEGIN __align(4)
|
||||
#endif /* __CC_ARM */
|
||||
#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****/
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ioreq.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief Header file for the usbd_ioreq.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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 *buf,
|
||||
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);
|
||||
|
||||
uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev ,
|
||||
uint8_t epnum);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_IOREQ_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_conf_template.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief USB Device configuration and interface file
|
||||
* This template should be copied to the user folder, renamed and customized
|
||||
* following user needs.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Initializes the Low Level portion of the Device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-Initializes the Low Level portion of the Device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the Low Level portion of the Device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the Low Level portion of the Device driver.
|
||||
* @param pdev: Device handle
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @param ep_type: Endpoint Type
|
||||
* @param ep_mps: Endpoint Max Packet Size
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr,
|
||||
uint8_t ep_type,
|
||||
uint16_t ep_mps)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flushes an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns Stall condition.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval Stall (1: Yes, 0: No)
|
||||
*/
|
||||
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assigns a USB address to the device.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmits data over an endpoint.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @param pbuf: Pointer to data to be sent
|
||||
* @param size: Data size
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr,
|
||||
uint8_t *pbuf,
|
||||
uint16_t size)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares an endpoint for reception.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @param pbuf: Pointer to data to be received
|
||||
* @param size: Data size
|
||||
* @retval USBD Status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||
uint8_t ep_addr,
|
||||
uint8_t *pbuf,
|
||||
uint16_t size)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the last transferred packet size.
|
||||
* @param pdev: Device handle
|
||||
* @param ep_addr: Endpoint Number
|
||||
* @retval Recived Data Size
|
||||
*/
|
||||
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delays routine for the USB Device Library.
|
||||
* @param Delay: Delay in ms
|
||||
* @retval None
|
||||
*/
|
||||
void USBD_LL_Delay(uint32_t Delay)
|
||||
{
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+569
@@ -0,0 +1,569 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_core.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief This file provides all the USBD core functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
{
|
||||
USBD_ErrLog("Invalid Device handle");
|
||||
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, 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 != 0)
|
||||
{
|
||||
/* link the class to the USB Device handle */
|
||||
pdev->pClass = pclass;
|
||||
status = USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_ErrLog("Invalid Class handle");
|
||||
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, 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)
|
||||
{
|
||||
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) == 0)
|
||||
{
|
||||
ret = USBD_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (1) { asm("nop"); }
|
||||
}
|
||||
}
|
||||
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 & 0x1F)
|
||||
{
|
||||
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 & 0x80);
|
||||
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 == 0)
|
||||
{
|
||||
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,
|
||||
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->pClass->DataOut != NULL)&&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->DataOut(pdev, epnum);
|
||||
}
|
||||
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 == 0)
|
||||
{
|
||||
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,
|
||||
pep->rem_length);
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
USBD_LL_PrepareReceive (pdev,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{ /* last packet is MPS multiple, so send ZLP packet */
|
||||
if((pep->total_length % pep->maxpacket == 0) &&
|
||||
(pep->total_length >= pep->maxpacket) &&
|
||||
(pep->total_length < pdev->ep0_data_len ))
|
||||
{
|
||||
|
||||
USBD_CtlContinueSendData(pdev , NULL, 0);
|
||||
pdev->ep0_data_len = 0;
|
||||
|
||||
/* Prepare endpoint for premature end of transfer */
|
||||
USBD_LL_PrepareReceive (pdev,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pdev->pClass->EP0_TxSent != NULL)&&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->EP0_TxSent(pdev);
|
||||
}
|
||||
USBD_CtlReceiveStatus(pdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pdev->dev_test_mode == 1)
|
||||
{
|
||||
USBD_RunTestMode(pdev);
|
||||
pdev->dev_test_mode = 0;
|
||||
}
|
||||
}
|
||||
else if((pdev->pClass->DataIn != NULL)&&
|
||||
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||
{
|
||||
pdev->pClass->DataIn(pdev, epnum);
|
||||
}
|
||||
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,
|
||||
0x00,
|
||||
USBD_EP_TYPE_CTRL,
|
||||
USB_MAX_EP0_SIZE);
|
||||
|
||||
pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
|
||||
/* Open EP0 IN */
|
||||
USBD_LL_OpenEP(pdev,
|
||||
0x80,
|
||||
USBD_EP_TYPE_CTRL,
|
||||
USB_MAX_EP0_SIZE);
|
||||
|
||||
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||
/* Upon Reset call user call back */
|
||||
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||
|
||||
if (pdev->pClassData)
|
||||
pdev->pClass->DeInit(pdev, 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_DevConnected
|
||||
* Handle device connection event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *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, pdev->dev_config);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+782
@@ -0,0 +1,782 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_req.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief This file provides the standard USB requests following chapter 9.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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->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;
|
||||
}
|
||||
|
||||
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 (pdev->dev_state)
|
||||
{
|
||||
case USBD_STATE_CONFIGURED:
|
||||
|
||||
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
|
||||
{
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
|
||||
if((req->wLength == 0)&& (ret == USBD_OK))
|
||||
{
|
||||
USBD_CtlSendStatus(pdev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev , req);
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
||||
uint8_t ep_addr;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
USBD_EndpointTypeDef *pep;
|
||||
ep_addr = LOBYTE(req->wIndex);
|
||||
|
||||
/* Check if it is a class request */
|
||||
if ((req->bmRequest & 0x60) == 0x20)
|
||||
{
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
switch (req->bRequest)
|
||||
{
|
||||
|
||||
case USB_REQ_SET_FEATURE :
|
||||
|
||||
switch (pdev->dev_state)
|
||||
{
|
||||
case USBD_STATE_ADDRESSED:
|
||||
if ((ep_addr != 0x00) && (ep_addr != 0x80))
|
||||
{
|
||||
USBD_LL_StallEP(pdev , ep_addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_EP_HALT)
|
||||
{
|
||||
if ((ep_addr != 0x00) && (ep_addr != 0x80))
|
||||
{
|
||||
USBD_LL_StallEP(pdev , ep_addr);
|
||||
|
||||
}
|
||||
}
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
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 != 0x00) && (ep_addr != 0x80))
|
||||
{
|
||||
USBD_LL_StallEP(pdev , ep_addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_EP_HALT)
|
||||
{
|
||||
if ((ep_addr & 0x7F) != 0x00)
|
||||
{
|
||||
USBD_LL_ClearStallEP(pdev , ep_addr);
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
}
|
||||
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 & 0x7F) != 0x00)
|
||||
{
|
||||
USBD_LL_StallEP(pdev , ep_addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
|
||||
&pdev->ep_out[ep_addr & 0x7F];
|
||||
if(USBD_LL_IsStallEP(pdev, ep_addr))
|
||||
{
|
||||
pep->status = 0x0001;
|
||||
}
|
||||
else
|
||||
{
|
||||
pep->status = 0x0000;
|
||||
}
|
||||
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&pep->status,
|
||||
2);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev , req);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
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;
|
||||
uint8_t *pbuf;
|
||||
|
||||
|
||||
switch (req->wValue >> 8)
|
||||
{
|
||||
#if (USBD_LPM_ENABLED == 1)
|
||||
case USB_DESC_TYPE_BOS:
|
||||
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
|
||||
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 = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
|
||||
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
pbuf = (uint8_t *)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:
|
||||
pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USBD_IDX_MFC_STR:
|
||||
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USBD_IDX_PRODUCT_STR:
|
||||
pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USBD_IDX_SERIAL_STR:
|
||||
pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USBD_IDX_CONFIG_STR:
|
||||
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
case USBD_IDX_INTERFACE_STR:
|
||||
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
|
||||
break;
|
||||
|
||||
default:
|
||||
#if (USBD_SUPPORT_USER_STRING == 1)
|
||||
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
|
||||
break;
|
||||
#else
|
||||
USBD_CtlError(pdev , req);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case USB_DESC_TYPE_DEVICE_QUALIFIER:
|
||||
|
||||
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||
{
|
||||
pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev , req);
|
||||
return;
|
||||
}
|
||||
|
||||
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
|
||||
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||
{
|
||||
pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
|
||||
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev , req);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev , req);
|
||||
return;
|
||||
}
|
||||
|
||||
if((len != 0)&& (req->wLength != 0))
|
||||
{
|
||||
|
||||
len = MIN(len , req->wLength);
|
||||
|
||||
USBD_CtlSendData (pdev,
|
||||
pbuf,
|
||||
len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 == 0) && (req->wLength == 0))
|
||||
{
|
||||
dev_addr = (uint8_t)(req->wValue) & 0x7F;
|
||||
|
||||
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 != 0)
|
||||
{
|
||||
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 == 0)
|
||||
{
|
||||
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 , 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);
|
||||
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 != 1)
|
||||
{
|
||||
USBD_CtlError(pdev , req);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pdev->dev_state )
|
||||
{
|
||||
case USBD_STATE_ADDRESSED:
|
||||
pdev->dev_default_config = 0;
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&pdev->dev_default_config,
|
||||
1);
|
||||
break;
|
||||
|
||||
case USBD_STATE_CONFIGURED:
|
||||
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)&pdev->dev_config,
|
||||
1);
|
||||
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_ADDRESSED:
|
||||
case USBD_STATE_CONFIGURED:
|
||||
|
||||
#if ( USBD_SELF_POWERED == 1)
|
||||
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
|
||||
#else
|
||||
pdev->dev_config_status = 0;
|
||||
#endif
|
||||
|
||||
if (pdev->dev_remote_wakeup)
|
||||
{
|
||||
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
|
||||
}
|
||||
|
||||
USBD_CtlSendData (pdev,
|
||||
(uint8_t *)& pdev->dev_config_status,
|
||||
2);
|
||||
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 = 1;
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
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_ADDRESSED:
|
||||
case USBD_STATE_CONFIGURED:
|
||||
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
|
||||
{
|
||||
pdev->dev_remote_wakeup = 0;
|
||||
pdev->pClass->Setup (pdev, req);
|
||||
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 + 1);
|
||||
req->wValue = SWAPBYTE (pdata + 2);
|
||||
req->wIndex = SWAPBYTE (pdata + 4);
|
||||
req->wLength = SWAPBYTE (pdata + 6);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 , 0x80);
|
||||
USBD_LL_StallEP(pdev , 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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 = 0;
|
||||
|
||||
if (desc != NULL)
|
||||
{
|
||||
*len = USBD_GetLen(desc) * 2 + 2;
|
||||
unicode[idx++] = *len;
|
||||
unicode[idx++] = USB_DESC_TYPE_STRING;
|
||||
|
||||
while (*desc != '\0')
|
||||
{
|
||||
unicode[idx++] = *desc++;
|
||||
unicode[idx++] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 = 0;
|
||||
|
||||
while (*buf != '\0')
|
||||
{
|
||||
len++;
|
||||
buf++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ioreq.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.4.2
|
||||
* @date 11-December-2015
|
||||
* @brief This file provides the IO requests APIs for control endpoints.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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, 0x00, 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, 0x00, 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,
|
||||
0,
|
||||
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,
|
||||
0,
|
||||
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, 0x00, NULL, 0);
|
||||
|
||||
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,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_GetRxCount
|
||||
* returns the received data length
|
||||
* @param pdev: device instance
|
||||
* @param ep_addr: endpoint address
|
||||
* @retval Rx Data blength
|
||||
*/
|
||||
uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , uint8_t ep_addr)
|
||||
{
|
||||
return USBD_LL_GetRxDataSize(pdev, ep_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contains all the prototypes for the usbh_msc.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_H
|
||||
#define __USBH_MSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE
|
||||
* @brief This file is the Header file for usbh_msc.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_INIT = 0,
|
||||
MSC_IDLE,
|
||||
MSC_TEST_UNIT_READY,
|
||||
MSC_READ_CAPACITY10,
|
||||
MSC_READ_INQUIRY,
|
||||
MSC_REQUEST_SENSE,
|
||||
MSC_READ,
|
||||
MSC_WRITE,
|
||||
MSC_UNRECOVERED_ERROR,
|
||||
MSC_PERIODIC_CHECK,
|
||||
}
|
||||
MSC_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_OK,
|
||||
MSC_NOT_READY,
|
||||
MSC_ERROR,
|
||||
|
||||
}
|
||||
MSC_ErrorTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_REQ_IDLE = 0,
|
||||
MSC_REQ_RESET,
|
||||
MSC_REQ_GET_MAX_LUN,
|
||||
MSC_REQ_ERROR,
|
||||
}
|
||||
MSC_ReqStateTypeDef;
|
||||
|
||||
#ifndef MAX_SUPPORTED_LUN
|
||||
#define MAX_SUPPORTED_LUN 2
|
||||
#endif
|
||||
|
||||
|
||||
/* Structure for LUN */
|
||||
typedef struct
|
||||
{
|
||||
MSC_StateTypeDef state;
|
||||
MSC_ErrorTypeDef error;
|
||||
USBH_StatusTypeDef prev_ready_state;
|
||||
SCSI_CapacityTypeDef capacity;
|
||||
SCSI_SenseTypeDef sense;
|
||||
SCSI_StdInquiryDataTypeDef inquiry;
|
||||
uint8_t state_changed;
|
||||
|
||||
}
|
||||
MSC_LUNTypeDef;
|
||||
|
||||
/* Structure for MSC process */
|
||||
typedef struct _MSC_Process
|
||||
{
|
||||
uint32_t max_lun;
|
||||
uint8_t InPipe;
|
||||
uint8_t OutPipe;
|
||||
uint8_t OutEp;
|
||||
uint8_t InEp;
|
||||
uint16_t OutEpSize;
|
||||
uint16_t InEpSize;
|
||||
MSC_StateTypeDef state;
|
||||
MSC_ErrorTypeDef error;
|
||||
MSC_ReqStateTypeDef req_state;
|
||||
MSC_ReqStateTypeDef prev_req_state;
|
||||
BOT_HandleTypeDef hbot;
|
||||
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
|
||||
uint16_t current_lun;
|
||||
uint16_t rw_lun;
|
||||
uint32_t timer;
|
||||
}
|
||||
MSC_HandleTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USB_REQ_BOT_RESET 0xFF
|
||||
#define USB_REQ_GET_MAX_LUN 0xFE
|
||||
|
||||
|
||||
/* MSC Class Codes */
|
||||
#define USB_MSC_CLASS 0x08
|
||||
|
||||
/* Interface Descriptor field values for HID Boot Protocol */
|
||||
#define MSC_BOT 0x50
|
||||
#define MSC_TRANSPARENT 0x06
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBH_ClassTypeDef USBH_msc;
|
||||
#define USBH_MSC_CLASS &USBH_msc
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Common APIs */
|
||||
uint8_t USBH_MSC_IsReady (USBH_HandleTypeDef *phost);
|
||||
|
||||
/* APIs for LUN */
|
||||
int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_bot.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_msc_bot.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_BOT_H
|
||||
#define __USBH_MSC_BOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT
|
||||
* @brief This file is the Header file for usbh_msc_bot.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
BOT_OK = 0,
|
||||
BOT_FAIL = 1,
|
||||
BOT_PHASE_ERROR = 2,
|
||||
BOT_BUSY = 3
|
||||
}
|
||||
BOT_StatusTypeDef;
|
||||
|
||||
typedef enum {
|
||||
BOT_CMD_IDLE = 0,
|
||||
BOT_CMD_SEND,
|
||||
BOT_CMD_WAIT,
|
||||
}
|
||||
BOT_CMDStateTypeDef;
|
||||
|
||||
/* CSW Status Definitions */
|
||||
typedef enum
|
||||
{
|
||||
|
||||
BOT_CSW_CMD_PASSED = 0x00,
|
||||
BOT_CSW_CMD_FAILED = 0x01,
|
||||
BOT_CSW_PHASE_ERROR = 0x02,
|
||||
}
|
||||
BOT_CSWStatusTypeDef;
|
||||
|
||||
typedef enum {
|
||||
BOT_SEND_CBW = 1,
|
||||
BOT_SEND_CBW_WAIT,
|
||||
BOT_DATA_IN,
|
||||
BOT_DATA_IN_WAIT,
|
||||
BOT_DATA_OUT,
|
||||
BOT_DATA_OUT_WAIT,
|
||||
BOT_RECEIVE_CSW,
|
||||
BOT_RECEIVE_CSW_WAIT,
|
||||
BOT_ERROR_IN,
|
||||
BOT_ERROR_OUT,
|
||||
BOT_UNRECOVERED_ERROR
|
||||
}
|
||||
BOT_StateTypeDef;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct __CBW
|
||||
{
|
||||
uint32_t Signature;
|
||||
uint32_t Tag;
|
||||
uint32_t DataTransferLength;
|
||||
uint8_t Flags;
|
||||
uint8_t LUN;
|
||||
uint8_t CBLength;
|
||||
uint8_t CB[16];
|
||||
}field;
|
||||
uint8_t data[31];
|
||||
}
|
||||
BOT_CBWTypeDef;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct __CSW
|
||||
{
|
||||
uint32_t Signature;
|
||||
uint32_t Tag;
|
||||
uint32_t DataResidue;
|
||||
uint8_t Status;
|
||||
}field;
|
||||
uint8_t data[13];
|
||||
}
|
||||
BOT_CSWTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[16];
|
||||
BOT_StateTypeDef state;
|
||||
BOT_StateTypeDef prev_state;
|
||||
BOT_CMDStateTypeDef cmd_state;
|
||||
BOT_CBWTypeDef cbw;
|
||||
uint8_t Reserved1;
|
||||
BOT_CSWTypeDef csw;
|
||||
uint8_t Reserved2[3];
|
||||
uint8_t *pbuf;
|
||||
}
|
||||
BOT_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define BOT_CBW_SIGNATURE 0x43425355
|
||||
#define BOT_CBW_TAG 0x20304050
|
||||
#define BOT_CSW_SIGNATURE 0x53425355
|
||||
#define BOT_CBW_LENGTH 31
|
||||
#define BOT_CSW_LENGTH 13
|
||||
|
||||
|
||||
|
||||
#define BOT_SEND_CSW_DISABLE 0
|
||||
#define BOT_SEND_CSW_ENABLE 1
|
||||
|
||||
#define BOT_DIR_IN 0
|
||||
#define BOT_DIR_OUT 1
|
||||
#define BOT_DIR_BOTH 2
|
||||
|
||||
#define BOT_PAGE_LENGTH 512
|
||||
|
||||
|
||||
#define BOT_CBW_CB_LENGTH 16
|
||||
|
||||
|
||||
#define USB_REQ_BOT_RESET 0xFF
|
||||
#define USB_REQ_GET_MAX_LUN 0xFE
|
||||
|
||||
#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk
|
||||
Endpoint continuously, this means
|
||||
that device and Host has phase error
|
||||
Hence a Reset is needed */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Error(USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_BOT_H__ */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_scsi.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_msc_scsi.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_SCSI_H
|
||||
#define __USBH_MSC_SCSI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI
|
||||
* @brief This file is the Header file for usbh_msc_scsi.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
// Capacity data.
|
||||
typedef struct
|
||||
{
|
||||
uint32_t block_nbr;
|
||||
uint16_t block_size;
|
||||
} SCSI_CapacityTypeDef;
|
||||
|
||||
|
||||
// Sense data.
|
||||
typedef struct
|
||||
{
|
||||
uint8_t key;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
} SCSI_SenseTypeDef;
|
||||
|
||||
// INQUIRY data.
|
||||
typedef struct
|
||||
{
|
||||
uint8_t PeripheralQualifier;
|
||||
uint8_t DeviceType;
|
||||
uint8_t RemovableMedia;
|
||||
uint8_t vendor_id[9];
|
||||
uint8_t product_id[17];
|
||||
uint8_t revision_id[5];
|
||||
}SCSI_StdInquiryDataTypeDef;
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define OPCODE_TEST_UNIT_READY 0x00
|
||||
#define OPCODE_READ_CAPACITY10 0x25
|
||||
#define OPCODE_READ10 0x28
|
||||
#define OPCODE_WRITE10 0x2A
|
||||
#define OPCODE_REQUEST_SENSE 0x03
|
||||
#define OPCODE_INQUIRY 0x12
|
||||
|
||||
#define DATA_LEN_MODE_TEST_UNIT_READY 0
|
||||
#define DATA_LEN_READ_CAPACITY10 8
|
||||
#define DATA_LEN_INQUIRY 36
|
||||
#define DATA_LEN_REQUEST_SENSE 14
|
||||
|
||||
#define CBW_CB_LENGTH 16
|
||||
#define CBW_LENGTH 10
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_SENSE_KEY_NO_SENSE 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_ASC_NO_ADDITIONAL_SENSE_INFORMATION 0x00
|
||||
#define SCSI_ASC_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASC_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASC_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20
|
||||
#define SCSI_ASC_NOT_READY_TO_READY_CHANGE 0x28
|
||||
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup _Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_CapacityTypeDef *capacity);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_StdInquiryDataTypeDef *inquiry);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_SenseTypeDef *sense_data);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_SCSI_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+805
@@ -0,0 +1,805 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements the MSC class driver functions
|
||||
* ===================================================================
|
||||
* MSC Class Description
|
||||
* ===================================================================
|
||||
* This module manages the MSC class V1.0 following the "Universal
|
||||
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
|
||||
* Sep. 31, 1999".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Bulk-Only Transport protocol
|
||||
* - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE
|
||||
* @brief This file includes the mass storage related functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit (USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
|
||||
USBH_ClassTypeDef USBH_msc =
|
||||
{
|
||||
"MSC",
|
||||
USB_MSC_CLASS,
|
||||
USBH_MSC_InterfaceInit,
|
||||
USBH_MSC_InterfaceDeInit,
|
||||
USBH_MSC_ClassRequest,
|
||||
USBH_MSC_Process,
|
||||
USBH_MSC_SOFProcess,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_InterfaceInit
|
||||
* The function init the MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t interface = 0;
|
||||
USBH_StatusTypeDef status = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle;
|
||||
|
||||
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, MSC_TRANSPARENT, MSC_BOT);
|
||||
|
||||
if(interface == 0xFF) /* Not Valid Interface */
|
||||
{
|
||||
USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_SelectInterface (phost, interface);
|
||||
|
||||
phost->pActiveClass->pData = (MSC_HandleTypeDef *)USBH_malloc (sizeof(MSC_HandleTypeDef));
|
||||
MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress & 0x80)
|
||||
{
|
||||
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress);
|
||||
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress);
|
||||
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
}
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress & 0x80)
|
||||
{
|
||||
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress);
|
||||
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress);
|
||||
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize;
|
||||
}
|
||||
|
||||
MSC_Handle->current_lun = 0;
|
||||
MSC_Handle->rw_lun = 0;
|
||||
MSC_Handle->state = MSC_INIT;
|
||||
MSC_Handle->error = MSC_OK;
|
||||
MSC_Handle->req_state = MSC_REQ_IDLE;
|
||||
MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp);
|
||||
MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp);
|
||||
|
||||
USBH_MSC_BOT_Init(phost);
|
||||
|
||||
/* De-Initialize LUNs information */
|
||||
USBH_memset(MSC_Handle->unit, 0, sizeof(MSC_Handle->unit));
|
||||
|
||||
/* Open the new channels */
|
||||
USBH_OpenPipe (phost,
|
||||
MSC_Handle->OutPipe,
|
||||
MSC_Handle->OutEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_BULK,
|
||||
MSC_Handle->OutEpSize);
|
||||
|
||||
USBH_OpenPipe (phost,
|
||||
MSC_Handle->InPipe,
|
||||
MSC_Handle->InEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_BULK,
|
||||
MSC_Handle->InEpSize);
|
||||
|
||||
|
||||
USBH_LL_SetToggle (phost, MSC_Handle->InPipe,0);
|
||||
USBH_LL_SetToggle (phost, MSC_Handle->OutPipe,0);
|
||||
status = USBH_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_InterfaceDeInit
|
||||
* The function DeInit the Pipes used for the MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_InterfaceDeInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ( MSC_Handle->OutPipe)
|
||||
{
|
||||
USBH_ClosePipe(phost, MSC_Handle->OutPipe);
|
||||
USBH_FreePipe (phost, MSC_Handle->OutPipe);
|
||||
MSC_Handle->OutPipe = 0; /* Reset the Channel as Free */
|
||||
}
|
||||
|
||||
if ( MSC_Handle->InPipe)
|
||||
{
|
||||
USBH_ClosePipe(phost, MSC_Handle->InPipe);
|
||||
USBH_FreePipe (phost, MSC_Handle->InPipe);
|
||||
MSC_Handle->InPipe = 0; /* Reset the Channel as Free */
|
||||
}
|
||||
|
||||
if(phost->pActiveClass->pData)
|
||||
{
|
||||
USBH_free (phost->pActiveClass->pData);
|
||||
phost->pActiveClass->pData = 0;
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_ClassRequest
|
||||
* The function is responsible for handling Standard requests
|
||||
* for MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
uint8_t i;
|
||||
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->req_state)
|
||||
{
|
||||
case MSC_REQ_IDLE:
|
||||
case MSC_REQ_GET_MAX_LUN:
|
||||
/* Issue GetMaxLUN request */
|
||||
status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, (uint8_t *)&MSC_Handle->max_lun);
|
||||
|
||||
/* When devices do not support the GetMaxLun request, this should
|
||||
be considred as only one logical unit is supported */
|
||||
if(status == USBH_NOT_SUPPORTED)
|
||||
{
|
||||
MSC_Handle->max_lun = 0;
|
||||
status = USBH_OK;
|
||||
}
|
||||
|
||||
if(status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->max_lun = (uint8_t )(MSC_Handle->max_lun) + 1;
|
||||
USBH_UsrLog ("Number of supported LUN: %lu", (int32_t)(MSC_Handle->max_lun));
|
||||
|
||||
for(i = 0; i < MSC_Handle->max_lun; i++)
|
||||
{
|
||||
MSC_Handle->unit[i].prev_ready_state = USBH_FAIL;
|
||||
MSC_Handle->unit[i].state_changed = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQ_ERROR :
|
||||
/* a Clear Feature should be issued here */
|
||||
if(USBH_ClrFeature(phost, 0x00) == USBH_OK)
|
||||
{
|
||||
MSC_Handle->req_state = MSC_Handle->prev_req_state;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Process
|
||||
* The function is for managing state machine for MSC data transfers
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
USBH_StatusTypeDef scsi_status = USBH_BUSY ;
|
||||
USBH_StatusTypeDef ready_status = USBH_BUSY ;
|
||||
|
||||
switch (MSC_Handle->state)
|
||||
{
|
||||
case MSC_INIT:
|
||||
|
||||
if(MSC_Handle->current_lun < MSC_Handle->max_lun)
|
||||
{
|
||||
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->unit[MSC_Handle->current_lun].state)
|
||||
{
|
||||
case MSC_INIT:
|
||||
USBH_UsrLog ("LUN #%d: ", MSC_Handle->current_lun);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY;
|
||||
MSC_Handle->timer = phost->Timer;
|
||||
|
||||
case MSC_READ_INQUIRY:
|
||||
scsi_status = USBH_MSC_SCSI_Inquiry(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
USBH_UsrLog ("Inquiry Vendor : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.vendor_id);
|
||||
USBH_UsrLog ("Inquiry Product : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.product_id);
|
||||
USBH_UsrLog ("Inquiry Version : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.revision_id);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_TEST_UNIT_READY:
|
||||
ready_status = USBH_MSC_SCSI_TestUnitReady(phost, MSC_Handle->current_lun);
|
||||
|
||||
if( ready_status == USBH_OK)
|
||||
{
|
||||
if( MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1;
|
||||
USBH_UsrLog ("MSC Device ready");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0;
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_CAPACITY10;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_OK;
|
||||
}
|
||||
if( ready_status == USBH_FAIL)
|
||||
{
|
||||
/* Media not ready, so try to check again during 10s */
|
||||
if( MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1;
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0;
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_FAIL;
|
||||
}
|
||||
else if(ready_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_READ_CAPACITY10:
|
||||
scsi_status = USBH_MSC_SCSI_ReadCapacity(phost,MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].capacity) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
if(MSC_Handle->unit[MSC_Handle->current_lun].state_changed == 1)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device capacity : %lu Bytes", \
|
||||
(int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr * MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
|
||||
USBH_UsrLog ("Block number : %lu", (int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr));
|
||||
USBH_UsrLog ("Block Size : %lu", (int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
|
||||
MSC_Handle->current_lun++;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_SENSE:
|
||||
scsi_status = USBH_MSC_SCSI_RequestSense(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].sense);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
if((MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_UNIT_ATTENTION) ||
|
||||
(MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY) )
|
||||
{
|
||||
|
||||
if((phost->Timer - MSC_Handle->timer) < 10000)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
USBH_UsrLog ("Sense Key : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.key);
|
||||
USBH_UsrLog ("Additional Sense Code : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.asc);
|
||||
USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.ascq);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->current_lun++;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_UNRECOVERED_ERROR:
|
||||
MSC_Handle->current_lun++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->current_lun = 0;
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_IDLE:
|
||||
error = USBH_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SOFProcess
|
||||
* The function is for SOF state
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_MSC_RdWrProcess
|
||||
* The function is for managing state machine for MSC I/O Process
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
USBH_StatusTypeDef scsi_status = USBH_BUSY ;
|
||||
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->unit[lun].state)
|
||||
{
|
||||
|
||||
case MSC_READ:
|
||||
scsi_status = USBH_MSC_SCSI_Read(phost,lun, 0, NULL, 0) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
error = USBH_OK;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MSC_WRITE:
|
||||
scsi_status = USBH_MSC_SCSI_Write(phost,lun, 0, NULL, 0) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
error = USBH_OK;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_SENSE:
|
||||
scsi_status = USBH_MSC_SCSI_RequestSense(phost, lun, &MSC_Handle->unit[lun].sense);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
USBH_UsrLog ("Sense Key : %x", MSC_Handle->unit[lun].sense.key);
|
||||
USBH_UsrLog ("Additional Sense Code : %x", MSC_Handle->unit[lun].sense.asc);
|
||||
USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq);
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[lun].error = MSC_ERROR;
|
||||
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_IsReady
|
||||
* The function check if the MSC function is ready
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
uint8_t USBH_MSC_IsReady (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
return (MSC_Handle->state == MSC_IDLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_GetMaxLUN
|
||||
* The function return the Max LUN supported
|
||||
* @param phost: Host handle
|
||||
* @retval logical Unit Number supported
|
||||
*/
|
||||
int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
|
||||
{
|
||||
return MSC_Handle->max_lun;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_UnitIsReady
|
||||
* The function check whether a LUN is ready
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval Lun status (0: not ready / 1: ready)
|
||||
*/
|
||||
uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, uint8_t lun)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
return (MSC_Handle->unit[lun].error == MSC_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_GetLUNInfo
|
||||
* The function return a LUN information
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
USBH_memcpy(info,&MSC_Handle->unit[lun], sizeof(MSC_LUNTypeDef));
|
||||
return USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Read
|
||||
* The function performs a Read operation
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to read
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length)
|
||||
{
|
||||
uint32_t timeout;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->unit[lun].state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
MSC_Handle->state = MSC_READ;
|
||||
MSC_Handle->unit[lun].state = MSC_READ;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
USBH_MSC_SCSI_Read(phost,
|
||||
lun,
|
||||
address,
|
||||
pbuf,
|
||||
length);
|
||||
|
||||
timeout = phost->Timer;
|
||||
|
||||
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
|
||||
{
|
||||
if(((phost->Timer - timeout) > (10000 * length)) || (phost->device.is_connected == 0))
|
||||
{
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
return USBH_FAIL;
|
||||
}
|
||||
}
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Write
|
||||
* The function performs a Write operation
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to write
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length)
|
||||
{
|
||||
uint32_t timeout;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->unit[lun].state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
MSC_Handle->state = MSC_WRITE;
|
||||
MSC_Handle->unit[lun].state = MSC_WRITE;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
USBH_MSC_SCSI_Write(phost,
|
||||
lun,
|
||||
address,
|
||||
pbuf,
|
||||
length);
|
||||
|
||||
timeout = phost->Timer;
|
||||
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
|
||||
{
|
||||
if(((phost->Timer - timeout) > (10000 * length)) || (phost->device.is_connected == 0))
|
||||
{
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
return USBH_FAIL;
|
||||
}
|
||||
}
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+633
@@ -0,0 +1,633 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_bot.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file includes the BOT protocol related functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT
|
||||
* @brief This file includes the mass storage related functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir);
|
||||
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_REQ_Reset
|
||||
* The function the MSC BOT Reset request.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \
|
||||
USB_REQ_RECIPIENT_INTERFACE;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
|
||||
phost->Control.setup.b.wValue.w = 0;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_REQ_GetMaxLUN
|
||||
* The function the MSC BOT GetMaxLUN request.
|
||||
* @param phost: Host handle
|
||||
* @param Maxlun: pointer to Maxlun variable
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
|
||||
USB_REQ_RECIPIENT_INTERFACE;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
|
||||
phost->Control.setup.b.wValue.w = 0;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 1;
|
||||
|
||||
return USBH_CtlReq(phost, Maxlun , 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Init
|
||||
* The function Initializes the BOT protocol.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
MSC_Handle->hbot.cbw.field.Signature = BOT_CBW_SIGNATURE;
|
||||
MSC_Handle->hbot.cbw.field.Tag = BOT_CBW_TAG;
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Process
|
||||
* The function handle the BOT protocol.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_StatusTypeDef error = USBH_BUSY;
|
||||
BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED;
|
||||
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
uint8_t toggle = 0;
|
||||
|
||||
switch (MSC_Handle->hbot.state)
|
||||
{
|
||||
case BOT_SEND_CBW:
|
||||
MSC_Handle->hbot.cbw.field.LUN = lun;
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT;
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.cbw.data,
|
||||
BOT_CBW_LENGTH,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
|
||||
break;
|
||||
|
||||
case BOT_SEND_CBW_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
|
||||
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
if ( MSC_Handle->hbot.cbw.field.DataTransferLength != 0 )
|
||||
{
|
||||
/* If there is Data Transfer Stage */
|
||||
if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{/* If there is NO Data Transfer Stage */
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
else if(URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Re-send CBW */
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_DATA_IN:
|
||||
/* Send first packet */
|
||||
USBH_BulkReceiveData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->InEpSize ,
|
||||
MSC_Handle->InPipe);
|
||||
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
|
||||
|
||||
break;
|
||||
|
||||
case BOT_DATA_IN_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
|
||||
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
/* Adjust Data pointer and data length */
|
||||
if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize)
|
||||
{
|
||||
MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize;
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = 0;
|
||||
}
|
||||
|
||||
/* More Data To be Received */
|
||||
if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0)
|
||||
{
|
||||
/* Send next packet */
|
||||
USBH_BulkReceiveData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->InEpSize ,
|
||||
MSC_Handle->InPipe);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If value was 0, and successful transfer, then change the state */
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
/* This is Data IN Stage STALL Condition */
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
6.7.2 Host expects to receive data from the device
|
||||
3. On a STALL condition receiving data, then:
|
||||
The host shall accept the data received.
|
||||
The host shall clear the Bulk-In pipe.
|
||||
4. The host shall attempt to receive a CSW.*/
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_DATA_OUT:
|
||||
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->OutEpSize ,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
|
||||
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
|
||||
break;
|
||||
|
||||
case BOT_DATA_OUT_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
|
||||
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
/* Adjust Data pointer and data length */
|
||||
if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize)
|
||||
{
|
||||
MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize;
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = 0;
|
||||
}
|
||||
|
||||
/* More Data To be Sent */
|
||||
if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0)
|
||||
{
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->OutEpSize ,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If value was 0, and successful transfer, then change the state */
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Resend same data */
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
6.7.3 Ho - Host expects to send data to the device
|
||||
3. On a STALL condition sending data, then:
|
||||
" The host shall clear the Bulk-Out pipe.
|
||||
4. The host shall attempt to receive a CSW.
|
||||
*/
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_RECEIVE_CSW:
|
||||
|
||||
USBH_BulkReceiveData (phost,
|
||||
MSC_Handle->hbot.csw.data,
|
||||
BOT_CSW_LENGTH ,
|
||||
MSC_Handle->InPipe);
|
||||
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
|
||||
break;
|
||||
|
||||
case BOT_RECEIVE_CSW_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
|
||||
|
||||
/* Decode CSW */
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
|
||||
CSW_Status = USBH_MSC_DecodeCSW(phost);
|
||||
|
||||
if(CSW_Status == BOT_CSW_CMD_PASSED)
|
||||
{
|
||||
status = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_ERROR_IN:
|
||||
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN);
|
||||
|
||||
if (error == USBH_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
else if (error == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
/* This means that there is a STALL Error limit, Do Reset Recovery */
|
||||
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_ERROR_OUT:
|
||||
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT);
|
||||
|
||||
if ( error == USBH_OK)
|
||||
{
|
||||
|
||||
toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe);
|
||||
USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1- toggle);
|
||||
USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0);
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
}
|
||||
else if (error == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case BOT_UNRECOVERED_ERROR:
|
||||
status = USBH_MSC_BOT_REQ_Reset(phost);
|
||||
if ( status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Abort
|
||||
* The function handle the BOT Abort process.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param dir: direction (0: out / 1 : in)
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_FAIL;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case BOT_DIR_IN :
|
||||
/* send ClrFeture on Bulk IN endpoint */
|
||||
status = USBH_ClrFeature(phost, MSC_Handle->InEp);
|
||||
|
||||
break;
|
||||
|
||||
case BOT_DIR_OUT :
|
||||
/*send ClrFeature on Bulk OUT endpoint */
|
||||
status = USBH_ClrFeature(phost, MSC_Handle->OutEp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_DecodeCSW
|
||||
* This function decodes the CSW received by the device and updates the
|
||||
* same to upper layer.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
* @notes
|
||||
* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
* 6.3.1 Valid CSW Conditions :
|
||||
* The host shall consider the CSW valid when:
|
||||
* 1. dCSWSignature is equal to 53425355h
|
||||
* 2. the CSW is 13 (Dh) bytes in length,
|
||||
* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
|
||||
*/
|
||||
|
||||
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
BOT_CSWStatusTypeDef status = BOT_CSW_CMD_FAILED;
|
||||
|
||||
/*Checking if the transfer length is different than 13*/
|
||||
if(USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != BOT_CSW_LENGTH)
|
||||
{
|
||||
/*(4) Hi > Dn (Host expects to receive data from the device,
|
||||
Device intends to transfer no data)
|
||||
(5) Hi > Di (Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(9) Ho > Dn (Host expects to send data to the device,
|
||||
Device intends to transfer no data)
|
||||
(11) Ho > Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)*/
|
||||
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
else
|
||||
{ /* CSW length is Correct */
|
||||
|
||||
/* Check validity of the CSW Signature and CSWStatus */
|
||||
if(MSC_Handle->hbot.csw.field.Signature == BOT_CSW_SIGNATURE)
|
||||
{/* Check Condition 1. dCSWSignature is equal to 53425355h */
|
||||
|
||||
if(MSC_Handle->hbot.csw.field.Tag == MSC_Handle->hbot.cbw.field.Tag)
|
||||
{
|
||||
/* Check Condition 3. dCSWTag matches the dCBWTag from the
|
||||
corresponding CBW */
|
||||
|
||||
if(MSC_Handle->hbot.csw.field.Status == 0)
|
||||
{
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
|
||||
Hn Host expects no data transfers
|
||||
Hi Host expects to receive data from the device
|
||||
Ho Host expects to send data to the device
|
||||
|
||||
Dn Device intends to transfer no data
|
||||
Di Device intends to send data to the host
|
||||
Do Device intends to receive data from the host
|
||||
|
||||
Section 6.7
|
||||
(1) Hn = Dn (Host expects no data transfers,
|
||||
Device intends to transfer no data)
|
||||
(6) Hi = Di (Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(12) Ho = Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)
|
||||
|
||||
*/
|
||||
|
||||
status = BOT_CSW_CMD_PASSED;
|
||||
}
|
||||
else if(MSC_Handle->hbot.csw.field.Status == 1)
|
||||
{
|
||||
status = BOT_CSW_CMD_FAILED;
|
||||
}
|
||||
|
||||
else if(MSC_Handle->hbot.csw.field.Status == 2)
|
||||
{
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
Section 6.7
|
||||
(2) Hn < Di ( Host expects no data transfers,
|
||||
Device intends to send data to the host)
|
||||
(3) Hn < Do ( Host expects no data transfers,
|
||||
Device intends to receive data from the host)
|
||||
(7) Hi < Di ( Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(8) Hi <> Do ( Host expects to receive data from the device,
|
||||
Device intends to receive data from the host)
|
||||
(10) Ho <> Di (Host expects to send data to the device,
|
||||
Di Device intends to send data to the host)
|
||||
(13) Ho < Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)
|
||||
*/
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
} /* CSW Tag Matching is Checked */
|
||||
} /* CSW Signature Correct Checking */
|
||||
else
|
||||
{
|
||||
/* If the CSW Signature is not valid, We sall return the Phase Error to
|
||||
Upper Layers for Reset Recovery */
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
} /* CSW Length Check*/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_scsi.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements the SCSI commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI
|
||||
* @brief This file includes the mass storage related functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_TestUnitReady
|
||||
* Issue TestUnitReady command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_ReadCapacity
|
||||
* Issue Read Capacity command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the capacity structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_CapacityTypeDef *capacity)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
|
||||
if(error == USBH_OK)
|
||||
{
|
||||
/*assign the capacity*/
|
||||
capacity->block_nbr = MSC_Handle->hbot.pbuf[3] | (MSC_Handle->hbot.pbuf[2] << 8) |\
|
||||
(MSC_Handle->hbot.pbuf[1] << 16) | (MSC_Handle->hbot.pbuf[0] << 24);
|
||||
|
||||
/*assign the page length*/
|
||||
capacity->block_size = MSC_Handle->hbot.pbuf[7] | (MSC_Handle->hbot.pbuf[6] << 8);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Inquiry
|
||||
* Issue Inquiry command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the inquiry structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_StdInquiryDataTypeDef *inquiry)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY;
|
||||
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = 0x24;
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = 0;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
|
||||
if(error == USBH_OK)
|
||||
{
|
||||
USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef));
|
||||
/*assign Inquiry Data */
|
||||
inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1F;
|
||||
inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5;
|
||||
inquiry->RemovableMedia = (MSC_Handle->hbot.pbuf[1] & 0x80)== 0x80;
|
||||
USBH_memcpy (inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8);
|
||||
USBH_memcpy (inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16);
|
||||
USBH_memcpy (inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_RequestSense
|
||||
* Issue RequestSense command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the sense data structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_SenseTypeDef *sense_data)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = DATA_LEN_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = 0;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
|
||||
if(error == USBH_OK)
|
||||
{
|
||||
sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0F;
|
||||
sense_data->asc = MSC_Handle->hbot.pbuf[12];
|
||||
sense_data->ascq = MSC_Handle->hbot.pbuf[13];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Write
|
||||
* Issue write10 command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to write
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_WRITE10;
|
||||
|
||||
/*logical block address*/
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]);
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]);
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
|
||||
/*Transfer length */
|
||||
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
|
||||
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
|
||||
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = pbuf;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Read
|
||||
* Issue Read10 command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to read
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint8_t *pbuf,
|
||||
uint32_t length)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ10;
|
||||
|
||||
/*logical block address*/
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]);
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]);
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
|
||||
/*Transfer length */
|
||||
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
|
||||
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
|
||||
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = pbuf;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_conf_template.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBH_CONF_TEMPLATE_H
|
||||
#define __USBH_CONF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup USBH_OTG_DRIVER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF
|
||||
* @brief usb otg low level driver configuration file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USBH_MAX_NUM_ENDPOINTS 2
|
||||
#define USBH_MAX_NUM_INTERFACES 2
|
||||
#define USBH_MAX_NUM_CONFIGURATION 1
|
||||
#define USBH_KEEP_CFG_DESCRIPTOR 1
|
||||
#define USBH_MAX_NUM_SUPPORTED_CLASS 1
|
||||
#define USBH_MAX_SIZE_CONFIGURATION 0x200
|
||||
#define USBH_MAX_DATA_BUFFER 0x200
|
||||
#define USBH_DEBUG_LEVEL 2
|
||||
#define USBH_USE_OS 1
|
||||
|
||||
/** @defgroup USBH_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Memory management macros */
|
||||
#define USBH_malloc malloc
|
||||
#define USBH_free free
|
||||
#define USBH_memset memset
|
||||
#define USBH_memcpy memcpy
|
||||
|
||||
/* DEBUG macros */
|
||||
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 0)
|
||||
#define USBH_UsrLog(...) printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_UsrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 1)
|
||||
|
||||
#define USBH_ErrLog(...) printf("ERROR: ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_ErrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 2)
|
||||
#define USBH_DbgLog(...) printf("DEBUG : ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_DbgLog(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_CONF_TEMPLATE_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_core.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_core.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_CORE_H
|
||||
#define __USBH_CORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_conf.h"
|
||||
#include "usbh_def.h"
|
||||
#include "usbh_ioreq.h"
|
||||
#include "usbh_pipes.h"
|
||||
#include "usbh_ctlreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE
|
||||
* @brief This file is the Header file for usbh_core.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#define HOST_USER_SELECT_CONFIGURATION 1
|
||||
#define HOST_USER_CLASS_ACTIVE 2
|
||||
#define HOST_USER_CLASS_SELECTED 3
|
||||
#define HOST_USER_CONNECTION 4
|
||||
#define HOST_USER_DISCONNECTION 5
|
||||
#define HOST_USER_UNRECOVERED_ERROR 6
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id);
|
||||
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass);
|
||||
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface);
|
||||
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t Class,
|
||||
uint8_t SubClass,
|
||||
uint8_t Protocol);
|
||||
uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost,
|
||||
uint8_t interface_number,
|
||||
uint8_t alt_settings);
|
||||
|
||||
USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_Process (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost);
|
||||
|
||||
/* USBH Low Level Driver */
|
||||
USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Start (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost);
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost);
|
||||
USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost);
|
||||
uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t );
|
||||
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t );
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost, uint8_t, uint8_t, uint8_t, uint8_t , uint8_t, uint16_t );
|
||||
USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t );
|
||||
USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost, uint8_t, uint8_t,uint8_t, uint8_t, uint8_t*, uint16_t, uint8_t );
|
||||
USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t );
|
||||
#if (USBH_USE_OS == 1)
|
||||
USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost);
|
||||
#endif
|
||||
USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t , uint8_t );
|
||||
uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t );
|
||||
|
||||
/* USBH Time base */
|
||||
void USBH_Delay (uint32_t Delay);
|
||||
void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t );
|
||||
void USBH_LL_IncTimer (USBH_HandleTypeDef *phost);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_CORE_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ctlreq.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_ctlreq.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_CTLREQ_H
|
||||
#define __USBH_CTLREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ
|
||||
* @brief This file is the
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/*Standard Feature Selector for clear feature command*/
|
||||
#define FEATURE_SELECTOR_ENDPOINT 0X00
|
||||
#define FEATURE_SELECTOR_DEVICE 0X01
|
||||
|
||||
|
||||
#define INTERFACE_DESC_TYPE 0x04
|
||||
#define ENDPOINT_DESC_TYPE 0x05
|
||||
#define INTERFACE_DESC_SIZE 0x09
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern uint8_t USBH_CfgDesc[512];
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost,
|
||||
uint8_t req_type,
|
||||
uint16_t value_idx,
|
||||
uint8_t* buff,
|
||||
uint16_t length );
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost,
|
||||
uint8_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost,
|
||||
uint8_t string_index,
|
||||
uint8_t *buff,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost,
|
||||
uint16_t configuration_value);
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost,
|
||||
uint8_t DeviceAddress);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num, uint8_t altSetting);
|
||||
|
||||
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num);
|
||||
|
||||
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf,
|
||||
uint16_t *ptr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_CTLREQ_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
+490
@@ -0,0 +1,490 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_def.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Definitions used in the USB host library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef USBH_DEF_H
|
||||
#define USBH_DEF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_conf.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_DEF
|
||||
* @brief This file is includes USB descriptors
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
|
||||
#define ValBit(VAR,POS) (VAR & (1 << POS))
|
||||
#define SetBit(VAR,POS) (VAR |= (1 << POS))
|
||||
#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
|
||||
|
||||
#define LE16(addr) (((uint16_t)(*((uint8_t *)(addr))))\
|
||||
+ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
|
||||
|
||||
#define LE16S(addr) (uint16_t)(LE16((addr)))
|
||||
|
||||
#define LE32(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 3))) << 24)))
|
||||
|
||||
#define LE64(addr) ((((uint64_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 1))) << 8) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 2))) << 16) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 3))) << 24) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 4))) << 32) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 5))) << 40) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 6))) << 48) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 7))) << 56)))
|
||||
|
||||
|
||||
#define LE24(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16)))
|
||||
|
||||
|
||||
#define LE32S(addr) (int32_t)(LE32((addr)))
|
||||
|
||||
|
||||
|
||||
#define USB_LEN_DESC_HDR 0x02
|
||||
#define USB_LEN_DEV_DESC 0x12
|
||||
#define USB_LEN_CFG_DESC 0x09
|
||||
#define USB_LEN_IF_DESC 0x09
|
||||
#define USB_LEN_EP_DESC 0x07
|
||||
#define USB_LEN_OTG_DESC 0x03
|
||||
#define USB_LEN_SETUP_PKT 0x08
|
||||
|
||||
/* bmRequestType :D7 Data Phase Transfer Direction */
|
||||
#define USB_REQ_DIR_MASK 0x80
|
||||
#define USB_H2D 0x00
|
||||
#define USB_D2H 0x80
|
||||
|
||||
/* bmRequestType D6..5 Type */
|
||||
#define USB_REQ_TYPE_STANDARD 0x00
|
||||
#define USB_REQ_TYPE_CLASS 0x20
|
||||
#define USB_REQ_TYPE_VENDOR 0x40
|
||||
#define USB_REQ_TYPE_RESERVED 0x60
|
||||
|
||||
/* bmRequestType D4..0 Recipient */
|
||||
#define USB_REQ_RECIPIENT_DEVICE 0x00
|
||||
#define USB_REQ_RECIPIENT_INTERFACE 0x01
|
||||
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
|
||||
#define USB_REQ_RECIPIENT_OTHER 0x03
|
||||
|
||||
/* Table 9-4. Standard Request Codes */
|
||||
/* bRequest , Value */
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
/* Table 9-5. Descriptor Types of USB Specifications */
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
#define USB_DESC_TYPE_INTERFACE_POWER 8
|
||||
#define USB_DESC_TYPE_HID 0x21
|
||||
#define USB_DESC_TYPE_HID_REPORT 0x22
|
||||
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE 18
|
||||
#define USB_CONFIGURATION_DESC_SIZE 9
|
||||
#define USB_HID_DESC_SIZE 9
|
||||
#define USB_INTERFACE_DESC_SIZE 9
|
||||
#define USB_ENDPOINT_DESC_SIZE 7
|
||||
|
||||
/* Descriptor Type and Descriptor Index */
|
||||
/* Use the following values when calling the function USBH_GetDescriptor */
|
||||
#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00)
|
||||
#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00)
|
||||
#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00)
|
||||
#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
|
||||
#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
|
||||
#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00)
|
||||
#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00)
|
||||
#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00)
|
||||
#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00)
|
||||
#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)
|
||||
|
||||
|
||||
#define USB_EP_TYPE_CTRL 0x00
|
||||
#define USB_EP_TYPE_ISOC 0x01
|
||||
#define USB_EP_TYPE_BULK 0x02
|
||||
#define USB_EP_TYPE_INTR 0x03
|
||||
|
||||
#define USB_EP_DIR_OUT 0x00
|
||||
#define USB_EP_DIR_IN 0x80
|
||||
#define USB_EP_DIR_MSK 0x80
|
||||
|
||||
#ifndef USBH_MAX_PIPES_NBR
|
||||
#define USBH_MAX_PIPES_NBR 15
|
||||
#endif /* USBH_MAX_PIPES_NBR */
|
||||
|
||||
#define USBH_DEVICE_ADDRESS_DEFAULT 0
|
||||
#define USBH_MAX_ERROR_COUNT 2
|
||||
#define USBH_DEVICE_ADDRESS 1
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
|
||||
+ USB_INTERFACE_DESC_SIZE\
|
||||
+ (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
|
||||
|
||||
|
||||
#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
|
||||
ConfigurationDescriptor.wTotalLength)
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t w;
|
||||
struct BW
|
||||
{
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
}
|
||||
uint16_t_uint8_t;
|
||||
|
||||
|
||||
typedef union _USB_Setup
|
||||
{
|
||||
uint32_t d8[2];
|
||||
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
}
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
typedef struct _DescHeader
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
}
|
||||
USBH_DescHeader_t;
|
||||
|
||||
typedef struct _DeviceDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB; /* USB Specification Number which device complies too */
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
/* If equal to Zero, each interface specifies its own class
|
||||
code if equal to 0xFF, the class code is vendor specified.
|
||||
Otherwise field is valid Class Code.*/
|
||||
uint8_t bMaxPacketSize;
|
||||
uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */
|
||||
uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */
|
||||
uint16_t bcdDevice; /* Device Release Number */
|
||||
uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */
|
||||
uint8_t iProduct; /* Index of Product String Descriptor */
|
||||
uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */
|
||||
uint8_t bNumConfigurations; /* Number of Possible Configurations */
|
||||
}
|
||||
USBH_DevDescTypeDef;
|
||||
|
||||
typedef struct _EndpointDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */
|
||||
uint8_t bmAttributes; /* specifies the transfer type. */
|
||||
uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */
|
||||
uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */
|
||||
}
|
||||
USBH_EpDescTypeDef;
|
||||
|
||||
typedef struct _InterfaceDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting; /* Value used to select alternative setting */
|
||||
uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */
|
||||
uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */
|
||||
uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */
|
||||
uint8_t bInterfaceProtocol; /* Protocol Code */
|
||||
uint8_t iInterface; /* Index of String Descriptor Describing this interface */
|
||||
USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS];
|
||||
}
|
||||
USBH_InterfaceDescTypeDef;
|
||||
|
||||
|
||||
typedef struct _ConfigurationDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength; /* Total Length of Data Returned */
|
||||
uint8_t bNumInterfaces; /* Number of Interfaces */
|
||||
uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
|
||||
uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */
|
||||
uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
|
||||
uint8_t bMaxPower; /*Maximum Power Consumption */
|
||||
USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
|
||||
}
|
||||
USBH_CfgDescTypeDef;
|
||||
|
||||
|
||||
/* Following USB Host status */
|
||||
typedef enum
|
||||
{
|
||||
USBH_OK = 0,
|
||||
USBH_BUSY,
|
||||
USBH_FAIL,
|
||||
USBH_NOT_SUPPORTED,
|
||||
USBH_UNRECOVERED_ERROR,
|
||||
USBH_ERROR_SPEED_UNKNOWN,
|
||||
}USBH_StatusTypeDef;
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USBH_SPEED_HIGH = 0,
|
||||
USBH_SPEED_FULL = 1,
|
||||
USBH_SPEED_LOW = 2,
|
||||
|
||||
}USBH_SpeedTypeDef;
|
||||
|
||||
/* Following states are used for gState */
|
||||
typedef enum
|
||||
{
|
||||
HOST_IDLE =0,
|
||||
HOST_DEV_WAIT_FOR_ATTACHMENT,
|
||||
HOST_DEV_ATTACHED,
|
||||
HOST_DEV_DISCONNECTED,
|
||||
HOST_DETECT_DEVICE_SPEED,
|
||||
HOST_ENUMERATION,
|
||||
HOST_CLASS_REQUEST,
|
||||
HOST_INPUT,
|
||||
HOST_SET_CONFIGURATION,
|
||||
HOST_CHECK_CLASS,
|
||||
HOST_CLASS,
|
||||
HOST_SUSPENDED,
|
||||
HOST_ABORT_STATE,
|
||||
}HOST_StateTypeDef;
|
||||
|
||||
/* Following states are used for EnumerationState */
|
||||
typedef enum
|
||||
{
|
||||
ENUM_IDLE = 0,
|
||||
ENUM_GET_FULL_DEV_DESC,
|
||||
ENUM_SET_ADDR,
|
||||
ENUM_GET_CFG_DESC,
|
||||
ENUM_GET_FULL_CFG_DESC,
|
||||
ENUM_GET_MFC_STRING_DESC,
|
||||
ENUM_GET_PRODUCT_STRING_DESC,
|
||||
ENUM_GET_SERIALNUM_STRING_DESC,
|
||||
} ENUM_StateTypeDef;
|
||||
|
||||
/* Following states are used for CtrlXferStateMachine */
|
||||
typedef enum
|
||||
{
|
||||
CTRL_IDLE =0,
|
||||
CTRL_SETUP,
|
||||
CTRL_SETUP_WAIT,
|
||||
CTRL_DATA_IN,
|
||||
CTRL_DATA_IN_WAIT,
|
||||
CTRL_DATA_OUT,
|
||||
CTRL_DATA_OUT_WAIT,
|
||||
CTRL_STATUS_IN,
|
||||
CTRL_STATUS_IN_WAIT,
|
||||
CTRL_STATUS_OUT,
|
||||
CTRL_STATUS_OUT_WAIT,
|
||||
CTRL_ERROR,
|
||||
CTRL_STALLED,
|
||||
CTRL_COMPLETE
|
||||
}CTRL_StateTypeDef;
|
||||
|
||||
|
||||
/* Following states are used for RequestState */
|
||||
typedef enum
|
||||
{
|
||||
CMD_IDLE =0,
|
||||
CMD_SEND,
|
||||
CMD_WAIT
|
||||
} CMD_StateTypeDef;
|
||||
|
||||
typedef enum {
|
||||
USBH_URB_IDLE = 0,
|
||||
USBH_URB_DONE,
|
||||
USBH_URB_NOTREADY,
|
||||
USBH_URB_NYET,
|
||||
USBH_URB_ERROR,
|
||||
USBH_URB_STALL
|
||||
}USBH_URBStateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USBH_PORT_EVENT = 1,
|
||||
USBH_URB_EVENT,
|
||||
USBH_CONTROL_EVENT,
|
||||
USBH_CLASS_EVENT,
|
||||
USBH_STATE_CHANGED_EVENT,
|
||||
}
|
||||
USBH_OSEventTypeDef;
|
||||
|
||||
/* Control request structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_in;
|
||||
uint8_t pipe_out;
|
||||
uint8_t pipe_size;
|
||||
uint8_t *buff;
|
||||
uint16_t length;
|
||||
uint16_t timer;
|
||||
USB_Setup_TypeDef setup;
|
||||
CTRL_StateTypeDef state;
|
||||
uint8_t errorcount;
|
||||
|
||||
} USBH_CtrlTypeDef;
|
||||
|
||||
/* Attached device structure */
|
||||
typedef struct
|
||||
{
|
||||
#if (USBH_KEEP_CFG_DESCRIPTOR == 1)
|
||||
uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION];
|
||||
#endif
|
||||
uint8_t Data[USBH_MAX_DATA_BUFFER];
|
||||
uint8_t address;
|
||||
uint8_t speed;
|
||||
__IO uint8_t is_connected;
|
||||
uint8_t current_interface;
|
||||
USBH_DevDescTypeDef DevDesc;
|
||||
USBH_CfgDescTypeDef CfgDesc;
|
||||
|
||||
}USBH_DeviceTypeDef;
|
||||
|
||||
struct _USBH_HandleTypeDef;
|
||||
|
||||
/* USB Host Class structure */
|
||||
typedef struct
|
||||
{
|
||||
const char *Name;
|
||||
uint8_t ClassCode;
|
||||
USBH_StatusTypeDef (*Init) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*DeInit) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*Requests) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*BgndProcess) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*SOFProcess) (struct _USBH_HandleTypeDef *phost);
|
||||
void* pData;
|
||||
} USBH_ClassTypeDef;
|
||||
|
||||
/* USB Host handle structure */
|
||||
typedef struct _USBH_HandleTypeDef
|
||||
{
|
||||
__IO HOST_StateTypeDef gState; /* Host State Machine Value */
|
||||
ENUM_StateTypeDef EnumState; /* Enumeration state Machine */
|
||||
CMD_StateTypeDef RequestState;
|
||||
USBH_CtrlTypeDef Control;
|
||||
USBH_DeviceTypeDef device;
|
||||
USBH_ClassTypeDef* pClass[USBH_MAX_NUM_SUPPORTED_CLASS];
|
||||
USBH_ClassTypeDef* pActiveClass;
|
||||
uint32_t ClassNumber;
|
||||
uint32_t Pipes[15];
|
||||
__IO uint32_t Timer;
|
||||
uint8_t id;
|
||||
void* pData;
|
||||
void (* pUser )(struct _USBH_HandleTypeDef *pHandle, uint8_t id);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessageQId os_event;
|
||||
osThreadId thread;
|
||||
#endif
|
||||
|
||||
} USBH_HandleTypeDef;
|
||||
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif /* __packed */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_DEF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ioreq.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_ioreq.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_IOREQ_H
|
||||
#define __USBH_IOREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_conf.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ
|
||||
* @brief This file is the header file for usbh_ioreq.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USBH_PID_SETUP 0
|
||||
#define USBH_PID_DATA 1
|
||||
|
||||
#define USBH_EP_CONTROL 0
|
||||
#define USBH_EP_ISO 1
|
||||
#define USBH_EP_BULK 2
|
||||
#define USBH_EP_INTERRUPT 3
|
||||
|
||||
#define USBH_SETUP_PKT_SIZE 8
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num,
|
||||
uint8_t do_ping );
|
||||
|
||||
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num,
|
||||
uint8_t do_ping );
|
||||
|
||||
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t hc_num);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_IOREQ_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_pipes.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief Header file for usbh_pipes.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_PIPES_H
|
||||
#define __USBH_PIPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES
|
||||
* @brief This file is the header file for usbh_pipes.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t ch_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps);
|
||||
|
||||
USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num);
|
||||
|
||||
uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_addr);
|
||||
|
||||
USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t idx);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_PIPES_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usb_bsp.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements the board support package for the USB host library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Init
|
||||
* Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DeInit
|
||||
* De-Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Start
|
||||
* Start the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Stop
|
||||
* Stop the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetSpeed
|
||||
* Return the USB Host Speed from the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Speeds
|
||||
*/
|
||||
USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
|
||||
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ResetPort
|
||||
* Reset the Host Port of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetLastXferSize
|
||||
* Return the last transferred packet size.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval Packet Size
|
||||
*/
|
||||
uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_OpenPipe
|
||||
* Open a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @param epnum: Endpoint Number
|
||||
* @param dev_address: Device USB address
|
||||
* @param speed: Device Speed
|
||||
* @param ep_type: Endpoint Type
|
||||
* @param mps: Endpoint Max Packet Size
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ClosePipe
|
||||
* Close a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SubmitURB
|
||||
* Submit a new URB to the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @param direction : Channel number
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : Output
|
||||
* 1 : Input
|
||||
* @param ep_type : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg EP_TYPE_CTRL: Control type
|
||||
* @arg EP_TYPE_ISOC: Isochronous type
|
||||
* @arg EP_TYPE_BULK: Bulk type
|
||||
* @arg EP_TYPE_INTR: Interrupt type
|
||||
* @param token : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg 0: PID_SETUP
|
||||
* @arg 1: PID_DATA
|
||||
* @param pbuff : pointer to URB data
|
||||
* @param length : Length of URB data
|
||||
* @param do_ping : activate do ping protocol (for high speed only)
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : do ping inactive
|
||||
* 1 : do ping active
|
||||
* @retval Status
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe,
|
||||
uint8_t direction ,
|
||||
uint8_t ep_type,
|
||||
uint8_t token,
|
||||
uint8_t* pbuff,
|
||||
uint16_t length,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetURBState
|
||||
* Get a URB state from the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @retval URB state
|
||||
* This parameter can be one of the these values:
|
||||
* @arg URB_IDLE
|
||||
* @arg URB_DONE
|
||||
* @arg URB_NOTREADY
|
||||
* @arg URB_NYET
|
||||
* @arg URB_ERROR
|
||||
* @arg URB_STALL
|
||||
*/
|
||||
USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return USBH_URB_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DriverVBUS
|
||||
* Drive VBUS.
|
||||
* @param phost: Host handle
|
||||
* @param state : VBUS state
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : VBUS Active
|
||||
* 1 : VBUS Inactive
|
||||
* @retval Status
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SetToggle
|
||||
* Set toggle for a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @param pipe_num: Pipe index
|
||||
* @param toggle: toggle (0/1)
|
||||
* @retval Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetToggle
|
||||
* Return the current toggle of a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval toggle (0/1)
|
||||
*/
|
||||
uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
uint8_t toggle = 0;
|
||||
|
||||
|
||||
return toggle;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_Delay
|
||||
* Delay routine for the USB Host Library
|
||||
* @param Delay: Delay in ms
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_Delay (uint32_t Delay)
|
||||
{
|
||||
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+933
@@ -0,0 +1,933 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_core.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements the functions for the core state machine process
|
||||
* the enumeration and the control transfer process
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_core.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE
|
||||
* @brief This file handles the basic enumeration when a device is connected
|
||||
* to the host.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
#define USBH_ADDRESS_DEFAULT 0
|
||||
#define USBH_ADDRESS_ASSIGNED 1
|
||||
#define USBH_MPS_DEFAULT 0x40
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost);
|
||||
static void USBH_HandleSof (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
static void USBH_Process_OS(void const * argument);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HCD_Init
|
||||
* Initialize the HOST Core.
|
||||
* @param phost: Host Handle
|
||||
* @param pUsrFunc: User Callback
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id)
|
||||
{
|
||||
/* Check whether the USB Host handle is valid */
|
||||
if(phost == NULL)
|
||||
{
|
||||
USBH_ErrLog("Invalid Host handle");
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
/* Set DRiver ID */
|
||||
phost->id = id;
|
||||
|
||||
/* Unlink class*/
|
||||
phost->pActiveClass = NULL;
|
||||
phost->ClassNumber = 0;
|
||||
|
||||
/* Restore default states and prepare EP0 */
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Assign User process */
|
||||
if(pUsrFunc != NULL)
|
||||
{
|
||||
phost->pUser = pUsrFunc;
|
||||
}
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
|
||||
/* Create USB Host Queue */
|
||||
osMessageQDef(USBH_Queue, 10, uint16_t);
|
||||
phost->os_event = osMessageCreate (osMessageQ(USBH_Queue), NULL);
|
||||
|
||||
/*Create USB Host Task */
|
||||
#if defined (USBH_PROCESS_STACK_SIZE)
|
||||
osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, USBH_PROCESS_STACK_SIZE);
|
||||
#else
|
||||
osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE);
|
||||
#endif
|
||||
phost->thread = osThreadCreate (osThread(USBH_Thread), phost);
|
||||
#endif
|
||||
|
||||
/* Initialize low level driver */
|
||||
USBH_LL_Init(phost);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HCD_Init
|
||||
* De-Initialize the Host portion of the driver.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
if(phost->pData != NULL)
|
||||
{
|
||||
phost->pActiveClass->pData = NULL;
|
||||
USBH_LL_Stop(phost);
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitStateMachine
|
||||
* De-Initialize the Host state machine.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
/* Clear Pipes flags*/
|
||||
for ( ; i < USBH_MAX_PIPES_NBR; i++)
|
||||
{
|
||||
phost->Pipes[i] = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i< USBH_MAX_DATA_BUFFER; i++)
|
||||
{
|
||||
phost->device.Data[i] = 0;
|
||||
}
|
||||
|
||||
phost->gState = HOST_IDLE;
|
||||
phost->EnumState = ENUM_IDLE;
|
||||
phost->RequestState = CMD_SEND;
|
||||
phost->Timer = 0;
|
||||
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->Control.pipe_size = USBH_MPS_DEFAULT;
|
||||
phost->Control.errorcount = 0;
|
||||
|
||||
phost->device.address = USBH_ADDRESS_DEFAULT;
|
||||
phost->device.speed = USBH_SPEED_FULL;
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_RegisterClass
|
||||
* Link class driver to Host Core.
|
||||
* @param phost : Host Handle
|
||||
* @param pclass: Class handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_OK;
|
||||
|
||||
if(pclass != 0)
|
||||
{
|
||||
if(phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS)
|
||||
{
|
||||
/* link the class to the USB Host handle */
|
||||
phost->pClass[phost->ClassNumber++] = pclass;
|
||||
status = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog("Max Class Number reached");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog("Invalid Class handle");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SelectInterface
|
||||
* Select current interface.
|
||||
* @param phost: Host Handle
|
||||
* @param interface: Interface number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_OK;
|
||||
|
||||
if(interface < phost->device.CfgDesc.bNumInterfaces)
|
||||
{
|
||||
phost->device.current_interface = interface;
|
||||
USBH_UsrLog ("Switching to Interface (#%d)", interface);
|
||||
USBH_UsrLog ("Class : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass );
|
||||
USBH_UsrLog ("SubClass : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass );
|
||||
USBH_UsrLog ("Protocol : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog ("Cannot Select This Interface.");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetActiveClass
|
||||
* Return Device Class.
|
||||
* @param phost: Host Handle
|
||||
* @param interface: Interface index
|
||||
* @retval Class Code
|
||||
*/
|
||||
uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
return (phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass);
|
||||
}
|
||||
/**
|
||||
* @brief USBH_FindInterface
|
||||
* Find the interface index for a specific class.
|
||||
* @param phost: Host Handle
|
||||
* @param Class: Class code
|
||||
* @param SubClass: SubClass code
|
||||
* @param Protocol: Protocol code
|
||||
* @retval interface index in the configuration structure
|
||||
* @note : (1)interface index 0xFF means interface index not found
|
||||
*/
|
||||
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_CfgDescTypeDef *pcfg ;
|
||||
int8_t if_ix = 0;
|
||||
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
pcfg = &phost->device.CfgDesc;
|
||||
|
||||
while (if_ix < USBH_MAX_NUM_INTERFACES)
|
||||
{
|
||||
pif = &pcfg->Itf_Desc[if_ix];
|
||||
if(((pif->bInterfaceClass == Class) || (Class == 0xFF))&&
|
||||
((pif->bInterfaceSubClass == SubClass) || (SubClass == 0xFF))&&
|
||||
((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFF)))
|
||||
{
|
||||
return if_ix;
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_FindInterfaceIndex
|
||||
* Find the interface index for a specific class interface and alternate setting number.
|
||||
* @param phost: Host Handle
|
||||
* @param interface_number: interface number
|
||||
* @param alt_settings : alternate setting number
|
||||
* @retval interface index in the configuration structure
|
||||
* @note : (1)interface index 0xFF means interface index not found
|
||||
*/
|
||||
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_CfgDescTypeDef *pcfg ;
|
||||
int8_t if_ix = 0;
|
||||
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
pcfg = &phost->device.CfgDesc;
|
||||
|
||||
while (if_ix < USBH_MAX_NUM_INTERFACES)
|
||||
{
|
||||
pif = &pcfg->Itf_Desc[if_ix];
|
||||
if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings))
|
||||
{
|
||||
return if_ix;
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Start
|
||||
* Start the USB Host Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/* Start the low level driver */
|
||||
USBH_LL_Start(phost);
|
||||
|
||||
/* Activate VBUS on the port */
|
||||
USBH_LL_DriverVBUS (phost, TRUE);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Stop
|
||||
* Stop the USB Host Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/* Stop and cleanup the low level driver */
|
||||
USBH_LL_Stop(phost);
|
||||
|
||||
/* DeActivate VBUS on the port */
|
||||
USBH_LL_DriverVBUS (phost, FALSE);
|
||||
|
||||
/* FRee Control Pipes */
|
||||
USBH_FreePipe (phost, phost->Control.pipe_in);
|
||||
USBH_FreePipe (phost, phost->Control.pipe_out);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HCD_ReEnumerate
|
||||
* Perform a new Enumeration phase.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/*Stop Host */
|
||||
USBH_Stop(phost);
|
||||
|
||||
/*Device has disconnected, so wait for 200 ms */
|
||||
USBH_Delay(200);
|
||||
|
||||
/* Set State machines in default state */
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Start again the host */
|
||||
USBH_Start(phost);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Process
|
||||
* Background process of the USB Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
__IO USBH_StatusTypeDef status = USBH_FAIL;
|
||||
uint8_t idx = 0;
|
||||
|
||||
switch (phost->gState)
|
||||
{
|
||||
case HOST_IDLE :
|
||||
|
||||
if (phost->device.is_connected)
|
||||
{
|
||||
/* Wait for 200 ms after connection */
|
||||
phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT;
|
||||
USBH_Delay(200);
|
||||
USBH_LL_ResetPort(phost);
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_DEV_WAIT_FOR_ATTACHMENT:
|
||||
break;
|
||||
|
||||
case HOST_DEV_ATTACHED :
|
||||
|
||||
USBH_UsrLog("USB Device Attached");
|
||||
|
||||
/* Wait for 100 ms after Reset */
|
||||
USBH_Delay(100);
|
||||
|
||||
phost->device.speed = USBH_LL_GetSpeed(phost);
|
||||
|
||||
phost->gState = HOST_ENUMERATION;
|
||||
|
||||
phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00);
|
||||
phost->Control.pipe_in = USBH_AllocPipe (phost, 0x80);
|
||||
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case HOST_ENUMERATION:
|
||||
/* Check for enumeration status */
|
||||
if ( USBH_HandleEnum(phost) == USBH_OK)
|
||||
{
|
||||
/* The function shall return USBH_OK when full enumeration is complete */
|
||||
USBH_UsrLog ("Enumeration done.");
|
||||
phost->device.current_interface = 0;
|
||||
if(phost->device.DevDesc.bNumConfigurations == 1)
|
||||
{
|
||||
USBH_UsrLog ("This device has only 1 configuration.");
|
||||
phost->gState = HOST_SET_CONFIGURATION;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_INPUT;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_INPUT:
|
||||
{
|
||||
/* user callback for end of device basic enumeration */
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION);
|
||||
phost->gState = HOST_SET_CONFIGURATION;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_SET_CONFIGURATION:
|
||||
/* set configuration */
|
||||
if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CHECK_CLASS;
|
||||
USBH_UsrLog ("Default configuration set.");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HOST_CHECK_CLASS:
|
||||
|
||||
if(phost->ClassNumber == 0)
|
||||
{
|
||||
USBH_UsrLog ("No Class has been registered.");
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pActiveClass = NULL;
|
||||
|
||||
for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)
|
||||
{
|
||||
if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
|
||||
{
|
||||
phost->pActiveClass = phost->pClass[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
if(phost->pActiveClass->Init(phost)== USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CLASS_REQUEST;
|
||||
USBH_UsrLog ("%s class started.", phost->pActiveClass->Name);
|
||||
|
||||
/* Inform user that a class has been activated */
|
||||
phost->pUser(phost, HOST_USER_CLASS_SELECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_UsrLog ("No registered class for this device.");
|
||||
}
|
||||
}
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HOST_CLASS_REQUEST:
|
||||
/* process class standard control requests state machine */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
status = phost->pActiveClass->Requests(phost);
|
||||
|
||||
if(status == USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CLASS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_ErrLog ("Invalid Class Driver.");
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_CLASS:
|
||||
/* process class state machine */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
phost->pActiveClass->BgndProcess(phost);
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_DEV_DISCONNECTED :
|
||||
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Re-Initilaize Host for new Enumeration */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
phost->pActiveClass->DeInit(phost);
|
||||
phost->pActiveClass = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_ABORT_STATE:
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleEnum
|
||||
* This function includes the complete enumeration process
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_StatusTypeDef Status = USBH_BUSY;
|
||||
|
||||
switch (phost->EnumState)
|
||||
{
|
||||
case ENUM_IDLE:
|
||||
/* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
|
||||
if ( USBH_Get_DevDesc(phost, 8) == USBH_OK)
|
||||
{
|
||||
phost->Control.pipe_size = phost->device.DevDesc.bMaxPacketSize;
|
||||
|
||||
phost->EnumState = ENUM_GET_FULL_DEV_DESC;
|
||||
|
||||
/* modify control channels configuration for MaxPacket size */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_FULL_DEV_DESC:
|
||||
/* Get FULL Device Desc */
|
||||
if ( USBH_Get_DevDesc(phost, USB_DEVICE_DESC_SIZE)== USBH_OK)
|
||||
{
|
||||
USBH_UsrLog("PID: %xh", phost->device.DevDesc.idProduct );
|
||||
USBH_UsrLog("VID: %xh", phost->device.DevDesc.idVendor );
|
||||
|
||||
phost->EnumState = ENUM_SET_ADDR;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_SET_ADDR:
|
||||
/* set address */
|
||||
if ( USBH_SetAddress(phost, USBH_DEVICE_ADDRESS) == USBH_OK)
|
||||
{
|
||||
USBH_Delay(2);
|
||||
phost->device.address = USBH_DEVICE_ADDRESS;
|
||||
|
||||
/* user callback for device address assigned */
|
||||
USBH_UsrLog("Address (#%d) assigned.", phost->device.address);
|
||||
phost->EnumState = ENUM_GET_CFG_DESC;
|
||||
|
||||
/* modify control channels to update device address */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_CFG_DESC:
|
||||
/* get standard configuration descriptor */
|
||||
if ( USBH_Get_CfgDesc(phost,
|
||||
USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
|
||||
{
|
||||
phost->EnumState = ENUM_GET_FULL_CFG_DESC;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_FULL_CFG_DESC:
|
||||
/* get FULL config descriptor (config, interface, endpoints) */
|
||||
if (USBH_Get_CfgDesc(phost,
|
||||
phost->device.CfgDesc.wTotalLength) == USBH_OK)
|
||||
{
|
||||
phost->EnumState = ENUM_GET_MFC_STRING_DESC;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_MFC_STRING_DESC:
|
||||
if (phost->device.DevDesc.iManufacturer != 0)
|
||||
{ /* Check that Manufacturer String is available */
|
||||
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iManufacturer,
|
||||
phost->device.Data ,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Manufacturing string */
|
||||
USBH_UsrLog("Manufacturer : %s", (char *)phost->device.Data);
|
||||
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Manufacturer : N/A");
|
||||
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_PRODUCT_STRING_DESC:
|
||||
if (phost->device.DevDesc.iProduct != 0)
|
||||
{ /* Check that Product string is available */
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iProduct,
|
||||
phost->device.Data,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Product string */
|
||||
USBH_UsrLog("Product : %s", (char *)phost->device.Data);
|
||||
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Product : N/A");
|
||||
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_SERIALNUM_STRING_DESC:
|
||||
if (phost->device.DevDesc.iSerialNumber != 0)
|
||||
{ /* Check that Serial number string is available */
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iSerialNumber,
|
||||
phost->device.Data,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Serial number string */
|
||||
USBH_UsrLog("Serial Number : %s", (char *)phost->device.Data);
|
||||
Status = USBH_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Serial Number : N/A");
|
||||
Status = USBH_OK;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SetTimer
|
||||
* Set the initial Host Timer tick
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t time)
|
||||
{
|
||||
phost->Timer = time;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_LL_IncTimer
|
||||
* Increment Host Timer tick
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_LL_IncTimer (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
phost->Timer ++;
|
||||
USBH_HandleSof(phost);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleSof
|
||||
* Call SOF process
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_HandleSof (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if((phost->gState == HOST_CLASS)&&(phost->pActiveClass != NULL))
|
||||
{
|
||||
phost->pActiveClass->SOFProcess(phost);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief USBH_LL_Connect
|
||||
* Handle USB Host connexion event
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if(phost->gState == HOST_IDLE )
|
||||
{
|
||||
phost->device.is_connected = 1;
|
||||
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_CONNECTION);
|
||||
}
|
||||
}
|
||||
else if(phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT )
|
||||
{
|
||||
phost->gState = HOST_DEV_ATTACHED ;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Disconnect
|
||||
* Handle USB Host disconnection event
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/*Stop Host */
|
||||
USBH_LL_Stop(phost);
|
||||
|
||||
/* FRee Control Pipes */
|
||||
USBH_FreePipe (phost, phost->Control.pipe_in);
|
||||
USBH_FreePipe (phost, phost->Control.pipe_out);
|
||||
|
||||
phost->device.is_connected = 0;
|
||||
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_DISCONNECTION);
|
||||
}
|
||||
USBH_UsrLog("USB Device disconnected");
|
||||
|
||||
/* Start the low level driver */
|
||||
USBH_LL_Start(phost);
|
||||
|
||||
phost->gState = HOST_DEV_DISCONNECTED;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
/**
|
||||
* @brief USB Host Thread task
|
||||
* @param pvParameters not used
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_Process_OS(void const * argument)
|
||||
{
|
||||
osEvent event;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever );
|
||||
|
||||
if( event.status == osEventMessage )
|
||||
{
|
||||
USBH_Process((USBH_HandleTypeDef *)argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_NotifyURBChange
|
||||
* Notify URB state Change
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
return USBH_OK;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+881
@@ -0,0 +1,881 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ctlreq.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements the control requests for device enumeration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_ctlreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ
|
||||
* @brief This file implements the standard requests for device enumeration
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost);
|
||||
|
||||
static void USBH_ParseDevDesc (USBH_DevDescTypeDef* , uint8_t *buf, uint16_t length);
|
||||
|
||||
static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length);
|
||||
|
||||
|
||||
static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor, uint8_t *buf);
|
||||
static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length);
|
||||
static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor, uint8_t *buf);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_DevDesc
|
||||
* Issue Get Device Descriptor command to the device. Once the response
|
||||
* received, it parses the device descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost, uint8_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_DEVICE,
|
||||
phost->device.Data,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseDevDesc(&phost->device.DevDesc, phost->device.Data, length);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_CfgDesc
|
||||
* Issues Configuration Descriptor to the device. Once the response
|
||||
* received, it parses the configuration descriptor and updates the
|
||||
* status.
|
||||
* @param phost: Host Handle
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
uint8_t *pData;
|
||||
#if (USBH_KEEP_CFG_DESCRIPTOR == 1)
|
||||
pData = phost->device.CfgDesc_Raw;
|
||||
#else
|
||||
pData = phost->device.Data;
|
||||
#endif
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_CONFIGURATION,
|
||||
pData,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseCfgDesc (&phost->device.CfgDesc,
|
||||
pData,
|
||||
length);
|
||||
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_StringDesc
|
||||
* Issues string Descriptor command to the device. Once the response
|
||||
* received, it parses the string descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param string_index: String index for the descriptor
|
||||
* @param buff: Buffer address for the descriptor
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost,
|
||||
uint8_t string_index,
|
||||
uint8_t *buff,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_STRING | string_index,
|
||||
phost->device.Data,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseStringDesc(phost->device.Data,buff, length);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetDescriptor
|
||||
* Issues Descriptor command to the device. Once the response received,
|
||||
* it parses the descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param req_type: Descriptor type
|
||||
* @param value_idx: Value for the GetDescriptr request
|
||||
* @param buff: Buffer to store the descriptor
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost,
|
||||
uint8_t req_type,
|
||||
uint16_t value_idx,
|
||||
uint8_t* buff,
|
||||
uint16_t length )
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H | req_type;
|
||||
phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
phost->Control.setup.b.wValue.w = value_idx;
|
||||
|
||||
if ((value_idx & 0xff00) == USB_DESC_STRING)
|
||||
{
|
||||
phost->Control.setup.b.wIndex.w = 0x0409;
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
}
|
||||
phost->Control.setup.b.wLength.w = length;
|
||||
}
|
||||
return USBH_CtlReq(phost, buff , length );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetAddress
|
||||
* This command sets the address to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param DeviceAddress: Device address to assign
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost,
|
||||
uint8_t DeviceAddress)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS;
|
||||
|
||||
phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetCfg
|
||||
* The command sets the configuration value to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param cfg_idx: Configuration value
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost,
|
||||
uint16_t cfg_idx)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
|
||||
phost->Control.setup.b.wValue.w = cfg_idx;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetInterface
|
||||
* The command sets the Interface value to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param altSetting: Interface value
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num, uint8_t altSetting)
|
||||
{
|
||||
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_INTERFACE;
|
||||
phost->Control.setup.b.wValue.w = altSetting;
|
||||
phost->Control.setup.b.wIndex.w = ep_num;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ClrFeature
|
||||
* This request is used to clear or disable a specific feature.
|
||||
* @param phost: Host Handle
|
||||
* @param ep_num: endpoint number
|
||||
* @param hc_num: Host channel number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_RECIPIENT_ENDPOINT |
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
|
||||
phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
|
||||
phost->Control.setup.b.wIndex.w = ep_num;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseDevDesc
|
||||
* This function Parses the device descriptor
|
||||
* @param dev_desc: device_descriptor destination address
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseDevDesc (USBH_DevDescTypeDef* dev_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length)
|
||||
{
|
||||
dev_desc->bLength = *(uint8_t *) (buf + 0);
|
||||
dev_desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
dev_desc->bcdUSB = LE16 (buf + 2);
|
||||
dev_desc->bDeviceClass = *(uint8_t *) (buf + 4);
|
||||
dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5);
|
||||
dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6);
|
||||
dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7);
|
||||
|
||||
if (length > 8)
|
||||
{ /* For 1st time after device connection, Host may issue only 8 bytes for
|
||||
Device Descriptor Length */
|
||||
dev_desc->idVendor = LE16 (buf + 8);
|
||||
dev_desc->idProduct = LE16 (buf + 10);
|
||||
dev_desc->bcdDevice = LE16 (buf + 12);
|
||||
dev_desc->iManufacturer = *(uint8_t *) (buf + 14);
|
||||
dev_desc->iProduct = *(uint8_t *) (buf + 15);
|
||||
dev_desc->iSerialNumber = *(uint8_t *) (buf + 16);
|
||||
dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseCfgDesc
|
||||
* This function Parses the configuration descriptor
|
||||
* @param cfg_desc: Configuration Descriptor address
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_EpDescTypeDef *pep;
|
||||
USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
|
||||
uint16_t ptr;
|
||||
int8_t if_ix = 0;
|
||||
int8_t ep_ix = 0;
|
||||
|
||||
pdesc = (USBH_DescHeader_t *)buf;
|
||||
|
||||
/* Parse configuration descriptor */
|
||||
cfg_desc->bLength = *(uint8_t *) (buf + 0);
|
||||
cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
cfg_desc->wTotalLength = LE16 (buf + 2);
|
||||
cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4);
|
||||
cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5);
|
||||
cfg_desc->iConfiguration = *(uint8_t *) (buf + 6);
|
||||
cfg_desc->bmAttributes = *(uint8_t *) (buf + 7);
|
||||
cfg_desc->bMaxPower = *(uint8_t *) (buf + 8);
|
||||
|
||||
|
||||
if (length > USB_CONFIGURATION_DESC_SIZE)
|
||||
{
|
||||
ptr = USB_LEN_CFG_DESC;
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
|
||||
|
||||
while ((if_ix < USBH_MAX_NUM_INTERFACES ) && (ptr < cfg_desc->wTotalLength))
|
||||
{
|
||||
pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
|
||||
{
|
||||
pif = &cfg_desc->Itf_Desc[if_ix];
|
||||
USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc);
|
||||
|
||||
ep_ix = 0;
|
||||
pep = (USBH_EpDescTypeDef *)0;
|
||||
while ((ep_ix < pif->bNumEndpoints) && (ptr < cfg_desc->wTotalLength))
|
||||
{
|
||||
pdesc = USBH_GetNextDesc((uint8_t*) pdesc, &ptr);
|
||||
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
|
||||
{
|
||||
pep = &cfg_desc->Itf_Desc[if_ix].Ep_Desc[ep_ix];
|
||||
USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
|
||||
ep_ix++;
|
||||
}
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseInterfaceDesc
|
||||
* This function Parses the interface descriptor
|
||||
* @param if_descriptor : Interface descriptor destination
|
||||
* @param buf: Buffer where the descriptor data is available
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor,
|
||||
uint8_t *buf)
|
||||
{
|
||||
if_descriptor->bLength = *(uint8_t *) (buf + 0);
|
||||
if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2);
|
||||
if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3);
|
||||
if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4);
|
||||
if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5);
|
||||
if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6);
|
||||
if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7);
|
||||
if_descriptor->iInterface = *(uint8_t *) (buf + 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseEPDesc
|
||||
* This function Parses the endpoint descriptor
|
||||
* @param ep_descriptor: Endpoint descriptor destination address
|
||||
* @param buf: Buffer where the parsed descriptor stored
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor,
|
||||
uint8_t *buf)
|
||||
{
|
||||
|
||||
ep_descriptor->bLength = *(uint8_t *) (buf + 0);
|
||||
ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2);
|
||||
ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3);
|
||||
ep_descriptor->wMaxPacketSize = LE16 (buf + 4);
|
||||
ep_descriptor->bInterval = *(uint8_t *) (buf + 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseStringDesc
|
||||
* This function Parses the string descriptor
|
||||
* @param psrc: Source pointer containing the descriptor data
|
||||
* @param pdest: Destination address pointer
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseStringDesc (uint8_t* psrc,
|
||||
uint8_t* pdest,
|
||||
uint16_t length)
|
||||
{
|
||||
uint16_t strlength;
|
||||
uint16_t idx;
|
||||
|
||||
/* The UNICODE string descriptor is not NULL-terminated. The string length is
|
||||
computed by substracting two from the value of the first byte of the descriptor.
|
||||
*/
|
||||
|
||||
/* Check which is lower size, the Size of string or the length of bytes read
|
||||
from the device */
|
||||
|
||||
if ( psrc[1] == USB_DESC_TYPE_STRING)
|
||||
{ /* Make sure the Descriptor is String Type */
|
||||
|
||||
/* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */
|
||||
strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length);
|
||||
psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */
|
||||
|
||||
for (idx = 0; idx < strlength; idx+=2 )
|
||||
{/* Copy Only the string and ignore the UNICODE ID, hence add the src */
|
||||
*pdest = psrc[idx];
|
||||
pdest++;
|
||||
}
|
||||
*pdest = 0; /* mark end of string */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetNextDesc
|
||||
* This function return the next descriptor header
|
||||
* @param buf: Buffer where the cfg descriptor is available
|
||||
* @param ptr: data pointer inside the cfg descriptor
|
||||
* @retval next header
|
||||
*/
|
||||
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr)
|
||||
{
|
||||
USBH_DescHeader_t *pnext;
|
||||
|
||||
*ptr += ((USBH_DescHeader_t *)pbuf)->bLength;
|
||||
pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \
|
||||
((USBH_DescHeader_t *)pbuf)->bLength);
|
||||
|
||||
return(pnext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlReq
|
||||
* USBH_CtlReq sends a control request and provide the status after
|
||||
* completion of the request
|
||||
* @param phost: Host Handle
|
||||
* @param req: Setup Request Structure
|
||||
* @param buff: data buffer address to store the response
|
||||
* @param length: length of the response
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
status = USBH_BUSY;
|
||||
|
||||
switch (phost->RequestState)
|
||||
{
|
||||
case CMD_SEND:
|
||||
/* Start a SETUP transfer */
|
||||
phost->Control.buff = buff;
|
||||
phost->Control.length = length;
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->RequestState = CMD_WAIT;
|
||||
status = USBH_BUSY;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CMD_WAIT:
|
||||
status = USBH_HandleControl(phost);
|
||||
if (status == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
phost->RequestState = CMD_SEND;
|
||||
phost->Control.state =CTRL_IDLE;
|
||||
status = USBH_OK;
|
||||
}
|
||||
else if (status == USBH_FAIL)
|
||||
{
|
||||
/* Failure Mode */
|
||||
phost->RequestState = CMD_SEND;
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleControl
|
||||
* Handles the USB control transfer state machine
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t direction;
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
|
||||
|
||||
switch (phost->Control.state)
|
||||
{
|
||||
case CTRL_SETUP:
|
||||
/* send a SETUP packet */
|
||||
USBH_CtlSendSetup (phost,
|
||||
(uint8_t *)phost->Control.setup.d8 ,
|
||||
phost->Control.pipe_out);
|
||||
|
||||
phost->Control.state = CTRL_SETUP_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_SETUP_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out);
|
||||
/* case SETUP packet sent successfully */
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
|
||||
|
||||
/* check if there is a data stage */
|
||||
if (phost->Control.setup.b.wLength.w != 0 )
|
||||
{
|
||||
if (direction == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
phost->Control.state = CTRL_DATA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
phost->Control.state = CTRL_DATA_OUT;
|
||||
}
|
||||
}
|
||||
/* No DATA stage */
|
||||
else
|
||||
{
|
||||
/* If there is No Data Transfer Stage */
|
||||
if (direction == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
phost->Control.state = CTRL_STATUS_IN;
|
||||
}
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if(URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_DATA_IN:
|
||||
/* Issue an IN token */
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlReceiveData(phost,
|
||||
phost->Control.buff,
|
||||
phost->Control.length,
|
||||
phost->Control.pipe_in);
|
||||
|
||||
phost->Control.state = CTRL_DATA_IN_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_DATA_IN_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in);
|
||||
|
||||
/* check is DATA packet transferred successfully */
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* manage error cases*/
|
||||
if (URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
/* In stall case, return to previous machine state*/
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
/* Device error */
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_DATA_OUT:
|
||||
|
||||
USBH_CtlSendData (phost,
|
||||
phost->Control.buff,
|
||||
phost->Control.length ,
|
||||
phost->Control.pipe_out,
|
||||
1);
|
||||
phost->Control.timer = phost->Timer;
|
||||
phost->Control.state = CTRL_DATA_OUT_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_DATA_OUT_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out);
|
||||
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{ /* If the Setup Pkt is sent successful, then change the state */
|
||||
phost->Control.state = CTRL_STATUS_IN;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* handle error cases */
|
||||
else if (URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
/* In stall case, return to previous machine state*/
|
||||
phost->Control.state = CTRL_STALLED;
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if (URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Nack received from device */
|
||||
phost->Control.state = CTRL_DATA_OUT;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
/* device error */
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
status = USBH_FAIL;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CTRL_STATUS_IN:
|
||||
/* Send 0 bytes out packet */
|
||||
USBH_CtlReceiveData (phost,
|
||||
0,
|
||||
0,
|
||||
phost->Control.pipe_in);
|
||||
phost->Control.timer = phost->Timer;
|
||||
phost->Control.state = CTRL_STATUS_IN_WAIT;
|
||||
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_IN_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in);
|
||||
|
||||
if ( URB_Status == USBH_URB_DONE)
|
||||
{ /* Control transfers completed, Exit the State Machine */
|
||||
phost->Control.state = CTRL_COMPLETE;
|
||||
status = USBH_OK;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
/* Control transfers completed, Exit the State Machine */
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_OUT:
|
||||
USBH_CtlSendData (phost,
|
||||
0,
|
||||
0,
|
||||
phost->Control.pipe_out,
|
||||
1);
|
||||
phost->Control.timer = phost->Timer;
|
||||
phost->Control.state = CTRL_STATUS_OUT_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_OUT_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out);
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
status = USBH_OK;
|
||||
phost->Control.state = CTRL_COMPLETE;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if (URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_ERROR:
|
||||
/*
|
||||
After a halt condition is encountered or an error is detected by the
|
||||
host, a control endpoint is allowed to recover by accepting the next Setup
|
||||
PID; i.e., recovery actions via some other pipe are not required for control
|
||||
endpoints. For the Default Control Pipe, a device reset will ultimately be
|
||||
required to clear the halt or error condition if the next Setup PID is not
|
||||
accepted.
|
||||
*/
|
||||
if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
|
||||
{
|
||||
/* try to recover control */
|
||||
USBH_LL_Stop(phost);
|
||||
|
||||
/* Do the transmission again, starting from SETUP Packet */
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->RequestState = CMD_SEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_UNRECOVERED_ERROR);
|
||||
phost->Control.errorcount = 0;
|
||||
USBH_ErrLog("Control error");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
|
||||
+358
@@ -0,0 +1,358 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ioreq.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file handles the issuing of the USB transactions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_ioreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ
|
||||
* @brief This file handles the standard protocol processing (USB v2.0)
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlSendSetup
|
||||
* Sends the Setup Packet to the Device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be send to Device
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_SETUP, /* Type setup */
|
||||
buff, /* data buffer */
|
||||
USBH_SETUP_PKT_SIZE, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlSendData
|
||||
* Sends a data Packet to the Device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be sent to Device
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
if(phost->device.speed != USBH_SPEED_HIGH)
|
||||
{
|
||||
do_ping = 0;
|
||||
}
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
do_ping); /* do ping (HS Only)*/
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlReceiveData
|
||||
* Receives the Device Response to the Setup Packet
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t* buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_BulkSendData
|
||||
* Sends the Bulk Packet to the device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be sent to Device
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
if(phost->device.speed != USBH_SPEED_HIGH)
|
||||
{
|
||||
do_ping = 0;
|
||||
}
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : IN */
|
||||
USBH_EP_BULK, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
do_ping); /* do ping (HS Only)*/
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_BulkReceiveData
|
||||
* Receives IN bulk packet from device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the received data packet to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_BULK, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_InterruptReceiveData
|
||||
* Receives the Device Response to the Interrupt IN token
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_INTERRUPT, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_InterruptSendData
|
||||
* Sends the data on Interrupt OUT Endpoint
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from where the data needs to be copied
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_INTERRUPT, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_IsocReceiveData
|
||||
* Receives the Device Response to the Isochronous IN token
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_ISO, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_IsocSendData
|
||||
* Sends the data on Isochronous OUT Endpoint
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from where the data needs to be copied
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_ISO, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_pipes.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file implements functions for opening and closing Pipes
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_pipes.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES
|
||||
* @brief This file includes opening and closing Pipes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost);
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Open_Pipe
|
||||
* Open a pipe
|
||||
* @param phost: Host Handle
|
||||
* @param pipe_num: Pipe Number
|
||||
* @param dev_address: USB Device address allocated to attached device
|
||||
* @param speed : USB device speed (Full/Low)
|
||||
* @param ep_type: end point type (Bulk/int/ctl)
|
||||
* @param mps: max pkt size
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps)
|
||||
{
|
||||
|
||||
USBH_LL_OpenPipe(phost,
|
||||
pipe_num,
|
||||
epnum,
|
||||
dev_address,
|
||||
speed,
|
||||
ep_type,
|
||||
mps);
|
||||
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ClosePipe
|
||||
* Close a pipe
|
||||
* @param phost: Host Handle
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
|
||||
USBH_LL_ClosePipe(phost, pipe_num);
|
||||
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Alloc_Pipe
|
||||
* Allocate a new Pipe
|
||||
* @param phost: Host Handle
|
||||
* @param ep_addr: End point for which the Pipe to be allocated
|
||||
* @retval Pipe number
|
||||
*/
|
||||
uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost, uint8_t ep_addr)
|
||||
{
|
||||
uint16_t pipe;
|
||||
|
||||
pipe = USBH_GetFreePipe(phost);
|
||||
|
||||
if (pipe != 0xFFFF)
|
||||
{
|
||||
phost->Pipes[pipe] = 0x8000 | ep_addr;
|
||||
}
|
||||
return pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Free_Pipe
|
||||
* Free the USB Pipe
|
||||
* @param phost: Host Handle
|
||||
* @param idx: Pipe number to be freed
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost, uint8_t idx)
|
||||
{
|
||||
if(idx < 11)
|
||||
{
|
||||
phost->Pipes[idx] &= 0x7FFF;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetFreePipe
|
||||
* @param phost: Host Handle
|
||||
* Get a free Pipe number for allocation to a device endpoint
|
||||
* @retval idx: Free Pipe number
|
||||
*/
|
||||
static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
for (idx = 0 ; idx < 11 ; idx++)
|
||||
{
|
||||
if ((phost->Pipes[idx] & 0x8000) == 0)
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user