mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-24 00:35:39 +03:00
Initiate APM32F40X MCU Support in Betaflight (#13709)
* Add APM32F4 driver libraries and USB middleware * Remove all duplicated APM32 driver files and retaining only the APM32 LIB directory
This commit is contained in:
parent
2ff71b0a1f
commit
14bcc13150
258 changed files with 290932 additions and 0 deletions
|
@ -0,0 +1,200 @@
|
|||
/*!
|
||||
* @file usbh_cdc.h
|
||||
*
|
||||
* @brief USB CDC core function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_CDC_H_
|
||||
#define _USBH_CDC_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CDC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CDC_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_CDC_ACM_CODE 0x02
|
||||
#define USBH_CDC_AT_COMMAND_CODE 0x01
|
||||
#define USBH_CDC_LINE_CODING_NUM 0x07
|
||||
|
||||
/**@} end of group USBH_CDC_Macros*/
|
||||
|
||||
/** @defgroup USBH_CDC_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB CDC state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_CDC_INIT = 0,
|
||||
USBH_CDC_IDLE = 1,
|
||||
USBH_CDC_SET_LINE_CODING_STATE,
|
||||
USBH_CDC_GET_LINE_CODING_STATE,
|
||||
USBH_CDC_SET_CONTROL_LINE_STATE,
|
||||
USBH_CDC_TRANSFER_DATA_STATE,
|
||||
USBH_CDC_ERROR_STATE,
|
||||
} USBH_CDC_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief USB CDC data state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_CDC_DATA_IDLE = 0,
|
||||
USBH_CDC_DATA_SEND,
|
||||
USBH_CDC_DATA_SEND_WAIT,
|
||||
USBH_CDC_DATA_RECEIVE,
|
||||
USBH_CDC_DATA_RECEIVE_WAIT,
|
||||
USBH_CDC_DATA_ERROR,
|
||||
} USBH_CDC_DATA_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief USB CDC device class requests type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0,
|
||||
USBH_CDC_REQ_SET_LINE_CODING = 0x20,
|
||||
USBH_CDC_REQ_GET_LINE_CODING,
|
||||
USBH_CDC_REQ_SET_CONTROL_LINE_STATE,
|
||||
} USBH_CDC_REQ_TYPE_T;
|
||||
|
||||
/**@} end of group USBH_CDC_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_CDC_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Host CDC class state handler function */
|
||||
typedef USBH_STA_T(*USBH_CDCStateHandler_T)(USBH_INFO_T* usbInfo);
|
||||
typedef USBH_STA_T(*USBH_CDCDataHandler_T)(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**
|
||||
* @brief CDC line coding structure
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint8_t data[USBH_CDC_LINE_CODING_NUM];
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t dwDTERate;
|
||||
uint8_t bCharFormat;
|
||||
uint8_t bParityType;
|
||||
uint8_t bDataBits;
|
||||
} DATA_B;
|
||||
} USBH_CDC_LINE_CODING_T;
|
||||
|
||||
/**
|
||||
* @brief CDC control line state structure
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint8_t bitmap;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t DTR : 1;
|
||||
uint8_t RTS : 1;
|
||||
uint8_t RESERVED : 6;
|
||||
} DATA_B;
|
||||
|
||||
} USBH_CDC_CONTROL_LINE_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief CDC communication data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t notifyChNum;
|
||||
uint8_t notifyEpAddr;
|
||||
uint16_t notifyEpsize;
|
||||
uint8_t notifyBuffer[8];
|
||||
} USBH_CDC_COMMUNICATION_T;
|
||||
|
||||
/**
|
||||
* @brief CDC transfer data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t txdLength;
|
||||
uint32_t rxdLength;
|
||||
uint8_t* txBuffer;
|
||||
uint8_t* rxBuffer;
|
||||
uint8_t inChNum;
|
||||
uint8_t outChNum;
|
||||
uint8_t inEpAddr;
|
||||
uint8_t outEpAddr;
|
||||
uint16_t inEpsize;
|
||||
uint16_t outEpsize;
|
||||
uint8_t dataBuffer[8];
|
||||
} USBH_CDC_XFER_T;
|
||||
|
||||
/**
|
||||
* @brief CDC information management
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_CDC_STATE_T state;
|
||||
USBH_CDC_DATA_STATE_T dataXferState;
|
||||
USBH_CDC_XFER_T dataXfer;
|
||||
USBH_CDC_LINE_CODING_T userLineCoding;
|
||||
USBH_CDC_LINE_CODING_T* lineCoding;
|
||||
USBH_CDC_CONTROL_LINE_STATE_T* controlLine;
|
||||
USBH_CDC_COMMUNICATION_T comm;
|
||||
uint32_t timer;
|
||||
} USBH_CDC_INFO_T;
|
||||
|
||||
extern USBH_CLASS_T USBH_CDC_CLASS;
|
||||
|
||||
/**@} end of group USBH_CDC_Structures*/
|
||||
|
||||
/** @defgroup USBH_CDC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_CDC_DATA_STATE_T USBH_CDC_ReadDataStatus(USBH_INFO_T* usbInfo);
|
||||
uint16_t USBH_CDC_ReadRevDataSize(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_CDC_SendData(USBH_INFO_T* usbInfo, uint8_t* buffer, uint32_t length);
|
||||
USBH_STA_T USBH_CDC_ReceiveData(USBH_INFO_T* usbInfo, uint8_t* buffer, uint32_t length);
|
||||
|
||||
void USBH_CDC_LineCodingIsChangeCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_CDC_XferEndCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_CDC_RevEndCallback(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_CDC_Functions */
|
||||
/**@} end of group USBH_CDC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,180 @@
|
|||
/*!
|
||||
* @file usbh_hid.h
|
||||
*
|
||||
* @brief USB HID core function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_HID_H_
|
||||
#define _USBH_HID_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_HID_CLASS_CODE 0x03
|
||||
#define USBH_HID_BOOT_CODE 0x01
|
||||
#define USBH_HID_MOUSE_BOOT_CODE 0x02
|
||||
#define USBH_HID_KEYBOARD_BOOT_CODE 0x01
|
||||
|
||||
#define USBH_HID_QUEUE_MAX_SIZE 10
|
||||
#define USBH_HID_POLL_MIN_NUM 10
|
||||
|
||||
/**@} end of group USBH_HID_Macros*/
|
||||
|
||||
/** @defgroup USBH_HID_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB HID state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_HID_INIT = 0,
|
||||
USBH_HID_IDLE = 1,
|
||||
USBH_HID_SYNC,
|
||||
USBH_HID_IN_DATA,
|
||||
USBH_HID_POLL,
|
||||
USBH_HID_OUT_DATA,
|
||||
USBH_HID_BUSY,
|
||||
USBH_HID_ERR,
|
||||
} USBH_HID_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief USB HID request state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_HID_REQ_INIT,
|
||||
USBH_HID_REQ_IDLE,
|
||||
USBH_HID_REQ_GET_REP_DESC,
|
||||
USBH_HID_REQ_GET_HID_DESC,
|
||||
USBH_HID_REQ_SET_IDLE,
|
||||
USBH_HID_REQ_SET_PROTOCOL,
|
||||
USBH_HID_REQ_SET_REPORT,
|
||||
} USBH_HID_REQ_STA_T;
|
||||
|
||||
/**
|
||||
* @brief USB HID report type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HID_INPUT_REPORT = 1,
|
||||
HID_OUTPUT_REPORT,
|
||||
HID_FEATURE_REPORT,
|
||||
} USBH_HID_REPORT_T;
|
||||
|
||||
/**
|
||||
* @brief USB HID device class requests type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_HID_GET_REPORT = 1,
|
||||
USBH_HID_GET_IDLE,
|
||||
USBH_HID_GET_PROTOCOL,
|
||||
USBH_HID_SET_REPORT = 9,
|
||||
USBH_HID_SET_IDLE,
|
||||
USBH_HID_SET_PROTOCOL,
|
||||
} USBH_HID_REQ_TYPE_T;
|
||||
|
||||
/**@} end of group USBH_HID_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB HID descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bcdHID[2];
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bReportDescriptorType;
|
||||
uint8_t wDescriptorLength[2];
|
||||
|
||||
} USBH_HID_DESC_T;
|
||||
|
||||
/* Host HID class state handler function */
|
||||
typedef USBH_STA_T(*USBH_HIDStateHandler_T)(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**
|
||||
* @brief USB host HID class handler
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_STA_T(*InitHandler)(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T(*DecodeHandler)(USBH_INFO_T* usbInfo);
|
||||
} USBH_HID_CLASS_T;
|
||||
|
||||
/**
|
||||
* @brief HID information management
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t* buffer;
|
||||
USBH_HID_STATE_T state;
|
||||
uint8_t classReqState;
|
||||
uint8_t inChNum;
|
||||
uint8_t outChNum;
|
||||
uint8_t intOutEpAddr;
|
||||
uint8_t intInEpAddr;
|
||||
|
||||
uint8_t epAddr;
|
||||
uint8_t epSize;
|
||||
uint16_t pollInterval;
|
||||
uint8_t dataFlag;
|
||||
USBH_HID_DESC_T desc;
|
||||
USBH_HID_CLASS_T* callback;
|
||||
uint32_t timer;
|
||||
} USBH_HID_INFO_T;
|
||||
|
||||
extern USBH_CLASS_T USBH_HID_CLASS;
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
void USBH_HID_PollCallback(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,342 @@
|
|||
/*!
|
||||
* @file usbh_hid_keyboard.h
|
||||
*
|
||||
* @brief USB host HID keyboard function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_HID_KEYBOARD_H_
|
||||
#define _USBH_HID_KEYBOARD_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_hid.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_HID_KEY_PRESSED_NUM_MAX 0x06
|
||||
|
||||
/**@} end of group USBH_HID_Macros*/
|
||||
|
||||
/** @defgroup USBH_HID_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HID keyboard value
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
KEYBOARD_NONE,
|
||||
KEYBOARD_ERROR_ROLL_OVER,
|
||||
KEYBOARD_POST_FAIL,
|
||||
KEYBOARD_ERROR_UNDEFINED,
|
||||
KEYBOARD_A,
|
||||
KEYBOARD_B,
|
||||
KEYBOARD_C,
|
||||
KEYBOARD_D,
|
||||
KEYBOARD_E,
|
||||
KEYBOARD_F,
|
||||
KEYBOARD_G,
|
||||
KEYBOARD_H,
|
||||
KEYBOARD_I,
|
||||
KEYBOARD_J,
|
||||
KEYBOARD_K,
|
||||
KEYBOARD_L,
|
||||
KEYBOARD_M,
|
||||
KEYBOARD_N,
|
||||
KEYBOARD_O,
|
||||
KEYBOARD_P,
|
||||
KEYBOARD_Q,
|
||||
KEYBOARD_R,
|
||||
KEYBOARD_S,
|
||||
KEYBOARD_T,
|
||||
KEYBOARD_U,
|
||||
KEYBOARD_V,
|
||||
KEYBOARD_W,
|
||||
KEYBOARD_X,
|
||||
KEYBOARD_Y,
|
||||
KEYBOARD_Z,
|
||||
KEYBOARD_1_EXCLAMATION,
|
||||
KEYBOARD_2_AT,
|
||||
KEYBOARD_3_NUMBER_SIGN,
|
||||
KEYBOARD_4_DOLLAR,
|
||||
KEYBOARD_5_PERCENT,
|
||||
KEYBOARD_6_CARET,
|
||||
KEYBOARD_7_AMPERSAND,
|
||||
KEYBOARD_8_ASTERISK,
|
||||
KEYBOARD_9_OPARENTHESIS,
|
||||
KEYBOARD_10_CPARENTHESIS,
|
||||
KEYBOARD_ENTER,
|
||||
KEYBOARD_ESCAPE,
|
||||
KEYBOARD_BACKSPACE,
|
||||
KEYBOARD_TAB,
|
||||
KEYBOARD_SPACEBAR,
|
||||
KEYBOARD_MINUS_UNDERSCORE,
|
||||
KEYBOARD_EQUAL_PLUS,
|
||||
KEYBOARD_OBRACKET_AND_OBRACE,
|
||||
KEYBOARD_CBRACKET_AND_CBRACE,
|
||||
KEYBOARD_BACKSLASH_VERTICAL_BAR,
|
||||
KEYBOARD_NONUS_NUMBER_SIGN_TILDE,
|
||||
KEYBOARD_SEMICOLON_COLON,
|
||||
KEYBOARD_SINGLE_AND_DOUBLE_QUOTE,
|
||||
KEYBOARD_GRAVE_ACCENT_AND_TILDE,
|
||||
KEYBOARD_COMMA_AND_LESS,
|
||||
KEYBOARD_DOT_GREATER,
|
||||
KEYBOARD_SLASH_QUESTION,
|
||||
KEYBOARD_CAPS_LOCK,
|
||||
KEYBOARD_F1,
|
||||
KEYBOARD_F2,
|
||||
KEYBOARD_F3,
|
||||
KEYBOARD_F4,
|
||||
KEYBOARD_F5,
|
||||
KEYBOARD_F6,
|
||||
KEYBOARD_F7,
|
||||
KEYBOARD_F8,
|
||||
KEYBOARD_F9,
|
||||
KEYBOARD_F10,
|
||||
KEYBOARD_F11,
|
||||
KEYBOARD_F12,
|
||||
KEYBOARD_PRINTSCREEN,
|
||||
KEYBOARD_SCROLL_LOCK,
|
||||
KEYBOARD_PAUSE,
|
||||
KEYBOARD_INSERT,
|
||||
KEYBOARD_HOME,
|
||||
KEYBOARD_PAGEUP,
|
||||
KEYBOARD_DELETE,
|
||||
KEYBOARD_END1,
|
||||
KEYBOARD_PAGEDOWN,
|
||||
KEYBOARD_RIGHTARROW,
|
||||
KEYBOARD_LEFTARROW,
|
||||
KEYBOARD_DOWNARROW,
|
||||
KEYBOARD_UPARROW,
|
||||
KEYBOARD_KEYBOARDPAD_NUM_LOCK_AND_CLEAR,
|
||||
KEYBOARD_KEYBOARDPAD_SLASH,
|
||||
KEYBOARD_KEYBOARDPAD_ASTERIKS,
|
||||
KEYBOARD_KEYBOARDPAD_MINUS,
|
||||
KEYBOARD_KEYBOARDPAD_PLUS,
|
||||
KEYBOARD_KEYBOARDPAD_ENTER,
|
||||
KEYBOARD_KEYBOARDPAD_1_END,
|
||||
KEYBOARD_KEYBOARDPAD_2_DOWN_ARROW,
|
||||
KEYBOARD_KEYBOARDPAD_3_PAGEDN,
|
||||
KEYBOARD_KEYBOARDPAD_4_LEFT_ARROW,
|
||||
KEYBOARD_KEYBOARDPAD_5,
|
||||
KEYBOARD_KEYBOARDPAD_6_RIGHT_ARROW,
|
||||
KEYBOARD_KEYBOARDPAD_7_HOME,
|
||||
KEYBOARD_KEYBOARDPAD_8_UP_ARROW,
|
||||
KEYBOARD_KEYBOARDPAD_9_PAGEUP,
|
||||
KEYBOARD_KEYBOARDPAD_0_INSERT,
|
||||
KEYBOARD_KEYBOARDPAD_DECIMAL_SEPARATOR_DELETE,
|
||||
KEYBOARD_NONUS_BACK_SLASH_VERTICAL_BAR,
|
||||
KEYBOARD_APPLICATION,
|
||||
KEYBOARD_POWER,
|
||||
KEYBOARD_KEYBOARDPAD_EQUAL,
|
||||
KEYBOARD_F13,
|
||||
KEYBOARD_F14,
|
||||
KEYBOARD_F15,
|
||||
KEYBOARD_F16,
|
||||
KEYBOARD_F17,
|
||||
KEYBOARD_F18,
|
||||
KEYBOARD_F19,
|
||||
KEYBOARD_F20,
|
||||
KEYBOARD_F21,
|
||||
KEYBOARD_F22,
|
||||
KEYBOARD_F23,
|
||||
KEYBOARD_F24,
|
||||
KEYBOARD_EXECUTE,
|
||||
KEYBOARD_HELP,
|
||||
KEYBOARD_MENU,
|
||||
KEYBOARD_SELECT,
|
||||
KEYBOARD_STOP,
|
||||
KEYBOARD_AGAIN,
|
||||
KEYBOARD_UNDO,
|
||||
KEYBOARD_CUT,
|
||||
KEYBOARD_COPY,
|
||||
KEYBOARD_PASTE,
|
||||
KEYBOARD_FIND,
|
||||
KEYBOARD_MUTE,
|
||||
KEYBOARD_VOLUME_UP,
|
||||
KEYBOARD_VOLUME_DOWN,
|
||||
KEYBOARD_LOCKING_CAPS_LOCK,
|
||||
KEYBOARD_LOCKING_NUM_LOCK,
|
||||
KEYBOARD_LOCKING_SCROLL_LOCK,
|
||||
KEYBOARD_KEYBOARDPAD_COMMA,
|
||||
KEYBOARD_KEYBOARDPAD_EQUAL_SIGN,
|
||||
KEYBOARD_INTERNATIONAL1,
|
||||
KEYBOARD_INTERNATIONAL2,
|
||||
KEYBOARD_INTERNATIONAL3,
|
||||
KEYBOARD_INTERNATIONAL4,
|
||||
KEYBOARD_INTERNATIONAL5,
|
||||
KEYBOARD_INTERNATIONAL6,
|
||||
KEYBOARD_INTERNATIONAL7,
|
||||
KEYBOARD_INTERNATIONAL8,
|
||||
KEYBOARD_INTERNATIONAL9,
|
||||
KEYBOARD_LANG1,
|
||||
KEYBOARD_LANG2,
|
||||
KEYBOARD_LANG3,
|
||||
KEYBOARD_LANG4,
|
||||
KEYBOARD_LANG5,
|
||||
KEYBOARD_LANG6,
|
||||
KEYBOARD_LANG7,
|
||||
KEYBOARD_LANG8,
|
||||
KEYBOARD_LANG9,
|
||||
KEYBOARD_ALTERNATE_ERASE,
|
||||
KEYBOARD_SYSREQ,
|
||||
KEYBOARD_CANCEL,
|
||||
KEYBOARD_CLEAR,
|
||||
KEYBOARD_PRIOR,
|
||||
KEYBOARD_RETURN,
|
||||
KEYBOARD_SEPARATOR,
|
||||
KEYBOARD_OUT,
|
||||
KEYBOARD_OPER,
|
||||
KEYBOARD_CLEAR_AGAIN,
|
||||
KEYBOARD_CRSEL,
|
||||
KEYBOARD_EXSEL,
|
||||
KEYBOARD_RESERVED1,
|
||||
KEYBOARD_RESERVED2,
|
||||
KEYBOARD_RESERVED3,
|
||||
KEYBOARD_RESERVED4,
|
||||
KEYBOARD_RESERVED5,
|
||||
KEYBOARD_RESERVED6,
|
||||
KEYBOARD_RESERVED7,
|
||||
KEYBOARD_RESERVED8,
|
||||
KEYBOARD_RESERVED9,
|
||||
KEYBOARD_RESERVED10,
|
||||
KEYBOARD_RESERVED11,
|
||||
KEYBOARD_KEYBOARDPAD_00,
|
||||
KEYBOARD_KEYBOARDPAD_000,
|
||||
KEYBOARD_THOUSANDS_SEPARATOR,
|
||||
KEYBOARD_DECIMAL_SEPARATOR,
|
||||
KEYBOARD_CURRENCY_UNIT,
|
||||
KEYBOARD_CURRENCY_SUB_UNIT,
|
||||
KEYBOARD_KEYBOARDPAD_OPARENTHESIS,
|
||||
KEYBOARD_KEYBOARDPAD_CPARENTHESIS,
|
||||
KEYBOARD_KEYBOARDPAD_OBRACE,
|
||||
KEYBOARD_KEYBOARDPAD_CBRACE,
|
||||
KEYBOARD_KEYBOARDPAD_TAB,
|
||||
KEYBOARD_KEYBOARDPAD_BACKSPACE,
|
||||
KEYBOARD_KEYBOARDPAD_A,
|
||||
KEYBOARD_KEYBOARDPAD_B,
|
||||
KEYBOARD_KEYBOARDPAD_C,
|
||||
KEYBOARD_KEYBOARDPAD_D,
|
||||
KEYBOARD_KEYBOARDPAD_E,
|
||||
KEYBOARD_KEYBOARDPAD_F,
|
||||
KEYBOARD_KEYBOARDPAD_XOR,
|
||||
KEYBOARD_KEYBOARDPAD_CARET,
|
||||
KEYBOARD_KEYBOARDPAD_PERCENT,
|
||||
KEYBOARD_KEYBOARDPAD_LESS,
|
||||
KEYBOARD_KEYBOARDPAD_GREATER,
|
||||
KEYBOARD_KEYBOARDPAD_AMPERSAND,
|
||||
KEYBOARD_KEYBOARDPAD_LOGICAL_AND,
|
||||
KEYBOARD_KEYBOARDPAD_VERTICAL_BAR,
|
||||
KEYBOARD_KEYBOARDPAD_LOGIACL_OR,
|
||||
KEYBOARD_KEYBOARDPAD_COLON,
|
||||
KEYBOARD_KEYBOARDPAD_NUMBER_SIGN,
|
||||
KEYBOARD_KEYBOARDPAD_SPACE,
|
||||
KEYBOARD_KEYBOARDPAD_AT,
|
||||
KEYBOARD_KEYBOARDPAD_EXCLAMATION_MARK,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_STORE,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_RECALL,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_CLEAR,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_ADD,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_SUBTRACT,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_MULTIPLY,
|
||||
KEYBOARD_KEYBOARDPAD_MEMORY_DIVIDE,
|
||||
KEYBOARD_KEYBOARDPAD_PLUSMINUS,
|
||||
KEYBOARD_KEYBOARDPAD_CLEAR,
|
||||
KEYBOARD_KEYBOARDPAD_CLEAR_ENTRY,
|
||||
KEYBOARD_KEYBOARDPAD_BINARY,
|
||||
KEYBOARD_KEYBOARDPAD_OCTAL,
|
||||
KEYBOARD_KEYBOARDPAD_DECIMAL,
|
||||
KEYBOARD_KEYBOARDPAD_HEXADECIMAL,
|
||||
KEYBOARD_RESERVED12,
|
||||
KEYBOARD_RESERVED13,
|
||||
KEYBOARD_LEFTCONTROL,
|
||||
KEYBOARD_LEFTSHIFT,
|
||||
KEYBOARD_LEFTALT,
|
||||
KEYBOARD_LEFT_GUI,
|
||||
KEYBOARD_RIGHTCONTROL,
|
||||
KEYBOARD_RIGHTSHIFT,
|
||||
KEYBOARD_RIGHTALT,
|
||||
KEYBOARD_RIGHT_GUI,
|
||||
} USBH_HID_KEYBOARD_VALUE_T;
|
||||
|
||||
/**@} end of group USBH_HID_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HID keyboard report information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[2];
|
||||
uint32_t rxBuffer[2];
|
||||
} USBH_HID_KEYBOARD_REPORT_T;
|
||||
|
||||
/**
|
||||
* @brief HID keyboard information management
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ctrlLeft;
|
||||
uint8_t shiftLeft;
|
||||
uint8_t altLeft;
|
||||
uint8_t winLeft;
|
||||
|
||||
uint8_t ctrlRight;
|
||||
uint8_t shiftRight;
|
||||
uint8_t altRight;
|
||||
uint8_t winRight;
|
||||
uint8_t key[USBH_HID_KEY_PRESSED_NUM_MAX];
|
||||
USBH_HID_KEYBOARD_REPORT_T report;
|
||||
} USBH_HID_KEYBOARD_INFO_T;
|
||||
|
||||
extern USBH_HID_CLASS_T USBH_HID_KEYBOARD_Handler;
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_HID_KeyBoardInit(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_HID_KeyboardDecode(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_HID_KeyboardCallback(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,92 @@
|
|||
/*!
|
||||
* @file usbh_hid_mouse.h
|
||||
*
|
||||
* @brief USB host HID mouse function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_HID_MOUSE_H_
|
||||
#define _USBH_HID_MOUSE_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_hid.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_HID_MOUSE_BUTTON_MAX_NUM 3
|
||||
|
||||
/**@} end of group USBH_HID_Macros*/
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief HID mouse report information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[2];
|
||||
uint32_t rxBuffer[2];
|
||||
} USBH_HID_MOUSE_REPORT_T;
|
||||
|
||||
/**
|
||||
* @brief HID mouse information management
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t z;
|
||||
uint8_t button[USBH_HID_MOUSE_BUTTON_MAX_NUM];
|
||||
USBH_HID_MOUSE_REPORT_T report;
|
||||
} USBH_HID_MOUSE_INFO_T;
|
||||
|
||||
extern USBH_HID_MOUSE_INFO_T usbHostHidMouse;
|
||||
extern USBH_HID_CLASS_T USBH_HID_MOUSE_Handler;
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_HID_MouseInit(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_HID_MouseDecode(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_HID_MouseCallback(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,952 @@
|
|||
/*!
|
||||
* @file usbh_hid.h
|
||||
*
|
||||
* @brief USB HID core function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_hid.h"
|
||||
#include "usbh_hid_mouse.h"
|
||||
#include "usbh_hid_keyboard.h"
|
||||
#include "usbh_stdReq.h"
|
||||
#include "usbh_dataXfer.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
static USBH_STA_T USBH_HID_ClassInitHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_ClassDeInitHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_ClassReqHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_SOFHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_CoreHandler(USBH_INFO_T* usbInfo);
|
||||
|
||||
static USBH_STA_T USBH_HID_InitHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_IdleHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_SyncHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_InDataHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_PollingHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_OutDataHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_BusyHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_HID_ErrorHandler(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/* HID class handler */
|
||||
USBH_CLASS_T USBH_HID_CLASS =
|
||||
{
|
||||
"Class HID",
|
||||
USBH_CLASS_HID,
|
||||
NULL,
|
||||
USBH_HID_ClassInitHandler,
|
||||
USBH_HID_ClassDeInitHandler,
|
||||
USBH_HID_ClassReqHandler,
|
||||
USBH_HID_CoreHandler,
|
||||
USBH_HID_SOFHandler,
|
||||
};
|
||||
|
||||
/* USB host HID state handler function */
|
||||
USBH_HIDStateHandler_T USBH_HID_Handler[] =
|
||||
{
|
||||
USBH_HID_InitHandler,
|
||||
USBH_HID_IdleHandler,
|
||||
USBH_HID_SyncHandler,
|
||||
USBH_HID_InDataHandler,
|
||||
USBH_HID_PollingHandler,
|
||||
USBH_HID_OutDataHandler,
|
||||
USBH_HID_BusyHandler,
|
||||
USBH_HID_ErrorHandler,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Config HID get report descriptor request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type
|
||||
*
|
||||
* @param reportType : type of report
|
||||
*
|
||||
* @param reportID : ID of report
|
||||
*
|
||||
* @param buffer : report buffer
|
||||
*
|
||||
* @param length : report length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_REQ_GetRepDescriptor(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t reportType, uint8_t reportID, \
|
||||
uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_HID_GET_REPORT;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = reportID;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = reportType;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = length & 0xFF;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = length >> 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, buffer, length);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID set idle request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param reportID : traget report ID
|
||||
*
|
||||
* @param duration : duration for idle request
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_REQ_SetIdle(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t reportID, uint8_t duration)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_HID_SET_IDLE;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = reportID;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = duration;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID set protocol request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param protocol : boot / report protocol
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_REQ_SetProtocol(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t protocol)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_HID_SET_PROTOCOL;
|
||||
|
||||
if (protocol)
|
||||
{
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = 1;
|
||||
}
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host get HID description
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param desLength : length of description
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_GetHIDDesc(USBH_INFO_T* usbInfo, uint16_t desLength)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_GetDescriptor(usbInfo, ((USBH_REQ_DIR_IN << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_INTERFACE)), \
|
||||
USBH_DESC_HID_REPORT,
|
||||
usbInfo->devInfo.data,
|
||||
desLength);
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host get HID report description
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reportType : type of report
|
||||
*
|
||||
* @param reportID : ID of report
|
||||
*
|
||||
* @param buffer : report buffer
|
||||
*
|
||||
* @param length : report length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_GetReportDesc(USBH_INFO_T* usbInfo, uint8_t reportType, \
|
||||
uint8_t reportID, uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_HID_REQ_GetRepDescriptor(usbInfo, ((USBH_REQ_DIR_IN << 7) | \
|
||||
(USBH_REQ_TYPE_CLASS << 5) | \
|
||||
(USBH_RECIPIENT_INTERFACE)), \
|
||||
reportType,
|
||||
reportID,
|
||||
buffer,
|
||||
length);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set HID idle
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reportID : traget report ID
|
||||
*
|
||||
* @param duration : duration for idle request
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_SetIdle(USBH_INFO_T* usbInfo, uint8_t reportID, uint8_t duration)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_HID_REQ_SetIdle(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_CLASS << 5) | \
|
||||
(USBH_RECIPIENT_INTERFACE)),
|
||||
reportID, \
|
||||
duration);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set HID protocol
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param protocol : boot / report protocol
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_SetProtocol(USBH_INFO_T* usbInfo, uint8_t protocol)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_HID_REQ_SetProtocol(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_CLASS << 5) | \
|
||||
(USBH_RECIPIENT_INTERFACE)),
|
||||
protocol);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID init handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_InitHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
usbHostHID->callback->InitHandler(usbInfo);
|
||||
|
||||
/* Notify User */
|
||||
usbInfo->userCallback(usbInfo, USBH_USER_CLASS_LAUNCHED);
|
||||
|
||||
usbHostHID->state = USBH_HID_IDLE;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID idle handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_IdleHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
uint8_t reqStatus = USBH_BUSY;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_IdleHandler");
|
||||
|
||||
reqStatus = USBH_HID_GetReportDesc(usbInfo,
|
||||
HID_INPUT_REPORT,
|
||||
0,
|
||||
usbHostHID->buffer,
|
||||
usbHostHID->epSize);
|
||||
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostHID->state = USBH_HID_SYNC;
|
||||
break;
|
||||
|
||||
case USBH_BUSY:
|
||||
usbHostHID->state = USBH_HID_IDLE;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
usbHostHID->state = USBH_HID_SYNC;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
usbHostHID->state = USBH_HID_ERR;
|
||||
usbStatus = USBH_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID SYNC handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_SyncHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_SyncHandler");
|
||||
|
||||
/* Sync with SOF */
|
||||
if (usbInfo->timer % 2)
|
||||
{
|
||||
usbHostHID->state = USBH_HID_IN_DATA;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID get data handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_InDataHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_InDataHandler");
|
||||
|
||||
USBH_IntReceiveDataReq(usbInfo, usbHostHID->inChNum, usbHostHID->buffer, \
|
||||
usbHostHID->epSize);
|
||||
|
||||
usbHostHID->state = USBH_HID_POLL;
|
||||
usbHostHID->timer = usbInfo->timer;
|
||||
usbHostHID->dataFlag = DISABLE;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID polling handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_PollingHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
uint8_t usbUrbStatus;
|
||||
uint8_t reqStatus = USBH_BUSY;
|
||||
uint32_t xferSize;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_PollingHandler");
|
||||
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbHostHID->inChNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
xferSize = USBH_ReadLastXferSizeCallback(usbInfo, usbHostHID->inChNum);
|
||||
|
||||
if ((xferSize != 0) && (usbHostHID->dataFlag == DISABLE))
|
||||
{
|
||||
usbHostHID->dataFlag = ENABLE;
|
||||
//USBH_HID_WriteFifo(&usbHostHID->fifo, usbHostHID->buffer, usbHostHID->epSize);
|
||||
|
||||
/* HID event callback */
|
||||
USBH_HID_PollCallback(usbInfo);
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
reqStatus = USBH_ClearFeature(usbInfo, usbHostHID->epAddr);
|
||||
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostHID->state = USBH_HID_IN_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID send data handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_OutDataHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID busy handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_BusyHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_BusyHandler");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID error handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_ErrorHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_ErrorHandler");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Parse HID descriptor
|
||||
*
|
||||
* @param hidDesc : HID descriptor
|
||||
*
|
||||
* @param buffer : source data of configuration descriptor
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_HidDescParse(USBH_HID_DESC_T* hidDesc, uint8_t* buffer)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
uint16_t totalLenTemp = 0;
|
||||
uint8_t subLen = 0;
|
||||
uint16_t parseIndex = 0;
|
||||
|
||||
totalLenTemp = *(uint8_t*)(buffer + 2) | (*(uint8_t*)(buffer + 3) << 8);
|
||||
totalLenTemp = ((totalLenTemp) < (CFG_DESC_MAX_LEN) ? (totalLenTemp) : (CFG_DESC_MAX_LEN));
|
||||
|
||||
if (totalLenTemp > STD_CFG_DESC_SIZE)
|
||||
{
|
||||
parseIndex = STD_CFG_DESC_SIZE;
|
||||
|
||||
while (totalLenTemp > parseIndex)
|
||||
{
|
||||
subLen = buffer[parseIndex];
|
||||
|
||||
switch (buffer[parseIndex + 1])
|
||||
{
|
||||
case USBH_DESC_HID:
|
||||
hidDesc->bLength = buffer[parseIndex + 0];
|
||||
hidDesc->bDescriptorType = buffer[parseIndex + 1];
|
||||
hidDesc->bcdHID[0] = buffer[parseIndex + 2];
|
||||
hidDesc->bcdHID[1] = buffer[parseIndex + 3];
|
||||
hidDesc->bCountryCode = buffer[parseIndex + 4];
|
||||
hidDesc->bNumDescriptors = buffer[parseIndex + 5];
|
||||
hidDesc->bReportDescriptorType = buffer[parseIndex + 6];
|
||||
hidDesc->wDescriptorLength[0] = buffer[parseIndex + 7];
|
||||
hidDesc->wDescriptorLength[1] = buffer[parseIndex + 8];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
parseIndex += subLen;
|
||||
|
||||
/* To avoid some useless data left */
|
||||
if ((totalLenTemp - parseIndex) < STD_EP_DESC_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID configuration handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_ClassInitHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID;
|
||||
uint8_t itfNum;
|
||||
uint8_t subClass;
|
||||
uint8_t classInterface;
|
||||
uint8_t protocolInterface;
|
||||
uint16_t mps;
|
||||
uint8_t epAddr;
|
||||
uint8_t pollInterval;
|
||||
uint8_t epNum;
|
||||
uint8_t epDir;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_ClassInitHandler");
|
||||
|
||||
/* Link class data */
|
||||
usbInfo->activeClass->classData = (USBH_HID_INFO_T*)malloc(sizeof(USBH_HID_INFO_T));
|
||||
usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
memset(usbHostHID, 0, sizeof(USBH_HID_INFO_T));
|
||||
|
||||
itfNum = USBH_ReadConfigurationItfNum(usbInfo);
|
||||
|
||||
while (itfNum--)
|
||||
{
|
||||
subClass = USBH_ReadInterfaceSubClass(usbInfo, itfNum);
|
||||
|
||||
if (subClass != USBH_HID_BOOT_CODE)
|
||||
{
|
||||
USBH_USR_Debug("Interface is not valid");
|
||||
usbStatus = USBH_FAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
classInterface = USBH_ReadInterfaceClass(usbInfo, itfNum);
|
||||
if (classInterface != USBH_CLASS_HID)
|
||||
{
|
||||
USBH_USR_Debug("Class type is not support");
|
||||
usbStatus = USBH_ERR_NOT_SUP;
|
||||
continue;
|
||||
}
|
||||
|
||||
protocolInterface = USBH_ReadInterfaceProtocol(usbInfo, itfNum);
|
||||
/* Decode class protocol */
|
||||
switch (protocolInterface)
|
||||
{
|
||||
case USBH_HID_KEYBOARD_BOOT_CODE:
|
||||
USBH_USR_LOG("Register keyboard class init");
|
||||
usbHostHID->callback = &USBH_HID_KEYBOARD_Handler;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USBH_HID_MOUSE_BOOT_CODE:
|
||||
USBH_USR_LOG("Register mouse class init");
|
||||
usbHostHID->callback = &USBH_HID_MOUSE_Handler;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
USBH_USR_LOG("Protocol is not support");
|
||||
usbStatus = USBH_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
epAddr = USBH_ReadEndpointAddress(usbInfo, itfNum, 0);
|
||||
mps = USBH_ReadEndpointMPS(usbInfo, itfNum, 0);
|
||||
pollInterval = USBH_ReadEndpointInterval(usbInfo, itfNum, 0);
|
||||
|
||||
usbHostHID->epAddr = epAddr;
|
||||
usbHostHID->epSize = mps;
|
||||
usbHostHID->pollInterval = pollInterval;
|
||||
usbHostHID->state = USBH_HID_INIT;
|
||||
usbHostHID->classReqState = USBH_HID_REQ_INIT;
|
||||
|
||||
if (usbHostHID->pollInterval < USBH_HID_POLL_MIN_NUM)
|
||||
{
|
||||
usbHostHID->pollInterval = USBH_HID_POLL_MIN_NUM;
|
||||
}
|
||||
|
||||
epNum = USBH_ReadInterfaceEpNum(usbInfo, itfNum);
|
||||
|
||||
if (epNum > ENDPOINT_DESC_MAX_NUM)
|
||||
{
|
||||
epNum = ENDPOINT_DESC_MAX_NUM;
|
||||
}
|
||||
|
||||
while (epNum--)
|
||||
{
|
||||
/* Get endpoint and size */
|
||||
epDir = epAddr & 0x80;
|
||||
|
||||
if (epDir)
|
||||
{
|
||||
usbHostHID->intInEpAddr = USBH_ReadEndpointAddress(usbInfo, itfNum, epNum);
|
||||
usbHostHID->inChNum = USBH_CH_AllocChannel(usbInfo, usbHostHID->intInEpAddr);
|
||||
|
||||
USBH_OpenChannelCallback(usbInfo, usbHostHID->inChNum,
|
||||
usbHostHID->intInEpAddr,
|
||||
usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed,
|
||||
EP_TYPE_INTERRUPT,
|
||||
usbHostHID->epSize);
|
||||
|
||||
USBH_ConfigDataPidCallback(usbInfo, usbHostHID->inChNum, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostHID->intOutEpAddr = USBH_ReadEndpointAddress(usbInfo, itfNum, epNum);
|
||||
usbHostHID->outChNum = USBH_CH_AllocChannel(usbInfo, usbHostHID->intOutEpAddr);
|
||||
|
||||
USBH_OpenChannelCallback(usbInfo, usbHostHID->outChNum,
|
||||
usbHostHID->intOutEpAddr,
|
||||
usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed,
|
||||
EP_TYPE_INTERRUPT,
|
||||
usbHostHID->epSize);
|
||||
|
||||
USBH_ConfigDataPidCallback(usbInfo, usbHostHID->outChNum, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID class reset handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_ClassDeInitHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_ClassDeInitHandler");
|
||||
|
||||
if (usbHostHID->inChNum != 0)
|
||||
{
|
||||
USBH_CloseChannelCallback(usbInfo, usbHostHID->inChNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbHostHID->inChNum);
|
||||
usbHostHID->inChNum = 0;
|
||||
}
|
||||
|
||||
if (usbHostHID->outChNum != 0)
|
||||
{
|
||||
USBH_CloseChannelCallback(usbInfo, usbHostHID->outChNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbHostHID->outChNum);
|
||||
usbHostHID->outChNum = 0;
|
||||
}
|
||||
|
||||
if (usbInfo->activeClass->classData != NULL)
|
||||
{
|
||||
free(usbInfo->activeClass->classData);
|
||||
usbInfo->activeClass->classData = 0;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID class reguest handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_ClassReqHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t reqStatus = USBH_BUSY;
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
uint16_t descLength;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_ClassReqHandler");
|
||||
|
||||
switch (usbHostHID->classReqState)
|
||||
{
|
||||
case USBH_HID_REQ_IDLE:
|
||||
break;
|
||||
|
||||
case USBH_HID_REQ_INIT:
|
||||
case USBH_HID_REQ_GET_HID_DESC:
|
||||
USBH_HidDescParse(&usbHostHID->desc, usbInfo->devInfo.desc.cfgDescBuf);
|
||||
usbHostHID->classReqState = USBH_HID_REQ_GET_REP_DESC;
|
||||
break;
|
||||
|
||||
case USBH_HID_REQ_GET_REP_DESC:
|
||||
descLength = usbHostHID->desc.wDescriptorLength[0] | usbHostHID->desc.wDescriptorLength[1] << 8;
|
||||
reqStatus = USBH_HID_GetHIDDesc(usbInfo, descLength);
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostHID->classReqState = USBH_HID_REQ_SET_IDLE;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("Class Req Error: Get report descriptor failed");
|
||||
usbStatus = USBH_FAIL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_HID_REQ_SET_IDLE:
|
||||
reqStatus = USBH_HID_SetIdle(usbInfo, 0, 0);
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostHID->classReqState = USBH_HID_REQ_SET_PROTOCOL;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
usbHostHID->classReqState = USBH_HID_REQ_SET_PROTOCOL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_HID_REQ_SET_PROTOCOL:
|
||||
reqStatus = USBH_HID_SetProtocol(usbInfo, 0);
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostHID->classReqState = USBH_HID_REQ_IDLE;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("Class Req Error: Set protocol failed");
|
||||
usbStatus = USBH_FAIL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID SOF handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_SOFHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
uint32_t interval;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_SOFHandler");
|
||||
|
||||
if (usbHostHID->state == USBH_HID_POLL)
|
||||
{
|
||||
interval = usbInfo->timer - usbHostHID->timer;
|
||||
|
||||
if (interval >= usbHostHID->pollInterval)
|
||||
{
|
||||
usbHostHID->state = USBH_HID_IN_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_HID_CoreHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_HID_CoreHandler");
|
||||
|
||||
usbStatus = USBH_HID_Handler[usbHostHID->state](usbInfo);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
__weak void USBH_HID_PollCallback(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
/* callback interface */
|
||||
usbHostHID->callback->DecodeHandler(usbInfo);
|
||||
}
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,192 @@
|
|||
/*!
|
||||
* @file usbh_hid_keyboard.c
|
||||
*
|
||||
* @brief USB host HID keyboard function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_hid_keyboard.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_HID_KEYBOARD_INFO_T usbHostHidKeyboard;
|
||||
|
||||
/* HID keyboard class handler */
|
||||
USBH_HID_CLASS_T USBH_HID_KEYBOARD_Handler =
|
||||
{
|
||||
USBH_HID_KeyBoardInit,
|
||||
USBH_HID_KeyboardDecode,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief USB host HID init keyboard
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_HID_KeyBoardInit(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
uint16_t i;
|
||||
|
||||
usbHostHidKeyboard.ctrlLeft = 0;
|
||||
usbHostHidKeyboard.altLeft = 0;
|
||||
usbHostHidKeyboard.shiftLeft = 0;
|
||||
usbHostHidKeyboard.winLeft = 0;
|
||||
|
||||
usbHostHidKeyboard.ctrlRight = 0;
|
||||
usbHostHidKeyboard.altRight = 0;
|
||||
usbHostHidKeyboard.shiftRight = 0;
|
||||
usbHostHidKeyboard.winRight = 0;
|
||||
|
||||
for (i = 0; i < USBH_HID_KEY_PRESSED_NUM_MAX; i++)
|
||||
{
|
||||
usbHostHidKeyboard.key[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (sizeof(usbHostHidKeyboard.report.data) \
|
||||
/ sizeof(usbHostHidKeyboard.report.data[0])); i++)
|
||||
{
|
||||
usbHostHidKeyboard.report.data[i] = 0;
|
||||
usbHostHidKeyboard.report.rxBuffer[i] = 0;
|
||||
}
|
||||
|
||||
if (usbHostHID->epSize > sizeof(usbHostHidKeyboard.report.data))
|
||||
{
|
||||
usbHostHID->epSize = (uint16_t)sizeof(usbHostHidKeyboard.report.data);
|
||||
}
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostHID->buffer = (uint8_t*)(void*)usbHostHidKeyboard.report.data;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID decode keyboard
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_HID_KeyboardDecode(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
uint8_t funKeyTemp;
|
||||
uint8_t i;
|
||||
|
||||
if ((usbHostHidKeyboard.report.data[1] == 0x01010101) && \
|
||||
(usbHostHidKeyboard.report.data[0] == 0x01010000))
|
||||
{
|
||||
USBH_USR_LOG("Keyboard do not support this operation");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 2; i < 2 + USBH_HID_KEY_PRESSED_NUM_MAX; i++)
|
||||
{
|
||||
funKeyTemp = *((uint8_t*)(void*)usbHostHidKeyboard.report.data + i);
|
||||
if ((funKeyTemp == KEYBOARD_ERROR_ROLL_OVER) || \
|
||||
(funKeyTemp == KEYBOARD_POST_FAIL) || \
|
||||
(funKeyTemp == KEYBOARD_ERROR_UNDEFINED))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
funKeyTemp = *((uint8_t*)(void*)usbHostHidKeyboard.report.data + 0);
|
||||
|
||||
usbHostHidKeyboard.ctrlLeft = (funKeyTemp & 0x01) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.shiftLeft = (funKeyTemp & 0x02) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.altLeft = (funKeyTemp & 0x04) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.winLeft = (funKeyTemp & 0x08) > 0 ? 1 : 0;
|
||||
|
||||
usbHostHidKeyboard.ctrlRight = (funKeyTemp & 0x10) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.shiftRight = (funKeyTemp & 0x20) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.altRight = (funKeyTemp & 0x40) > 0 ? 1 : 0;
|
||||
usbHostHidKeyboard.winRight = (funKeyTemp & 0x80) > 0 ? 1 : 0;
|
||||
|
||||
for (i = 0; i < USBH_HID_KEY_PRESSED_NUM_MAX; i++)
|
||||
{
|
||||
usbHostHidKeyboard.key[i] = *((uint8_t*)(void*)usbHostHidKeyboard.report.data + i + 2);
|
||||
}
|
||||
|
||||
/* Process keyboard data */
|
||||
USBH_HID_KeyboardCallback(usbInfo);
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID keyboard data process
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
__weak USBH_STA_T USBH_HID_KeyboardCallback(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
uint8_t i;
|
||||
|
||||
USBH_USR_LOG("CTRL L:%02X", usbHostHidKeyboard.ctrlLeft);
|
||||
USBH_USR_LOG("SHIFT L:%02X", usbHostHidKeyboard.shiftLeft);
|
||||
USBH_USR_LOG("ALT L:%02X", usbHostHidKeyboard.altLeft);
|
||||
USBH_USR_LOG("WIN L:%02X", usbHostHidKeyboard.winLeft);
|
||||
|
||||
USBH_USR_LOG("CTRL R:%02X", usbHostHidKeyboard.ctrlRight);
|
||||
USBH_USR_LOG("SHIFT R:%02X", usbHostHidKeyboard.shiftRight);
|
||||
USBH_USR_LOG("ALT R:%02X", usbHostHidKeyboard.altRight);
|
||||
USBH_USR_LOG("WIN R:%02X", usbHostHidKeyboard.winRight);
|
||||
|
||||
for (i = 0; i < USBH_HID_KEY_PRESSED_NUM_MAX; i++)
|
||||
{
|
||||
USBH_USR_LOG("KEY[%d] :%02X", i, usbHostHidKeyboard.key[i]);
|
||||
}
|
||||
|
||||
USBH_USR_LOG(" ");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,154 @@
|
|||
/*!
|
||||
* @file usbh_hid_mouse.c
|
||||
*
|
||||
* @brief USB host HID mouse function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_hid_mouse.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_HID_MOUSE_INFO_T usbHostHidMouse;
|
||||
|
||||
/* HID mouse class handler */
|
||||
USBH_HID_CLASS_T USBH_HID_MOUSE_Handler =
|
||||
{
|
||||
USBH_HID_MouseInit,
|
||||
USBH_HID_MouseDecode,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_HID_Structures*/
|
||||
|
||||
/** @defgroup USBH_HID_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief USB host HID init mouse
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_HID_MouseInit(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
USBH_HID_INFO_T* usbHostHID = (USBH_HID_INFO_T*)usbInfo->activeClass->classData;
|
||||
uint16_t i;
|
||||
|
||||
usbHostHidMouse.x = 0;
|
||||
usbHostHidMouse.y = 0;
|
||||
|
||||
for (i = 0; i < USBH_HID_MOUSE_BUTTON_MAX_NUM; i++)
|
||||
{
|
||||
usbHostHidMouse.button[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < (sizeof(usbHostHidMouse.report.data) \
|
||||
/ sizeof(usbHostHidMouse.report.data[0])); i++)
|
||||
{
|
||||
usbHostHidMouse.report.data[i] = 0;
|
||||
usbHostHidMouse.report.rxBuffer[i] = 0;
|
||||
}
|
||||
|
||||
if (usbHostHID->epSize > sizeof(usbHostHidMouse.report.data))
|
||||
{
|
||||
usbHostHID->epSize = (uint16_t)sizeof(usbHostHidMouse.report.data);
|
||||
}
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostHID->buffer = (uint8_t*)(void*)usbHostHidMouse.report.data;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID decode mouse
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_HID_MouseDecode(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
uint8_t buttonTemp;
|
||||
uint8_t coordinateX;
|
||||
uint8_t coordinateY;
|
||||
uint8_t coordinateZ;
|
||||
|
||||
buttonTemp = *((uint8_t*)(void*)usbHostHidMouse.report.data + 0);
|
||||
coordinateX = *((uint8_t*)(void*)usbHostHidMouse.report.data + 1);
|
||||
coordinateY = *((uint8_t*)(void*)usbHostHidMouse.report.data + 2);
|
||||
coordinateZ = *((uint8_t*)(void*)usbHostHidMouse.report.data + 3);
|
||||
|
||||
usbHostHidMouse.button[0] = (buttonTemp & 0x01) > 0 ? 1 : 0;
|
||||
usbHostHidMouse.button[1] = (buttonTemp & 0x02) > 0 ? 1 : 0;
|
||||
usbHostHidMouse.button[2] = (buttonTemp & 0x04) > 0 ? 1 : 0;
|
||||
|
||||
usbHostHidMouse.x = coordinateX;
|
||||
usbHostHidMouse.y = coordinateY;
|
||||
usbHostHidMouse.z = coordinateZ;
|
||||
|
||||
/* Process mouse data */
|
||||
USBH_HID_MouseCallback(usbInfo);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host HID mouse data process
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
__weak USBH_STA_T USBH_HID_MouseCallback(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_USR_LOG("x:%02X", usbHostHidMouse.x);
|
||||
USBH_USR_LOG("y:%02X", usbHostHidMouse.y);
|
||||
USBH_USR_LOG("z:%02X", usbHostHidMouse.z);
|
||||
USBH_USR_LOG("b1:%02X", usbHostHidMouse.button[0]);
|
||||
USBH_USR_LOG("b2:%02X", usbHostHidMouse.button[1]);
|
||||
USBH_USR_LOG("b3:%02X", usbHostHidMouse.button[2]);
|
||||
USBH_USR_LOG(" ");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_HID_Functions */
|
||||
/**@} end of group USBH_HID_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,167 @@
|
|||
/*!
|
||||
* @file usbh_msc.h
|
||||
*
|
||||
* @brief usb host msc class handler header file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_MSC_H_
|
||||
#define _USBH_MSC_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_CLASS_GET_MAX_LUN 0xFE
|
||||
#define USBH_CLASS_BOT_RESET 0xFF
|
||||
#define USBH_SUPPORTED_LUN_MAX 0x02
|
||||
#define USBH_MSC_SCSI_CLASS_CODE 0x06
|
||||
|
||||
/**@} end of group USBH_MSC_Macros*/
|
||||
|
||||
/** @defgroup USBH_MSC_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief MSC state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_MSC_INIT = 0,
|
||||
USBH_MSC_IDLE = 1,
|
||||
USBH_MSC_INQUIRY,
|
||||
USBH_MSC_TEST_UNIT_READY,
|
||||
USBH_MSC_REQUEST_SENSE,
|
||||
USBH_MSC_READ_CAPACITY,
|
||||
USBH_MSC_UNRECOVERED_STATE,
|
||||
|
||||
USBH_MSC_RW_READ,
|
||||
USBH_MSC_RW_WRITE,
|
||||
USBH_MSC_RW_REQIEST_SENSE,
|
||||
} USBH_MSC_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief MSC error state type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_MSC_OK,
|
||||
USBH_MSC_BUSY,
|
||||
USBH_MSC_ERR,
|
||||
} USBH_MSC_ERR_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief MSC class request state table
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_MSC_REQ_GET_MAX_LUN,
|
||||
USBH_MSC_REQ_BOT_RESET,
|
||||
USBH_MSC_REQ_CTRL_ERROR
|
||||
} USBH_MSC_REQ_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief MSC protocol code
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_MSC_PROTOCOL_CBI_00 = 0x00,
|
||||
USBH_MSC_PROTOCOL_CBI_01 = 0x01,
|
||||
USBH_MSC_PROTOCOL_BBB = 0x50,
|
||||
USBH_MSC_PROTOCOL_UAS = 0x62
|
||||
} USBH_MSC_PROTOCOL_CODE_T;
|
||||
|
||||
/**@} end of group USBH_MSC_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_MSC_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief MSC Storage info
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_SCSI_READ_CAPACITY_REQ_T capacity;
|
||||
USBH_SCSI_INQUIRY_REQ_T inquiryReq;
|
||||
USBH_SCSI_SENSE_REQ_T sense;
|
||||
USBH_MSC_STATE_T state;
|
||||
uint8_t changeState;
|
||||
uint8_t preReadyState;
|
||||
USBH_MSC_ERR_STATE_T errState;
|
||||
} USBH_MSC_STORAGE_INFO_T;
|
||||
|
||||
/* Host MSC class state handler function */
|
||||
typedef USBH_STA_T(*USBH_MscStateHandler_T)(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
|
||||
/**
|
||||
* @brief MSC information management
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_MSC_STATE_T state;
|
||||
USBH_MSC_ERR_STATE_T errState;
|
||||
USBH_MSC_REQ_STATE_T preClassReqState;
|
||||
USBH_MSC_REQ_STATE_T classReqState;
|
||||
uint8_t maxLun;
|
||||
uint8_t curLun;
|
||||
uint8_t opLun;
|
||||
uint32_t timer;
|
||||
USBH_MSC_STORAGE_INFO_T storage[USBH_SUPPORTED_LUN_MAX];
|
||||
USBH_BOT_INFO_T usbHostBOT;
|
||||
} USBH_MSC_INFO_T;
|
||||
|
||||
extern USBH_CLASS_T USBH_MSC_CLASS;
|
||||
|
||||
/**@} end of group USBH_MSC_Structures*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_MSC_ReadDevInfo(USBH_INFO_T* usbInfo, uint8_t lun, USBH_MSC_STORAGE_INFO_T* device);
|
||||
uint8_t USBH_MSC_DevStatus(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
uint8_t USBH_MSC_ReadDevWP(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
USBH_STA_T USBH_MSC_DevRead(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt);
|
||||
USBH_STA_T USBH_MSC_DevWrite(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt);
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
/**@} end of group USBH_MSC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,203 @@
|
|||
/*!
|
||||
* @file usbh_msc_bot.h
|
||||
*
|
||||
* @brief USB host MSC bot
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_MSC_BOT_H_
|
||||
#define _USBH_MSC_BOT_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
/* CBW parameter */
|
||||
#define USBH_MSC_BOT_CBW_SIGNATURE (uint32_t)(0x43425355)
|
||||
#define USBH_MSC_BOT_CBW_TAG (uint32_t)(0x20304050)
|
||||
#define USBH_MSC_BOT_CBW_LEN 31
|
||||
#define USBH_BOT_CBW_CB_LEN 16
|
||||
#define USBH_LEN_CBW 10
|
||||
|
||||
/* CSW parameter */
|
||||
#define USBH_MSC_BOT_CSW_SIGNATURE (uint32_t)(0x53425355)
|
||||
#define USBH_MSC_BOT_CSW_LEN 13
|
||||
#define USBH_LEN_CSW_MAX 63
|
||||
|
||||
/**@} end of group USBH_MSC_Macros*/
|
||||
|
||||
/** @defgroup USBH_MSC_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SCSI transmission state of BOT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_BOT_SEND_CBW,
|
||||
USBH_BOT_SEND_CBW_WAIT,
|
||||
USBH_BOT_DATAIN,
|
||||
USBH_BOT_DATAIN_WAIT,
|
||||
USBH_BOT_DATAOUT,
|
||||
USBH_BOT_DATAOUT_WAIT,
|
||||
USBH_BOT_RECEIVE_CSW,
|
||||
USBH_BOT_RECEIVE_CSW_WAIT,
|
||||
USBH_BOT_ERROR_IN,
|
||||
USBH_BOT_ERROR_OUT,
|
||||
USBH_BOT_ERROR_UNRECOVERED,
|
||||
} USBH_BOT_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief CSW status
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_BOT_CSW_OK,
|
||||
USBH_BOT_CSW_FAIL,
|
||||
USBH_BOT_CSW_ERR,
|
||||
} USBH_BOT_CSW_STA_T;
|
||||
|
||||
/**
|
||||
* @brief SCSI transmission command state of BOT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_BOT_XFER_IDLE,
|
||||
USBH_BOT_XFER_START,
|
||||
USBH_BOT_XFER_WAITING,
|
||||
} USBH_BOT_XFER_STA_T;
|
||||
|
||||
/**@} end of group USBH_MSC_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_MSC_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief CBW flag
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint8_t CBW_Flag;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t reserved : 7;
|
||||
uint8_t dir : 1;
|
||||
} CBW_FLAG_B;
|
||||
|
||||
} USBH_BOT_CBW_FLAG_T;
|
||||
|
||||
/**
|
||||
* @brief Command Block Wrapper
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataXferLen;
|
||||
USBH_BOT_CBW_FLAG_T bmFlags;
|
||||
uint8_t bLUN;
|
||||
uint8_t bCBLen;
|
||||
uint8_t CB[16];
|
||||
} DATA_FIELD;
|
||||
|
||||
uint8_t buffer[31];
|
||||
} USBH_BOT_CBW_T;
|
||||
|
||||
/**
|
||||
* @brief Command Status Wrapper
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataResidue;
|
||||
uint8_t bStatus;
|
||||
} DATA_FIELD;
|
||||
|
||||
uint8_t buffer[13];
|
||||
} USBH_BOT_CSW_T;
|
||||
|
||||
/**
|
||||
* @brief BOT transmission parameter
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_BOT_CBW_T CBW;
|
||||
USBH_BOT_CSW_T CSW;
|
||||
} USBH_BOT_CMDPACK_T;
|
||||
|
||||
/* Host BOT state handler function */
|
||||
typedef USBH_STA_T(*USBH_BotStateHandler_T)(struct _USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
|
||||
/**
|
||||
* @brief MSC BOT information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t* buffer;
|
||||
uint32_t data[16];
|
||||
uint8_t inChNum;
|
||||
uint8_t outChNum;
|
||||
uint8_t bulkOutEpAddr;
|
||||
uint8_t bulkInEpAddr;
|
||||
uint16_t bulkInEpSize;
|
||||
uint16_t bulkOutEpSize;
|
||||
USBH_BOT_STATE_T state;
|
||||
uint8_t xferState;
|
||||
USBH_BOT_CMDPACK_T cmdPack;
|
||||
} USBH_BOT_INFO_T;
|
||||
|
||||
extern USBH_BotStateHandler_T USBH_MSC_BOT_Handler[];
|
||||
|
||||
/**@} end of group USBH_MSC_Structures*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_MSC_BOT_Init(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_MSC_BOT_REQ_Reset(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_MSC_BOT_REQ_GetMaxLunHandler(USBH_INFO_T* usbInfo, uint8_t* maxLun);
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
/**@} end of group USBH_MSC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,191 @@
|
|||
/*!
|
||||
* @file usbh_msc_scsi.h
|
||||
*
|
||||
* @brief USB host MSC scsi
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef __USBH_MSC_SCSI_H_
|
||||
#define __USBH_MSC_SCSI_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Length define of command */
|
||||
#define LEN_XFER_TEST_UNIT_READY 0
|
||||
#define LEN_XFER_READ_CAPACITY 8
|
||||
#define LEN_XFER_REQUEST_SENSE 14
|
||||
#define LEN_XFER_INQUIRY 36
|
||||
|
||||
/* SCSI Commands */
|
||||
#define USBH_SCSI_CMD_FORMAT_UNIT ((uint8_t)0x04)
|
||||
#define USBH_SCSI_CMD_INQUIRY ((uint8_t)0x12)
|
||||
#define USBH_SCSI_CMD_MODE_SELECT_6 ((uint8_t)0x15)
|
||||
#define USBH_SCSI_CMD_MODE_SELECT_10 ((uint8_t)0x55)
|
||||
#define USBH_SCSI_CMD_MODE_SENSE_6 ((uint8_t)0x1A)
|
||||
#define USBH_SCSI_CMD_MODE_SENSE_10 ((uint8_t)0x5A)
|
||||
#define USBH_SCSI_CMD_ALLOW_MEDIUM_REMOVAL ((uint8_t)0x1E)
|
||||
#define USBH_SCSI_CMD_READ_6 ((uint8_t)0x08)
|
||||
#define USBH_SCSI_CMD_READ_10 ((uint8_t)0x28)
|
||||
#define USBH_SCSI_CMD_READ_12 ((uint8_t)0xA8)
|
||||
#define USBH_SCSI_CMD_READ_16 ((uint8_t)0x88)
|
||||
|
||||
#define USBH_SCSI_CMD_READ_CAPACITY ((uint8_t)0x25)
|
||||
#define USBH_SCSI_CMD_READ_CAPACITY_16 ((uint8_t)0x9E)
|
||||
|
||||
#define USBH_SCSI_CMD_REQUEST_SENSE ((uint8_t)0x03)
|
||||
#define USBH_SCSI_CMD_START_STOP_UNIT ((uint8_t)0x1B)
|
||||
#define USBH_SCSI_CMD_TEST_UNIT_READY ((uint8_t)0x00)
|
||||
#define USBH_SCSI_CMD_WRITE6 ((uint8_t)0x0A)
|
||||
#define USBH_SCSI_CMD_WRITE10 ((uint8_t)0x2A)
|
||||
#define USBH_SCSI_CMD_WRITE12 ((uint8_t)0xAA)
|
||||
#define USBH_SCSI_CMD_WRITE16 ((uint8_t)0x8A)
|
||||
|
||||
#define USBH_SCSI_CMD_VERIFY_10 ((uint8_t)0x2F)
|
||||
#define USBH_SCSI_CMD_VERIFY_12 ((uint8_t)0xAF)
|
||||
#define USBH_SCSI_CMD_VERIFY_16 ((uint8_t)0x8F)
|
||||
|
||||
#define USBH_SCSI_CMD_SEND_DIAGNOSTIC ((uint8_t)0x1D)
|
||||
#define USBH_SCSI_CMD_READ_FORMAT_CAPACITIES ((uint8_t)0x23)
|
||||
|
||||
/**@} end of group USBH_MSC_Macros*/
|
||||
|
||||
/** @defgroup USBH_MSC_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SCSI sense ASC type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_SCSI_ASC_NO_ADDITIONAL_SENSE_INFORMATION = 0x00,
|
||||
USBH_SCSI_ASCQ_FORMAT_COMMAND_FAILED = 0x01,
|
||||
USBH_SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED = 0x02,
|
||||
USBH_SCSI_ASC_LOGICAL_UNIT_NOT_READY = 0x04,
|
||||
USBH_SCSI_ASCQ_OPERATION_IN_PROGRESS = 0x07,
|
||||
USBH_SCSI_ASC_INVALID_COMMAND_OPERATION_CODE = 0x20,
|
||||
USBH_SCSI_ASC_INVALID_FIELD_IN_CDB = 0x24,
|
||||
USBH_SCSI_ASC_WRITE_PROTECTED = 0x27,
|
||||
USBH_SCSI_ASC_NOT_READY_TO_READY_CHANGE = 0x28,
|
||||
USBH_SCSI_ASC_FORMAT_ERROR = 0x31,
|
||||
USBH_SCSI_ASC_MEDIUM_NOT_PRESENT = 0x3A,
|
||||
} USBH_SCSI_SENSE_ASC_T;
|
||||
|
||||
/**
|
||||
* @brief SCSI sense key type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_SCSI_SENSE_KEY_NO_SENSE = 0x00,
|
||||
USBH_SCSI_SENSE_KEY_RECOVERED_ERROR,
|
||||
USBH_SCSI_SENSE_KEY_NOT_READY,
|
||||
USBH_SCSI_SENSE_KEY_MEDIUM_ERROR,
|
||||
USBH_SCSI_SENSE_KEY_HARDWARE_ERROR,
|
||||
USBH_SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
USBH_SCSI_SENSE_KEY_UNIT_ATTENTION,
|
||||
USBH_SCSI_SENSE_KEY_DATA_PROTECT,
|
||||
USBH_SCSI_SENSE_KEY_BLANK_CHECK,
|
||||
USBH_SCSI_SENSE_KEY_VENDOR_SPECIFIC,
|
||||
USBH_SCSI_SENSE_KEY_COPY_ABORTED,
|
||||
USBH_SCSI_SENSE_KEY_ABORTED_COMMAND,
|
||||
USBH_SCSI_SENSE_KEY_VOLUME_OVERFLOW = 0x0D,
|
||||
USBH_SCSI_SENSE_KEY_MISCOMPARE = 0x0E,
|
||||
} USBH_SCSI_SENSE_KEY_T;
|
||||
|
||||
/**@} end of group USBH_MSC_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_MSC_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SCSI inquiry response data type
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t peripheral;
|
||||
uint8_t devType;
|
||||
uint8_t media;
|
||||
uint8_t vendorID[9];
|
||||
uint8_t productID[17];
|
||||
uint8_t revID[5];
|
||||
} USBH_SCSI_INQUIRY_REQ_T;
|
||||
|
||||
/**
|
||||
* @brief SCSI read capacity response data type
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t blockNum;
|
||||
uint32_t blockSize;
|
||||
} USBH_SCSI_READ_CAPACITY_REQ_T;
|
||||
|
||||
/**
|
||||
* @brief SCSI sense response data type
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t key;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
} USBH_SCSI_SENSE_REQ_T;
|
||||
|
||||
/**@} end of group USBH_MSC_Structures*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_MSC_SCSI_Inquiry(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_INQUIRY_REQ_T* inquiry);
|
||||
USBH_STA_T USBH_MSC_SCSI_TestUnitReady(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
|
||||
USBH_STA_T USBH_MSC_SCSI_ReadCapacity(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_READ_CAPACITY_REQ_T* capacity);
|
||||
|
||||
USBH_STA_T USBH_MSC_SCSI_RequestSense(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_SENSE_REQ_T* sense);
|
||||
|
||||
USBH_STA_T USBH_MSC_SCSI_Read(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt);
|
||||
|
||||
USBH_STA_T USBH_MSC_SCSI_Write(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt);
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
/**@} end of group USBH_MSC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,672 @@
|
|||
/*!
|
||||
* @file usbh_msc_bot.c
|
||||
*
|
||||
* @brief USB host MSC bot
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_dataXfer.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
static USBH_STA_T USBH_MSC_BOT_SendCBWHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_SendCBWWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_DataInHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_DataInWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_DataOutHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_DataOutWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_RevCSWHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_RevCSWWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorInHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorOutHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorUnrecoveredHandler(USBH_INFO_T* usbInfo, uint8_t lun);
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
|
||||
/** @defgroup USBH_MSC_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/* USB host BOT state handler function */
|
||||
USBH_BotStateHandler_T USBH_MSC_BOT_Handler[] =
|
||||
{
|
||||
USBH_MSC_BOT_SendCBWHandler,
|
||||
USBH_MSC_BOT_SendCBWWaitHandler,
|
||||
USBH_MSC_BOT_DataInHandler,
|
||||
USBH_MSC_BOT_DataInWaitHandler,
|
||||
USBH_MSC_BOT_DataOutHandler,
|
||||
USBH_MSC_BOT_DataOutWaitHandler,
|
||||
USBH_MSC_BOT_RevCSWHandler,
|
||||
USBH_MSC_BOT_RevCSWWaitHandler,
|
||||
USBH_MSC_BOT_ErrorInHandler,
|
||||
USBH_MSC_BOT_ErrorOutHandler,
|
||||
USBH_MSC_BOT_ErrorUnrecoveredHandler,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_MSC_Structures*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT send CBW handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval CSW decode status
|
||||
*/
|
||||
static USBH_BOT_CSW_STA_T USBH_MSC_BOT_DecodeCSW(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_BOT_CSW_STA_T cswStatus = USBH_BOT_CSW_FAIL;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
uint32_t lastXferSize;
|
||||
|
||||
lastXferSize = USBH_ReadLastXferSizeCallback(usbInfo, usbHostMSC->usbHostBOT.inChNum);
|
||||
|
||||
/* CSW length is Correct */
|
||||
if (lastXferSize == USBH_MSC_BOT_CSW_LEN)
|
||||
{
|
||||
/* dSignature is equal to 0x53425355 */
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CSW.DATA_FIELD.dSignature == USBH_MSC_BOT_CSW_SIGNATURE)
|
||||
{
|
||||
/* dTag matches the dTag from the corresponding CBW */
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CSW.DATA_FIELD.dTag == usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dTag)
|
||||
{
|
||||
switch (usbHostMSC->usbHostBOT.cmdPack.CSW.DATA_FIELD.bStatus)
|
||||
{
|
||||
case USBH_BOT_CSW_OK:
|
||||
cswStatus = USBH_BOT_CSW_OK;
|
||||
break;
|
||||
|
||||
case USBH_BOT_CSW_FAIL:
|
||||
cswStatus = USBH_BOT_CSW_FAIL;
|
||||
break;
|
||||
|
||||
case USBH_BOT_CSW_ERR:
|
||||
cswStatus = USBH_BOT_CSW_ERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cswStatus = USBH_BOT_CSW_ERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cswStatus = USBH_BOT_CSW_ERR;
|
||||
}
|
||||
|
||||
return cswStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT send CBW handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_SendCBWHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bLUN = lun;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_SendCBWHandler");
|
||||
|
||||
USBH_BulkSendDataReq(usbInfo, usbHostMSC->usbHostBOT.outChNum, usbHostMSC->usbHostBOT.cmdPack.CBW.buffer, \
|
||||
USBH_MSC_BOT_CBW_LEN, ENABLE);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT send CBW wait handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_SendCBWWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_SendCBWWaitHandler");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbHostMSC->usbHostBOT.outChNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen == 0)
|
||||
{
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_RECEIVE_CSW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir == USBH_REQ_DIR_IN)
|
||||
{
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_DATAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_DATAOUT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_NOREADY:
|
||||
/* Resend CBW */
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_OUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT data IN handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_DataInHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_DataInHandler");
|
||||
USBH_BulkReceiveDataReq(usbInfo, usbHostMSC->usbHostBOT.inChNum, usbHostMSC->usbHostBOT.buffer, \
|
||||
usbHostMSC->usbHostBOT.bulkInEpSize);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_DATAIN_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT data IN wait handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_DataInWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_DataInWaitHandler");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbHostMSC->usbHostBOT.inChNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen <= usbHostMSC->usbHostBOT.bulkInEpSize)
|
||||
{
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostMSC->usbHostBOT.buffer += usbHostMSC->usbHostBOT.bulkInEpSize;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen -= usbHostMSC->usbHostBOT.bulkInEpSize;
|
||||
}
|
||||
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen > 0)
|
||||
{
|
||||
/* Receive the next bulk packet */
|
||||
USBH_BulkReceiveDataReq(usbInfo, usbHostMSC->usbHostBOT.inChNum, usbHostMSC->usbHostBOT.buffer, \
|
||||
usbHostMSC->usbHostBOT.bulkInEpSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_RECEIVE_CSW;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_IN;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT data OUT handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_DataOutHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_DataOutHandler");
|
||||
|
||||
USBH_BulkSendDataReq(usbInfo, usbHostMSC->usbHostBOT.outChNum, usbHostMSC->usbHostBOT.buffer, \
|
||||
usbHostMSC->usbHostBOT.bulkOutEpSize, ENABLE);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_DATAOUT_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT data OUT wait handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_DataOutWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_DataOutWaitHandler");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbHostMSC->usbHostBOT.outChNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen <= usbHostMSC->usbHostBOT.bulkOutEpSize)
|
||||
{
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostMSC->usbHostBOT.buffer += usbHostMSC->usbHostBOT.bulkOutEpSize;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen -= usbHostMSC->usbHostBOT.bulkOutEpSize;
|
||||
}
|
||||
|
||||
if (usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen > 0)
|
||||
{
|
||||
/* Send the next bulk packet */
|
||||
USBH_BulkSendDataReq(usbInfo, usbHostMSC->usbHostBOT.outChNum, usbHostMSC->usbHostBOT.buffer, \
|
||||
usbHostMSC->usbHostBOT.bulkOutEpSize, ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_RECEIVE_CSW;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_NOREADY:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_DATAOUT;
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_OUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT receive CSW handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_RevCSWHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_RevCSWHandler");
|
||||
|
||||
USBH_BulkReceiveDataReq(usbInfo, usbHostMSC->usbHostBOT.inChNum, usbHostMSC->usbHostBOT.cmdPack.CSW.buffer, \
|
||||
USBH_MSC_BOT_CSW_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_RECEIVE_CSW_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT reveive CSW wait handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_RevCSWWaitHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_BOT_CSW_STA_T cswStatus = USBH_BOT_CSW_FAIL;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_RevCSWWaitHandler");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbHostMSC->usbHostBOT.inChNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_START;
|
||||
cswStatus = USBH_MSC_BOT_DecodeCSW(usbInfo);
|
||||
|
||||
if (cswStatus == USBH_BOT_CSW_OK)
|
||||
{
|
||||
usbStatus = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbStatus = USBH_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_IN;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT IN error handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorInHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t reqStatus = USBH_OK;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_ErrorInHandler");
|
||||
|
||||
reqStatus = USBH_ClearFeature(usbInfo, usbHostMSC->usbHostBOT.bulkInEpAddr);
|
||||
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_RECEIVE_CSW;
|
||||
break;
|
||||
|
||||
case USBH_ERR_UNRECOVERED:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_UNRECOVERED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT OUT error handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorOutHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t reqStatus = USBH_OK;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
uint8_t toggle;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_ErrorOutHandler");
|
||||
|
||||
reqStatus = USBH_ClearFeature(usbInfo, usbHostMSC->usbHostBOT.bulkOutEpAddr);
|
||||
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
toggle = USBH_ReadToggleCallback(usbInfo, usbHostMSC->usbHostBOT.outChNum);
|
||||
|
||||
USBH_ConfigToggleCallback(usbInfo, usbHostMSC->usbHostBOT.outChNum, 1 - toggle);
|
||||
USBH_ConfigToggleCallback(usbInfo, usbHostMSC->usbHostBOT.inChNum, 0);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_IN;
|
||||
break;
|
||||
|
||||
case USBH_ERR_UNRECOVERED:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_ERROR_UNRECOVERED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC BOT unrecovered error handler
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param lun : logical unit numer
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
static USBH_STA_T USBH_MSC_BOT_ErrorUnrecoveredHandler(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t reqStatus = USBH_OK;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
USBH_USR_Debug("USBH_MSC_BOT_ErrorUnrecoveredHandler");
|
||||
|
||||
reqStatus = USBH_MSC_BOT_REQ_Reset(usbInfo);
|
||||
|
||||
switch (reqStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Init BOT of USB host MSC
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_BOT_Init(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dSignature = USBH_MSC_BOT_CBW_SIGNATURE;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dTag = USBH_MSC_BOT_CBW_TAG;
|
||||
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_START;
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reset request of MSC BOT
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_BOT_REQ_Reset(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Config Request */
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = USBH_REQ_DIR_OUT;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = USBH_RECIPIENT_INTERFACE;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = USBH_REQ_TYPE_CLASS;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_CLASS_BOT_RESET;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = 0x00;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0x00;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0x00;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0x00;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0x00;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the max lun of MSC BOT
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param maxLun: max of logic unit number
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_BOT_REQ_GetMaxLunHandler(USBH_INFO_T* usbInfo, uint8_t* maxLun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Config Request */
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = USBH_REQ_DIR_IN;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = USBH_RECIPIENT_INTERFACE;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = USBH_REQ_TYPE_CLASS;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_CLASS_GET_MAX_LUN;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = 0x00;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0x00;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0x00;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0x00;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0x01;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0x00;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, maxLun, 1);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
/**@} end of group USBH_MSC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,395 @@
|
|||
/*!
|
||||
* @file usbh_msc_scsi.c
|
||||
*
|
||||
* @brief USB host MSC scsi
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_msc_scsi.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_Class
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI INQUIRY handler
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param inquiry: inquiry response
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_Inquiry(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_INQUIRY_REQ_T* inquiry)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = LEN_XFER_INQUIRY;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_IN;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_INQUIRY;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[1] = (lun << 5);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[2] = 0;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[3] = 0;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[4] = 36;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[5] = 0;
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostMSC->usbHostBOT.buffer = (uint8_t*)(void*)usbHostMSC->usbHostBOT.data;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
memset(inquiry, 0, sizeof(USBH_SCSI_INQUIRY_REQ_T));
|
||||
|
||||
inquiry->devType = usbHostMSC->usbHostBOT.buffer[0] & 0x1F;
|
||||
inquiry->peripheral = usbHostMSC->usbHostBOT.buffer[0] >> 5;
|
||||
|
||||
if (((uint32_t) usbHostMSC->usbHostBOT.buffer[1] & 0x80) == 0x80)
|
||||
{
|
||||
inquiry->media = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
inquiry->media = 0;
|
||||
}
|
||||
|
||||
memcpy(inquiry->revID, &usbHostMSC->usbHostBOT.buffer[32], 4);
|
||||
memcpy(inquiry->productID, &usbHostMSC->usbHostBOT.buffer[16], 16);
|
||||
memcpy(inquiry->vendorID, &usbHostMSC->usbHostBOT.buffer[8], 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI TEST UNIT READY handler
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param inquiry: inquiry response
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_TestUnitReady(USBH_INFO_T* usbInfo, uint8_t lun)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
usbStatus = USBH_BUSY;
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = LEN_XFER_TEST_UNIT_READY;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_OUT;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_TEST_UNIT_READY;
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI READ CAPACITY handler
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param capacity: capacity response
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_ReadCapacity(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_READ_CAPACITY_REQ_T* capacity)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = LEN_XFER_READ_CAPACITY;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_IN;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_READ_CAPACITY;
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostMSC->usbHostBOT.buffer = (uint8_t*)(void*)usbHostMSC->usbHostBOT.data;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
capacity->blockNum = usbHostMSC->usbHostBOT.buffer[3] | (usbHostMSC->usbHostBOT.buffer[2] << 8) | \
|
||||
(usbHostMSC->usbHostBOT.buffer[1] << 16) | (usbHostMSC->usbHostBOT.buffer[0] << 24);
|
||||
|
||||
capacity->blockSize = usbHostMSC->usbHostBOT.buffer[7] | (usbHostMSC->usbHostBOT.buffer[6] << 8) | \
|
||||
(usbHostMSC->usbHostBOT.buffer[5] << 16) | (usbHostMSC->usbHostBOT.buffer[4] << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI request sense handler
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param sense: sense response
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_RequestSense(USBH_INFO_T* usbInfo, uint8_t lun, \
|
||||
USBH_SCSI_SENSE_REQ_T* sense)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = LEN_XFER_REQUEST_SENSE;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_IN;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_REQUEST_SENSE;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[1] = (lun << 5);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[2] = 0;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[3] = 0;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[4] = LEN_XFER_REQUEST_SENSE;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[5] = 0;
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostMSC->usbHostBOT.buffer = (uint8_t*)(void*)usbHostMSC->usbHostBOT.data;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
sense->key = usbHostMSC->usbHostBOT.buffer[2] & 0x0F;
|
||||
sense->asc = usbHostMSC->usbHostBOT.buffer[12];
|
||||
sense->ascq = usbHostMSC->usbHostBOT.buffer[13];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI read10 handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param address: sector address
|
||||
*
|
||||
* @param buffer: buffer point to data
|
||||
*
|
||||
* @param cnt: count number of data
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_Read(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = cnt * usbHostMSC->storage[0].capacity.blockSize;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_IN;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_READ_10;
|
||||
|
||||
/* logical block address*/
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[2] = (((uint8_t*)&address)[3]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[3] = (((uint8_t*)&address)[2]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[4] = (((uint8_t*)&address)[1]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
/* Transfer length */
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[7] = (((uint8_t*)&cnt)[1]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[8] = (((uint8_t*)&cnt)[0]);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostMSC->usbHostBOT.buffer = buffer;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host MSC SCSI write10 handler
|
||||
*
|
||||
* @param usbInfo: usb host information
|
||||
*
|
||||
* @param lun: logical unit number
|
||||
*
|
||||
* @param address: sector address
|
||||
*
|
||||
* @param buffer: buffer point to data
|
||||
*
|
||||
* @param cnt: count number of data
|
||||
*
|
||||
* @retval USB host operation status
|
||||
*/
|
||||
USBH_STA_T USBH_MSC_SCSI_Write(USBH_INFO_T* usbInfo, uint8_t lun, uint32_t address, \
|
||||
uint8_t* buffer, uint16_t cnt)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
USBH_MSC_INFO_T* usbHostMSC = (USBH_MSC_INFO_T*)usbInfo->activeClass->classData;
|
||||
|
||||
switch (usbHostMSC->usbHostBOT.xferState)
|
||||
{
|
||||
case USBH_BOT_XFER_START:
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.dDataXferLen = cnt * usbHostMSC->storage[0].capacity.blockSize;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bmFlags.CBW_FLAG_B.dir = USBH_REQ_DIR_OUT;
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.bCBLen = USBH_LEN_CBW;
|
||||
|
||||
memset(usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB, 0, USBH_BOT_CBW_CB_LEN);
|
||||
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[0] = USBH_SCSI_CMD_WRITE10;
|
||||
|
||||
/* logical block address*/
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[2] = (((uint8_t*)&address)[3]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[3] = (((uint8_t*)&address)[2]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[4] = (((uint8_t*)&address)[1]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
/* Transfer length */
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[7] = (((uint8_t*)&cnt)[1]);
|
||||
usbHostMSC->usbHostBOT.cmdPack.CBW.DATA_FIELD.CB[8] = (((uint8_t*)&cnt)[0]);
|
||||
|
||||
usbHostMSC->usbHostBOT.state = USBH_BOT_SEND_CBW;
|
||||
usbHostMSC->usbHostBOT.xferState = USBH_BOT_XFER_WAITING;
|
||||
|
||||
/* Init buffer point */
|
||||
usbHostMSC->usbHostBOT.buffer = buffer;
|
||||
break;
|
||||
|
||||
case USBH_BOT_XFER_WAITING:
|
||||
usbStatus = USBH_MSC_BOT_Handler[usbHostMSC->usbHostBOT.state](usbInfo, lun);
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_MSC_Functions */
|
||||
/**@} end of group USBH_MSC_Class */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,53 @@
|
|||
/*!
|
||||
* @file usbh_channel.h
|
||||
*
|
||||
* @brief USB host channel handler function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_CHANNEL_H_
|
||||
#define _USBH_CHANNEL_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_config.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
void USBH_CH_Clear(USBH_INFO_T* usbInfo);
|
||||
void USBH_CH_FreeChannel(USBH_INFO_T* usbInfo, uint8_t chNum);
|
||||
uint8_t USBH_CH_AllocChannel(USBH_INFO_T* usbInfo, uint8_t epAddr);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,491 @@
|
|||
/*!
|
||||
* @file usbh_config.h
|
||||
*
|
||||
* @brief usb host config header file
|
||||
*
|
||||
* @version V1.0.1
|
||||
*
|
||||
* @date 2023-03-27
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_CONFIG_H_
|
||||
#define _USBH_CONFIG_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_board.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!< [31:16] APM32 USB Host Library main version V1.1.3*/
|
||||
#define __APM32_USB_HOST_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||
#define __APM32_USB_HOST_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */
|
||||
#define __APM32_USB_HOST_VERSION_SUB2 (0x03) /*!< [15:8] sub2 version */
|
||||
#define __APM32_USB_HOST_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __APM32_USB_HOST_VERSION ((__APM32_USB_HOST_VERSION_MAIN << 24)\
|
||||
|(__APM32_USB_HOST_VERSION_SUB1 << 16)\
|
||||
|(__APM32_USB_HOST_VERSION_SUB2 << 8 )\
|
||||
|(__APM32_USB_HOST_VERSION_RC))
|
||||
|
||||
#define USBH_EP0_PACKET_SIZE 0x40
|
||||
#define USBH_LANG_ID 0x0409
|
||||
|
||||
#define USB_REQ_DIR_OUT 0x00
|
||||
#define USB_REQ_DIR_IN 0x80
|
||||
|
||||
#define USBH_DEVICE_RESET_TIMEOUT 0x64
|
||||
#define USBH_DEVICE_DEFAULT_ADDRESS 0
|
||||
#define USBH_DEVICE_CONFIGURED_ADDRESS 1
|
||||
|
||||
#define STD_DEV_DESC_SIZE 18
|
||||
#define STD_CFG_DESC_SIZE 9
|
||||
#define STD_INTERFACE_DESC_SIZE 9
|
||||
#define STD_EP_DESC_SIZE 7
|
||||
#define STD_HID_DESC_SIZE 9
|
||||
|
||||
#define CFG_DESC_MAX_LEN 256
|
||||
#define STRING_DESC_MAX_LEN 0x200
|
||||
|
||||
#ifndef USBH_Delay
|
||||
#define USBH_Delay DAL_Delay
|
||||
#endif
|
||||
|
||||
/**@} end of group USBH_Core_Macros*/
|
||||
|
||||
/** @defgroup USBH_Core_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB host speed type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_SPEED_FS,
|
||||
USBH_SPEED_HS,
|
||||
} USBH_SPEED_T;
|
||||
|
||||
/**
|
||||
* @brief USB device speed
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_DEVICE_SPEED_HS,
|
||||
USBH_DEVICE_SPEED_FS,
|
||||
USBH_DEVICE_SPEED_LS
|
||||
} USBH_DEVICE_SPEED_T;
|
||||
|
||||
/**
|
||||
* @brief USB host operation status
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_OK,
|
||||
USBH_BUSY,
|
||||
USBH_FAIL,
|
||||
USBH_ERR_NOT_SUP,
|
||||
USBH_ERR_UNRECOVERED,
|
||||
USBH_ERR_SPEED_UNKOWN,
|
||||
} USBH_STA_T;
|
||||
|
||||
/**
|
||||
* @brief USB host state machine
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_HOST_IDLE,
|
||||
USBH_HOST_DEVICE_ATTACHED,
|
||||
USBH_HOST_DEVICE_DISCONNECTED,
|
||||
USBH_HOST_ENUMERATION,
|
||||
USBH_HOST_CLASS_REQ,
|
||||
USBH_HOST_USER_INPUT,
|
||||
USBH_HOST_SET_CONFIGURATION,
|
||||
USBH_HOST_SET_FEATURE,
|
||||
USBH_HOST_CLASS_ACTIVE,
|
||||
USBH_HOST_CLASS,
|
||||
USBH_HOST_SUSPEND,
|
||||
USBH_HOST_ABORT,
|
||||
} USBH_HOST_STA_T;
|
||||
|
||||
/**
|
||||
* @brief USB host enumeration state
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_ENUM_IDLE, //!< enum idle
|
||||
USBH_ENUM_GET_DEV_DESC, //!< Get device descriptor
|
||||
USBH_ENUM_SET_ADDR, //!< Set address
|
||||
USBH_ENUM_GET_CFG_DESC, //!< Get Configuration descriptor
|
||||
USBH_ENUM_GET_FULL_CFG_DESC, //!< Get Full Configuration descriptor
|
||||
USBH_ENUM_GET_MFC_STRING_DESC, //!< Get Manufacturer string
|
||||
USBH_ENUM_GET_PRODUCT_STRING_DESC, //!< Get Product string
|
||||
USBH_ENUM_GET_SERIALNUM_STRING_DESC, //!< Get serial number string
|
||||
} USBH_ENUM_STA_T;
|
||||
|
||||
/**
|
||||
* @brief USB transfer state
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_XFER_START,
|
||||
USBH_XFER_WAITING,
|
||||
USBH_XFER_OK,
|
||||
} USBH_XFER_STA_T;
|
||||
|
||||
/**
|
||||
* @brief USB Host control transfer state
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_CTRL_IDLE,
|
||||
USBH_CTRL_SETUP,
|
||||
USBH_CTRL_SETUP_WAIT,
|
||||
USBH_CTRL_DATA_IN,
|
||||
USBH_CTRL_DATA_IN_WAIT,
|
||||
USBH_CTRL_DATA_OUT,
|
||||
USBH_CTRL_DATA_OUT_WAIT,
|
||||
USBH_CTRL_STA_IN,
|
||||
USBH_CTRL_STA_IN_WAIT,
|
||||
USBH_CTRL_STA_OUT,
|
||||
USBH_CTRL_STA_OUT_WAIT,
|
||||
USBH_CTRL_ERROR,
|
||||
USBH_CTRL_STALL,
|
||||
USBH_CTRL_OK
|
||||
} USBH_CTRL_STATE_T;
|
||||
|
||||
/**
|
||||
* @brief USB device feature request type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_FEATURE_SELECTOR_ENDPOINT_HALT,
|
||||
USBH_FEATURE_REMOTE_WAKEUP,
|
||||
USBH_FEATURE_TEST_MODE,
|
||||
} USBH_REQ_FEATURE_T;
|
||||
|
||||
/**
|
||||
* @brief USB device request direction
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_REQ_DIR_OUT,
|
||||
USBH_REQ_DIR_IN
|
||||
} USBH_DEV_REQ_DIR_T;
|
||||
|
||||
/**
|
||||
* @brief USB device request type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_REQ_TYPE_STANDARD = 0,
|
||||
USBH_REQ_TYPE_CLASS,
|
||||
USBH_REQ_TYPE_VENDOR,
|
||||
USBH_REQ_TYPE_RESERVED
|
||||
} USBH_DEV_REQ_TYPE_T;
|
||||
|
||||
/**
|
||||
* @brief USB device request recipient
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_RECIPIENT_DEVICE = 0,
|
||||
USBH_RECIPIENT_INTERFACE,
|
||||
USBH_RECIPIENT_ENDPOINT,
|
||||
USBH_RECIPIENT_OTHER
|
||||
} USBH_DEV_RECIPIENT_T;
|
||||
|
||||
/**
|
||||
* @brief USB standard device standard requests type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_STD_GET_STATUS = 0,
|
||||
USBH_STD_CLEAR_FEATURE = 1,
|
||||
USBH_STD_SET_FEATURE = 3,
|
||||
USBH_STD_SET_ADDRESS = 5,
|
||||
USBH_STD_GET_DESCRIPTOR = 6,
|
||||
USBH_STD_SET_DESCRIPTOR = 7,
|
||||
USBH_STD_GET_CONFIGURATION = 8,
|
||||
USBH_STD_SET_CONFIGURATION = 9,
|
||||
USBH_STD_GET_INTERFACE = 10,
|
||||
USBH_STD_SET_INTERFACE = 11,
|
||||
USBH_STD_SYNCH_FRAME = 12
|
||||
} USBH_STD_REQ_TYPE_T;
|
||||
|
||||
/**
|
||||
* @brief USB descriptor types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_DESC_DEVICE = 1,
|
||||
USBH_DESC_CONFIGURATION = 2,
|
||||
USBH_DESC_STRING = 3,
|
||||
USBH_DESC_INTERFACE = 4,
|
||||
USBH_DESC_ENDPOINT = 5,
|
||||
USBH_DESC_DEVICE_QUALIFIER = 6,
|
||||
USBH_DESC_OTHER_SPEED = 7,
|
||||
USBH_DESC_INTERFACE_POWER = 8,
|
||||
USBH_DESC_HID = 0x21,
|
||||
USBH_DESC_HID_REPORT = 0x22,
|
||||
USBH_DESC_HID_PHY = 0x23,
|
||||
} USBH_DESC_TYPE_T;
|
||||
|
||||
/**
|
||||
* @brief USB Class type
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_CLASS_AUDIO = 0x01, //!< Audio
|
||||
USBH_CLASS_CDCC = 0x02, //!< Communications and CDC Control
|
||||
USBH_CLASS_HID = 0x03, //!< HID (Human Interface Device)
|
||||
USBH_CLASS_PRINTER = 0x07, //!< Printer
|
||||
USBH_CLASS_MSC = 0x08, //!< Mass Storage
|
||||
USBH_CLASS_HUB = 0x09, //!< Hub
|
||||
USBH_CLASS_CDCD = 0x0A, //!< CDC-Data
|
||||
USBH_CLASS_SMARTCARD = 0x0B, //!< Smart Card
|
||||
USBH_CLASS_VIDEO = 0x0E, //!< Video
|
||||
USBH_CLASS_AVD = 0x10 //!< Audio/Video Devices
|
||||
} USBH_CLASS_TYPE_T;
|
||||
|
||||
/**@} end of group USBH_Core_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_Core_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB request type
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
uint8_t REQ_TYPE;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t recipient : 5;
|
||||
uint8_t type : 2;
|
||||
uint8_t dir : 1;
|
||||
} REQ_TYPE_B;
|
||||
} USBH_REQ_TYPE_T;
|
||||
|
||||
/**
|
||||
* @brief USB Host request data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t REQ_DATA[8];
|
||||
|
||||
struct
|
||||
{
|
||||
USBH_REQ_TYPE_T bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint8_t wValue[2];
|
||||
uint8_t wIndex[2];
|
||||
uint8_t wLength[2];
|
||||
} DATA_FIELD;
|
||||
};
|
||||
|
||||
} USBH_REQ_DATA_T;
|
||||
|
||||
/**
|
||||
* @brief USB device descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Descriptor length
|
||||
uint8_t bDescriptorType; //!< Descriptor Type
|
||||
uint8_t bcdUSB[2]; //!< BCD of the supported USB specification
|
||||
uint8_t bDeviceClass; //!< USB device class
|
||||
uint8_t bDeviceSubClass; //!< USB device subclass
|
||||
uint8_t bDeviceProtocol; //!< USB device protocol
|
||||
uint8_t bMaxPacketSize; //!< Max Packet Size
|
||||
uint8_t idVendor[2]; //!< Vendor ID
|
||||
uint8_t idProduct[2]; //!< Product ID
|
||||
uint8_t bcdDevice[2]; //!< 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_DEV_DESC_T;
|
||||
|
||||
/**
|
||||
* @brief USB Endpoint descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Descriptor length
|
||||
uint8_t bDescriptorType; //!< Descriptor Type
|
||||
uint8_t bEndpointAddress; //!< Indicates what endpoint this descriptor is describing
|
||||
uint8_t bmAttributes; //!< Specifies the transfer type
|
||||
uint8_t wMaxPacketSize[2]; //!< Maximum Packet Size this endpoint is capable of sending or receiving
|
||||
uint8_t bInterval; //!< Polling interval in milliseconds for the endpoint
|
||||
} USBH_EP_DESC_T;
|
||||
|
||||
/**
|
||||
* @brief USB Interface descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Descriptor length
|
||||
uint8_t bDescriptorType; //!< Descriptor Type
|
||||
uint8_t bInterfaceNumber; //!< Interface Number
|
||||
uint8_t bAlternateSetting; //!< Value used to select alternative setting
|
||||
uint8_t bNumEndpoints; //!< Number of Endpoints used for this interface
|
||||
uint8_t bInterfaceClass; //!< Class Code
|
||||
uint8_t bInterfaceSubClass; //!< Sub class Code
|
||||
uint8_t bInterfaceProtocol; //!< Protocol Code
|
||||
uint8_t iInterface; //!< Index of String Descriptor of this interface
|
||||
} USBH_ITF_DESC_T;
|
||||
|
||||
/**
|
||||
* @brief USB Configuration descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength; //!< Descriptor length
|
||||
uint8_t bDescriptorType; //!< Descriptor Type
|
||||
uint8_t wTotalLength[2]; //!< Total Length of Configuration Descriptor gather
|
||||
uint8_t bNumInterfaces; //!< Total number of interfaces in the configuration
|
||||
uint8_t bConfigurationValue; //!< Configuration index of the current configuration
|
||||
uint8_t iConfiguration; //!< Index of a string descriptor describing the configuration
|
||||
uint8_t bmAttributes; //!< Configuration attributes
|
||||
uint8_t bMaxPower; //!< Maximum power consumption
|
||||
} USBH_CFG_DESC_T;
|
||||
|
||||
/**
|
||||
* @brief USB Interface and Endpoint descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_ITF_DESC_T interfaceDesc;
|
||||
USBH_EP_DESC_T endpointDesc[ENDPOINT_DESC_MAX_NUM];
|
||||
} USBH_INTERFACE_T;
|
||||
|
||||
/**
|
||||
* @brief USB Host Descriptor structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USBH_DEV_DESC_T device;
|
||||
USBH_CFG_DESC_T configuration;
|
||||
USBH_INTERFACE_T interface[INTERFACE_DESC_MAX_NUM];
|
||||
uint8_t cfgDescBuf[CFG_DESC_MAX_LEN];
|
||||
uint8_t stringBuf[STRING_DESC_MAX_LEN];
|
||||
} USBH_DESC_T;
|
||||
|
||||
/**
|
||||
* @brief USB Host device information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t data[USBH_DATA_BUF_MAX_NUM];
|
||||
uint8_t address;
|
||||
uint8_t speed;
|
||||
__IO uint8_t connectedStatus;
|
||||
__IO uint8_t disconnectedStatus;
|
||||
__IO uint8_t reEnumStatus;
|
||||
uint8_t portEnable;
|
||||
uint8_t rstCnt;
|
||||
uint8_t enumCnt;
|
||||
USBH_DESC_T desc;
|
||||
} USBH_DEV_INFO_T;
|
||||
|
||||
/**
|
||||
* @brief USB Control thansfer info
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state;
|
||||
uint8_t errCnt;
|
||||
uint8_t channelInNum;
|
||||
uint8_t channelOutNum;
|
||||
uint8_t channelSize;
|
||||
uint8_t* buffer;
|
||||
uint16_t length;
|
||||
USBH_REQ_DATA_T reqData;
|
||||
} USBH_CTRL_T;
|
||||
|
||||
struct _USBH_INFO_T;
|
||||
|
||||
/* Class callback function type define */
|
||||
typedef USBH_STA_T(*USBH_ClassCallback_T)(struct _USBH_INFO_T* usbInfo);
|
||||
|
||||
/**
|
||||
* @brief USB host class handler
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char* className;
|
||||
uint8_t classCode;
|
||||
void* classData;
|
||||
USBH_ClassCallback_T classInitHandler;
|
||||
USBH_ClassCallback_T classDeInitHandler;
|
||||
USBH_ClassCallback_T classReqHandler;
|
||||
USBH_ClassCallback_T classCoreHandler;
|
||||
USBH_ClassCallback_T classSofHandler;
|
||||
} USBH_CLASS_T;
|
||||
|
||||
/* Host state handler function */
|
||||
typedef USBH_STA_T(*USBH_CoreHandler_T)(struct _USBH_INFO_T* usbInfo);
|
||||
|
||||
/* Host enum state handler function */
|
||||
typedef USBH_STA_T(*USBH_EnumHandler_T)(struct _USBH_INFO_T* usbInfo);
|
||||
|
||||
/* Host control transfer state handler function */
|
||||
typedef USBH_STA_T(*USBH_CtrlStateHandler_T)(struct _USBH_INFO_T* usbInfo);
|
||||
|
||||
/**
|
||||
* @brief USB host information
|
||||
*/
|
||||
typedef struct _USBH_INFO_T
|
||||
{
|
||||
USBH_HOST_STA_T hostState; /*!< USB Host State Machine*/
|
||||
USBH_ENUM_STA_T hostEnumState;
|
||||
USBH_SPEED_T hostSpeed;
|
||||
USBH_DEV_INFO_T devInfo;
|
||||
uint8_t xferState;
|
||||
USBH_CTRL_T ctrl; /*!< Control Thansfer info management*/
|
||||
USBH_CLASS_T* hostClass[USBH_SUP_CLASS_MAX_NUM]; /*!< USB host class */
|
||||
USBH_CLASS_T* activeClass;
|
||||
uint32_t classNum;
|
||||
__IO uint32_t timer;
|
||||
uint32_t timeout;
|
||||
uint32_t xferChannel[USBH_CHANNEL_MAX_NUM]; /*!< Thansfer data management (The sixteenth bit is indicate free or not status)*/
|
||||
void (*userCallback)(struct _USBH_INFO_T* usbInfo, uint8_t userStatus);
|
||||
void* dataPoint;
|
||||
} USBH_INFO_T;
|
||||
|
||||
|
||||
/**@} end of group USBH_Core_Structures*/
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,104 @@
|
|||
/*!
|
||||
* @file usbh_core.h
|
||||
*
|
||||
* @brief USB host core function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_CORE_H_
|
||||
#define _USBH_CORE_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_config.h"
|
||||
#include "usbh_channel.h"
|
||||
#include "usbh_stdReq.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Enumerates Enumerates
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USB host user status
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBH_USER_CONNECTION = 1,
|
||||
USBH_USER_DISCONNECTION,
|
||||
USBH_USER_DETECTED_SPEED,
|
||||
USBH_USER_ENUMERATION,
|
||||
USBH_USER_CLASS_LAUNCHED,
|
||||
USBH_USER_NOT_SUPPORT,
|
||||
USBH_USER_ERROR,
|
||||
} USBH_USER_STATUS;
|
||||
|
||||
/**@} end of group USBH_Core_Enumerates*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_Init(USBH_INFO_T* usbInfo, USBH_SPEED_T usbHostSpeed, USBH_CLASS_T* usbHostClass,
|
||||
void (*userCallbackFunc)(struct _USBH_INFO_T*, uint8_t));
|
||||
USBH_STA_T USBH_DeInit(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_RegisterClass(USBH_INFO_T* usbInfo, USBH_CLASS_T* usbHostClass);
|
||||
USBH_STA_T USBH_PollingProcess(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_Disconnect(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_Connect(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_PortEnable(USBH_INFO_T* usbInfo);
|
||||
USBH_STA_T USBH_PortDisable(USBH_INFO_T* usbInfo);
|
||||
void USBH_IncTimer(USBH_INFO_T* usbInfo);
|
||||
void USBH_ConfigTimer(USBH_INFO_T* usbInfo, uint32_t tick);
|
||||
void USBH_HardwareInit(USBH_INFO_T* usbInfo);
|
||||
void USBH_HardwareReset(USBH_INFO_T* usbInfo);
|
||||
void USBH_StopHostCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_StartCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_StopCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_ResetCallback(USBH_INFO_T* usbInfo);
|
||||
uint8_t USBH_ReadSpeedCallback(USBH_INFO_T* usbInfo);
|
||||
void USBH_OpenChannelCallback(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t endPointNum, uint8_t devAddr, \
|
||||
uint8_t devSpeed, uint8_t epType, uint16_t packetMaxSize);
|
||||
|
||||
void USBH_UrbSubmitCallback(USBH_INFO_T* usbInfo, uint8_t chNum, uint8_t dir, \
|
||||
uint8_t epType, uint8_t tokenType, uint8_t* buffer, \
|
||||
uint16_t length, uint8_t pingStatus);
|
||||
|
||||
uint8_t USBH_ReadUrbStatusCallback(USBH_INFO_T* usbInfo, uint8_t channelNum);
|
||||
void USBH_ConfigDataPidCallback(USBH_INFO_T* usbInfo, uint8_t channelNum, uint8_t dataPid);
|
||||
void USBH_CloseChannelCallback(USBH_INFO_T* usbInfo, uint8_t channelNum);
|
||||
uint32_t USBH_ReadLastXferSizeCallback(USBH_INFO_T* usbInfo, uint8_t channelNum);
|
||||
uint8_t USBH_ReadToggleCallback(USBH_INFO_T* usbInfo, uint8_t channelNum);
|
||||
void USBH_ConfigToggleCallback(USBH_INFO_T* usbInfo, uint8_t channelNum, uint8_t toggle);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
/*!
|
||||
* @file usbh_dataXfer.h
|
||||
*
|
||||
* @brief USB host input and output hander function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_DATAXFER_H_
|
||||
#define _USBH_DATAXFER_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_config.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
extern USBH_CtrlStateHandler_T USBH_CtrlStateHandler[];
|
||||
|
||||
/**@} end of group USBH_Core_Structures*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_BulkSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length, \
|
||||
uint8_t pingStatus);
|
||||
|
||||
USBH_STA_T USBH_BulkReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length);
|
||||
|
||||
USBH_STA_T USBH_IntSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length);
|
||||
|
||||
USBH_STA_T USBH_IntReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length);
|
||||
|
||||
USBH_STA_T USBH_IntSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length);
|
||||
|
||||
USBH_STA_T USBH_IsoReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*!
|
||||
* @file usbh_enum.h
|
||||
*
|
||||
* @brief USB host enum hander function head file
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_ENUM_H_
|
||||
#define _USBH_ENUM_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_config.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
extern USBH_EnumHandler_T USBH_EnumHandler[];
|
||||
|
||||
/**@} end of group USBH_Core_Structures*/
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,96 @@
|
|||
/*!
|
||||
* @file usbh_stdReq.h
|
||||
*
|
||||
* @brief USB standard request process
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion */
|
||||
#ifndef _USBH_STDREQ_H_
|
||||
#define _USBH_STDREQ_H_
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_config.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Macros Macros
|
||||
@{
|
||||
*/
|
||||
|
||||
#define USBH_SETUP_PACKET_SIZE 8
|
||||
#define USBH_ReadConfigurationItfNum(usbInfo) \
|
||||
usbInfo->devInfo.desc.configuration.bNumInterfaces
|
||||
|
||||
#define USBH_ReadInterfaceClass(usbInfo, itfIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].interfaceDesc.bInterfaceClass
|
||||
|
||||
#define USBH_ReadInterfaceSubClass(usbInfo, itfIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].interfaceDesc.bInterfaceSubClass
|
||||
|
||||
#define USBH_ReadInterfaceProtocol(usbInfo, itfIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].interfaceDesc.bInterfaceProtocol
|
||||
|
||||
#define USBH_ReadInterfaceEpNum(usbInfo, itfIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].interfaceDesc.bNumEndpoints
|
||||
|
||||
#define USBH_ReadEndpointAddress(usbInfo, itfIndex, epIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].endpointDesc[epIndex].bEndpointAddress
|
||||
|
||||
#define USBH_ReadEndpointMPS(usbInfo, itfIndex, epIndex) \
|
||||
((uint16_t)usbInfo->devInfo.desc.interface[itfIndex].endpointDesc[epIndex].wMaxPacketSize[0] | \
|
||||
(uint16_t)usbInfo->devInfo.desc.interface[itfIndex].endpointDesc[epIndex].wMaxPacketSize[1] << 8)
|
||||
|
||||
#define USBH_ReadEndpointInterval(usbInfo, itfIndex, epIndex) \
|
||||
usbInfo->devInfo.desc.interface[itfIndex].endpointDesc[epIndex].bInterval
|
||||
|
||||
/**@} end of group USBH_Core_Macros*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
USBH_STA_T USBH_GetDevDesc(USBH_INFO_T* usbInfo, uint8_t desLength);
|
||||
USBH_STA_T USBH_SetAddr(USBH_INFO_T* usbInfo, uint8_t address);
|
||||
USBH_STA_T USBH_GetCfgDesc(USBH_INFO_T* usbInfo, uint16_t desLength);
|
||||
USBH_STA_T USBH_GetStringDesc(USBH_INFO_T* usbInfo, uint8_t stringIndex, \
|
||||
uint8_t* buffer, uint16_t desLength);
|
||||
|
||||
USBH_STA_T USBH_REQ_GetDescriptor(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint16_t desType, uint8_t* buffer, uint16_t length);
|
||||
|
||||
USBH_STA_T USBH_SetConfiguration(USBH_INFO_T* usbInfo, uint16_t configuration);
|
||||
USBH_STA_T USBH_SetFeature(USBH_INFO_T* usbInfo, uint8_t feature);
|
||||
USBH_STA_T USBH_ClearFeature(USBH_INFO_T* usbInfo, uint8_t epNum);
|
||||
|
||||
USBH_STA_T USBH_REQ_CtrlXferHandler(USBH_INFO_T* usbInfo, uint8_t* buffer, uint16_t length);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
/*!
|
||||
* @file usbh_core.c
|
||||
*
|
||||
* @brief USB host core function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_channel.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Clear all of the pipe data buffer.
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_CH_Clear(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < USBH_CHANNEL_MAX_NUM; i++)
|
||||
{
|
||||
usbInfo->xferChannel[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the free channel.
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @retval None.
|
||||
*/
|
||||
uint16_t USBH_CH_ReadFreeChannel(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < USBH_CHANNEL_MAX_NUM; i++)
|
||||
{
|
||||
if ((usbInfo->xferChannel[i] & 0x8000) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Free the channel.
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param chNum : channel to be free.
|
||||
*
|
||||
* @retval None.
|
||||
*/
|
||||
void USBH_CH_FreeChannel(USBH_INFO_T* usbInfo, uint8_t chNum)
|
||||
{
|
||||
if (chNum < USBH_CHANNEL_MAX_NUM)
|
||||
{
|
||||
usbInfo->xferChannel[chNum] &= 0x7FFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Alloc a channel for a endpoint by address.
|
||||
*
|
||||
* @param usbInfo
|
||||
*
|
||||
* @param epAddr : endpoint address to be alloc channel.
|
||||
*
|
||||
* @retval channel number.
|
||||
*/
|
||||
uint8_t USBH_CH_AllocChannel(USBH_INFO_T* usbInfo, uint8_t epAddr)
|
||||
{
|
||||
uint16_t channelNum;
|
||||
|
||||
channelNum = USBH_CH_ReadFreeChannel(usbInfo);
|
||||
|
||||
if (channelNum != 0xFFFF)
|
||||
{
|
||||
usbInfo->xferChannel[channelNum & 0x0F] = (uint32_t)(0x8000 | epAddr);
|
||||
}
|
||||
|
||||
return (uint8_t)channelNum;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,808 @@
|
|||
/*!
|
||||
* @file usbh_dataXfer.c
|
||||
*
|
||||
* @brief USB host input and output hander function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_dataXfer.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_stdReq.h"
|
||||
#include "usbh_channel.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
static USBH_STA_T USBH_CtrlXferIdle(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferSetup(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferSetupWait(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferInData(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferInDataWait(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferOutData(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferOutDataWait(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferInSta(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferInStaWait(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferOutSta(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferOutStaWait(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferError(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferStall(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_CtrlXferOk(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
|
||||
/** @defgroup USBH_Core_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/* USB control transfer state handler function */
|
||||
USBH_CtrlStateHandler_T USBH_CtrlStateHandler[] =
|
||||
{
|
||||
USBH_CtrlXferIdle,
|
||||
USBH_CtrlXferSetup,
|
||||
USBH_CtrlXferSetupWait,
|
||||
USBH_CtrlXferInData,
|
||||
USBH_CtrlXferInDataWait,
|
||||
USBH_CtrlXferOutData,
|
||||
USBH_CtrlXferOutDataWait,
|
||||
USBH_CtrlXferInSta,
|
||||
USBH_CtrlXferInStaWait,
|
||||
USBH_CtrlXferOutSta,
|
||||
USBH_CtrlXferOutStaWait,
|
||||
USBH_CtrlXferError,
|
||||
USBH_CtrlXferStall,
|
||||
USBH_CtrlXferOk,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_Core_Structures*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Control transfer send data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @param pingStatus : ping status
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length, \
|
||||
uint8_t pingStatus)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
if ((usbInfo->devInfo.speed != USBH_DEVICE_SPEED_HS) && (pingStatus == ENABLE))
|
||||
{
|
||||
pingStatus = DISABLE;
|
||||
}
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_OUT, \
|
||||
EP_TYPE_CONTROL, \
|
||||
USBH_PID_DATA, \
|
||||
(uint8_t*)buffer, \
|
||||
length, \
|
||||
pingStatus);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Control transfer receive data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_IN, \
|
||||
EP_TYPE_CONTROL, \
|
||||
USBH_PID_DATA, \
|
||||
(uint8_t*)buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Start control setup transfer
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be sent
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlSetupReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
USBH_REQ_DATA_T* buffer)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_OUT, \
|
||||
EP_TYPE_CONTROL, \
|
||||
USBH_PID_SETUP, \
|
||||
(uint8_t*)buffer, \
|
||||
USBH_SETUP_PACKET_SIZE, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control idle state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferIdle(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_IDLE;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferIdle");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control setup transfer
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferSetup(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferSetup");
|
||||
|
||||
/* Sent setup packet */
|
||||
USBH_CtrlSetupReq(usbInfo, usbInfo->ctrl.channelOutNum, &usbInfo->ctrl.reqData);
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_SETUP_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control setup wait URB status transfer
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferSetupWait(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
uint16_t reqLenghTemp;
|
||||
uint8_t reqDirTemp;
|
||||
//static uint32_t timeout = 0;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferSetupWait");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
//timeout = 0;
|
||||
reqDirTemp = usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir;
|
||||
reqLenghTemp = usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] << 8 | \
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0];
|
||||
|
||||
/* Goto DATA state */
|
||||
if (reqLenghTemp != 0)
|
||||
{
|
||||
if (reqDirTemp == USB_REQ_DIR_OUT)
|
||||
{
|
||||
usbInfo->ctrl.state = USBH_CTRL_DATA_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbInfo->ctrl.state = USBH_CTRL_DATA_IN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reqDirTemp == USB_REQ_DIR_OUT)
|
||||
{
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_OUT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_URB_ERROR:
|
||||
case USB_URB_NOREADY:
|
||||
//timeout = 0;
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
//timeout++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*if(timeout >= 500)
|
||||
{
|
||||
timeout = 0;
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
}*/
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control IN state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferInData(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferInData");
|
||||
|
||||
USBH_CtrlReceiveDataReq(usbInfo, usbInfo->ctrl.channelInNum, \
|
||||
usbInfo->ctrl.buffer, usbInfo->ctrl.length);
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_DATA_IN_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control IN wait URB status state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferInDataWait(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferInDataWait");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_OUT;
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbStatus = USBH_ERR_NOT_SUP;
|
||||
break;
|
||||
|
||||
case USB_URB_ERROR:
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control OUT state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferOutData(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferOutData");
|
||||
|
||||
USBH_CtrlSendDataReq(usbInfo, usbInfo->ctrl.channelOutNum, \
|
||||
usbInfo->ctrl.buffer, usbInfo->ctrl.length, \
|
||||
ENABLE);
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_DATA_OUT_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Handle control OUT wait URB status state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferOutDataWait(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferOutDataWait");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_IN;
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbInfo->ctrl.state = USBH_CTRL_STALL;
|
||||
usbStatus = USBH_ERR_NOT_SUP;
|
||||
break;
|
||||
|
||||
case USB_URB_NOREADY:
|
||||
usbInfo->ctrl.state = USBH_CTRL_DATA_OUT;
|
||||
break;
|
||||
|
||||
case USB_URB_ERROR:
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
usbStatus = USBH_FAIL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control STATUS IN state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferInSta(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferInSta");
|
||||
|
||||
/* Send 0 byte out packet */
|
||||
USBH_CtrlReceiveDataReq(usbInfo, usbInfo->ctrl.channelInNum, \
|
||||
NULL, 0);
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_IN_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control STATUS IN wait state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferInStaWait(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferInStaWait");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
usbInfo->ctrl.state = USBH_CTRL_OK;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USB_URB_STALL:
|
||||
usbStatus = USBH_ERR_NOT_SUP;
|
||||
break;
|
||||
|
||||
case USB_URB_ERROR:
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control STATUS OUT state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferOutSta(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferOutSta");
|
||||
|
||||
/* Send 0 byte out packet */
|
||||
USBH_CtrlSendDataReq(usbInfo, usbInfo->ctrl.channelOutNum, \
|
||||
NULL, 0, ENABLE);
|
||||
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_OUT_WAIT;
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control STATUS OUT wait state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferOutStaWait(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
uint8_t usbUrbStatus = USB_URB_IDLE;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferOutStaWait");
|
||||
|
||||
/* Read USB URB status */
|
||||
usbUrbStatus = USBH_ReadUrbStatusCallback(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
switch (usbUrbStatus)
|
||||
{
|
||||
case USB_URB_OK:
|
||||
usbInfo->ctrl.state = USBH_CTRL_OK;
|
||||
usbStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USB_URB_NOREADY:
|
||||
usbInfo->ctrl.state = USBH_CTRL_STA_OUT;
|
||||
break;
|
||||
|
||||
case USB_URB_ERROR:
|
||||
usbInfo->ctrl.state = USBH_CTRL_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control ERROR state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferError(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferError");
|
||||
|
||||
usbInfo->ctrl.errCnt++;
|
||||
|
||||
if (usbInfo->ctrl.errCnt > 2)
|
||||
{
|
||||
/* Notify user */
|
||||
usbInfo->userCallback(usbInfo, USBH_USER_ERROR);
|
||||
usbInfo->ctrl.errCnt = 0;
|
||||
USBH_USR_LOG("Control error: Device No Response");
|
||||
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
usbInfo->hostState = USBH_HOST_IDLE;
|
||||
usbStatus = USBH_FAIL;
|
||||
// usbStatus = USBH_ERR_NOT_SUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Retry again */
|
||||
usbInfo->ctrl.state = USBH_CTRL_SETUP;
|
||||
usbInfo->xferState = USBH_XFER_START;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control STALL state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferStall(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_ERR_NOT_SUP;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferStall");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control OK state
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_CtrlXferOk(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
USBH_USR_Debug("USBH_CtrlXferOk");
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Bulk transfer send data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @param pingStatus : ping status
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_BulkSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length, \
|
||||
uint8_t pingStatus)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
if ((usbInfo->devInfo.speed != USBH_DEVICE_SPEED_HS) && (pingStatus == ENABLE))
|
||||
{
|
||||
pingStatus = DISABLE;
|
||||
}
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_OUT, \
|
||||
EP_TYPE_BULK, \
|
||||
USBH_PID_DATA, \
|
||||
(uint8_t*)buffer, \
|
||||
length, \
|
||||
pingStatus);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Bulk transfer receive data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_BulkReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_IN, \
|
||||
EP_TYPE_BULK, \
|
||||
USBH_PID_DATA, \
|
||||
buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Interrupt transfer receive data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_IntReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_IN, \
|
||||
EP_TYPE_INTERRUPT, \
|
||||
USBH_PID_DATA, \
|
||||
buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Interrupt transfer send data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_IntSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_OUT, \
|
||||
EP_TYPE_INTERRUPT, \
|
||||
USBH_PID_DATA, \
|
||||
buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Isochronous transfer receive data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_IsoReceiveDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_IN, \
|
||||
EP_TYPE_ISO, \
|
||||
USBH_PID_DATA, \
|
||||
buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Isochronous transfer send data request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param channelNum : channel number
|
||||
*
|
||||
* @param buffer : buffer to be receive data
|
||||
*
|
||||
* @param length : transfer length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_IsoSendDataReq(USBH_INFO_T* usbInfo, uint8_t channelNum, \
|
||||
uint8_t* buffer, uint8_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
/* Callback USB URB submit */
|
||||
USBH_UrbSubmitCallback(usbInfo, channelNum, \
|
||||
EP_DIR_OUT, \
|
||||
EP_TYPE_ISO, \
|
||||
USBH_PID_DATA, \
|
||||
buffer, \
|
||||
length, \
|
||||
0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,495 @@
|
|||
/*!
|
||||
* @file usbh_enum.c
|
||||
*
|
||||
* @brief USB host enum hander function
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_enum.h"
|
||||
#include "usbh_stdReq.h"
|
||||
#include "usbh_core.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
static USBH_STA_T USBH_ENUM_IdleHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetDevDescHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_SetAddressHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetConfigurationDescHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetFullConfigurationDescHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetMFCStringHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetProductStringHandler(USBH_INFO_T* usbInfo);
|
||||
static USBH_STA_T USBH_ENUM_GetSerialNumStringHandler(USBH_INFO_T* usbInfo);
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
|
||||
/** @defgroup USBH_Core_Structures Structures
|
||||
@{
|
||||
*/
|
||||
|
||||
/* USB host enum state handler function */
|
||||
USBH_EnumHandler_T USBH_EnumHandler[] =
|
||||
{
|
||||
USBH_ENUM_IdleHandler,
|
||||
USBH_ENUM_GetDevDescHandler,
|
||||
USBH_ENUM_SetAddressHandler,
|
||||
USBH_ENUM_GetConfigurationDescHandler,
|
||||
USBH_ENUM_GetFullConfigurationDescHandler,
|
||||
USBH_ENUM_GetMFCStringHandler,
|
||||
USBH_ENUM_GetProductStringHandler,
|
||||
USBH_ENUM_GetSerialNumStringHandler,
|
||||
};
|
||||
|
||||
/**@} end of group USBH_Core_Structures*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Handle enum idle stage and get 8 bytes device descriptor
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_IdleHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
usbStatus = USBH_GetDevDesc(usbInfo, 0x08);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbInfo->ctrl.channelSize = usbInfo->devInfo.desc.device.bMaxPacketSize;
|
||||
|
||||
/* Open and config in channel */
|
||||
USBH_OpenChannelCallback(usbInfo, usbInfo->ctrl.channelInNum,
|
||||
0x80, usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed, EP_TYPE_CONTROL,
|
||||
usbInfo->ctrl.channelSize);
|
||||
|
||||
/* Open and config out channel */
|
||||
USBH_OpenChannelCallback(usbInfo, usbInfo->ctrl.channelOutNum,
|
||||
0x00, usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed, EP_TYPE_CONTROL,
|
||||
usbInfo->ctrl.channelSize);
|
||||
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_DEV_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("CTRL error: get device descriptor");
|
||||
usbInfo->devInfo.enumCnt++;
|
||||
|
||||
if (usbInfo->devInfo.enumCnt <= 3)
|
||||
{
|
||||
/* Free control channel */
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
/* Reset USB host state machine */
|
||||
usbInfo->hostState = USBH_HOST_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_USR_LOG("CTRL error: device no response, please unplug the device");
|
||||
usbInfo->hostState = USBH_HOST_ABORT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get full bytes device descriptor stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetDevDescHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetDevDescHandler");
|
||||
|
||||
usbStatus = USBH_GetDevDesc(usbInfo, STD_DEV_DESC_SIZE);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
USBH_USR_LOG("PID: 0x%04X", usbInfo->devInfo.desc.device.idProduct[0] | \
|
||||
usbInfo->devInfo.desc.device.idProduct[1] << 8);
|
||||
|
||||
USBH_USR_LOG("VID: 0x%04X", usbInfo->devInfo.desc.device.idVendor[0] | \
|
||||
usbInfo->devInfo.desc.device.idVendor[1] << 8);
|
||||
USBH_USR_LOG("Endpoint 0 max packet size if %d", usbInfo->devInfo.desc.device.bMaxPacketSize);
|
||||
|
||||
|
||||
usbInfo->hostEnumState = USBH_ENUM_SET_ADDR;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("CTRL error: get full device descriptor");
|
||||
usbInfo->devInfo.enumCnt++;
|
||||
|
||||
if (usbInfo->devInfo.enumCnt <= 3)
|
||||
{
|
||||
/* Free control channel */
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
/* Reset USB host state machine */
|
||||
usbInfo->hostState = USBH_HOST_IDLE;
|
||||
usbInfo->hostEnumState = USBH_ENUM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_USR_LOG("CTRL error: device no response, please unplug the device");
|
||||
usbInfo->hostState = USBH_HOST_ABORT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum set address stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_SetAddressHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_SetAddressHandler");
|
||||
|
||||
usbStatus = USBH_SetAddr(usbInfo, USBH_DEVICE_CONFIGURED_ADDRESS);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
/* Update device address */
|
||||
usbInfo->devInfo.address = USBH_DEVICE_CONFIGURED_ADDRESS;
|
||||
USBH_USR_LOG("USB device address: %d", usbInfo->devInfo.address);
|
||||
|
||||
USBH_Delay(5);
|
||||
|
||||
/* Modify channels to new device address */
|
||||
/* Open and config out channel */
|
||||
USBH_OpenChannelCallback(usbInfo, usbInfo->ctrl.channelOutNum,
|
||||
0x00, usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed, EP_TYPE_CONTROL,
|
||||
usbInfo->ctrl.channelSize);
|
||||
|
||||
/* Open and config in channel */
|
||||
USBH_OpenChannelCallback(usbInfo, usbInfo->ctrl.channelInNum,
|
||||
0x80, usbInfo->devInfo.address,
|
||||
usbInfo->devInfo.speed, EP_TYPE_CONTROL,
|
||||
usbInfo->ctrl.channelSize);
|
||||
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_CFG_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("CTRL error: set device address");
|
||||
USBH_USR_LOG("CTRL error: device no response, please unplug the device");
|
||||
usbInfo->hostState = USBH_HOST_ABORT;
|
||||
usbInfo->hostEnumState = USBH_ENUM_IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get configuration descriptor stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetConfigurationDescHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetConfigurationDescHandler");
|
||||
|
||||
usbStatus = USBH_GetCfgDesc(usbInfo, STD_CFG_DESC_SIZE);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_FULL_CFG_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("CTRL error: get configuration descriptor");
|
||||
|
||||
usbInfo->devInfo.enumCnt++;
|
||||
|
||||
if (usbInfo->devInfo.enumCnt <= 3)
|
||||
{
|
||||
/* Free control channel */
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
/* Reset USB host state machine */
|
||||
usbInfo->hostState = USBH_HOST_IDLE;
|
||||
usbInfo->hostEnumState = USBH_ENUM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_USR_LOG("CTRL error: device no response, please unplug the device");
|
||||
usbInfo->hostState = USBH_HOST_ABORT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get full configuration descriptor stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetFullConfigurationDescHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
uint16_t cfgDescTotalTemp;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetFullConfigurationDescHandler");
|
||||
|
||||
cfgDescTotalTemp = usbInfo->devInfo.desc.configuration.wTotalLength[0] | \
|
||||
usbInfo->devInfo.desc.configuration.wTotalLength[1] << 8;
|
||||
|
||||
usbStatus = USBH_GetCfgDesc(usbInfo, cfgDescTotalTemp);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_MFC_STRING_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("CTRL error: get full configuration descriptor");
|
||||
|
||||
usbInfo->devInfo.enumCnt++;
|
||||
|
||||
if (usbInfo->devInfo.enumCnt <= 3)
|
||||
{
|
||||
/* Free control channel */
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelInNum);
|
||||
USBH_CH_FreeChannel(usbInfo, usbInfo->ctrl.channelOutNum);
|
||||
|
||||
/* Reset USB host state machine */
|
||||
usbInfo->hostState = USBH_HOST_IDLE;
|
||||
usbInfo->hostEnumState = USBH_ENUM_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_USR_LOG("CTRL error: device no response, please unplug the device");
|
||||
usbInfo->hostState = USBH_HOST_ABORT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get manufacturer string stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetMFCStringHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetMFCStringHandler");
|
||||
|
||||
if (usbInfo->devInfo.desc.device.iManufacturer == 0)
|
||||
{
|
||||
USBH_USR_LOG("Manufacturer is N/A");
|
||||
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_PRODUCT_STRING_DESC;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbStatus = USBH_GetStringDesc(usbInfo, usbInfo->devInfo.desc.device.iManufacturer, \
|
||||
usbInfo->devInfo.desc.stringBuf, 0xFF);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
USBH_USR_LOG("Manufacturer: %s", (char*)usbInfo->devInfo.desc.stringBuf);
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_PRODUCT_STRING_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("Manufacturer is N/A");
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_PRODUCT_STRING_DESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get product string stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetProductStringHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetProductStringHandler");
|
||||
|
||||
if (usbInfo->devInfo.desc.device.iProduct == 0)
|
||||
{
|
||||
USBH_USR_LOG("Product is N/A");
|
||||
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbStatus = USBH_GetStringDesc(usbInfo, usbInfo->devInfo.desc.device.iProduct, \
|
||||
usbInfo->devInfo.desc.stringBuf, 0xFF);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
USBH_USR_LOG("Product: %s", (char*)usbInfo->devInfo.desc.stringBuf);
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("Product is N/A");
|
||||
usbInfo->hostEnumState = USBH_ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle enum get serial number string stage
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
static USBH_STA_T USBH_ENUM_GetSerialNumStringHandler(USBH_INFO_T* usbInfo)
|
||||
{
|
||||
USBH_STA_T usbEnumStatus = USBH_BUSY;
|
||||
uint8_t usbStatus = USBH_BUSY;
|
||||
|
||||
USBH_USR_Debug("USBH_ENUM_GetSerialNumStringHandler");
|
||||
|
||||
if (usbInfo->devInfo.desc.device.iSerialNumber == 0)
|
||||
{
|
||||
USBH_USR_LOG("SerialNumber is N/A");
|
||||
usbEnumStatus = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbStatus = USBH_GetStringDesc(usbInfo, usbInfo->devInfo.desc.device.iSerialNumber, \
|
||||
usbInfo->devInfo.desc.stringBuf, 0xFF);
|
||||
|
||||
switch (usbStatus)
|
||||
{
|
||||
case USBH_OK:
|
||||
USBH_USR_LOG("SerialNumber: %s", (char*)usbInfo->devInfo.desc.stringBuf);
|
||||
usbEnumStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
case USBH_ERR_NOT_SUP:
|
||||
USBH_USR_LOG("SerialNumber is N/A");
|
||||
usbEnumStatus = USBH_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return usbEnumStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
|
@ -0,0 +1,723 @@
|
|||
/*!
|
||||
* @file usbh_stdReq.c
|
||||
*
|
||||
* @brief USB standard request process
|
||||
*
|
||||
* @version V1.0.0
|
||||
*
|
||||
* @date 2023-01-16
|
||||
*
|
||||
* @attention
|
||||
*
|
||||
* Copyright (C) 2023 Geehy Semiconductor
|
||||
*
|
||||
* You may not use this file except in compliance with the
|
||||
* GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
|
||||
*
|
||||
* The program is only for reference, which is distributed in the hope
|
||||
* that it will be useful and instructional for customers to develop
|
||||
* their software. Unless required by applicable law or agreed to in
|
||||
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include "usbh_stdReq.h"
|
||||
#include "usbh_dataXfer.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup APM32_USB_Library
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_Core
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_Core_Functions Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Parse string descriptor
|
||||
*
|
||||
* @param stringDesc : string descriptor
|
||||
*
|
||||
* @param buffer : source recevice data
|
||||
*
|
||||
* @param length : device descriptor length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_StringDescParse(uint8_t* stringDesc, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
uint8_t descType;
|
||||
uint16_t stringLen;
|
||||
uint16_t i;
|
||||
|
||||
descType = *(uint8_t*)(buffer + 1);
|
||||
|
||||
if (descType == USBH_DESC_STRING)
|
||||
{
|
||||
stringLen = *(uint8_t*)(buffer + 0) - 2;
|
||||
if (stringLen > length)
|
||||
{
|
||||
stringLen = length;
|
||||
}
|
||||
|
||||
buffer += 2;
|
||||
|
||||
/* only copy UNICODE bsting */
|
||||
for (i = 0; i < stringLen; i += 2)
|
||||
{
|
||||
*stringDesc = buffer[i];
|
||||
stringDesc++;
|
||||
}
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Copy data from source buffer to destination buffer.
|
||||
*
|
||||
* @param desBuffer: point to destination buffer
|
||||
*
|
||||
* @param srcBuf : point to source buffer
|
||||
*
|
||||
* @param len: copy length
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_CopyBuffer(uint8_t* desBuffer, uint8_t* srcBuf, uint32_t len)
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
desBuffer[len] = srcBuf[len];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Parse configuration descriptor
|
||||
*
|
||||
* @param cfgDesc : configuration descriptor
|
||||
*
|
||||
* @param interface : interface of intDesc and epDesc
|
||||
*
|
||||
* @param buffer : source recevice data
|
||||
*
|
||||
* @param length : device descriptor length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_CfgDescParse(USBH_CFG_DESC_T* cfgDesc, USBH_INTERFACE_T* interface, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
uint16_t totalLenTemp = 0;
|
||||
uint16_t parseIndex = 0;
|
||||
uint8_t itfIndex = 0;
|
||||
uint8_t epIndex = 0;
|
||||
uint8_t subLen = 0;
|
||||
|
||||
cfgDesc->bLength = *(uint8_t*)(buffer + 0);
|
||||
cfgDesc->bDescriptorType = *(uint8_t*)(buffer + 1);
|
||||
|
||||
totalLenTemp = *(uint8_t*)(buffer + 2) | (*(uint8_t*)(buffer + 3) << 8);
|
||||
totalLenTemp = ((totalLenTemp) < (CFG_DESC_MAX_LEN) ? (totalLenTemp) : (CFG_DESC_MAX_LEN));
|
||||
|
||||
cfgDesc->wTotalLength[0] = totalLenTemp & 0xFF;
|
||||
cfgDesc->wTotalLength[1] = (totalLenTemp >> 8) & 0xFF;
|
||||
cfgDesc->bNumInterfaces = *(uint8_t*)(buffer + 4);
|
||||
cfgDesc->bConfigurationValue = *(uint8_t*)(buffer + 5);
|
||||
cfgDesc->iConfiguration = *(uint8_t*)(buffer + 6);
|
||||
cfgDesc->bmAttributes = *(uint8_t*)(buffer + 7);
|
||||
cfgDesc->bMaxPower = *(uint8_t*)(buffer + 8);
|
||||
|
||||
if (cfgDesc->bLength != STD_CFG_DESC_SIZE)
|
||||
{
|
||||
cfgDesc->bLength = STD_CFG_DESC_SIZE;
|
||||
}
|
||||
|
||||
/* USB configuration descriptor lenght > STD_CFG_DESC_SIZE */
|
||||
if (length > STD_CFG_DESC_SIZE)
|
||||
{
|
||||
parseIndex = STD_CFG_DESC_SIZE;
|
||||
|
||||
while (totalLenTemp > parseIndex)
|
||||
{
|
||||
/* Get descriptor length at first byte */
|
||||
subLen = buffer[parseIndex];
|
||||
|
||||
/* Check the descriptor Type at second byte */
|
||||
switch (buffer[parseIndex + 1])
|
||||
{
|
||||
case USBH_DESC_INTERFACE:
|
||||
if (itfIndex < INTERFACE_DESC_MAX_NUM)
|
||||
{
|
||||
/* Move data from parse Buffer to Interface descriptor */
|
||||
USBH_CopyBuffer((uint8_t*)&interface[itfIndex].interfaceDesc,
|
||||
&buffer[parseIndex],
|
||||
STD_INTERFACE_DESC_SIZE);
|
||||
|
||||
itfIndex++;
|
||||
epIndex = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_DESC_ENDPOINT:
|
||||
if ((itfIndex > 0) && (epIndex < ENDPOINT_DESC_MAX_NUM))
|
||||
{
|
||||
/* Move data from parse Buffer to Endpoint descriptor */
|
||||
USBH_CopyBuffer((uint8_t*)&interface[itfIndex - 1].endpointDesc[epIndex],
|
||||
&buffer[parseIndex],
|
||||
STD_INTERFACE_DESC_SIZE);
|
||||
|
||||
epIndex++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
parseIndex += subLen;
|
||||
|
||||
/* To avoid some useless data left */
|
||||
if ((totalLenTemp - parseIndex) < STD_EP_DESC_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Parse device descriptor
|
||||
*
|
||||
* @param devDesc : device descriptor
|
||||
*
|
||||
* @param buffer : source recevice data
|
||||
*
|
||||
* @param length : device descriptor length
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_DevDescParse(USBH_DEV_DESC_T* devDesc, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
devDesc->bLength = *(uint8_t*)(buffer + 0);
|
||||
devDesc->bDescriptorType = *(uint8_t*)(buffer + 1);
|
||||
devDesc->bcdUSB[0] = *(uint8_t*)(buffer + 2);
|
||||
devDesc->bcdUSB[1] = *(uint8_t*)(buffer + 3);
|
||||
devDesc->bDeviceClass = *(uint8_t*)(buffer + 4);
|
||||
devDesc->bDeviceSubClass = *(uint8_t*)(buffer + 5);
|
||||
devDesc->bDeviceProtocol = *(uint8_t*)(buffer + 6);
|
||||
devDesc->bMaxPacketSize = *(uint8_t*)(buffer + 7);
|
||||
|
||||
switch (devDesc->bMaxPacketSize)
|
||||
{
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
devDesc->bMaxPacketSize = devDesc->bMaxPacketSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
devDesc->bMaxPacketSize = 64;
|
||||
break;
|
||||
}
|
||||
|
||||
if (length > 8)
|
||||
{
|
||||
devDesc->idVendor[0] = *(uint8_t*)(buffer + 8);
|
||||
devDesc->idVendor[1] = *(uint8_t*)(buffer + 9);
|
||||
devDesc->idProduct[0] = *(uint8_t*)(buffer + 10);
|
||||
devDesc->idProduct[1] = *(uint8_t*)(buffer + 11);
|
||||
devDesc->bcdDevice[0] = *(uint8_t*)(buffer + 12);
|
||||
devDesc->bcdDevice[1] = *(uint8_t*)(buffer + 13);
|
||||
devDesc->iManufacturer = *(uint8_t*)(buffer + 14);
|
||||
devDesc->iProduct = *(uint8_t*)(buffer + 15);
|
||||
devDesc->iSerialNumber = *(uint8_t*)(buffer + 16);
|
||||
devDesc->bNumConfigurations = *(uint8_t*)(buffer + 17);
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Handle control setup transfer.
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param buffer : control transfer buffer
|
||||
*
|
||||
* @param length : length of response
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_CtrlXferHandler(USBH_INFO_T* usbInfo, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
USBH_USR_Debug("USBH_XFER_START");
|
||||
usbInfo->ctrl.buffer = buffer;
|
||||
usbInfo->ctrl.length = length;
|
||||
usbInfo->ctrl.state = USBH_CTRL_SETUP;
|
||||
usbInfo->xferState = USBH_XFER_WAITING;
|
||||
usbStatus = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case USBH_XFER_WAITING:
|
||||
USBH_USR_Debug("USBH_XFER_WAITING");
|
||||
usbStatus = USBH_CtrlStateHandler[usbInfo->ctrl.state](usbInfo);
|
||||
|
||||
if ((usbStatus == USBH_OK) || (usbStatus == USBH_ERR_NOT_SUP))
|
||||
{
|
||||
usbInfo->xferState = USBH_XFER_START;
|
||||
usbInfo->ctrl.state = USBH_CTRL_IDLE;
|
||||
}
|
||||
else if (usbStatus == USBH_FAIL)
|
||||
{
|
||||
usbInfo->xferState = USBH_XFER_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set device feature request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param feature : feature value
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_SetFeature(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t feature)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_STD_SET_FEATURE;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = feature;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host clear device feature request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param feature : feature value
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_ClearFeature(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t epNum)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_STD_CLEAR_FEATURE;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = USBH_FEATURE_SELECTOR_ENDPOINT_HALT;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = epNum;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set device configuration request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param configuration : configuration value
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_SetConfiguration(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint16_t configuration)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_STD_SET_CONFIGURATION;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = configuration;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set device address request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type.
|
||||
*
|
||||
* @param addr : device address
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_SetAddr(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint8_t addr)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_STD_SET_ADDRESS;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = addr;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, NULL, 0);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Config standard get descriptor request
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param reqType : Select request type
|
||||
*
|
||||
* @param desType : Specifies descriptor type
|
||||
* This value can be one of the following values:
|
||||
* @arg USBH_DESC_DEVICE
|
||||
* @arg USBH_DESC_CONFIGURATION
|
||||
* @arg USBH_DESC_STRING
|
||||
* @arg USBH_DESC_INTERFACE
|
||||
* @arg USBH_DESC_ENDPOINT
|
||||
* @arg USBH_DESC_DEVICE_QUALIFIER
|
||||
* @arg USBH_DESC_OTHER_SPEED
|
||||
* @arg USBH_INTERFACE_POWER
|
||||
*
|
||||
* @param buffer : buffer to store descriptor
|
||||
*
|
||||
* @param length : Specifies len of request
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_REQ_GetDescriptor(USBH_INFO_T* usbInfo, uint8_t reqType, \
|
||||
uint16_t desType, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
switch (usbInfo->xferState)
|
||||
{
|
||||
case USBH_XFER_START:
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.dir = ((reqType & 0x80) >> 7);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.type = ((reqType & 0x60) >> 5);
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bmRequestType.REQ_TYPE_B.recipient = (reqType & 0x1F);
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.bRequest = USBH_STD_GET_DESCRIPTOR;
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[0] = (desType >> 8) & 0xFF;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wValue[1] = desType & 0xFF;
|
||||
|
||||
if ((desType & 0xFF) == USBH_DESC_STRING)
|
||||
{
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = USBH_LANG_ID & 0xFF;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = USBH_LANG_ID >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[0] = 0;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wIndex[1] = 0;
|
||||
}
|
||||
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[0] = length & 0xFF;
|
||||
usbInfo->ctrl.reqData.DATA_FIELD.wLength[1] = length >> 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
usbStatus = USBH_REQ_CtrlXferHandler(usbInfo, buffer, length);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set feature
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param feature : value of feature
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_SetFeature(USBH_INFO_T* usbInfo, uint8_t feature)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_SetFeature(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)),
|
||||
feature);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host clear feature
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param epNum : number of endpoint
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_ClearFeature(USBH_INFO_T* usbInfo, uint8_t epNum)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_ClearFeature(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_ENDPOINT)),
|
||||
epNum);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set configuration
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param configuration : value of configuration
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_SetConfiguration(USBH_INFO_T* usbInfo, uint16_t configuration)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_SetConfiguration(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)),
|
||||
configuration);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host get configuration description
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param desLength : length of description
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_GetCfgDesc(USBH_INFO_T* usbInfo, uint16_t desLength)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_GetDescriptor(usbInfo, ((USBH_REQ_DIR_IN << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)), \
|
||||
USBH_DESC_CONFIGURATION,
|
||||
usbInfo->devInfo.desc.cfgDescBuf,
|
||||
desLength);
|
||||
if (usbStatus == USBH_OK)
|
||||
{
|
||||
/* Store received data */
|
||||
USBH_CfgDescParse(&usbInfo->devInfo.desc.configuration, \
|
||||
usbInfo->devInfo.desc.interface,
|
||||
usbInfo->devInfo.desc.cfgDescBuf, desLength);
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host get string description
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param stringIndex : string index
|
||||
*
|
||||
* @param buffer : buffer to store descriptor
|
||||
*
|
||||
* @param desLength : length of description
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_GetStringDesc(USBH_INFO_T* usbInfo, uint8_t stringIndex, uint8_t* buffer, uint16_t desLength)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_GetDescriptor(usbInfo, ((USBH_REQ_DIR_IN << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)), \
|
||||
(USBH_DESC_STRING | stringIndex << 8),
|
||||
usbInfo->devInfo.desc.stringBuf,
|
||||
desLength);
|
||||
|
||||
if (usbStatus == USBH_OK)
|
||||
{
|
||||
/* Store received data */
|
||||
USBH_StringDescParse(usbInfo->devInfo.desc.stringBuf, buffer, desLength);
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host set device address
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param address : device address
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_SetAddr(USBH_INFO_T* usbInfo, uint8_t address)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_SetAddr(usbInfo, ((USBH_REQ_DIR_OUT << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)),
|
||||
address);
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief USB host get device description
|
||||
*
|
||||
* @param usbInfo : usb handler information
|
||||
*
|
||||
* @param desLength : length of description
|
||||
*
|
||||
* @retval usb host status
|
||||
*/
|
||||
USBH_STA_T USBH_GetDevDesc(USBH_INFO_T* usbInfo, uint8_t desLength)
|
||||
{
|
||||
USBH_STA_T usbStatus = USBH_OK;
|
||||
|
||||
usbStatus = USBH_REQ_GetDescriptor(usbInfo, ((USBH_REQ_DIR_IN << 7) | \
|
||||
(USBH_REQ_TYPE_STANDARD << 5) | \
|
||||
(USBH_RECIPIENT_DEVICE)), \
|
||||
USBH_DESC_DEVICE,
|
||||
usbInfo->devInfo.data,
|
||||
desLength);
|
||||
|
||||
if (usbStatus == USBH_OK)
|
||||
{
|
||||
/* Store received data */
|
||||
USBH_DevDescParse(&usbInfo->devInfo.desc.device, usbInfo->devInfo.data, desLength);
|
||||
}
|
||||
|
||||
return usbStatus;
|
||||
}
|
||||
|
||||
/**@} end of group USBH_Core_Functions */
|
||||
/**@} end of group USBH_Core */
|
||||
/**@} end of group APM32_USB_Library */
|
Loading…
Add table
Add a link
Reference in a new issue