feat: KT mBMS 펌웨어 3종(HW1/2/3) 및 통합 빌드 환경 초기 커밋 (V4.0.0.1)

This commit is contained in:
2026-11-05 14:31:31 +09:00
commit c52dc2f348
10803 changed files with 4642514 additions and 0 deletions

View File

@@ -0,0 +1,499 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_hid_class.c
**
** A detailed description is available at
** @link
This file is the HID Layer Handlers for USB Host HID class.
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_hid_class.h"
#include "usb_host_hid_mouseapp.h"
#include "usb_host_hid_keyboardapp.h"
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN HID_Machine_TypeDef HID_Machine __USB_ALIGN_END ;
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN HID_Report_TypeDef HID_Report __USB_ALIGN_END ;
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN usb_setup_typedef HID_Setup __USB_ALIGN_END ;
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN USB_HOST_HDIDesc_TypeDef HID_Desc __USB_ALIGN_END ;
__IO uint8_t start_toggle = 0;
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
HOST_STATUS usb_host_hid_itfinit(usb_core_instance *pdev, void *phost);
void usb_host_hid_itfdeinit(usb_core_instance *pdev);
void usb_host_parse_hiddesc(USB_HOST_HDIDesc_TypeDef *desc, uint8_t *buf);
HOST_STATUS usb_host_hid_process(usb_core_instance *pdev, void *phost);
HOST_STATUS usb_host_hid_classreq(usb_core_instance *pdev, void *phost);
HOST_STATUS usb_host_get_hidreportdesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length);
HOST_STATUS usb_host_get_hiddesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length);
HOST_STATUS usb_host_set_hididle(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t duration,
uint8_t reportId);
HOST_STATUS usb_host_set_hidprotocol(usb_core_instance *pdev, USBH_HOST *phost, uint8_t protocol);
usb_host_class_callback_func USBH_HID_cb =
{
usb_host_hid_itfinit,
usb_host_hid_itfdeinit,
usb_host_hid_classreq,
usb_host_hid_process
};
/**
*******************************************************************************
** \brief initialize the hid class
** \param pdev : device instance
** \param phost: host state set
** \retval status: defination by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_hid_itfinit(usb_core_instance *pdev, void *phost)
{
uint8_t maxEP;
USBH_HOST *pphost = phost;
uint8_t epnum =0;
HOST_STATUS status = HSTATUS_BUSY ;
HID_Machine.state = HID_ERROR;
if(pphost->device_prop.devitfdesc[0].bInterfaceSubClass == HID_BOOT_CODE)
{
switch(pphost->device_prop.devitfdesc[0].bInterfaceProtocol)
{
case HID_MOUSE_BOOT_CODE:
HID_Machine.cb = &HID_MOUSE_cb;
break;
case HID_KEYBRD_BOOT_CODE:
HID_Machine.cb = &HID_KEYBRD_cb;
break;
default:
break;
}
HID_Machine.state = HID_IDLE;
HID_Machine.ctl_state = HID_REQ_IDLE;
HID_Machine.ep_addr = pphost->device_prop.devepdesc[0][0].bEndpointAddress;
HID_Machine.length = pphost->device_prop.devepdesc[0][0].wMaxPacketSize;
HID_Machine.poll = pphost->device_prop.devepdesc[0][0].bInterval ;
if (HID_Machine.poll < HID_MIN_POLL)
{
HID_Machine.poll = HID_MIN_POLL;
}
/* Check fo available number of endpoints */
/* Find the number of EPs in the Interface Descriptor */
/* Choose the lower number in order not to overrun the buffer allocated */
maxEP = ( (pphost->device_prop.devitfdesc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
pphost->device_prop.devitfdesc[0].bNumEndpoints :
USBH_MAX_NUM_ENDPOINTS);
/* Decode endpoint IN and OUT address from interface descriptor */
for (epnum=0; epnum < maxEP; epnum++)
{
if(pphost->device_prop.devepdesc[0][epnum].bEndpointAddress & 0x80)
{
HID_Machine.HIDIntInEp = (pphost->device_prop.devepdesc[0][epnum].bEndpointAddress);
HID_Machine.hc_num_in = usb_host_distrch(pdev,
pphost->device_prop.devepdesc[0][epnum].bEndpointAddress);
usb_host_chopen(pdev,
HID_Machine.hc_num_in,
pphost->device_prop.devaddr,
pphost->device_prop.devspeed,
EP_TYPE_INTR,
HID_Machine.length);
}
else
{
HID_Machine.HIDIntOutEp = (pphost->device_prop.devepdesc[0][epnum].bEndpointAddress);
HID_Machine.hc_num_out = usb_host_distrch(pdev,
pphost->device_prop.devepdesc[0][epnum].bEndpointAddress);
usb_host_chopen(pdev,
HID_Machine.hc_num_out,
pphost->device_prop.devaddr,
pphost->device_prop.devspeed,
EP_TYPE_INTR,
HID_Machine.length);
}
}
start_toggle =0;
status = HSTATUS_OK;
}
else
{
pphost->user_callbk->huser_devunsupported();
}
return status;
}
/**
*******************************************************************************
** \brief deinitialize the channels for the hid class
** \param pdev : device instance
** \retval none
******************************************************************************/
void usb_host_hid_itfdeinit(usb_core_instance *pdev)
{
if(HID_Machine.hc_num_in != 0x00)
{
hd_usb_hchstop(pdev, HID_Machine.hc_num_in);
usb_host_freech(pdev, HID_Machine.hc_num_in);
HID_Machine.hc_num_in = 0;
}
if(HID_Machine.hc_num_out != 0x00)
{
hd_usb_hchstop(pdev, HID_Machine.hc_num_out);
usb_host_freech(pdev, HID_Machine.hc_num_out);
HID_Machine.hc_num_out = 0;
}
start_toggle = 0;
}
/**
*******************************************************************************
** \brief This function is responsible for handling requests about HID class.
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_hid_classreq(usb_core_instance *pdev, void *phost)
{
HOST_STATUS status;
HOST_STATUS classReqStatus;
USBH_HOST *pphost = phost;
status = HSTATUS_BUSY;
classReqStatus = HSTATUS_BUSY;
switch (HID_Machine.ctl_state)
{
case HID_IDLE:
case HID_REQ_GET_HID_DESC:
if (usb_host_get_hiddesc(pdev, pphost, USB_HID_DESC_SIZE)== HSTATUS_OK)
{
usb_host_parse_hiddesc(&HID_Desc, pdev->host.Rx_Buffer);
HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC;
}
break;
case HID_REQ_GET_REPORT_DESC:
if (usb_host_get_hidreportdesc(pdev , pphost, HID_Desc.wItemLength) == HSTATUS_OK)
{
HID_Machine.ctl_state = HID_REQ_SET_IDLE;
}
break;
case HID_REQ_SET_IDLE:
classReqStatus = usb_host_set_hididle (pdev, pphost, 0, 0);
if (classReqStatus == HSTATUS_OK)
{
HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
}
else if(classReqStatus == HSTATUS_UNSUPPORTED)
{
HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
}
break;
case HID_REQ_SET_PROTOCOL:
if (usb_host_set_hidprotocol (pdev ,pphost, 0) == HSTATUS_OK)
{
HID_Machine.ctl_state = HID_REQ_IDLE;
status = HSTATUS_OK;
}
break;
default:
break;
}
return status;
}
/**
*******************************************************************************
** \brief This function is to process the state machine for HID data transmitting
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_hid_process(usb_core_instance *pdev, void *phost)
{
HOST_STATUS status;
USBH_HOST *pphost = phost;
status = HSTATUS_OK;
switch (HID_Machine.state)
{
case HID_IDLE:
HID_Machine.cb->Init();
HID_Machine.state = HID_SYNC;
case HID_SYNC:
if(hd_usb_ifevenframe(pdev) == TRUE)
{
HID_Machine.state = HID_GET_DATA;
}
break;
case HID_GET_DATA:
usb_host_recvintdata(pdev,
HID_Machine.buff,
HID_Machine.length,
HID_Machine.hc_num_in);
start_toggle = 1;
HID_Machine.state = HID_POLL;
HID_Machine.timer = host_driver_getcurrentfrm(pdev);
break;
case HID_POLL:
if(( host_driver_getcurrentfrm(pdev) - HID_Machine.timer) >= HID_Machine.poll)
{
HID_Machine.state = HID_GET_DATA;
}
else if(host_driver_getxferstate(pdev , HID_Machine.hc_num_in) == HOST_CH_XFER_DONE)
{
if(start_toggle == 1)
{
start_toggle = 0;
HID_Machine.cb->Decode(HID_Machine.buff);
}
}
else if(host_driver_getxferstate(pdev, HID_Machine.hc_num_in) == HOST_CH_XFER_STALL)
{
/* Issue Clear Feature on interrupt IN endpoint */
if( (usb_host_clrfeature(pdev,
pphost,
HID_Machine.ep_addr,
HID_Machine.hc_num_in)) == HSTATUS_OK)
{
HID_Machine.state = HID_GET_DATA;
}
}
break;
default:
break;
}
return status;
}
/**
*******************************************************************************
** \brief Issue hid report descriptor command to the device, parse the report
** descriptor and update the status once the response received.
** \param pdev : device instance
** \param phost: host state set
** \param length : the length of the hid descriptor in bytes
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_get_hidreportdesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length)
{
HOST_STATUS status;
status = usb_host_getdesc(pdev,
phost,
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
USB_DESC_HID_REPORT,
pdev->host.Rx_Buffer,
length);
return status;
}
/**
*******************************************************************************
** \brief Issue HID descriptor command to the device, parse the descriptor
** and update the status once the response received.
** \param pdev : device instance
** \param phost: host state set
** \param length : length of HID descriptor in bytes
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_get_hiddesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length)
{
HOST_STATUS status;
status = usb_host_getdesc(pdev,
phost,
USB_REQ_RECIPIENT_INTERFACE
| USB_REQ_TYPE_STANDARD,
USB_DESC_HID,
pdev->host.Rx_Buffer,
length);
return status;
}
/**
*******************************************************************************
** \brief Set hid application to be idle status.
** \param pdev : device instance
** \param phost: host state set
** \param duration: Duration for HID Idle request
** \param reportID : Targetted report ID for Set Idle request
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_set_hididle(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t duration,
uint8_t reportId)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_CLASS;
phost->ctrlparam.setup.b.bRequest = USB_HID_SET_IDLE;
phost->ctrlparam.setup.b.wValue.w = (duration << 8 ) | reportId;
phost->ctrlparam.setup.b.wIndex.w = 0;
phost->ctrlparam.setup.b.wLength.w = 0;
return usb_host_ctrlreq(pdev, phost, 0 , 0 );
}
/**
*******************************************************************************
** \brief Issues a command to set report
** \param pdev : device instance
** \param phost: host state set
** \param reportType : the report type to be sent
** \param reportID : target report ID for set report request
** \param reportLen : length of data of report to be sent in bytes
** \param reportBuff : report buffer
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_set_hidreport(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t reportLen,
uint8_t* reportBuff)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_CLASS;
phost->ctrlparam.setup.b.bRequest = USB_HID_SET_REPORT;
phost->ctrlparam.setup.b.wValue.w = (reportType << 8 ) | reportId;
phost->ctrlparam.setup.b.wIndex.w = 0;
phost->ctrlparam.setup.b.wLength.w = reportLen;
return usb_host_ctrlreq(pdev, phost, reportBuff , reportLen );
}
/**
*******************************************************************************
** \brief Set protocol state of the hid application.
** \param pdev : device instance
** \param phost: host state set
** \param protocol : protocol for HID application
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_set_hidprotocol(usb_core_instance *pdev, USBH_HOST *phost, uint8_t protocol)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_CLASS;
phost->ctrlparam.setup.b.bRequest = USB_HID_SET_PROTOCOL;
if(protocol != 0)
{
// Boot Protocol
phost->ctrlparam.setup.b.wValue.w = 0;
}
else
{
//Report Protocol
phost->ctrlparam.setup.b.wValue.w = 1;
}
phost->ctrlparam.setup.b.wIndex.w = 0;
phost->ctrlparam.setup.b.wLength.w = 0;
return usb_host_ctrlreq(pdev, phost, 0 , 0 );
}
/**
*******************************************************************************
** \brief parse the HID descriptor
** \param desc: used to get the fields parsed from the data buffer
** \param buf: Buffer where the source descriptor is available
** \retval none
******************************************************************************/
void usb_host_parse_hiddesc(USB_HOST_HDIDesc_TypeDef *desc, uint8_t *buf)
{
desc->bLength = *(uint8_t *) (buf + 0);
desc->bDescriptorType = *(uint8_t *) (buf + 1);
desc->bcdHID = SMALL_END(buf + 2);
desc->bCountryCode = *(uint8_t *) (buf + 4);
desc->bNumDescriptors = *(uint8_t *) (buf + 5);
desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
desc->wItemLength = SMALL_END(buf + 7);
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,173 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_hid_class.h
**
** A detailed description is available at
** @link
This file contains all the prototypes for the usbh_hid_core.c
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB host mouse and kb demo.
**
******************************************************************************/
#ifndef __USB_HOST_HID_CLASS_H__
#define __USB_HOST_HID_CLASS_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_core.h"
#include "usb_host_stdreq.h"
#include "usb_bsp.h"
#include "usb_host_ctrltrans.h"
#include "usb_host_cfgch.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
#define HID_MIN_POLL 10
/* States for HID State Machine */
typedef enum
{
HID_IDLE= 0,
HID_SEND_DATA,
HID_BUSY,
HID_GET_DATA,
HID_SYNC,
HID_POLL,
HID_ERROR,
}
HID_State;
typedef enum
{
HID_REQ_IDLE = 0,
HID_REQ_GET_REPORT_DESC,
HID_REQ_GET_HID_DESC,
HID_REQ_SET_IDLE,
HID_REQ_SET_PROTOCOL,
HID_REQ_SET_REPORT,
}
HID_CtlState;
typedef struct
{
void (*Init) (void);
void (*Decode) (uint8_t *data);
} HID_cb_TypeDef;
typedef struct
{
uint8_t ReportID;
uint8_t ReportType;
uint16_t UsagePage;
uint32_t Usage[2];
uint32_t NbrUsage;
uint32_t UsageMin;
uint32_t UsageMax;
int32_t LogMin;
int32_t LogMax;
int32_t PhyMin;
int32_t PhyMax;
int32_t UnitExp;
uint32_t Unit;
uint32_t ReportSize;
uint32_t ReportCnt;
uint32_t Flag;
uint32_t PhyUsage;
uint32_t AppUsage;
uint32_t LogUsage;
} HID_Report_TypeDef;
/* Structure for HID process */
typedef struct
{
uint8_t buff[64];
uint8_t hc_num_in;
uint8_t hc_num_out;
HID_State state;
uint8_t HIDIntOutEp;
uint8_t HIDIntInEp;
HID_CtlState ctl_state;
uint16_t length;
uint8_t ep_addr;
uint16_t poll;
__IO uint16_t timer;
HID_cb_TypeDef *cb;
} HID_Machine_TypeDef;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define USB_HID_REQ_GET_REPORT 0x01
#define USB_HID_GET_IDLE 0x02
#define USB_HID_GET_PROTOCOL 0x03
#define USB_HID_SET_REPORT 0x09
#define USB_HID_SET_IDLE 0x0A
#define USB_HID_SET_PROTOCOL 0x0B
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
extern usb_host_class_callback_func USBH_HID_cb;
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern HOST_STATUS usb_host_set_hidreport(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t reportType,
uint8_t reportId,
uint8_t reportLen,
uint8_t* reportBuff);
#endif /* __USB_HOST_HID_CLASS_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,309 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_houst_hid_keybouarapp.c
**
** A detailed description is available at
** @link
This file is the application layer for USB Host HID Keyboard handling
QWERTY and AZERTY Keyboard are supported as per the selection in
usb_host_hid_keyboardapp.h
@endlink
**
** - 2019-12-13 1.0 zhangxl First version for USB HID keyboard demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_hid_keyboardapp.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
void keyboard_init(void);
void keyboard_decode(uint8_t *pbuf);
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined (__CC_ARM) /*!< ARM Compiler */
__align(4)
#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma pack(4)
#endif /* __CC_ARM */
#endif
HID_cb_TypeDef HID_KEYBRD_cb=
{
keyboard_init,
keyboard_decode
};
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static const uint8_t HID_KEYBRD_Codes[] =
{
0, 0, 0, 0, 31, 50, 48, 33,
19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */
52, 51, 25, 26, 17, 20, 32, 21,
23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */
4, 5, 6, 7, 8, 9, 10, 11,
43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */
28, 29, 42, 40, 41, 1, 53, 54,
55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */
118, 119, 120, 121, 122, 123, 124, 125,
126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */
79, 84, 83, 90, 95, 100, 105, 106,
108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */
96, 101, 99, 104, 45, 129, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */
0, 0, 0, 0, 0, 107, 0, 56,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */
58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */
};
#ifdef QWERTY_KEYBOARD
static const int8_t HID_KEYBRD_Key[] =
{
'\0', '`' , '1' , '2' , '3' , '4' , '5' , '6' ,
'7' , '8' , '9' , '0' , '-' , '=' , '\0', '\r',
'\t', 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' ,
'i' , 'o' , 'p' , '[' , ']' , '\\',
'\0', 'a' , 's' , 'd' , 'f' , 'g' , 'h' , 'j' ,
'k' , 'l' , ';' , '\'', '\0', '\n',
'\0', '\0', 'z' , 'x' , 'c' , 'v' , 'b' , 'n' ,
'm' , ',' , '.' , '/' , '\0', '\0',
'\0', '\0', '\0', ' ' , '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '7' , '4' , '1' ,
'\0', '/', '8' , '5' , '2' ,
'0' , '*', '9' , '6' , '3' ,
'.' , '-', '+' , '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0'
};
static const int8_t HID_KEYBRD_ShiftKey[] = {
'\0', '~' , '!' , '@' , '#' , '$' , '%' , '^' , '&' , '*' , '(' , ')' ,
'_' , '+' , '\0', '\0', '\0', 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' ,
'I' , 'O' , 'P' , '{' , '}' , '|' , '\0', 'A' , 'S' , 'D' , 'F' , 'G' ,
'H' , 'J' , 'K' , 'L' , ':' , '"' , '\0', '\n', '\0', '\0', 'Z' , 'X' ,
'C' , 'V' , 'B' , 'N' , 'M' , '<' , '>' , '?' , '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
#else
static const int8_t HID_KEYBRD_Key[] = {
'\0', '`' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0',
'-' , '=' , '\0', '\r', '\t', 'a' , 'z' , 'e' , 'r' , 't' , 'y' , 'u',
'i' , 'o' , 'p' , '[' , ']' , '\\', '\0', 'q' , 's' , 'd' , 'f' , 'g',
'h' , 'j' , 'k' , 'l' , 'm' , '\0', '\0', '\n', '\0', '\0', 'w' , 'x',
'c' , 'v' , 'b' , 'n' , ',' , ';' , ':' , '!' , '\0', '\0', '\0', '\0',
'\0', ' ' , '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '7' , '4' , '1' , '\0', '/',
'8' , '5' , '2' , '0' , '*' , '9' , '6' , '3' , '.' , '-' , '+' , '\0',
'\n', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
static const int8_t HID_KEYBRD_ShiftKey[] = {
'\0', '~' , '!' , '@' , '#' , '$' , '%' , '^' , '&' , '*' , '(' , ')' , '_' ,
'+' , '\0', '\0', '\0', 'A' , 'Z' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , 'O' ,
'P' , '{' , '}' , '*' , '\0', 'Q' , 'S' , 'D' , 'F' , 'G' , 'H' , 'J' , 'K' ,
'L' , 'M' , '%' , '\0', '\n', '\0', '\0', 'W' , 'X' , 'C' , 'V' , 'B' , 'N' ,
'?' , '.' , '/' , '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
#endif
/**
*******************************************************************************
** \brief Initialize the keyboard function.
** \param none
** \retval none
******************************************************************************/
void keyboard_init(void)
{
user_keyboard_init();
}
/**
*******************************************************************************
* \brief The function is to decode the pressed keys when receives key value.
* \param pbuf : buffer contain the HID IN report data.
* \retval none
******************************************************************************/
void keyboard_decode(uint8_t *pbuf)
{
static uint8_t shift;
static uint8_t keys[KBR_MAX_NBR_PRESSED];
static uint8_t keys_new[KBR_MAX_NBR_PRESSED];
static uint8_t keys_last[KBR_MAX_NBR_PRESSED];
static uint8_t key_newest;
static uint8_t nbr_keys;
static uint8_t nbr_keys_new;
static uint8_t nbr_keys_last;
uint8_t ix;
uint8_t jx;
uint8_t error;
uint8_t output;
nbr_keys = 0;
nbr_keys_new = 0;
nbr_keys_last = 0;
key_newest = 0x00;
/* Check if Shift key is pressed */
if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT))
{
shift = TRUE;
}
else
{
shift = FALSE;
}
error = FALSE;
/* Check for the value of pressed key */
for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++)
{
if ((pbuf[ix] == 0x01) || (pbuf[ix] == 0x02) || (pbuf[ix] == 0x03))
{
error = TRUE;
}
}
if (error == TRUE)
{
return;
}
nbr_keys = 0;
nbr_keys_new = 0;
for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++)
{
if (pbuf[ix] != 0)
{
keys[nbr_keys] = pbuf[ix];
nbr_keys++;
for (jx = 0; jx < nbr_keys_last; jx++)
{
if (pbuf[ix] == keys_last[jx])
{
break;
}
}
if (jx == nbr_keys_last)
{
keys_new[nbr_keys_new] = pbuf[ix];
nbr_keys_new++;
}
}
}
if (nbr_keys_new == 1)
{
key_newest = keys_new[0];
if (shift == TRUE)
{
output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]];
}
else
{
output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]];
}
/* call user process handle */
user_keyboard_dataprocess(output);
}
else
{
key_newest = 0x00;
}
nbr_keys_last = nbr_keys;
for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++)
{
keys_last[ix] = keys[ix];
}
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,98 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_houst_hid_keybouarapp.h
**
** A detailed description is available at
** @link
This file contains all the prototypes for the usbh_hid_keybd.c.
@endlink
**
** - 2019-12-13 1.0 zhangxl First version for USB mouse_keyboard demo.
**
******************************************************************************/
#ifndef __USB_HOST_HID_KEYBOARDAPP_H__
#define __USB_HOST_HID_KEYBOARDAPP_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
#include "usb_host_hid_class.h"
#include "usb_host_user.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define QWERTY_KEYBOARD
//#define AZERTY_KEYBOARD
#define KBD_LEFT_CTRL 0x01
#define KBD_LEFT_SHIFT 0x02
#define KBD_LEFT_ALT 0x04
#define KBD_LEFT_GUI 0x08
#define KBD_RIGHT_CTRL 0x10
#define KBD_RIGHT_SHIFT 0x20
#define KBD_RIGHT_ALT 0x40
#define KBD_RIGHT_GUI 0x80
#define KBR_MAX_NBR_PRESSED 6
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
extern HID_cb_TypeDef HID_KEYBRD_cb;
/*******************************************************************************
* Global function prototypes (definition in C source)
******************************************************************************/
#endif /* __USB_HOST_HID_KEYBOARDAPP_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,126 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_hid_mouseapp.c
**
** A detailed description is available at
** @link
This file is the application layer for USB Host HID Mouse Handling.
@endlink
**
** - 2019-12-13 1.0 zhangxl First version for USB HID mouse demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_hid_mouseapp.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
void mouse_init(void);
void mouse_decode(uint8_t *data);
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined (__CC_ARM) /*!< ARM Compiler */
__align(4)
#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma pack(4)
#elif defined (__TASKING__) /*!< TASKING Compiler */
__align(4)
#endif /* __CC_ARM */
#endif
HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
HID_cb_TypeDef HID_MOUSE_cb =
{
mouse_init,
mouse_decode,
};
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief initialize the mouse application of the hid class
** \param none
** \retval none
******************************************************************************/
void mouse_init(void)
{
/* Call User Init*/
USR_MOUSE_Init();
}
/**
*******************************************************************************
** \brief decode the mouse report data
** \param data : buffer of the hid report data
** \retval none
******************************************************************************/
void mouse_decode(uint8_t *data)
{
HID_MOUSE_Data.button = data[0];
HID_MOUSE_Data.x = data[1];
HID_MOUSE_Data.y = data[2];
USR_MOUSE_ProcessData(&HID_MOUSE_Data);
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,90 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_hid_mouseapp.h
**
** A detailed description is available at
** @link
This file contains all the prototypes for the usbh_hid_mouse.c。
@endlink
**
** - 2019-12-13 1.0 zhangxl First version for USB hid mouse demo.
**
******************************************************************************/
#ifndef __USB_HOST_HID_MOUSEAPP_H__
#define __USB_HOST_HID_MOUSEAPP_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_hid_class.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
typedef struct _HID_MOUSE_Data
{
uint8_t z;
uint8_t button;
uint8_t x; /* Not Supported */
uint8_t y;
}
HID_MOUSE_Data_TypeDef;
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
extern HID_cb_TypeDef HID_MOUSE_cb;
extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
void USR_MOUSE_Init (void);
void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data);
#endif /* __USB_HOST_HID_MOUSEAPP_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,526 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usbh_msc_bot.c
**
** A detailed description is available at
** @link
This file includes the mass storage related functions
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_msc_class.h"
#include "usb_host_msc_scsi.h"
#include "usb_host_msc_bot.h"
#include "usb_host_ctrltrans.h"
#include "usb_host_stddef.h"
#include "usb_host_int.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData __USB_ALIGN_END ;
USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam;
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData __USB_ALIGN_END ;
static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initializes original state of the mass storage parameters
** \param pdev : device instance
** \retval none
******************************************************************************/
void usb_host_msc_init(usb_core_instance *pdev)
{
if(host_driver_ifdevconnected(pdev))
{
USBH_MSC_CBWData.field.CBWSignature = HOST_MSC_BOT_CBW_SIGNATURE;
USBH_MSC_CBWData.field.CBWTag = HOST_MSC_BOT_CBW_TAG;
USBH_MSC_CBWData.field.CBWLUN = 0u;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
}
BOTStallErrorCount = 0ul;
MSCErrorCount = 0u;
}
/**
*******************************************************************************
** \brief manages the different states of BOT transfer and updates the
** status for the upper layer.
** \param pdev : device instance
** \param phost: host state set
** \retval none
**
******************************************************************************/
void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost)
{
uint8_t xferDirection, index;
static uint32_t remainingDataLength;
static uint8_t *datapointer , *datapointer_prev;
static uint8_t error_direction;
HOST_STATUS status;
HOST_CH_XFER_STATE URB_Status = HOST_CH_XFER_IDLE;
if(host_driver_ifdevconnected(pdev))
{
switch (USBH_MSC_BOTXferParam.BOTState)
{
case HOST_MSC_SEND_CBW:
// send a CBW
usb_host_sendbulkdata(pdev,
&USBH_MSC_CBWData.CBWArray[0],
HOST_MSC_BOT_CBW_PACKET_LENGTH ,
MSC_Machine.hc_num_out);
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SEND_CBW;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SENT_CBW;
break;
case HOST_MSC_SENT_CBW:
URB_Status = host_driver_getxferstate(pdev , MSC_Machine.hc_num_out);
switch(URB_Status)
{
case HOST_CH_XFER_DONE:
BOTStallErrorCount = 0u;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SENT_CBW;
// If the CBW packet is sent successful, then update the state
xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK);
if ( USBH_MSC_CBWData.field.CBWTransferLength != 0ul )
{
remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ;
datapointer = USBH_MSC_BOTXferParam.pRxTxBuff;
datapointer_prev = datapointer;
// If there has data transfer stage, update the direction whether it is D2H or H2D
if (xferDirection == USB_D2H)
{
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAIN_STATE;
}
else
{
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAOUT_STATE;
}
}
else
{
// If there has not data transfer stage also update the state
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE;
}
break;
case HOST_CH_XFER_UNREADY:
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
break;
case HOST_CH_XFER_STALL:
error_direction = HOST_MSC_DIR_OUT;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT;
break;
default:
break;
}
break;
case HOST_MSC_BOT_DATAIN_STATE:
URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_in);
if((URB_Status == HOST_CH_XFER_DONE) \
||(USBH_MSC_BOTXferParam.BOTStateBkp != HOST_MSC_BOT_DATAIN_STATE))
{
BOTStallErrorCount = 0u;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAIN_STATE;
if(remainingDataLength > MSC_Machine.MSC_BulkInEpSize)
{
usb_host_recvbulkdata(pdev,
datapointer,
MSC_Machine.MSC_BulkInEpSize ,
MSC_Machine.hc_num_in);
remainingDataLength -= MSC_Machine.MSC_BulkInEpSize;
datapointer = datapointer + MSC_Machine.MSC_BulkInEpSize;
}
else if ( remainingDataLength == 0ul)
{
// If value was 0, and successful transfer, then change the state
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE;
}
else
{
usb_host_recvbulkdata(pdev,
datapointer,
(uint16_t)remainingDataLength ,
MSC_Machine.hc_num_in);
remainingDataLength = 0ul;
}
}
else if(URB_Status == HOST_CH_XFER_STALL)
{
error_direction = HOST_MSC_DIR_IN;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE;
}
else
{
//
}
break;
case HOST_MSC_BOT_DATAOUT_STATE:
URB_Status = host_driver_getxferstate(pdev , MSC_Machine.hc_num_out);
if(URB_Status == HOST_CH_XFER_DONE)
{
BOTStallErrorCount = 0ul;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAOUT_STATE;
if(remainingDataLength > MSC_Machine.MSC_BulkOutEpSize)
{
usb_host_sendbulkdata(pdev,
datapointer,
MSC_Machine.MSC_BulkOutEpSize ,
MSC_Machine.hc_num_out);
datapointer_prev = datapointer;
datapointer = datapointer + MSC_Machine.MSC_BulkOutEpSize;
remainingDataLength = remainingDataLength - MSC_Machine.MSC_BulkOutEpSize;
}
else if ( remainingDataLength == 0ul)
{
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE;
}
else
{
usb_host_sendbulkdata(pdev,
datapointer,
(uint16_t)remainingDataLength ,
MSC_Machine.hc_num_out);
remainingDataLength = 0ul;
}
}
else if(URB_Status == HOST_CH_XFER_UNREADY)
{
if(datapointer != datapointer_prev)
{
usb_host_sendbulkdata(pdev,
(datapointer - MSC_Machine.MSC_BulkOutEpSize),
MSC_Machine.MSC_BulkOutEpSize ,
MSC_Machine.hc_num_out);
}
else
{
usb_host_sendbulkdata(pdev,
datapointer,
MSC_Machine.MSC_BulkOutEpSize ,
MSC_Machine.hc_num_out);
}
}
else if(URB_Status == HOST_CH_XFER_STALL)
{
error_direction = HOST_MSC_DIR_OUT;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE;
}
else
{
}
break;
case HOST_MSC_RECEIVE_CSW_STATE:
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH;
for(index=0u; index<HOST_MSC_CSW_LENGTH; index++)
{
USBH_MSC_CSWData.CSWArray[index] = 0u;
}
USBH_MSC_CSWData.CSWArray[0] = 0u;
usb_host_recvbulkdata(pdev,
USBH_MSC_BOTXferParam.pRxTxBuff,
HOST_MSC_CSW_MAX_LENGTH ,
MSC_Machine.hc_num_in);
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_DECODE_CSW;
break;
case HOST_MSC_DECODE_CSW:
URB_Status = host_driver_getxferstate(pdev , MSC_Machine.hc_num_in);
if(URB_Status == HOST_CH_XFER_DONE)
{
BOTStallErrorCount = 0ul;
USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE;
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ;
USBH_MSC_BOTXferParam.BOTXferStatus = usb_host_msc_cswdecode(pdev , phost);
}
else if(URB_Status == HOST_CH_XFER_STALL)
{
error_direction = HOST_MSC_DIR_IN;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN;
}
else
{
;
}
break;
case HOST_MSC_BOT_ERROR_IN:
status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_IN);
if (status == HSTATUS_OK)
{
if (error_direction == HOST_MSC_BOTH_DIR)
{
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT;
}
else
{
//switch back to the original state
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
}
}
else if (status == HSTATUS_UNRECOVERED_ERROR)
{
// This means that there is a STALL Error limit, Do Reset Recovery
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_PHASE_ERROR;
}
else
{
;
}
break;
case HOST_MSC_BOT_ERROR_OUT:
status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_OUT);
if ( status == HSTATUS_OK)
{ //switch back to the original state
USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
}
else if (status == HSTATUS_UNRECOVERED_ERROR)
{
// This means that there is a STALL Error limit, Do Reset Recovery
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_PHASE_ERROR;
}
else
{
//
}
break;
default:
break;
}
}
}
/**
*******************************************************************************
** \brief usb_host_msc_botabort
** This function manages the different Error handling for STALL
** \param direction : IN / OUT
** \retval None
******************************************************************************/
HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction)
{
HOST_STATUS status;
status = HSTATUS_BUSY;
switch (direction)
{
case HOST_MSC_DIR_IN :
// send ClrFeture on Bulk IN endpoint
status = usb_host_clrfeature(pdev,
phost,
MSC_Machine.MSC_BulkInEp,
MSC_Machine.hc_num_in);
break;
case HOST_MSC_DIR_OUT :
//send ClrFeature on Bulk OUT endpoint
status = usb_host_clrfeature(pdev,
phost,
MSC_Machine.MSC_BulkOutEp,
MSC_Machine.hc_num_out);
break;
default:
break;
}
BOTStallErrorCount++;
if (BOTStallErrorCount > 4 )
{
status = HSTATUS_UNRECOVERED_ERROR;
}
return status;
}
/**
*******************************************************************************
** \brief usb_host_msc_cswdecode
** This function decodes the CSW received by the device and updates the
** same to upper layer.
** \param None
** \retval On success USB_HOST_MSC_OK, on failure USB_HOST_MSC_FAIL
******************************************************************************/
uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev , USBH_HOST *phost)
{
uint8_t status;
uint32_t dataXferCount = 0ul;
status = USB_HOST_MSC_FAIL;
if(host_driver_ifdevconnected(pdev))
{
dataXferCount = host_driver_getxfercnt(pdev, MSC_Machine.hc_num_in);
if(dataXferCount != HOST_MSC_CSW_LENGTH)
{
/*(4) Hi > Dn (Host expects to receive data from the device,
Device intends to transfer no data)
(5) Hi > Di (Host expects to receive data from the device,
Device intends to send data to the host)
(9) Ho > Dn (Host expects to send data to the device,
Device intends to transfer no data)
(11) Ho > Do (Host expects to send data to the device,
Device intends to receive data from the host)*/
status = USB_HOST_MSC_PHASE_ERROR;
}
else
{ /* CSW length is Correct */
/* Check validity of the CSW Signature and CSWStatus */
if(USBH_MSC_CSWData.field.dCSWSignature == HOST_MSC_BOT_CSW_SIGNATURE)
{/* Check Condition 1. dCSWSignature is equal to 53425355h */
if(USBH_MSC_CSWData.field.dCSWTag == USBH_MSC_CBWData.field.CBWTag)
{
/* Check Condition 3. dCSWTag matches the dCBWTag from the
corresponding CBW */
if(USBH_MSC_CSWData.field.dCSWStatus == USB_HOST_MSC_OK)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Hn Host expects no data transfers
Hi Host expects to receive data from the device
Ho Host expects to send data to the device
Dn Device intends to transfer no data
Di Device intends to send data to the host
Do Device intends to receive data from the host
Section 6.7
(1) Hn = Dn (Host expects no data transfers,
Device intends to transfer no data)
(6) Hi = Di (Host expects to receive data from the device,
Device intends to send data to the host)
(12) Ho = Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = USB_HOST_MSC_OK;
}
else if(USBH_MSC_CSWData.field.dCSWStatus == USB_HOST_MSC_FAIL)
{
status = USB_HOST_MSC_FAIL;
}
else if(USBH_MSC_CSWData.field.dCSWStatus == USB_HOST_MSC_PHASE_ERROR)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Section 6.7
(2) Hn < Di ( Host expects no data transfers,
Device intends to send data to the host)
(3) Hn < Do ( Host expects no data transfers,
Device intends to receive data from the host)
(7) Hi < Di ( Host expects to receive data from the device,
Device intends to send data to the host)
(8) Hi <> Do ( Host expects to receive data from the device,
Device intends to receive data from the host)
(10) Ho <> Di (Host expects to send data to the device,
Di Device intends to send data to the host)
(13) Ho < Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = USB_HOST_MSC_PHASE_ERROR;
}
else
{
}
}
}
else
{
status = USB_HOST_MSC_PHASE_ERROR;
}
}
}
USBH_MSC_BOTXferParam.BOTXferStatus = status;
return status;
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,183 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usbh_msc_bot.h
**
** A detailed description is available at
** @link
Header file for usbh_msc_bot.c
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_MSC_BOT_H__
#define __USB_HOST_MSC_BOT_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_stdreq.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* \brief This file is the Header file for usbh_msc_core.c
* @{
*/
/** @defgroup USBH_MSC_BOT_Exported_Types
* @{
*/
typedef union _USBH_CBW_Block
{
struct __CBW
{
uint32_t CBWSignature;
uint32_t CBWTag;
uint32_t CBWTransferLength;
uint8_t CBWFlags;
uint8_t CBWLUN;
uint8_t CBWLength;
uint8_t CBWCB[16];
}field;
uint8_t CBWArray[31];
}HostCBWPkt_TypeDef;
#define HOST_MSC_BOT_INIT_STATE 0
#define HOST_MSC_BOT_RESET 1
#define HOST_MSC_GET_MAX_LUN 2
#define HOST_MSC_TEST_UNIT_READY 3
#define HOST_MSC_READ_CAPACITY10 4
#define HOST_MSC_MODE_SENSE6 5
#define HOST_MSC_REQUEST_SENSE 6
#define HOST_MSC_BOT_USB_TRANSFERS 7
#define HOST_MSC_DEFAULT_APPLI_STATE 8
#define HOST_MSC_CTRL_ERROR_STATE 9
#define HOST_MSC_UNRECOVERED_STATE 10
typedef struct
{
uint8_t MSCState;
uint8_t MSCStateBkp;
uint8_t MSCStateCurrent;
uint8_t CmdStateMachine;
uint8_t BOTState;
uint8_t BOTStateBkp;
uint8_t *pRxTxBuff;
uint16_t DataLength;
uint8_t BOTXferStatus;
} USB_HOST_BOTXFER_TypeDef;
typedef union
{
struct
{
uint32_t dCSWSignature;
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
uint8_t dCSWStatus;
}field;
uint8_t CSWArray[13];
}HOST_CSW_PACKET_TypeDef;
#define HOST_MSC_SEND_CBW 1
#define HOST_MSC_SENT_CBW 2
#define HOST_MSC_BOT_DATAIN_STATE 3
#define HOST_MSC_BOT_DATAOUT_STATE 4
#define HOST_MSC_RECEIVE_CSW_STATE 5
#define HOST_MSC_DECODE_CSW 6
#define HOST_MSC_BOT_ERROR_IN 7
#define HOST_MSC_BOT_ERROR_OUT 8
#define HOST_MSC_BOT_CBW_SIGNATURE (0x43425355ul)
#define HOST_MSC_BOT_CBW_TAG (0x20304050ul)
#define HOST_MSC_BOT_CSW_SIGNATURE (0x53425355ul)
#define HOST_MSC_CSW_DATA_LENGTH 13
#define HOST_MSC_BOT_CBW_PACKET_LENGTH 31
#define HOST_MSC_CSW_LENGTH 13
#define HOST_MSC_CSW_MAX_LENGTH 63
#define HOST_MSC_DIR_IN 0
#define HOST_MSC_DIR_OUT 1
#define HOST_MSC_BOTH_DIR 2
#define HOST_MSC_PAGE_LENGTH 512
#define CBW_CB_LENGTH 16
#define CBW_LENGTH 10
#define CBW_LENGTH_TEST_UNIT_READY 6
extern USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam;
extern HostCBWPkt_TypeDef USBH_MSC_CBWData;
extern HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData;
extern void usb_host_msc_init(usb_core_instance *pdev);
extern void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost);
extern uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev, USBH_HOST *phost);
extern HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction);
/**
* @}
*/
#endif //__USB_HOST_MSC_BOT_H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,444 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usbh_msc_core.c
**
** A detailed description is available at
** @link
This file implements the MSC class driver functions
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_msc_class.h"
#include "usb_host_msc_scsi.h"
#include "usb_host_msc_bot.h"
#include "usb_host_core.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost);
void usb_host_msc_itfdeinit(usb_core_instance *pdev);
HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost);
HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost);
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define USBH_MSC_ERROR_RETRY_LIMIT 10u
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
__USB_ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine __USB_ALIGN_END ;
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_INTERNAL_DMA_ENABLED */
uint8_t MSCErrorCount = 0u;
usb_host_class_callback_func USBH_MSC_cb =
{
&usb_host_msc_itfinit,
&usb_host_msc_itfdeinit,
&usb_host_msc_classreq,
&usb_host_msc_process,
};
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief This request is used to issue a request to reset the msc device and
** its related interface. This class-specific request shall prepare the
** device for the next CBW from the host.
** \param pdev : device instance
** \param phost: host state set
** \retval status define by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_msc_bot_reset(usb_core_instance *pdev, USBH_HOST *phost)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \
USB_REQ_RECIPIENT_INTERFACE;
phost->ctrlparam.setup.b.bRequest = USB_REQ_BOT_RESET;
phost->ctrlparam.setup.b.wValue.w = 0u;
phost->ctrlparam.setup.b.wIndex.w = 0u;
phost->ctrlparam.setup.b.wLength.w = 0u;
return usb_host_ctrlreq(pdev, phost, 0u , 0u );
}
/**
*******************************************************************************
** \brief this request is used to issue a request to get the max logic unit of
** the msc device.
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_msc_maxlun_get(usb_core_instance *pdev, USBH_HOST *phost)
{
phost->ctrlparam.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
USB_REQ_RECIPIENT_INTERFACE;
phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
phost->ctrlparam.setup.b.wValue.w = 0u;
phost->ctrlparam.setup.b.wIndex.w = 0u;
phost->ctrlparam.setup.b.wLength.w = 1u;
return usb_host_ctrlreq(pdev, phost, MSC_Machine.buff , 1u );
}
/**
*******************************************************************************
** \brief The function is used for handling errors during processing the MSC
** state machine
** \param status
** \retval none
******************************************************************************/
void usb_host_msc_error_process(uint8_t status)
{
switch(status)
{
case USB_HOST_MSC_FAIL:
MSCErrorCount++;
if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT)
{
/* Try MSC level error recovery, Issue the request Sense to get
driver error reason */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_REQUEST_SENSE;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
}
else
{
/* Error trials exceeded the limit, go to unrecovered state */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE;
}
break;
case USB_HOST_MSC_PHASE_ERROR:
/* Phase error, Go to Unrecoovered state */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE;
break;
default:
break;
}
}
/**
*******************************************************************************
** \brief Interface initialization for msc class application, the channels for
** the IN and OUT EP will be distributed.
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost)
{
USBH_HOST *pphost = phost;
if((pphost->device_prop.devitfdesc[0].bInterfaceClass == MSC_CLASS) && \
(pphost->device_prop.devitfdesc[0].bInterfaceProtocol == MSC_PROTOCOL))
{
if(pphost->device_prop.devepdesc[0][0].bEndpointAddress & 0x80)
{
MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress);
MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][0].wMaxPacketSize;
}
else
{
MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress);
MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0] [0].wMaxPacketSize;
}
if(pphost->device_prop.devepdesc[0][1].bEndpointAddress & 0x80)
{
MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress);
MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize;
}
else
{
MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress);
MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize;
}
//distribute the channels for the EPs
MSC_Machine.hc_num_out = usb_host_distrch(pdev, MSC_Machine.MSC_BulkOutEp);
MSC_Machine.hc_num_in = usb_host_distrch(pdev, MSC_Machine.MSC_BulkInEp);
//open the channels that have distributed
usb_host_chopen(pdev,
MSC_Machine.hc_num_out,
pphost->device_prop.devaddr,
pphost->device_prop.devspeed,
EP_TYPE_BULK,
MSC_Machine.MSC_BulkOutEpSize);
usb_host_chopen(pdev,
MSC_Machine.hc_num_in,
pphost->device_prop.devaddr,
pphost->device_prop.devspeed,
EP_TYPE_BULK,
MSC_Machine.MSC_BulkInEpSize);
}
else
{
pphost->user_callbk->huser_devunsupported();
}
return HSTATUS_OK ;
}
/**
*******************************************************************************
** \brief deinitialize interface of msc class by freeing host channels
** \param pdev : device instance
** \retval none
******************************************************************************/
void usb_host_msc_itfdeinit(usb_core_instance *pdev)
{
if ( MSC_Machine.hc_num_out)
{
hd_usb_hchstop(pdev, MSC_Machine.hc_num_out);
usb_host_freech(pdev, MSC_Machine.hc_num_out);
MSC_Machine.hc_num_out = 0;
}
if ( MSC_Machine.hc_num_in)
{
hd_usb_hchstop(pdev, MSC_Machine.hc_num_in);
usb_host_freech(pdev, MSC_Machine.hc_num_in);
MSC_Machine.hc_num_in = 0;
}
}
/**
*******************************************************************************
** \brief initialize the msc state machine
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost)
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_INIT_STATE;
return HSTATUS_OK;
}
/**
*******************************************************************************
** \brief process the msc state machine
** \param pdev : device instance
** \param phost: host state set
** \retval status defined by HOST_STATUS
******************************************************************************/
HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost)
{
USBH_HOST *pphost = phost;
HOST_STATUS status = HSTATUS_BUSY;
uint8_t mscStatus = USB_HOST_MSC_BUSY;
uint8_t appliStatus = 0u;
static uint8_t maxLunExceed = FALSE;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.MSCState)
{
case HOST_MSC_BOT_INIT_STATE:
usb_host_msc_init(pdev);
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_RESET;
break;
case HOST_MSC_BOT_RESET:
//issue a request to reset the bot.
status = usb_host_msc_bot_reset(pdev, phost);
if(status == HSTATUS_OK )
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_GET_MAX_LUN;
}
if(status == HSTATUS_UNSUPPORTED )
{
//if the request fails, it needs to move to next state and should save the next state as backup
USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_GET_MAX_LUN;
//a clear feature should be issued if the request fails.
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE;
}
break;
case HOST_MSC_GET_MAX_LUN:
//issue a request to get the max logical unit(MAXLUN).
status = usb_host_msc_maxlun_get(pdev, phost);
if(status == HSTATUS_OK )
{
MSC_Machine.maxLun = *(MSC_Machine.buff) ;
if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))
{
maxLunExceed = TRUE;
pphost->user_callbk->huser_devunsupported();
break;
}
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_TEST_UNIT_READY;
}
if(status == HSTATUS_UNSUPPORTED )
{
//if the request fails, it needs to move to next state and should save the next state as backup
USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_TEST_UNIT_READY;
//a clear feature should be issued if the request fails.
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE;
}
break;
case HOST_MSC_CTRL_ERROR_STATE:
//issue a request to clear feature
status = usb_host_clrfeature(pdev,
phost,
0x00u,
pphost->ctrlparam.hc_num_out);
if(status == HSTATUS_OK )
{
/* If GetMaxLun Request not support, assume Single LUN configuration */
MSC_Machine.maxLun = 0;
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
}
break;
case HOST_MSC_TEST_UNIT_READY:
//issue the request Test Unit Ready[0] of SCSI command
mscStatus = usb_host_msc_TestUnitReady(pdev);
if(mscStatus == USB_HOST_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_READ_CAPACITY10;
MSCErrorCount = 0;
status = HSTATUS_OK;
}
else
{
usb_host_msc_error_process(mscStatus);
}
break;
case HOST_MSC_READ_CAPACITY10:
//issue the request Read Capacity[0] of SCSI command.
mscStatus = usb_host_msc_ReadCapacity10(pdev);
if(mscStatus == USB_HOST_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_MODE_SENSE6;
MSCErrorCount = 0;
status = HSTATUS_OK;
}
else
{
usb_host_msc_error_process(mscStatus);
}
break;
case HOST_MSC_MODE_SENSE6:
//issue the request ModeSense6 of SCSI command for detecting whelth the deviec is write-protected.
mscStatus = usb_host_msc_ModeSense6(pdev);
if(mscStatus == USB_HOST_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE;
MSCErrorCount = 0;
status = HSTATUS_OK;
}
else
{
usb_host_msc_error_process(mscStatus);
}
break;
case HOST_MSC_REQUEST_SENSE:
//issue the request RequestSense of SCSI command for retreiving error code.
mscStatus = usb_host_msc_RequestSense(pdev);
if(mscStatus == USB_HOST_MSC_OK )
{
USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
status = HSTATUS_OK;
}
else
{
usb_host_msc_error_process(mscStatus);
}
break;
case HOST_MSC_BOT_USB_TRANSFERS:
//handle the BOT state machine.
usb_host_msc_botxferprocess(pdev , phost);
break;
case HOST_MSC_DEFAULT_APPLI_STATE:
//handle the user callback for the msc application.
appliStatus = pphost->user_callbk->huser_application();
if(appliStatus == 0)
{
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE;
}
else if (appliStatus == 1)
{
//deinit requested from the application layer.
status = HSTATUS_APP_DEINIT;
}
else
{
;
}
break;
case HOST_MSC_UNRECOVERED_STATE:
status = HSTATUS_UNRECOVERED_ERROR;
break;
default:
break;
}
}
return status;
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,110 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_msc_class.h
**
** A detailed description is available at
** @link
This file contains all the prototypes for the usbh_msc_core.c
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_MSC_CLASS_H__
#define __USB_HOST_MSC_CLASS_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_core.h"
#include "usb_host_stdreq.h"
#include "usb_bsp.h"
#include "usb_host_ctrltrans.h"
#include "usb_host_cfgch.h"
#include "usb_host_msc_class.h"
#include "usb_host_msc_scsi.h"
#include "usb_host_msc_bot.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
*******************************************************************************
** \brief Structure for MSC process
**
******************************************************************************/
typedef struct
{
uint8_t hc_num_in;
uint8_t hc_num_out;
uint8_t MSC_BulkOutEp;
uint8_t MSC_BulkInEp;
uint16_t MSC_BulkInEpSize;
uint16_t MSC_BulkOutEpSize;
uint8_t buff[USBH_MSC_MPS_SIZE];
uint8_t maxLun;
}MSC_Machine_TypeDef;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define USB_REQ_BOT_RESET (0xFFu)
#define USB_REQ_GET_MAX_LUN (0xFEu)
/*******************************************************************************
* Global definitions ('extern')
******************************************************************************/
extern usb_host_class_callback_func USBH_MSC_cb;
extern MSC_Machine_TypeDef MSC_Machine;
extern uint8_t MSCErrorCount;
#endif /* __USB_HOST_MSC_CLASS_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,267 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_msc_fatfs.c
**
** A detailed description is available at
** @link
This file provides the fatfs functions.
@endlink
**
** - 2018-12-26 1.0 wangmin First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
#ifdef CONFIG_FAT_VALID
#include "diskio.h"
#include "usb_host_msc_class.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
extern usb_core_instance usb_app_instance;
extern USBH_HOST usb_app_host;
/**
*******************************************************************************
** \brief Initialize Disk Drive
** \param drv Physical drive number (0)
** \retval DSTATUS
******************************************************************************/
DSTATUS disk_initialize (BYTE drv)
{
if(host_driver_ifdevconnected(&usb_app_instance))
{
Stat &= (DSTATUS)~STA_NOINIT;
}
return Stat;
}
/**
*******************************************************************************
** \brief Get Disk Status
** \param drv Physical drive number (0)
** \retval DSTATUS
******************************************************************************/
DSTATUS disk_status (BYTE drv)
{
DSTATUS status = Stat;
if (drv)
{
status = STA_NOINIT; /* Supports only single drive */
}
return status;
}
/**
*******************************************************************************
** \brief Read Sector(s)
** \param drv Physical drive number (0)
** \param buff Pointer to the data buffer to store read data
** \param sector Start sector number (LBA)
** \param count Sector count (1..255)
** \retval DSTATUS
******************************************************************************/
DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count )
{
BYTE status = USB_HOST_MSC_OK;
if (drv || (!count))
{
return RES_PARERR;
}
if (Stat & STA_NOINIT)
{
return RES_NOTRDY;
}
if(host_driver_ifdevconnected(&usb_app_instance))
{
do
{
status = usb_host_msc_Read10(&usb_app_instance, buff,sector,512ul * (uint32_t)count);
usb_host_msc_botxferprocess(&usb_app_instance ,&usb_app_host);
if(!host_driver_ifdevconnected(&usb_app_instance))
{
return RES_ERROR;
}
}
while(status == USB_HOST_MSC_BUSY );
}
if(status == USB_HOST_MSC_OK)
{
return RES_OK;
}
return RES_ERROR;
}
#if _READONLY == 0
/**
*******************************************************************************
** \brief Write Sector(s)
** \param drv Physical drive number (0)
** \param buff Pointer to the data to be written
** \param sector Start sector number (LBA)
** \param count Sector count (1..255)
** \retval DSTATUS
******************************************************************************/
DRESULT disk_write (BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
{
BYTE status = USB_HOST_MSC_OK;
if (drv || (!count))
{
return RES_PARERR;
}
if (Stat & STA_NOINIT)
{
return RES_NOTRDY;
}
if (Stat & STA_PROTECT)
{
return RES_WRPRT;
}
if(host_driver_ifdevconnected(&usb_app_instance))
{
do
{
status = usb_host_msc_Write10(&usb_app_instance,(BYTE*)buff,sector,512ul * (uint32_t)count);
usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host);
if(!host_driver_ifdevconnected(&usb_app_instance))
{
return RES_ERROR;
}
}
while(status == USB_HOST_MSC_BUSY );
}
if(status == USB_HOST_MSC_OK)
{
return RES_OK;
}
return RES_ERROR;
}
#endif /* _READONLY == 0 */
#if _USE_IOCTL != 0
/**
*******************************************************************************
** \brief Miscellaneous Functions
** \param drv Physical drive number (0)
** \param ctrl Control code
** \param buff Buffer to send/receive control data
**
** \retval DSTATUS
******************************************************************************/
DRESULT disk_ioctl (BYTE drv, BYTE ctrl, void *buff)
{
DRESULT res = RES_OK;
if (drv)
{
return RES_PARERR;
}
res = RES_ERROR;
if (Stat & STA_NOINIT)
{
return RES_NOTRDY;
}
switch (ctrl)
{
case CTRL_SYNC : /* Make sure that no pending write process */
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
*(DWORD*)buff = (DWORD) USB_HOST_MSC_Param.MSC_Capacity;
res = RES_OK;
break;
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
*(WORD*)buff = 512u;
res = RES_OK;
break;
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
*(DWORD*)buff = 512u;
break;
default:
res = RES_PARERR;
break;
}
return res;
}
#endif
#endif /* _USE_IOCTL != 0 */

View File

@@ -0,0 +1,573 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_msc_scsi.c
**
** A detailed description is available at
** @link
This file implements the SCSI commands。
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_msc_class.h"
#include "usb_host_msc_scsi.h"
#include "usb_host_msc_bot.h"
#include "usb_host_ctrltrans.h"
#include "usb_host_stddef.h"
#include <stdio.h>
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
MSC_PARAMETER USB_HOST_MSC_Param;
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ )
#pragma data_alignment=4
#endif
#endif
__USB_ALIGN_BEGIN uint8_t USB_HOST_DataInBuf[512] __USB_ALIGN_END ;
#ifdef USB_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ )
#pragma data_alignment=4
#endif
#endif
__USB_ALIGN_BEGIN uint8_t USB_HOST_DataOutBuf[512] __USB_ALIGN_END ;
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Issues 'Test Unit Ready' command to the device. Once the response
** received, it updates the status to upper layer, the length of the
** command are 31bytes.
** \param pdev : device instance
** \retval status define by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_TestUnitReady(usb_core_instance *pdev)
{
uint8_t index;
USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
USBH_MSC_CBWData.field.CBWTransferLength = 0u;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY;
USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH;
USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_TEST_UNIT_READY;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_FAIL;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/**
*******************************************************************************
** \brief Issue the 'Read capacity10' command to the device. Once the response
** received, it updates the status to upper layer
** \param pdev : device instance
** \retval status define by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_ReadCapacity10(usb_core_instance *pdev)
{
uint8_t index;
USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf;
USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_READ_CAPACITY10;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine manage the other
transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
/*assign the capacity*/
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Capacity )[3]) = USB_HOST_DataInBuf[0];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Capacity )[2]) = USB_HOST_DataInBuf[1];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Capacity )[1]) = USB_HOST_DataInBuf[2];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Capacity )[0]) = USB_HOST_DataInBuf[3];
/*assign the page length*/
(((uint8_t*)&USB_HOST_MSC_Param.MSC_PageLength )[1]) = USB_HOST_DataInBuf[6];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_PageLength )[0]) = USB_HOST_DataInBuf[7];
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_FAIL;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/**
*******************************************************************************
** \brief Issue the 'Mode Sense6' Command to the device. This function is used
** for reading the WriteProtect Status of the MSC device.
** \param pdev : device instance
** \retval status by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_ModeSense6(usb_core_instance *pdev)
{
uint8_t index;
USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf;
USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_MODE_SENSE6;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6;
USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \
MODE_SENSE_PAGE_CODE;
USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine manage the other
transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
/* Assign the Write Protect status */
/* If WriteProtect = 0, Writing is allowed
If WriteProtect != 0, Disk is Write Protected */
if ( USB_HOST_DataInBuf[2] & MASK_MODE_SENSE_WRITE_PROTECT)
{
USB_HOST_MSC_Param.MSC_WriteProtect = DISK_WRITE_PROTECTED;
}
else
{
USB_HOST_MSC_Param.MSC_WriteProtect = 0u;
}
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_FAIL;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/**
*******************************************************************************
** \brief usb_host_msc_RequestSense
** Issues the Request Sense command to the device. Once the response
** received, it updates the status to upper layer
** \param pdev : device instance
** \retval status defined by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_RequestSense(usb_core_instance *pdev)
{
USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
uint8_t index;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = \
ALLOCATION_LENGTH_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf;
USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent;
USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_REQUEST_SENSE;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE;
USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine magage
the other transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
/* Get Sense data*/
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Sense )[3]) = USB_HOST_DataInBuf[0];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Sense )[2]) = USB_HOST_DataInBuf[1];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Sense )[1]) = USB_HOST_DataInBuf[2];
(((uint8_t*)&USB_HOST_MSC_Param.MSC_Sense )[0]) = USB_HOST_DataInBuf[3];
/* Commands successfully sent and Response Received */
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_FAIL;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/**
*******************************************************************************
** \brief issue the 'Write10 ' command to the device. Once the response received,
** it updates the status to upper layer
** \param pdev : device instance
** \param dataBuffer : data buffer contains the data to write
** \param address : address to which the data will be written
** \param nbOfbytes : NbOfbytes to be written
** \retval status define by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_Write10(usb_core_instance *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
uint16_t nbOfPages;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10;
/*logical block address*/
USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ;
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
/*HOST_MSC_PAGE_LENGTH = 512*/
nbOfPages = (uint16_t)(nbOfbytes/ HOST_MSC_PAGE_LENGTH);
/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/**
*******************************************************************************
** \brief issue the read command to the device. Once the response received,
** it updates the status to upper layer
** \param pdev : device instance
** \param dataBuffer : data buffer will contain the data to be read
** \param address : Address from which the data will be read
** \param nbOfbytes : number of bytes to be read
** \retval status defined by USB_HOST_MSC_STATUS
******************************************************************************/
uint8_t usb_host_msc_Read10(usb_core_instance *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes)
{
uint8_t index;
static USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY;
uint16_t nbOfPages;
status = USB_HOST_MSC_BUSY;
if(host_driver_ifdevconnected(pdev))
{
switch(USBH_MSC_BOTXferParam.CmdStateMachine)
{
case USB_HOST_MSC_CMD_SEND:
/*Prepare the CBW and relevent field*/
USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
for(index=0u; index<CBW_CB_LENGTH; index++)
{
USBH_MSC_CBWData.field.CBWCB[index] = 0x00u;
}
USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;
/*logical block address*/
USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
/*HOST_MSC_PAGE_LENGTH = 512*/
nbOfPages = (uint16_t)(nbOfbytes/ HOST_MSC_PAGE_LENGTH);
/*Tranfer length */
USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW;
/* Start the transfer, then let the state machine
magage the other transactions */
USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS;
USBH_MSC_BOTXferParam.BOTXferStatus = USB_HOST_MSC_BUSY;
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT;
status = USB_HOST_MSC_BUSY;
break;
case USB_HOST_MSC_CMD_WAIT:
switch(USBH_MSC_BOTXferParam.BOTXferStatus)
{
case USB_HOST_MSC_OK:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_OK;
break;
case USB_HOST_MSC_FAIL:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
break;
case USB_HOST_MSC_PHASE_ERROR:
USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND;
status = USB_HOST_MSC_PHASE_ERROR;
break;
default:
break;
}
break;
default:
break;
}
}
return status;
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,137 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_msc_scsi.h
**
** A detailed description is available at
** @link
Header file for usbh_msc_scsi.c
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_MSC_SCSI_H__
#define __USB_HOST_MSC_SCSI_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_stdreq.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
*******************************************************************************
** \brief USBH_MSC_SCSI_Exported_Types
**
******************************************************************************/
typedef enum {
USB_HOST_MSC_OK = 0u,
USB_HOST_MSC_FAIL,
USB_HOST_MSC_PHASE_ERROR,
USB_HOST_MSC_BUSY
}USB_HOST_MSC_STATUS;
typedef struct
{
uint32_t MSC_Capacity;
uint32_t MSC_Sense;
uint16_t MSC_PageLength;
uint8_t MSC_BulkOutEP;
uint8_t MSC_BulkInEP;
uint8_t MSC_WriteProtect;
}MSC_PARAMETER;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define USB_HOST_MSC_CMD_SEND 1
#define USB_HOST_MSC_CMD_WAIT 2
#define OPCODE_TEST_UNIT_READY (0x00u)
#define OPCODE_READ_CAPACITY10 (0x25u)
#define OPCODE_MODE_SENSE6 (0x1Au)
#define OPCODE_READ10 (0x28u)
#define OPCODE_WRITE10 (0x2Au)
#define OPCODE_REQUEST_SENSE (0x03u)
#define DESC_REQUEST_SENSE (0x00u)
#define ALLOCATION_LENGTH_REQUEST_SENSE (63u)
#define XFER_LEN_READ_CAPACITY10 (8u)
#define XFER_LEN_MODE_SENSE6 (63u)
#define MASK_MODE_SENSE_WRITE_PROTECT (0x80u)
#define MODE_SENSE_PAGE_CONTROL_FIELD (0x00u)
#define MODE_SENSE_PAGE_CODE (0x3Fu)
#define DISK_WRITE_PROTECTED (0x01u)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
extern MSC_PARAMETER USB_HOST_MSC_Param;
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern uint8_t usb_host_msc_TestUnitReady(usb_core_instance *pdev);
extern uint8_t usb_host_msc_ReadCapacity10(usb_core_instance *pdev);
extern uint8_t usb_host_msc_ModeSense6(usb_core_instance *pdev);
extern uint8_t usb_host_msc_RequestSense(usb_core_instance *pdev);
extern uint8_t usb_host_msc_Write10(usb_core_instance *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes);
extern uint8_t usb_host_msc_Read10(usb_core_instance *pdev,
uint8_t *dataBuffer,
uint32_t address,
uint32_t nbOfbytes);
#endif //__USB_HOST_MSC_SCSI_H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,232 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_cfgch.c
**
** A detailed description is available at
** @link
This file implements functions for opening and closing host channels
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_cfgch.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
uint16_t usb_host_getfreech(usb_core_instance *pdev);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief configure and open a pipe
** \param pdev : device instance
** \param hc_num: host channel index
** \param dev_address: USB Device address allocated to attached device
** \param speed : core speed
** \param ep_type: communication type of the EP
** \param mps: max size of the packet
** \retval none
******************************************************************************/
void usb_host_chopen(usb_core_instance *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
pdev->host.hc[hc_num].ep_idx =(uint8_t) pdev->host.channel[hc_num]& 0x7Fu;
pdev->host.hc[hc_num].is_epin = (pdev->host.channel[hc_num] & 0x80u ) == 0x80u;
pdev->host.hc[hc_num].dev_addr = dev_address;
pdev->host.hc[hc_num].ep_type = ep_type;
pdev->host.hc[hc_num].max_packet = mps;
pdev->host.hc[hc_num].ch_speed = speed;
pdev->host.hc[hc_num].in_toggle = 0u;
pdev->host.hc[hc_num].out_toggle = 0u;
hd_usb_inithch(pdev, hc_num) ;
}
/**
*******************************************************************************
** \brief change a pipe on host
** \param pdev : device instance
** \param hc_num: host channel index
** \param dev_address: USB Device address allocated to attached device
** \param speed : core speed
** \param ep_type: communication type of EP
** \param mps: max size of packet
** \retval none
******************************************************************************/
void usb_host_mdfch(usb_core_instance *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
if(dev_address != 0u)
{
pdev->host.hc[hc_num].dev_addr = dev_address;
}
if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0u))
{
pdev->host.hc[hc_num].max_packet = mps;
}
if((pdev->host.hc[hc_num].ch_speed != speed ) && (speed != 0u ))
{
pdev->host.hc[hc_num].ch_speed = speed;
}
hd_usb_inithch(pdev, hc_num);
}
/**
*******************************************************************************
** \brief distribute a new channel for the pipe
** \param pdev : device instance
** \param ep_addr: EP index the channel distributed for
** \retval hc_num: host channel index
******************************************************************************/
uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr)
{
__IO uint16_t hc_num;
hc_num = usb_host_getfreech(pdev);
if (hc_num != HC_ERROR)
{
pdev->host.channel[hc_num & (USB_MAX_TX_FIFOS-1u)] = HC_USED | ep_addr;
}
return (uint8_t)hc_num;
}
/**
*******************************************************************************
** \brief free the USB host channel assigned by idx
** \param pdev : device instance
** \param idx: Channel number to be freed
** \retval Status
******************************************************************************/
uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx)
{
if(idx < MAX_CHNUM)
{
pdev->host.channel[idx & (USB_MAX_TX_FIFOS-1u)] &= HC_USED_MASK;
}
return HSTATUS_OK;
}
/**
*******************************************************************************
** \brief free all the USB host channels
** \param pdev : device instance
** \retval none
******************************************************************************/
void usb_host_dedistrallch(usb_core_instance *pdev)
{
uint8_t idx;
for (idx = 2u; idx < MAX_CHNUM ; idx ++)
{
pdev->host.channel[idx & (USB_MAX_TX_FIFOS-1u)] = 0u;
}
}
/**
*******************************************************************************
** \brief Get a free channel number so that can be distributed to a device endpoint
** \param pdev : device instance
** \retval idx: the free channel index
******************************************************************************/
uint16_t usb_host_getfreech(usb_core_instance *pdev)
{
__IO uint8_t tmp_idx = 0u;
uint16_t u16Ret = HC_ERROR;
for (tmp_idx = 0u ; tmp_idx < MAX_CHNUM ; tmp_idx++)
{
if ((pdev->host.channel[tmp_idx & (USB_MAX_TX_FIFOS-1u)] & HC_USED) == 0u)
{
u16Ret = HC_OK;
break;
}
}
if(u16Ret == HC_OK)
{
u16Ret = tmp_idx;
}
else
{
u16Ret = HC_ERROR;
}
return u16Ret;
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,110 @@
/*****************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_cfgch.h
**
** A detailed description is available at
** @link header file for the usbh_hcs.c @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_CFGCH_H__
#define __USB_HOST_CFGCH_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_core.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
*******************************************************************************
** \brief USBH_HCS_Exported_Defines
**
******************************************************************************/
#define MAX_CHNUM (12u)
#define HC_OK (0x0000u)
#define HC_USED (0x8000u)
#define HC_ERROR (0xFFFFu)
#define HC_USED_MASK (0x7FFFu)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr);
extern uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx);
extern void usb_host_dedistrallch(usb_core_instance *pdev);
extern void usb_host_chopen(usb_core_instance *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
extern void usb_host_mdfch(usb_core_instance *pdev,
uint8_t hc_num,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
#endif /* __USB_HOST_CFGCH_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,671 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_core.c
**
** A detailed description is available at
** @link
This file implements the functions for the core state machine process
the enumeration and the control transfer process
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include "usb_host_ctrltrans.h"
#include "usb_bsp.h"
#include "usb_host_cfgch.h"
#include "usb_host_stdreq.h"
#include "usb_host_core.h"
#include "usb_host_int.h"
#include "usb_host_user.h"
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost);
HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost);
/*******************************************************************************
* This is the poiter which will be called in the interrupt file and declared
* with extern.
******************************************************************************/
/**
*******************************************************************************
** \brief initialization for the host application
** \param pdev : device instance
** \param phost: host state set
** \param class_cbk: the call back function for the class application
** \param user_cbk: the call back function for user
** \retval none
******************************************************************************/
void usb_host_init(usb_core_instance *pdev,
USBH_HOST *phost,
usb_host_class_callback_func *class_cbk,
usb_host_user_callback_func *user_cbk)
{
hd_usb_bsp_init(pdev);
hd_usb_bsp_cfgvbus(pdev);
usb_host_deinit(pdev, phost);
phost->class_callbk = class_cbk;
phost->user_callbk = user_cbk;
host_driver_init(pdev);
phost->user_callbk->huser_init();
usb_bsp_nvic();
}
/**
*******************************************************************************
** \brief deinitialize the host application
** \param pdev : device instance
** \param phost: host state set
** \retval none
******************************************************************************/
void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost)
{
phost->host_state = HOST_IDLE;
phost->host_state_backup = HOST_IDLE;
phost->enum_state = ENUM_IDLE;
phost->req_state = REQ_CMD_TX;
phost->ctrlparam.ctrl_state = CTRL_SETUP;
phost->ctrlparam.ctrlmaxsize = USB_MAX_EP0_SIZE;
phost->device_prop.devaddr = DEV_DEFAULT_ADDRESS;
phost->device_prop.devspeed = PRTSPD_FULL_SPEED;
usb_host_freech(pdev, phost->ctrlparam.hc_num_in);
usb_host_freech(pdev, phost->ctrlparam.hc_num_out);
}
/**
*******************************************************************************
** \brief This is the main process function for the host core, it will process
** the main machine, such as connect,disconnect, emunation etc.
** \param pdev : device instance
** \param *phost: host state set
** \retval none
******************************************************************************/
void usb_host_mainprocess(usb_core_instance *pdev , USBH_HOST *phost)
{
__IO HOST_STATUS tmp_status;
tmp_status = HSTATUS_FAIL;
HOST_HANDLE_STATE tmp_host_state;
if ((host_driver_ifdevconnected(pdev) == 0ul)&& (phost->host_state != HOST_IDLE))
{
if(phost->host_state != HOST_DEV_DISCONNECTED)
{
if ((phost->device_prop.devspeed == USB_SPEED_LOW) && (phost->host_state == HOST_DEV_CONNECTED))
{
phost->host_state = HOST_DEV_CONNECTED;
}
else
{
phost->host_state = HOST_DEV_DISCONNECTED;
}
}
}
tmp_host_state = phost->host_state;
if(tmp_host_state == HOST_IDLE)
{
if (host_driver_ifdevconnected(pdev))
{
phost->host_state = HOST_DEV_CONNECTED;
hd_usb_mdelay(100ul);
}
}
else if(tmp_host_state == HOST_DEV_CONNECTED)
{
#ifdef MSC_HID_COMPOSITE
if(msc_flag == 1 && host_driver_getcurrentspd(pdev) == 2)
{
host_driver_init(pdev);
msc_flag = 0;
}
#endif //MSC_HID_COMPOSITE
phost->user_callbk->huser_devattached();
phost->ctrlparam.hc_num_out = usb_host_distrch(pdev, 0x00u);
phost->ctrlparam.hc_num_in = usb_host_distrch(pdev, 0x80u);
host_driver_portrst(pdev);
phost->user_callbk->huser_devreset();
phost->device_prop.devspeed = (uint8_t)host_driver_getcurrentspd(pdev);
phost->host_state = HOST_ENUM;
phost->user_callbk->huser_devspddetected(phost->device_prop.devspeed);
usb_host_chopen(pdev,
phost->ctrlparam.hc_num_in,
phost->device_prop.devaddr,
phost->device_prop.devspeed,
EP_TYPE_CTRL,
(uint16_t)phost->ctrlparam.ctrlmaxsize);
usb_host_chopen(pdev,
phost->ctrlparam.hc_num_out,
phost->device_prop.devaddr,
phost->device_prop.devspeed,
EP_TYPE_CTRL,
(uint16_t)phost->ctrlparam.ctrlmaxsize);
}
else if(tmp_host_state == HOST_ENUM)
{
if( usb_host_enumprocess(pdev , phost) == HSTATUS_OK)
{
phost->user_callbk->huser_enumcompl();
phost->host_state = HOST_USER_INPUT;
}
}
else if(tmp_host_state == HOST_USER_INPUT)
{
if((phost->class_callbk->host_class_init(pdev, phost)) == HSTATUS_OK)
{
phost->host_state = HOST_CLASS_REQ;
}
}
else if(tmp_host_state == HOST_CLASS_REQ)
{
tmp_status = phost->class_callbk->host_class_request(pdev, phost);
if(tmp_status == HSTATUS_OK)
{
phost->host_state = HOST_CLASS_PROCESS;
}
else
{
usb_host_errorprocess(phost, tmp_status);
}
}
else if(tmp_host_state == HOST_CLASS_PROCESS)
{
tmp_status = phost->class_callbk->host_class_process(pdev, phost);
usb_host_errorprocess(phost, tmp_status);
}
else if(tmp_host_state == HOST_CTRL_TRANSMIT)
{
usb_host_ctrlprocess(pdev, phost);
}
else if(tmp_host_state == HOST_ERROR_STATE)
{
usb_host_deinit(pdev, phost);
phost->user_callbk->huser_deinit();
phost->class_callbk->host_class_deinit(pdev);
}
else if(tmp_host_state == HOST_DEV_DISCONNECTED)
{
phost->user_callbk->huser_devdisconn();
usb_host_deinit(pdev, phost);
phost->user_callbk->huser_deinit();
phost->class_callbk->host_class_deinit(pdev);
usb_host_dedistrallch(pdev);
phost->host_state = HOST_IDLE;
}
else
{
;
}
}
/**
*******************************************************************************
** \brief process the status when related error status happens.
** \param *phost: host state set
** \param errType : host status
** \retval none
******************************************************************************/
void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType)
{
switch(errType)
{
case HSTATUS_APP_DEINIT:
phost->host_state = HOST_ERROR_STATE;
phost->user_callbk->huser_init();
break;
case HSTATUS_SPEED_UNKNOWN:
case HSTATUS_UNRECOVERED_ERROR:
phost->user_callbk->huser_unrecoverederror();
phost->host_state = HOST_ERROR_STATE;
break;
default:
break;
}
}
/**
*******************************************************************************
** \brief this function process all the emunation steps.
** \param pdev : device instance
** \param phost: host state set
** \retval status
******************************************************************************/
HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost)
{
HOST_STATUS tmp_status;
uint8_t Local_Buffer[64];
ENUM_HANDLE_STATE tmp_enum_state;
tmp_status = HSTATUS_BUSY;
tmp_enum_state = phost->enum_state;
if(tmp_enum_state == ENUM_IDLE)
{
if ( usb_host_getdevdesc(pdev , phost, 8u) == HSTATUS_OK)
{
phost->ctrlparam.ctrlmaxsize = phost->device_prop.devdesc.bMaxPacketSize0;
host_driver_portrst(pdev);
phost->enum_state = ENUM_GET_FULL_DEVDESC;
usb_host_mdfch (pdev,
phost->ctrlparam.hc_num_out,
0u,
0u,
0u,
(uint16_t)phost->ctrlparam.ctrlmaxsize);
usb_host_mdfch (pdev,
phost->ctrlparam.hc_num_in,
0u,
0u,
0u,
(uint16_t)phost->ctrlparam.ctrlmaxsize);
}
}
if(tmp_enum_state == ENUM_GET_FULL_DEVDESC)
{
if ( usb_host_getdevdesc(pdev, phost, USB_DEVICE_DESC_SIZE) == HSTATUS_OK)
{
phost->user_callbk->huser_devdescavailable(&phost->device_prop.devdesc);
phost->enum_state = ENUM_SET_DEVADDR;
}
}
if(tmp_enum_state == ENUM_SET_DEVADDR)
{
if ( usb_host_setdevaddr(pdev, phost, DEV_ASSIGNED_ADDRESS) == HSTATUS_OK)
{
hd_usb_mdelay(2ul);
phost->device_prop.devaddr = DEV_ASSIGNED_ADDRESS;
phost->user_callbk->huser_devaddrdistributed();
phost->enum_state = ENUM_GET_CFGDESC;
usb_host_mdfch (pdev,
phost->ctrlparam.hc_num_in,
phost->device_prop.devaddr,
0u,
0u,
0u);
usb_host_mdfch (pdev,
phost->ctrlparam.hc_num_out,
phost->device_prop.devaddr,
0u,
0u,
0u);
}
}
if(tmp_enum_state == ENUM_GET_CFGDESC)
{
if ( usb_host_getcfgdesc(pdev, phost, USB_CONFIGURATION_DESC_SIZE) == HSTATUS_OK)
{
phost->enum_state = ENUM_GET_FULL_CFGDESC;
}
}
if(tmp_enum_state == ENUM_GET_FULL_CFGDESC)
{
if (usb_host_getcfgdesc(pdev, phost, phost->device_prop.devcfgdesc.wTotalLength) == HSTATUS_OK)
{
phost->user_callbk->huser_cfgdescavailable(&phost->device_prop.devcfgdesc,
phost->device_prop.devitfdesc,
phost->device_prop.devepdesc[0]);
phost->enum_state = ENUM_GET_MFCSTRINGDESC;
}
}
if(tmp_enum_state == ENUM_GET_MFCSTRINGDESC)
{
if (phost->device_prop.devdesc.iManufacturer != (uint8_t)0)
{
if (usb_host_getstringdesc(pdev,
phost,
phost->device_prop.devdesc.iManufacturer,
Local_Buffer ,
0xffu) == HSTATUS_OK)
{
phost->user_callbk->huser_mfcstring(Local_Buffer);
phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC;
}
}
else
{
phost->user_callbk->huser_mfcstring("N/A");
phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC;
}
}
if(tmp_enum_state == ENUM_GET_PRODUCT_STRINGDESC)
{
if (phost->device_prop.devdesc.iProduct != (uint8_t)0)
{
if (usb_host_getstringdesc(pdev,
phost,
phost->device_prop.devdesc.iProduct,
Local_Buffer,
0xffu) == HSTATUS_OK)
{
phost->user_callbk->huser_productstring(Local_Buffer);
phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC;
}
}
else
{
phost->user_callbk->huser_productstring("N/A");
phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC;
}
}
if(tmp_enum_state == ENUM_GET_SERIALNUM_STRINGDESC)
{
if (phost->device_prop.devdesc.iSerialNumber != (uint8_t)0)
{
if (usb_host_getstringdesc(pdev,
phost,
phost->device_prop.devdesc.iSerialNumber,
Local_Buffer,
0xffu) == HSTATUS_OK)
{
phost->user_callbk->huser_serialnum(Local_Buffer);
phost->enum_state = ENUM_SET_CFG;
}
}
else
{
phost->user_callbk->huser_serialnum("N/A");
phost->enum_state = ENUM_SET_CFG;
}
}
if(tmp_enum_state == ENUM_SET_CFG)
{
if (usb_host_setconfig(pdev, phost,
(uint16_t)phost->device_prop.devcfgdesc.bConfigurationValue) == HSTATUS_OK)
{
phost->enum_state = ENUM_DEV_CFG_OVER;
}
}
if(tmp_enum_state == ENUM_DEV_CFG_OVER)
{
tmp_status = HSTATUS_OK;
}
else
{
;
}
return tmp_status;
}
/**
*******************************************************************************
** \brief process the state machine of control transfer
** \param pdev : device instance
** \retval status
******************************************************************************/
HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost)
{
uint8_t direction;
CTRL_HANDLE_STATE tmp_ctrl_state;
static uint16_t timeout = 0;
HOST_STATUS status = HSTATUS_OK;
HOST_CH_XFER_STATE URB_Status = HOST_CH_XFER_IDLE;
phost->ctrlparam.ctrl_status = CTRL_START;
tmp_ctrl_state = phost->ctrlparam.ctrl_state;
if(tmp_ctrl_state == CTRL_SETUP)
{
/* transmit a setup packet to the device */
usb_host_sendctrlsetup(pdev, phost->ctrlparam.setup.d8, phost->ctrlparam.hc_num_out);
phost->ctrlparam.ctrl_state = CTRL_SETUP_WAIT;
timeout = DATA_STAGE_TIMEOUT * 6u;
phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev);
}
else if(tmp_ctrl_state == CTRL_SETUP_WAIT)
{
URB_Status = host_driver_getxferstate(pdev , phost->ctrlparam.hc_num_out);
/* case SETUP packet sent successfully */
if(URB_Status == HOST_CH_XFER_DONE)
{
/* parse the direction of the request from the setup just sent */
direction = (phost->ctrlparam.setup.b.bmRequestType & USB_REQ_DIR_MASK);
/* judge if there is a data stage, if wLength is not zero, there may be a in or out
data stage */
if (phost->ctrlparam.setup.b.wLength.w != 0u )
{
timeout = DATA_STAGE_TIMEOUT;
if (direction == USB_D2H)
{
/* Data Direction is IN, device should send data in */
phost->ctrlparam.ctrl_state = CTRL_DATA_IN;
}
else
{
/* Data Direction is OUT, host will send data out for device */
phost->ctrlparam.ctrl_state = CTRL_DATA_OUT;
}
}
/* No DATA stage */
else
{
timeout = NODATA_STAGE_TIMEOUT;
/* If there is No Data Transfer Stage */
if (direction == USB_D2H)
{
/* Data Direction is IN */
phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT;
}
else
{
/* Data Direction is OUT */
phost->ctrlparam.ctrl_state = CTRL_STATUS_IN;
}
}
/* Set the delay timer to enable timeout for data stage completion */
phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev);
}
else if(URB_Status == HOST_CH_XFER_ERROR)
{
phost->ctrlparam.ctrl_state = CTRL_ERROR;
phost->ctrlparam.ctrl_status = CTRL_XACTERR;
}
else if ((host_driver_getcurrentfrm(pdev)- phost->ctrlparam.sof_num) > timeout)
{
printf("Device not responding\n");
}
else
{
;
}
}
else if(tmp_ctrl_state == CTRL_DATA_IN)
{
/* Issue an IN token */
usb_host_recvctrldata(pdev, phost->ctrlparam.buff, phost->ctrlparam.length, phost->ctrlparam.hc_num_in);
phost->ctrlparam.ctrl_state = CTRL_DATA_IN_WAIT;
}
else if(tmp_ctrl_state == CTRL_DATA_IN_WAIT)
{
URB_Status = host_driver_getxferstate(pdev , phost->ctrlparam.hc_num_in);
/* check is DATA packet transfered successfully */
if (URB_Status == HOST_CH_XFER_DONE)
{
phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT;
}
/* manage error cases*/
if (URB_Status == HOST_CH_XFER_STALL)
{
/* In stall case, return to previous machine state*/
phost->host_state = phost->host_state_backup;
}
else if (URB_Status == HOST_CH_XFER_ERROR)
{
/* Device error */
phost->ctrlparam.ctrl_state = CTRL_ERROR;
}
else if ((host_driver_getcurrentfrm(pdev)- phost->ctrlparam.sof_num) > timeout)
{
/* timeout for IN transfer */
phost->ctrlparam.ctrl_state = CTRL_ERROR;
}
else
{
;
}
}
else if(tmp_ctrl_state == CTRL_DATA_OUT)
{
/* Start DATA out transfer (only one DATA packet)*/
pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle = 1;
usb_host_sendctrldata (pdev,
phost->ctrlparam.buff,
phost->ctrlparam.length ,
phost->ctrlparam.hc_num_out);
phost->ctrlparam.ctrl_state = CTRL_DATA_OUT_WAIT;
}
else if(tmp_ctrl_state == CTRL_DATA_OUT_WAIT)
{
URB_Status = host_driver_getxferstate(pdev , phost->ctrlparam.hc_num_out);
switch(URB_Status)
{
case HOST_CH_XFER_DONE:
phost->ctrlparam.ctrl_state = CTRL_STATUS_IN;
break;
case HOST_CH_XFER_STALL:
phost->host_state = phost->host_state_backup;
phost->ctrlparam.ctrl_state = CTRL_STALLED;
break;
case HOST_CH_XFER_UNREADY:
phost->ctrlparam.ctrl_state = CTRL_DATA_OUT;
break;
case HOST_CH_XFER_ERROR:
phost->ctrlparam.ctrl_state = CTRL_ERROR;
break;
default:
break;
}
}
else if(tmp_ctrl_state == CTRL_STATUS_IN)
{
/* receive a packet with 0 byte */
usb_host_recvctrldata (pdev, 0u, 0u, phost->ctrlparam.hc_num_in);
phost->ctrlparam.ctrl_state = CTRL_STATUS_IN_WAIT;
}
else if(tmp_ctrl_state == CTRL_STATUS_IN_WAIT)
{
URB_Status = host_driver_getxferstate(pdev , phost->ctrlparam.hc_num_in);
if ( URB_Status == HOST_CH_XFER_DONE)
{ /* Control transfers completed, Exit the State Machine */
phost->host_state = phost->host_state_backup;
phost->ctrlparam.ctrl_state = CTRL_COMPLETE;
}
else if (URB_Status == HOST_CH_XFER_ERROR)
{
phost->ctrlparam.ctrl_state = CTRL_ERROR;
}
else if((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout)
{
phost->ctrlparam.ctrl_state = CTRL_ERROR;
}
else if(URB_Status == HOST_CH_XFER_STALL)
{
/* Control transfers completed, Exit the State Machine */
phost->host_state = phost->host_state_backup;
phost->ctrlparam.ctrl_status = CTRL_STALL;
status = HSTATUS_UNSUPPORTED;
}
else
{
;
}
}
else if(tmp_ctrl_state == CTRL_STATUS_OUT)
{
pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle ^= 1;
usb_host_sendctrldata (pdev, 0u, 0u, phost->ctrlparam.hc_num_out);
phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT_WAIT;
}
else if(tmp_ctrl_state == CTRL_STATUS_OUT_WAIT)
{
URB_Status = host_driver_getxferstate(pdev , phost->ctrlparam.hc_num_out);
switch(URB_Status)
{
case HOST_CH_XFER_DONE:
phost->host_state = phost->host_state_backup;
phost->ctrlparam.ctrl_state = CTRL_COMPLETE;
break;
case HOST_CH_XFER_UNREADY:
phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT;
break;
case HOST_CH_XFER_ERROR:
phost->ctrlparam.ctrl_state = CTRL_ERROR;
break;
default:
break;
}
}
else if(tmp_ctrl_state == CTRL_ERROR)
{
if (++ phost->ctrlparam.err_cnt <= HOST_MAX_ERROR_CNT)
{
/* re-start the transmission, starting from SETUP packet */
phost->ctrlparam.ctrl_state = CTRL_SETUP;
}
else
{
phost->ctrlparam.ctrl_status = CTRL_FAIL;
phost->host_state = phost->host_state_backup;
status = HSTATUS_FAIL;
}
}
else
{
;
}
return status;
}
/*******************************************************************************
** EOF
******************************************************************************/

View File

@@ -0,0 +1,251 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_core.h
**
** A detailed description is available at
** @link header file for the usbh_core.c @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_CORE_H__
#define __USB_HOST_CORE_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_driver.h"
#include "usb_host_stddef.h"
#include "usbh_conf.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
*******************************************************************************
** \brief USBH_CORE_Exported_Types
**
******************************************************************************/
/* Host status */
typedef enum {
HSTATUS_OK = 0,
HSTATUS_BUSY,
HSTATUS_FAIL,
HSTATUS_UNSUPPORTED,
HSTATUS_UNRECOVERED_ERROR,
HSTATUS_SPEED_UNKNOWN,
HSTATUS_APP_DEINIT
}HOST_STATUS;
/* states about the handle stages on the host side */
typedef enum {
HOST_IDLE = 0,
HOST_DEV_CONNECTED,
HOST_DEV_DISCONNECTED,
HOST_GET_DEVSPEED,
HOST_ENUM,
HOST_CLASS_REQ,
HOST_CLASS_PROCESS,
HOST_CTRL_TRANSMIT,
HOST_USER_INPUT,
HOST_SUSPENDED,
HOST_ERROR_STATE
}HOST_HANDLE_STATE;
/* states of the enumeration stage on the host side */
typedef enum {
ENUM_IDLE = 0,
ENUM_GET_FULL_DEVDESC,
ENUM_SET_DEVADDR,
ENUM_GET_CFGDESC,
ENUM_GET_FULL_CFGDESC,
ENUM_GET_MFCSTRINGDESC,
ENUM_GET_PRODUCT_STRINGDESC,
ENUM_GET_SERIALNUM_STRINGDESC,
ENUM_SET_CFG,
ENUM_DEV_CFG_OVER
} ENUM_HANDLE_STATE;
/* states of the control stages on the host side */
typedef enum {
CTRL_IDLE =0,
CTRL_SETUP,
CTRL_SETUP_WAIT,
CTRL_DATA_IN,
CTRL_DATA_IN_WAIT,
CTRL_DATA_OUT,
CTRL_DATA_OUT_WAIT,
CTRL_STATUS_IN,
CTRL_STATUS_IN_WAIT,
CTRL_STATUS_OUT,
CTRL_STATUS_OUT_WAIT,
CTRL_ERROR,
CTRL_STALLED,
CTRL_COMPLETE
}CTRL_HANDLE_STATE;
/* Following states are state machine for the request transferring */
typedef enum {
REQ_CMD_IDLE = 0,
REQ_CMD_TX,
REQ_CMD_WAIT
} REQ_HANDLE_STATE;
typedef enum {
USER_HAVE_RESP = 0,
USER_NONE_RESP
}HOST_USER_STATUS;
typedef struct
{
uint8_t hc_num_in; //channel number for the IN EP
uint8_t hc_num_out; //channel number for the OUT EP
uint8_t ctrlmaxsize; //the max size of EP0 parsed from the device descriptor
uint8_t err_cnt; //the error counter
uint16_t sof_num; //the frame number for sof packet
uint16_t length; //length of data in byte
uint8_t *buff; //data buffer
CTRL_HANDLE_STATUS ctrl_status; //status of control pipe
CTRL_HANDLE_STATE ctrl_state; //running state of the control transfer
usb_setup_typedef setup; //setup packet
} usb_host_ctrl_param;
/* Device information parsed from the related descriptors requested from the connected device
the following data are all parsed from the data sent by the connnected device */
typedef struct
{
uint8_t devaddr; //the address of the connected device
uint8_t devspeed; //the core speed of the connected device
usb_host_devdesc_typedef devdesc; //the device descriptor parsed from the data sent by device
usb_host_cfgdesc_typedef devcfgdesc; //the device configuration descriptor parsed from the data sent by device
usb_host_itfdesc_typedef devitfdesc[USBH_MAX_NUM_INTERFACES]; //the interface descritpor
USB_HOST_EPDesc_TypeDef devepdesc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS]; //the endpoint descriptor
USB_HOST_HDIDesc_TypeDef hiddesc; //the hid descriptor
}usb_host_devinformation;
typedef struct
{
HOST_STATUS (*host_class_init) (usb_core_instance *pdev , void *phost);
void (*host_class_deinit) (usb_core_instance *pdev);
HOST_STATUS (*host_class_request)(usb_core_instance *pdev , void *phost);
HOST_STATUS (*host_class_process)(usb_core_instance *pdev , void *phost);
} usb_host_class_callback_func;
typedef struct
{
void (*huser_init)(void);
void (*huser_deinit)(void);
void (*huser_devattached)(void);
void (*huser_devreset)(void);
void (*huser_devdisconn)(void);
void (*huser_overcurrent)(void);
void (*huser_devspddetected)(uint8_t DeviceSpeed);
void (*huser_devdescavailable)(void *);
void (*huser_devaddrdistributed)(void);
void (*huser_cfgdescavailable)(usb_host_cfgdesc_typedef *,
usb_host_itfdesc_typedef *,
USB_HOST_EPDesc_TypeDef *);
/* Configuration Descriptor available */
void (*huser_mfcstring)(void *);
void (*huser_productstring)(void *);
void (*huser_serialnum)(void *);
void (*huser_enumcompl)(void);
HOST_USER_STATUS (*huser_userinput)(void);
int (*huser_application) (void);
void (*huser_devunsupported)(void);
void (*huser_unrecoverederror)(void);
}usb_host_user_callback_func;
typedef struct
{
/* states for the host, enumeration, request */
REQ_HANDLE_STATE req_state; // value of state machine about the request
ENUM_HANDLE_STATE enum_state; // state machine while enumerating
HOST_HANDLE_STATE host_state_backup; // backup value of state machine about the host
HOST_HANDLE_STATE host_state; // value of state machine about the host
/* control informations */
usb_host_ctrl_param ctrlparam; // values about the control parameters
/* device information parsed from the descriptors from the device */
usb_host_devinformation device_prop;
/* functions: call back functions for the class and user */
usb_host_class_callback_func *class_callbk;
usb_host_user_callback_func *user_callbk;
} USBH_HOST;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
*******************************************************************************
** \brief USBH_CORE_Exported_Defines
**
******************************************************************************/
#define MSC_CLASS (0x08u)
#define HID_CLASS (0x03u)
#define MSC_PROTOCOL (0x50u)
#define CBI_PROTOCOL (0x01u)
#define DEV_DEFAULT_ADDRESS (0u)
#define DEV_ASSIGNED_ADDRESS (1u)
#define HOST_MAX_ERROR_CNT (2u)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern void usb_host_init(usb_core_instance *pdev,
USBH_HOST *phost,
usb_host_class_callback_func *class_cbk,
usb_host_user_callback_func *user_cbk);
extern void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost);
extern void usb_host_mainprocess(usb_core_instance *pdev, USBH_HOST *phost);
extern void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType);
#endif /* __USB_HOST_CORE_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,366 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_ctrltrans.c
**
** A detailed description is available at
** @link
This file handles the issuing of the USB transactions
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_ctrltrans.h"
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Start a setup transfer by changing the state-machine and
** initializing the required variables needed for the Control Transfer
** \param pdev : device instance
** \param buff: data buffer used for setup request
** \param length: data length in byte
** \retval status
******************************************************************************/
void usb_host_submitsetupreq(USBH_HOST *phost, uint8_t *buff, uint16_t length)
{
/* Save Global State */
phost->host_state_backup = phost->host_state;
/* Prepare the Transactions */
phost->host_state = HOST_CTRL_TRANSMIT;
phost->ctrlparam.buff = buff;
phost->ctrlparam.length = length;
phost->ctrlparam.ctrl_state = CTRL_SETUP;
}
/**
*******************************************************************************
** \brief send a control request and update the status after the request sent.
** \param pdev : device instance
** \param phost: host state set
** \param buff: data buffer whose data will be sent in the control pipe.
** \param length: length of the data sent.
** \retval status
******************************************************************************/
HOST_STATUS usb_host_ctrlreq(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t *buff,
uint16_t length)
{
HOST_STATUS status;
REQ_HANDLE_STATE tmp_req_state;
status = HSTATUS_BUSY;
tmp_req_state = phost->req_state;
if(tmp_req_state == REQ_CMD_TX)
{
/* prepare a setup packet for transferring */
usb_host_submitsetupreq(phost, buff, length);
/* update the request state */
phost->req_state = REQ_CMD_WAIT;
/* The status would be returned in this function */
status = HSTATUS_BUSY;
}
else if(tmp_req_state == REQ_CMD_WAIT)
{
switch(phost->ctrlparam.ctrl_state)
{
case CTRL_COMPLETE:
// Commands have been successfully sent and Responses have been Received
phost->req_state = REQ_CMD_TX;
// update the control state
phost->ctrlparam.ctrl_state = CTRL_IDLE;
status = HSTATUS_OK;
break;
case CTRL_ERROR:
//fail transfer
phost->req_state = REQ_CMD_TX;
status = HSTATUS_FAIL;
break;
case CTRL_STALLED:
// Commands have been successfully sent and Responses have been Received
phost->req_state = REQ_CMD_TX;
status = HSTATUS_UNSUPPORTED;
break;
default:
break;
}
}
else
{
;
}
return status;
}
/**
*******************************************************************************
** \brief sends a setup packet to the control EP of the USB device
** \param pdev : device instance
** \param buff: data buffer whose data will be sent in the control pipe to the
** control EP of the device.
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = 0u;
pdev->host.hc[hc_num].pid_type = PID_SETUP;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = 8;
host_driver_submitrequest(pdev, hc_num);
}
/**
*******************************************************************************
** \brief sends a data packet to the USB device
** \param pdev : device instance
** \param buff: data buffer whose data will be sent to the USB device
** \param length: the data length in byte that would be sent
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if ( length == 0u )
{ // For Status OUT stage, Length==0, Status Out PID = 1 always
pdev->host.hc[hc_num].out_toggle = 1;
}
// Set the Data Toggle bit
if ( pdev->host.hc[hc_num].out_toggle == 0)
{
pdev->host.hc[hc_num].pid_type = PID_DATA0;
}
else
{
pdev->host.hc[hc_num].pid_type = PID_DATA1 ;
}
host_driver_submitrequest (pdev , hc_num);
}
/**
*******************************************************************************
** \brief Receives the response data to the setup packet
** \param pdev : device instance
** \param buff: data buffer when received data.
** \param length: the length data in byte have received.
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t* buff, uint16_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)1;
pdev->host.hc[hc_num].pid_type = PID_DATA1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief sent the bulk packet to the device
** \param pdev : device instance
** \param buff: data buffer whose data will be sent
** \param length: data length in byte
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_sendbulkdata(usb_core_instance *pdev,
uint8_t *buff,
uint16_t length,
uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = 0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
// Set the Data Toggle bit
if ( pdev->host.hc[hc_num].out_toggle == 0)
{
pdev->host.hc[hc_num].pid_type = PID_DATA0;
}
else
{
pdev->host.hc[hc_num].pid_type = PID_DATA1 ;
}
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief receives bulk packet from device
** \param pdev : device instance
** \param buff: buffer to save the data received from the device
** \param length: data length in byte
** \param hc_num: host channel index
** \retval status
******************************************************************************/
void usb_host_recvbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if( pdev->host.hc[hc_num].in_toggle == (uint8_t)0)
{
pdev->host.hc[hc_num].pid_type = PID_DATA0;
}
else
{
pdev->host.hc[hc_num].pid_type = PID_DATA1;
}
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief receives the device response to the Interrupt IN token
** \param pdev : device instance
** \param buff: buffer to save the data received from the device
** \param length: data length in byte
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if(pdev->host.hc[hc_num].in_toggle == (uint8_t)0)
{
pdev->host.hc[hc_num].pid_type = PID_DATA0;
}
else
{
pdev->host.hc[hc_num].pid_type = PID_DATA1;
}
/* toggle the DATA PID */
pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1;
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief send the data on Interrupt OUT Endpoint
** \param pdev : device instance
** \param buff: data buffer whose data will be sent
** \param length: data length in byte
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_sentintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
if(pdev->host.hc[hc_num].in_toggle == (uint8_t)0)
{
pdev->host.hc[hc_num].pid_type = PID_DATA0;
}
else
{
pdev->host.hc[hc_num].pid_type = PID_DATA1;
}
pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1;
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief receives the Device Response to the Isochronous IN token
** \param pdev : device instance
** \param buff: buffer to save the data received from the device
** \param length: data length in byte
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)1;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
pdev->host.hc[hc_num].pid_type = PID_DATA0;
host_driver_submitrequest(pdev , hc_num);
}
/**
*******************************************************************************
** \brief Sends the data through Isochronous OUT Endpoint
** \param pdev : device instance
** \param buff: data buffer whose data will be sent
** \param length: data length in byte
** \param hc_num: host channel index
** \retval none
******************************************************************************/
void usb_host_sendisocdata( usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num)
{
pdev->host.hc[hc_num].is_epin = (uint8_t)0;
pdev->host.hc[hc_num].xfer_buff = buff;
pdev->host.hc[hc_num].xfer_len = length;
pdev->host.hc[hc_num].pid_type = PID_DATA0;
host_driver_submitrequest(pdev , hc_num);
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,91 @@
/*****************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_ctrltrans.h
**
** A detailed description is available at
** @link header file for the usbh_ioreq.c @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_CTRLTRANS_H__
#define __USB_HOST_CTRLTRANS_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
#include "usb_host_core.h"
#include "usb_host_stddef.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num);
extern void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num);
extern void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t* buff, uint16_t length, uint8_t hc_num);
extern void usb_host_recvbulkdata( usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num);
extern void usb_host_sendbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num);
extern void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num);
extern void usb_host_sentintdata( usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num);
extern HOST_STATUS usb_host_ctrlreq (usb_core_instance *pdev, USBH_HOST *phost, uint8_t *buff, uint16_t length);
extern void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num);
extern void usb_host_sendisocdata( usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num);
#endif /* __USB_HOST_CTRLTRANS_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,224 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_driver.c
**
** A detailed description is available at
** @link
Host Interface Layer.
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_core_driver.h"
#include "usb_host_driver.h"
#include "usb_conf.h"
#include "usb_bsp.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Initialize the driver for the host mode
** \param pdev : device instance
** \retval none
******************************************************************************/
void host_driver_init(usb_core_instance *pdev)
{
uint8_t i = 0u;
pdev->host.is_dev_connect = 0u;
for (i= 0u; i< USB_MAX_TX_FIFOS; i++)
{
pdev->host.ErrCnt[i] = 0u;
pdev->host.XferCnt[i] = 0u;
pdev->host.HC_Status[i] = HOST_CH_IDLE;
}
pdev->host.hc[0].max_packet = 8u;
hd_usb_setregaddr(pdev);
hd_usb_gintdis(pdev);
hd_usb_initusbcore(pdev);
/* force to work in host mode*/
hd_usb_modeset(pdev, HOST_MODE);
hd_usb_hostmodeinit(pdev);
hd_usb_ginten(pdev);
}
/**
*******************************************************************************
** \brief get current speed when in host mode
** \param pdev : device instance
** \retval current speed
******************************************************************************/
uint32_t host_driver_getcurrentspd (usb_core_instance *pdev)
{
USB_CORE_HPRT_TypeDef tmp_hppt;
tmp_hppt.b = *(__IO stc_bUSB_CORE_HPRT0_t*)&HD_USB_RDREG32(pdev->regs.HPRT0);
return tmp_hppt.b.prtspd;
}
/**
*******************************************************************************
** \brief issue a command to reset the port
** \param pdev : device instance
** \retval none
******************************************************************************/
void host_driver_portrst(usb_core_instance *pdev)
{
hd_usb_hprtrst(pdev);
}
/**
*******************************************************************************
** \brief get the connected status of the device
** \param pdev : device instance
** \retval 1 @connected or 0 @disconnected
**
******************************************************************************/
uint32_t host_driver_ifdevconnected(usb_core_instance *pdev)
{
return (pdev->host.is_dev_connect);
}
/**
*******************************************************************************
** \brief gets the frame number for of sof packet
** \param pdev : device instance
** \retval number of frame
******************************************************************************/
uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev)
{
return (HD_USB_RDREG32(&pdev->regs.HREGS->HFNUM) & 0xFFFFul) ;
}
/**
*******************************************************************************
** \brief gets the last xfer state
** \param pdev : device instance
** \retval HOST_CH_XFER_STATE
******************************************************************************/
HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num)
{
return pdev->host.URB_State[ch_num] ;
}
/**
*******************************************************************************
** \brief gets the xfer count
** \param pdev : device instance
** \param hc_num: channel number
** \retval number of data trandmitted in bytes
******************************************************************************/
uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num)
{
return pdev->host.XferCnt[ch_num] ;
}
/**
*******************************************************************************
** \brief gets the host channel status
** \param pdev : device instance
** \param hc_num: channel number
** \retval HOST_CH_STATUS
******************************************************************************/
HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num)
{
return pdev->host.HC_Status[ch_num] ;
}
/**
*******************************************************************************
** \brief prepare a host channel and start a transfer
** \param pdev : device instance
** \param hc_num: channel number
** \retval status
******************************************************************************/
uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num)
{
return hd_usb_inithch(pdev, hc_num);
}
/**
*******************************************************************************
** \brief prepare a host channel and start a transfer
** \param pdev : device instance
** \param hc_num: channel number
** \retval status
******************************************************************************/
uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num)
{
pdev->host.URB_State[hc_num] = HOST_CH_XFER_IDLE;
pdev->host.hc[hc_num].xfer_count = 0u ;
return hd_usb_hchtransbegin(pdev, hc_num);
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,92 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_driver.h
**
** A detailed description is available at
** @link Host layer Header file @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_DRIVER_H__
#define __USB_HOST_DRIVER_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_core_regs.h"
#include "usb_core_driver.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern void host_driver_init(usb_core_instance *pdev);
extern uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num);
extern uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num);
extern uint32_t host_driver_getcurrentspd (usb_core_instance *pdev);
extern void host_driver_portrst(usb_core_instance *pdev);
extern uint32_t host_driver_ifdevconnected(usb_core_instance *pdev);
extern uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev);
extern HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num);
extern uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num);
extern HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num);
#endif //__USB_HOST_DRIVER_H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,735 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usbd_desc.c
**
** A detailed description is available at
** @link
Host driver interrupt subroutines.
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_core_driver.h"
#include "usb_defines.h"
#include "usb_host_int.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#if defined (__CC_ARM) /*!< ARM Compiler */
#pragma O0
#elif defined (__GNUC__) /*!< GNU Compiler */
#pragma GCC optimize ("O0")
#elif defined (__TASKING__) /*!< TASKING Compiler */
#pragma optimize=0
#endif /* __CC_ARM */
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
*******************************************************************************
** \brief processes interrupt for a specific host channel which is used for OUT EP
** \param pdev : device instance
** \param chnum: channel index
** \retval none
******************************************************************************/
void hd_usb_host_chx_out_isr(usb_core_instance *pdev , uint8_t chnum)
{
USB_CORE_HCCHAR_TypeDef hcchar;
uint32_t hcintval, hcintmskval;
hcchar.b = *(__IO stc_bUSB_CORE_HCCHAR_t*)&HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCCHAR);
hcintval = HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCINT);
hcintmskval = HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCINTMSK);
hcintval = hcintval & hcintmskval;
if(hcintval & HCINT_AHBERR)
{
hd_usb_host_clrint(pdev, chnum, hc_ahberr);
hd_usb_host_int_unmskchhltd(pdev, chnum);
}
else if(hcintval & HCINT_ACK)
{
hd_usb_host_clrint(pdev, chnum, hc_ack);
}
else if(hcintval & HCINT_FRMOVRUN)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_frmovrun);
}
else if(hcintval & HCINT_XFERCOMPL)
{
pdev->host.ErrCnt[chnum] = 0u;
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_xfercompl);
pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL;
}
else if(hcintval & HCINT_STALL)
{
hd_usb_host_clrint(pdev, chnum, hc_stall);
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
pdev->host.HC_Status[chnum] = HOST_CH_STALL;
}
else if(hcintval & HCINT_NAK)
{
pdev->host.ErrCnt[chnum] = 0u;
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_nak);
pdev->host.HC_Status[chnum] = HOST_CH_NAK;
}
else if(hcintval & HCINT_XACTERR)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
pdev->host.ErrCnt[chnum] ++;
pdev->host.HC_Status[chnum] = HOST_CH_XACTERR;
hd_usb_host_clrint(pdev, chnum, hc_xacterr);
}
else if(hcintval & HCINT_NYET)
{
pdev->host.ErrCnt[chnum] = 0u;
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_nyet);
pdev->host.HC_Status[chnum] = HOST_CH_NYET;
}
else if(hcintval & HCINT_DATATGLERR)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_nak);
pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR;
hd_usb_host_clrint(pdev, chnum, hc_datatglerr);
}
else if(hcintval & HCINT_CHHLTD)
{
hd_usb_host_int_mskchhltd(pdev, chnum);
if(pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE;
if (hcchar.b.eptype == EP_TYPE_BULK)
{
pdev->host.hc[chnum].out_toggle ^= 1;
}
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_NAK)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY;
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_NYET)
{
if(pdev->host.hc[chnum].do_ping == 1)
{
hd_usb_pingtokenissue(pdev, chnum);
}
pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY;
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_STALL)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL;
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_XACTERR)
{
if (pdev->host.ErrCnt[chnum] == 3ul)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR;
pdev->host.ErrCnt[chnum] = 0ul;
}
}
else
{
;
}
hd_usb_host_clrint(pdev, chnum, hc_chhltd);
}
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
*******************************************************************************
** \brief processes interrupt for a specific host Channel which is used for IN EP
** \param pdev : device instance
** \param chnum: channel index
** \retval none
******************************************************************************/
void hd_usb_host_chx_in_isr(usb_core_instance *pdev, uint8_t chnum)
{
USB_CORE_HCCHAR_TypeDef hcchar;
USB_CORE_HCTSIZn_TypeDef hctsiz;
uint32_t u32eptypetmp = 0ul;
uint32_t hcintval, hcintmskval;
hcchar.b = *(__IO stc_bUSB_CORE_HCCHAR_t*)&HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCCHAR);
hcintval = HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCINT);
hcintmskval = HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCINTMSK);
hcintval = hcintval & hcintmskval;
if(hcintval & HCINT_AHBERR)
{
hd_usb_host_clrint(pdev, chnum, hc_ahberr);
hd_usb_host_int_unmskchhltd(pdev, chnum);
}
else if(hcintval & HCINT_ACK)
{
hd_usb_host_clrint(pdev, chnum, hc_ack);
}
else if(hcintval & HCINT_STALL)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
pdev->host.HC_Status[chnum] = HOST_CH_STALL;
hd_usb_host_clrint(pdev, chnum, hc_nak);
hd_usb_host_clrint(pdev, chnum, hc_stall);
hd_usb_hchstop(pdev, chnum);
}
else if(hcintval & HCINT_DATATGLERR)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_nak);
pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR;
hd_usb_host_clrint(pdev, chnum, hc_datatglerr);
}
else if(hcintval & HCINT_FRMOVRUN)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_frmovrun);
}
else if(hcintval & HCINT_XFERCOMPL)
{
if (pdev->basic_cfgs.dmaen == 1u)
{
hctsiz.b = *(__IO stc_bUSB_CORE_HCTSIZn_t*)&HD_USB_RDREG32(&pdev->regs.HC_REGS[chnum]->HCTSIZ);
pdev->host.XferCnt[chnum] = pdev->host.hc[chnum].xfer_len - hctsiz.b.xfersize;
}
pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL;
pdev->host.ErrCnt [chnum]= 0u;
hd_usb_host_clrint(pdev, chnum, hc_xfercompl);
switch(hcchar.b.eptype)
{
case EP_TYPE_CTRL:
case EP_TYPE_BULK:
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_nak);
pdev->host.hc[chnum].in_toggle ^= (uint8_t)1;
break;
case EP_TYPE_INTR:
hcchar.b.oddfrm = 1u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[chnum]->HCCHAR, *(uint32_t*)&hcchar.b);
pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE;
break;
case EP_TYPE_ISOC:
if(pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE;
}
break;
default:
break;
}
}
else if(hcintval & HCINT_CHHLTD)
{
hd_usb_host_int_mskchhltd(pdev, chnum);
if(pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE;
}
else if (pdev->host.HC_Status[chnum] == HOST_CH_STALL)
{
pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL;
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_XACTERR)
{
pdev->host.ErrCnt[chnum] = 0u;
pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR;
}
else if(pdev->host.HC_Status[chnum] == HOST_CH_DATATGLERR)
{
pdev->host.ErrCnt[chnum] = 0u;
pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR;
}
else if(hcchar.b.eptype == EP_TYPE_INTR)
{
pdev->host.hc[chnum].in_toggle ^= (uint8_t)1;
}
else
{
;
}
hd_usb_host_clrint(pdev, chnum, hc_chhltd);
}
else if(hcintval & HCINT_XACTERR)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
pdev->host.ErrCnt[chnum] ++;
pdev->host.HC_Status[chnum] = HOST_CH_XACTERR;
hd_usb_hchstop(pdev, chnum);
hd_usb_host_clrint(pdev, chnum, hc_xacterr);
}
else if(hcintval & HCINT_NAK)
{
u32eptypetmp = hcchar.b.eptype;
if(u32eptypetmp == EP_TYPE_INTR)
{
hd_usb_host_int_unmskchhltd(pdev, chnum);
hd_usb_hchstop(pdev, chnum);
}
else if ((u32eptypetmp == EP_TYPE_CTRL)||(u32eptypetmp == EP_TYPE_BULK))
{
hcchar.b.chen = 1u;
hcchar.b.chdis = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[chnum]->HCCHAR, *(uint32_t*)&hcchar.b);
}
else
{
;
}
pdev->host.HC_Status[chnum] = HOST_CH_NAK;
hd_usb_host_clrint(pdev, chnum, hc_nak);
}
}
/**
*******************************************************************************
** \brief this function processes the channel interrupt
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_hc_isr(usb_core_instance *pdev)
{
USB_CORE_HCCHAR_TypeDef hcchar;
uint32_t tmp_cnt = 0ul;
uint32_t haintval;
haintval = HD_USB_RDREG32(&pdev->regs.HREGS->HAINT);
for (tmp_cnt = 0ul; tmp_cnt < pdev->basic_cfgs.host_chnum ; tmp_cnt++)
{
if(haintval & ((uint32_t)1 << tmp_cnt))
{
hcchar.b = *(__IO stc_bUSB_CORE_HCCHAR_t*)&HD_USB_RDREG32(&pdev->regs.HC_REGS[tmp_cnt]->HCCHAR);
if (hcchar.b.epdir)
{
hd_usb_host_chx_in_isr(pdev, tmp_cnt);
}
else
{
hd_usb_host_chx_out_isr(pdev, tmp_cnt);
}
}
}
}
/**
*******************************************************************************
** \brief process the start-of-frame interrupt in host mode.
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_sof_isr(usb_core_instance *pdev)
{
USB_CORE_GINTSTS_TypeDef tmp_gintsts;
tmp_gintsts.d32 = 0ul;
tmp_gintsts.b.sofintr = 1u;
HD_USB_WRREG32(&pdev->regs.GREGS->GINTSTS, tmp_gintsts.d32);
}
/**
*******************************************************************************
** \brief processes disconnect interrupt
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_disconn_isr(usb_core_instance *pdev)
{
USB_CORE_GINTSTS_TypeDef gintsts;
pdev->host.is_dev_connect = 0u;
gintsts.d32 = 0ul;
gintsts.b.disconnect = 1u;
HD_USB_WRREG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
*******************************************************************************
** \brief processes non-periodic txFIFO empty interrupt.
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_nptxfifoempty_isr(usb_core_instance *pdev)
{
USB_CORE_GINTMSK_TypeDef intmsk;
USB_CORE_HNPTXSTS_TypeDef hnptxsts;
uint16_t len_words , len;
hnptxsts.b = *(__IO stc_bUSB_CORE_HNPTXSTS_t*)&HD_USB_RDREG32(&pdev->regs.GREGS->GNPTXSTS);
len_words = (uint16_t)((pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len + (uint32_t)3) / 4ul);
while ((hnptxsts.b.nptxfspcavail > len_words)&& (pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len != 0u))
{
len = (uint16_t)(hnptxsts.b.nptxfspcavail * 4ul);
if (len > pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len)
{
len = (uint16_t)pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len;
intmsk.d32 = 0ul;
intmsk.b.nptxfempty = 1u;
HD_USB_MDFREG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0ul);
}
len_words = (uint16_t)((pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len + 3ul) / 4ul);
hd_usb_wrpkt (pdev , pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_buff, (uint8_t)hnptxsts.b.nptxqtop_chnep, len);
pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_buff += len;
pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_len -= len;
pdev->host.hc[hnptxsts.b.nptxqtop_chnep].xfer_count += len;
hnptxsts.b = *(__IO stc_bUSB_CORE_HNPTXSTS_t*)&HD_USB_RDREG32(&pdev->regs.GREGS->GNPTXSTS);
}
}
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
/**
*******************************************************************************
** \brief processes periodic txFIFO empty interrupt
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_ptxfifoempty_isr(usb_core_instance *pdev)
{
USB_CORE_GINTMSK_TypeDef intmsk;
USB_CORE_HPTXSTS_TypeDef hptxsts;
uint16_t len_words, len;
hptxsts.b = *(__IO stc_bUSB_CORE_HPTXSTS_t*)&HD_USB_RDREG32(&pdev->regs.HREGS->HPTXSTS);
len_words = (uint16_t)((pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3ul) / 4ul);
while ((hptxsts.b.ptxfspcavail > len_words)&&(pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len != 0u))
{
len = (uint16_t)(hptxsts.b.ptxfspcavail * 4ul);
if (len > pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len)
{
len = (uint16_t)pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len;
intmsk.d32 = 0ul;
intmsk.b.ptxfempty = 1u;
HD_USB_MDFREG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0ul);
}
len_words = (uint16_t)((pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3ul) / 4ul);
hd_usb_wrpkt (pdev , pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff, (uint8_t)hptxsts.b.ptxqtop.chnum, len);
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff += len;
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len -= len;
pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_count += len;
hptxsts.b = *(__IO stc_bUSB_CORE_HPTXSTS_t*)&HD_USB_RDREG32(&pdev->regs.HREGS->HPTXSTS);
}
}
/**
*******************************************************************************
** \brief This function determines which interrupt conditions have occurred
** \param pdev : device instance
** \retval none
******************************************************************************/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
void hd_usb_host_port_isr(usb_core_instance *pdev)
{
USB_CORE_HPRT_TypeDef tmp_hprt;
USB_CORE_HPRT_TypeDef tmp_hprt_bk;
USB_CORE_HCFG_TypeDef hcfg;
uint32_t do_reset = 0ul;
tmp_hprt_bk.d32 = 0ul;
tmp_hprt.b = *(__IO stc_bUSB_CORE_HPRT0_t*)&HD_USB_RDREG32(pdev->regs.HPRT0);
tmp_hprt_bk.d32 = HD_USB_RDREG32(pdev->regs.HPRT0);
/* Clear the interrupt bits in GINTSTS */
tmp_hprt_bk.b.prtena = 0u;
tmp_hprt_bk.b.prtconndet = 0u;
tmp_hprt_bk.b.prtenchng = 0u;
tmp_hprt_bk.b.prtovrcurrchng = 0u;
//check if a port connect have been detected
if (tmp_hprt.b.prtconndet)
{
tmp_hprt_bk.b.prtconndet = 1u;
pdev->host.is_dev_connect = 1u;
}
//check if port enable or disable change
if (tmp_hprt.b.prtenchng)
{
tmp_hprt_bk.b.prtenchng = 1u;
if (tmp_hprt.b.prtena == 1u)
{
pdev->host.is_dev_connect = 1u;
if ((tmp_hprt.b.prtspd == PRTSPD_LOW_SPEED) ||
(tmp_hprt.b.prtspd == PRTSPD_FULL_SPEED))
{
hcfg.b = *(__IO stc_bUSB_CORE_HCFG_t*)&HD_USB_RDREG32(&pdev->regs.HREGS->HCFG);
if (tmp_hprt.b.prtspd == PRTSPD_LOW_SPEED)
{
if (hcfg.b.fslspclksel != HCFG_6_MHZ)
{
do_reset = 1u;
}
}
else
{
//1ms*(PHY clock frequency for FS/LS)-1
HD_USB_WRREG32(&pdev->regs.HREGS->HFIR, 48000ul );
if (hcfg.b.fslspclksel != HCFG_48_MHZ)
{
hd_usb_fslspclkselset(pdev, HCFG_48_MHZ);
do_reset = 1u;
}
}
}
else
{
do_reset = 1u;
}
}
}
if (tmp_hprt.b.prtovrcurrchng)
{
tmp_hprt_bk.b.prtovrcurrchng = 1u;
}
if (do_reset)
{
hd_usb_hprtrst(pdev);
}
HD_USB_WRREG32(pdev->regs.HPRT0, tmp_hprt_bk.d32);
}
/**
*******************************************************************************
** \brief processes the rxFIFO non-empty interrupt
** \param pdev : device instance
** \retval none
******************************************************************************/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
void hd_usb_host_rxflvl_isr(usb_core_instance *pdev)
{
USB_CORE_GRXFSTS_TypeDef grxsts;
USB_CORE_GINTMSK_TypeDef tmp_gintmsk;
USB_CORE_HCTSIZn_TypeDef hctsiz;
USB_CORE_HCCHAR_TypeDef hcchar;
__IO uint8_t chnum = 0u;
uint32_t count;
uint8_t u8Tmp = 0u;
uint8_t* pu8Tmp = (void *)0u;
uint8_t tmp_chnum = 0u;
uint32_t u32Tmp;
tmp_gintmsk.d32 = 0ul;
tmp_gintmsk.b.rxstsqlvl = 1u;
HD_USB_MDFREG32( &pdev->regs.GREGS->GINTMSK, tmp_gintmsk.d32, 0ul);
u32Tmp = HD_USB_RDREG32(&pdev->regs.GREGS->GRXSTSP);
grxsts.b = *(__IO stc_bUSB_CORE_GRXSTS_t*)&u32Tmp;
chnum = (uint8_t)grxsts.b.chnum;
u8Tmp = chnum;
hcchar.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[u8Tmp]->HCCHAR);
switch (grxsts.b.pktsts)
{
case GRXSTS_PKTSTS_IN:
pu8Tmp = pdev->host.hc[chnum].xfer_buff;
if ((grxsts.b.bcnt > 0u) && (pu8Tmp != (void *)0u))
{
hd_usb_rdpkt(pdev, pdev->host.hc[chnum].xfer_buff, (uint16_t)grxsts.b.bcnt);
pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt;
pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt;
count = pdev->host.hc[chnum].xfer_count;
pdev->host.XferCnt[chnum] = count;
tmp_chnum = chnum;
hctsiz.b = *(__IO stc_bUSB_CORE_HCTSIZn_t*)&HD_USB_RDREG32(&pdev->regs.HC_REGS[tmp_chnum]->HCTSIZ);
if(hctsiz.b.pktcnt > 0u)
{
hcchar.b.chen = 1u;
hcchar.b.chdis = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[chnum]->HCCHAR, hcchar.d32);
}
}
break;
case GRXSTS_PKTSTS_IN_XFER_COMP:
break;
case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
break;
case GRXSTS_PKTSTS_CH_HALTED:
break;
default:
break;
}
tmp_gintmsk.b.rxstsqlvl = 1u;
HD_USB_MDFREG32(&pdev->regs.GREGS->GINTMSK, 0ul, tmp_gintmsk.d32);
}
/**
*******************************************************************************
** \brief process the incomplete periodic transfer interrupt(incompIP)
** \param pdev : device instance
** \retval none
******************************************************************************/
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma optimize = none
#endif /* __CC_ARM */
void hd_usb_host_incomplisoout_isr(usb_core_instance *pdev)
{
USB_CORE_GINTSTS_TypeDef gintsts;
USB_CORE_HCCHAR_TypeDef hcchar;
hcchar.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[0]->HCCHAR);
hcchar.b.chen = 1u;
hcchar.b.chdis = 1u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32);
gintsts.d32 = 0ul;
gintsts.b.incomplisoout = 1u;
HD_USB_WRREG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
}
/**
*******************************************************************************
** \brief process the resume/remote wakeup detected interrupt(WkUpInt)
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_wkupint_isr(usb_core_instance *pdev)
{
USB_CORE_HPRT_TypeDef tmp_hprt;
tmp_hprt.d32 = hd_usb_rdhprt(pdev);
tmp_hprt.b.prtres = 0u;
HD_USB_WRREG32(pdev->regs.HPRT0, tmp_hprt.d32);
}
/**
*******************************************************************************
** \brief This function process all interrupt of USB in host mode
** \param pdev : device instance
** \retval none
******************************************************************************/
void hd_usb_host_isr(usb_core_instance *pdev)
{
uint32_t gintstsval;
if (hd_usb_getcurmod(pdev))
{
gintstsval = hd_usb_getcoreintr(pdev);
if(gintstsval & (((uint32_t)1)<<3))
{
hd_usb_host_sof_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<4))
{
hd_usb_host_rxflvl_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<5))
{
hd_usb_host_nptxfifoempty_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<26))
{
hd_usb_host_ptxfifoempty_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<25))
{
hd_usb_host_hc_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<24))
{
hd_usb_host_port_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<29))
{
hd_usb_host_disconn_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<21))
{
hd_usb_host_incomplisoout_isr(pdev);
}
if(gintstsval & (((uint32_t)1)<<31))
{
hd_usb_host_wkupint_isr(pdev);
}
}
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,158 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_int.h
**
** A detailed description is available at
** @link Peripheral Device Interface Layer @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_INT_H__
#define __USB_HOST_INT_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_driver.h"
#define HCINT_XFERCOMPL ((uint32_t)1)<<0
#define HCINT_CHHLTD ((uint32_t)1)<<1
#define HCINT_AHBERR ((uint32_t)1)<<2
#define HCINT_STALL ((uint32_t)1)<<3
#define HCINT_NAK ((uint32_t)1)<<4
#define HCINT_ACK ((uint32_t)1)<<5
#define HCINT_NYET ((uint32_t)1)<<6
#define HCINT_XACTERR ((uint32_t)1)<<7
#define HCINT_FRMOVRUN ((uint32_t)1)<<9
#define HCINT_DATATGLERR ((uint32_t)1)<<10
/**
*******************************************************************************
** \brief clear the interrupt flag bit
** \param pdev : device instance
** \param ch_num: the channel index
** \param intbit: the interrupt bit of the register HCINTn
** \retval none
******************************************************************************/
static __INLINE void hd_usb_host_clrint(usb_core_instance *pdev, uint32_t ch_num, uint32_t intbit)
{
USB_CORE_HCINTn_TypeDef tmp_hcintx;
*(uint32_t*)&tmp_hcintx.b = intbit;
HD_USB_WRREG32(&(pdev->regs.HC_REGS[ch_num]->HCINT), tmp_hcintx.d32);
}
/**
*******************************************************************************
** \brief mask the interrupt of ChHltd
** \param pdev : device instance
** \param ch_num: channel index of the host application
** \retval none
******************************************************************************/
static __INLINE void hd_usb_host_int_mskchhltd(usb_core_instance *pdev, uint32_t ch_num)
{
USB_CORE_HCINTMSK_TypeDef tmp_hcintmsk;
tmp_hcintmsk.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK);
tmp_hcintmsk.b.chhltd = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK, tmp_hcintmsk.d32);
}
/**
*******************************************************************************
** \brief unmask the interrupt of ChHltd
** \param pdev : device instance
** \param ch_num: channel index of the host application
** \retval none
******************************************************************************/
static __INLINE void hd_usb_host_int_unmskchhltd(usb_core_instance *pdev, uint32_t ch_num)
{
USB_CORE_HCINTMSK_TypeDef tmp_hcintmsk;
tmp_hcintmsk.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK);
tmp_hcintmsk.b.chhltd = 1u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK, tmp_hcintmsk.d32);
}
/**
*******************************************************************************
** \brief mask the interrupt of ACK
** \param pdev : device instance
** \param ch_num: channel index of the host application
** \retval none
******************************************************************************/
static __INLINE void hd_usb_host_int_mskack(usb_core_instance *pdev, uint32_t ch_num)
{
USB_CORE_HCINTMSK_TypeDef tmp_hcintmsk;
tmp_hcintmsk.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK);
tmp_hcintmsk.b.ack = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK, tmp_hcintmsk.d32);
}
/**
*******************************************************************************
** \brief unmask the interrupt of ACK
** \param pdev : device instance
** \param ch_num: channel index of the host application
** \retval none
******************************************************************************/
static __INLINE void hd_usb_host_int_unmskack(usb_core_instance *pdev, uint32_t ch_num)
{
USB_CORE_HCINTMSK_TypeDef tmp_hcintmsk;
tmp_hcintmsk.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK);
tmp_hcintmsk.b.ack = 1u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[ch_num]->HCINTMSK, tmp_hcintmsk.d32);
}
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern void hd_usb_host_isr(usb_core_instance *pdev);
#endif //__USB_HOST_INT_H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,306 @@
/*****************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_stddef.h
**
** A detailed description is available at
** @link Definitions used in the USB host library @endlink
**
** - 2018-12-26 1.0 wangmin First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_STDDEF_H__
#define __USB_HOST_STDDEF_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "stdint.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/* This Union is copied from usb_core.h */
typedef union
{
uint16_t w;
struct BW
{
uint8_t msb;
uint8_t lsb;
}
bw;
}uint16_t_uint8_t;
/* standard setup packet defination */
typedef union
{
uint8_t d8[8];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
} usb_setup_typedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
} USB_HOST_DescHeader_TypeDef;
/* Standard Device Descriptor */
typedef struct
{
uint8_t bLength; //Size of this descriptor in bytes
uint8_t bDescriptorType; //Device descriptor type
uint16_t bcdUSB; //USB Specification Release Numbrer in Binary-Coded Decimal(i.e.,2.10 is 210H)
uint8_t bDeviceClass; //Class code(assigned by the USB-IF)
uint8_t bDeviceSubClass; //Subclass code(assigned by the USB-IF) this code is qualified by the value of the bDeviceClass field.
uint8_t bDeviceProtocol; //Protocol code(assigned by the USB-IF), this code is qualified by the value of the bDeviceClass and the bDeviceSubClass fields.
uint8_t bMaxPacketSize0; //Maximum packet size for EP0
uint16_t idVendor; // Vendor ID (assigned by the USB-IF)
uint16_t idProduct; // Product ID (assigned by manufacturer)
uint16_t bcdDevice; // Device Release Number in binary-coded decimal
uint8_t iManufacturer; // Index of string descriptor describing manufacturer
uint8_t iProduct; // Index of string descriptor describing product
uint8_t iSerialNumber; // Index of string descriptor describing the device's serial number
uint8_t bNumConfigurations;// Number of possible configurations
}usb_host_devdesc_typedef;
/* Standard Configuration Descriptor */
typedef struct
{
uint8_t bLength; //Size of this descriptor in bytes
uint8_t bDescriptorType; //CONFIGURATION descriptor type
uint16_t wTotalLength; // Total length of data returned for this configuration
uint8_t bNumInterfaces; // Number of interfaces supported by this configuration
uint8_t bConfigurationValue; // Value to use as an argument to the SetConfiguration() request to select this configuration
uint8_t iConfiguration; // Index of string descriptor describing this configuration
uint8_t bmAttributes; // Configuration characteristics: D7:Reserved(set to one) D6:Self-powered D5:Remote Wakeup D4..0 Reserved(set to zero)
uint8_t bMaxPower; // Maximum power consumption of the device from the bus in this specific configuration when the device is fully operational
}usb_host_cfgdesc_typedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
uint8_t bCountryCode; /* specifies the transfer type. */
uint8_t bNumDescriptors; /* specifies the transfer type. */
uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
}USB_HOST_HDIDesc_TypeDef;
/* Standard Interface Descriptor */
typedef struct
{
uint8_t bLength; //Size of this descriptor in bytes
uint8_t bDescriptorType; //INTERFACE Descriptor Type
uint8_t bInterfaceNumber; //Number of this interface
uint8_t bAlternateSetting; // Value used to select this alternate setting for the interface identifiled in the prior field
uint8_t bNumEndpoints; // Number of Endpoints used by this interface
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF)
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF)
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB)
uint8_t iInterface; // Index of string descriptor describing this interface
}usb_host_itfdesc_typedef;
/* Standard Endpoint Descriptor */
typedef struct
{
uint8_t bLength; // Size of this descriptor in bytes
uint8_t bDescriptorType; // ENDPOINT descriptor type
uint8_t bEndpointAddress; // The address of the endpoint on the device described by this descriptor
uint8_t bmAttributes; // refer to the related standard of USB 2.0
uint16_t wMaxPacketSize; // Maximum Packet Size this endpoint is capable of sending or receiving when this configuration is selected
uint8_t bInterval; // Interval for servicing the endpoint for data transfers
}USB_HOST_EPDesc_TypeDef;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#ifndef USBH_NULL
#define USBH_NULL ((void *)0u)
#endif
#ifndef FALSE
#define FALSE 0u
#endif
#ifndef TRUE
#define TRUE 1u
#endif
//Get a 16bits data from buffer in little end mode.
#define SMALL_END(addr) (((uint16_t)(*((uint8_t *)(addr)))) + (((uint16_t)(*(((uint8_t *)(addr)) + 1u))) << 8u))
#define USB_LEN_CFG_DESC (0x09u)
/* bmRequestType
D7: Data transfer direction
0 = Host-to-device
1 = Device-to-host
*/
#define USB_REQ_DIR_MASK (0x80u)
#define USB_H2D (0x00u)
#define USB_D2H (0x80u)
/* bmRequestType
D6...5: Type
0 = Standard
1 = Class
2 = Vendor
3 = Reserved
*/
#define USB_REQ_TYPE_STANDARD (0x00u)
#define USB_REQ_TYPE_CLASS (0x20u)
#define USB_REQ_TYPE_VENDOR (0x40u)
#define USB_REQ_TYPE_RESERVED (0x60u)
/* bmRequestType
D4...0: Recipient
0 = Device
1 = Interface
2 = Endpoint
3 = Other
4...31 = Reserved
*/
#define USB_REQ_RECIPIENT_DEVICE (0x00u)
#define USB_REQ_RECIPIENT_INTERFACE (0x01u)
#define USB_REQ_RECIPIENT_ENDPOINT (0x02u)
#define USB_REQ_RECIPIENT_OTHER (0x03u)
/* Table 9-4. Standard Request Codes [USB Specification] */
/* bRequest Value */
#define USB_REQ_GET_STATUS (0x00u)
#define USB_REQ_CLEAR_FEATURE (0x01u)
#define USB_REQ_SET_FEATURE (0x03u)
#define USB_REQ_SET_ADDRESS (0x05u)
#define USB_REQ_GET_DESCRIPTOR (0x06u)
#define USB_REQ_SET_DESCRIPTOR (0x07u)
#define USB_REQ_GET_CONFIGURATION (0x08u)
#define USB_REQ_SET_CONFIGURATION (0x09u)
#define USB_REQ_GET_INTERFACE (0x0Au)
#define USB_REQ_SET_INTERFACE (0x0Bu)
#define USB_REQ_SYNCH_FRAME (0x0Cu)
/* Table 9-5. Descriptor Types [USB Specification] */
/* Descriptor Types Value */
#define USB_DESC_TYPE_DEVICE (1u)
#define USB_DESC_TYPE_CONFIGURATION (2u)
#define USB_DESC_TYPE_STRING (3u)
#define USB_DESC_TYPE_INTERFACE (4u)
#define USB_DESC_TYPE_ENDPOINT (5u)
#define USB_DESC_TYPE_DEVICE_QUALIFIER (6u)
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION (7u)
#define USB_DESC_TYPE_INTERFACE_POWER (8u)
#define USB_DESC_TYPE_HID (0x21u)
#define USB_DESC_TYPE_HID_REPORT (0x22u)
#define USB_DEVICE_DESC_SIZE (18u)
#define USB_CONFIGURATION_DESC_SIZE (9u)
#define USB_HID_DESC_SIZE (9u)
#define USB_INTERFACE_DESC_SIZE (9u)
#define USB_ENDPOINT_DESC_SIZE (7u)
/* Descriptor Type and Descriptor Index */
/* Use the following values when calling the function usb_host_getdesc */
#define USB_DESC_DEVICE (((uint16_t)USB_DESC_TYPE_DEVICE << 8u) & 0xFF00u)
#define USB_DESC_CONFIGURATION (((uint16_t)USB_DESC_TYPE_CONFIGURATION << 8u) & 0xFF00u)
#define USB_DESC_STRING (((uint16_t)USB_DESC_TYPE_STRING << 8u) & 0xFF00u)
#define USB_DESC_INTERFACE (((uint16_t)USB_DESC_TYPE_INTERFACE << 8u) & 0xFF00u)
#define USB_DESC_ENDPOINT (((uint16_t)USB_DESC_TYPE_INTERFACE << 8u) & 0xFF00u)
#define USB_DESC_DEVICE_QUALIFIER (((uint16_t)USB_DESC_TYPE_DEVICE_QUALIFIER << 8u) & 0xFF00u)
#define USB_DESC_OTHER_SPEED_CONFIGURATION (((uint16_t)USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8u) & 0xFF00u)
#define USB_DESC_INTERFACE_POWER (((uint16_t)USB_DESC_TYPE_INTERFACE_POWER << 8u) & 0xFF00u)
#define USB_DESC_HID_REPORT (((uint16_t)USB_DESC_TYPE_HID_REPORT << 8u) & 0xFF00u)
#define USB_DESC_HID (((uint16_t)USB_DESC_TYPE_HID << 8u) & 0xFF00u)
#define USB_EP_TYPE_CTRL (0x00u)
#define USB_EP_TYPE_ISOC (0x01u)
#define USB_EP_TYPE_BULK (0x02u)
#define USB_EP_TYPE_INTR (0x03u)
#define USB_EP_DIR_OUT (0x00u)
#define USB_EP_DIR_IN (0x80u)
#define USB_EP_DIR_MSK (0x80u)
/* supported classes */
#define USB_MSC_CLASS (0x08u)
#define USB_HID_CLASS (0x03u)
/* Interface Descriptor field values for HID Boot Protocol */
#define HID_BOOT_CODE (0x01u)
#define HID_KEYBRD_BOOT_CODE (0x01u)
#define HID_MOUSE_BOOT_CODE (0x02u)
/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec
Standard request with no data stage timeout : 50ms */
#define DATA_STAGE_TIMEOUT (5000u)
#define NODATA_STAGE_TIMEOUT (50u)
#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
+ USB_INTERFACE_DESC_SIZE\
+ (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
ConfigurationDescriptor.wTotalLength)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
#endif /* __USB_HOST_STDDEF_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,544 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_stdreq.c
**
** A detailed description is available at
** @link
This file implements the standard requests for device enumeration
@endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_host_ctrltrans.h"
#include "usb_host_stdreq.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
//#ifdef USB_INTERNAL_DMA_ENABLED
// #if defined ( __ICCARM__ ) /*!< IAR Compiler */
// #pragma data_alignment=4
// #endif
//#endif /* USB_INTERNAL_DMA_ENABLED */
/*******************************************************************************
* Local function prototypes declared in the last part.
******************************************************************************/
void usb_host_parsedevdesc (usb_host_devdesc_typedef* , uint8_t *buf, uint16_t length);
void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc,
usb_host_itfdesc_typedef *itf_desc,
USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
uint8_t *buf,
uint16_t length);
void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf);
void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf);
void usb_host_parsestringdesc(uint8_t* psrc, uint8_t* pdest, uint16_t length);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief issue a command descriptor from the connected device. parses the
** descriptor and updates the status once the response has been received.
** \param pdev : device instance
** \param phost: host state set
** \param req_type: type of the descriptor
** \param value_idx: wValue of setup for the request to get Descriptr
** \param buff: buffer to save the the descriptor
** \param length: the length of the description.
** \retval status
******************************************************************************/
HOST_STATUS usb_host_getdesc(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t req_type,
uint16_t value_idx,
uint8_t *buff,
uint16_t length )
{
phost->ctrlparam.setup.b.bmRequestType = USB_D2H | req_type;
phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
phost->ctrlparam.setup.b.wValue.w = value_idx;
if ((value_idx & 0xff00u) == USB_DESC_STRING)
{
phost->ctrlparam.setup.b.wIndex.w = 0x0409u;
}
else
{
phost->ctrlparam.setup.b.wIndex.w = 0u;
}
phost->ctrlparam.setup.b.wLength.w = length;
return usb_host_ctrlreq(pdev, phost, buff, length );
}
/**
*******************************************************************************
** \brief Issue command to the device to get the device discription. it parses
** the device descriptor and updates the status once getting the device
** description.
** \param pdev : device instance
** \param phost: host state set.
** \param length: the length of the description.
** \retval status
******************************************************************************/
HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t length)
{
HOST_STATUS status;
status = usb_host_getdesc(pdev,
phost,
(uint8_t)(USB_REQ_RECIPIENT_DEVICE |USB_REQ_TYPE_STANDARD),
USB_DESC_DEVICE,
pdev->host.Rx_Buffer,
(uint16_t)length);
if(status == HSTATUS_OK)
{
/* Commands successfully sent and Response Received */
usb_host_parsedevdesc(&phost->device_prop.devdesc, pdev->host.Rx_Buffer, (uint16_t)length);
}
return status;
}
/**
*******************************************************************************
** \brief Issue a command to get the configuration description from the device
** connected, parse the configuration descriptor and update the
** status once the response has been received.
** \param pdev : device instance
** \param phost: host state set.
** \param length: the length of the description.
** \retval status
******************************************************************************/
HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev,
USBH_HOST *phost,
uint16_t length)
{
HOST_STATUS status;
status = usb_host_getdesc(pdev,
phost,
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
USB_DESC_CONFIGURATION,
pdev->host.Rx_Buffer,
length);
if(status == HSTATUS_OK)
{
usb_host_parsecfgdesc(&phost->device_prop.devcfgdesc,
phost->device_prop.devitfdesc,
phost->device_prop.devepdesc,
pdev->host.Rx_Buffer,
length);
}
return status;
}
/**
*******************************************************************************
** \brief Issues string Descriptor command to the device. Once the response
** received, it parses the string descriptor and updates the status.
** \param pdev : device instance
** \param phost: host state set
** \param string_index: the index for the string
** \param buff: buffer to save the the string descriptor
** \param length: the length of the description.
** \retval status
******************************************************************************/
HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t string_index,
uint8_t *buff,
uint16_t length)
{
HOST_STATUS status;
status = usb_host_getdesc(pdev,
phost,
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
USB_DESC_STRING | string_index,
pdev->host.Rx_Buffer,
length);
if(status == HSTATUS_OK)
{
usb_host_parsestringdesc(pdev->host.Rx_Buffer,buff, length);
}
return status;
}
/**
*******************************************************************************
** \brief issue a command to set the address for the device that have connected.
** \param pdev : device instance
** \param phost: host state set
** \param DeviceAddress: Device address which would be set to the conected device
** \retval status
******************************************************************************/
HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t DeviceAddress)
{
/*
Refer to table9-3 of 9.4
*/
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_ADDRESS;
phost->ctrlparam.setup.b.wValue.w = (uint16_t)DeviceAddress;
phost->ctrlparam.setup.b.wIndex.w = 0u;
phost->ctrlparam.setup.b.wLength.w = 0u;
return usb_host_ctrlreq(pdev, phost, 0u , 0u );
}
/**
*******************************************************************************
** \brief issue a command to set the configuration to the connected device.
** \param pdev : device instance
** \param phost: host state set
** \param cfg_idx: value for the configuration setup
** \retval status
******************************************************************************/
HOST_STATUS usb_host_setconfig(usb_core_instance *pdev,
USBH_HOST *phost,
uint16_t cfg_idx)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD;
phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
phost->ctrlparam.setup.b.wValue.w = cfg_idx;
phost->ctrlparam.setup.b.wIndex.w = 0u;
phost->ctrlparam.setup.b.wLength.w = 0u;
return usb_host_ctrlreq(pdev, phost, 0u , 0u );
}
/**
*******************************************************************************
** \brief issue a command to set the Interface value to the connected device
** \param pdev : device instance
** \param phost: host state set
** \param ep_num: the index of the endpoint
** \param altSetting: the value for the setup of set interface
** \retval status
******************************************************************************/
HOST_STATUS usb_host_setintf(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t ep_num,
uint8_t altSetting)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD;
phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_INTERFACE;
phost->ctrlparam.setup.b.wValue.w = altSetting;
phost->ctrlparam.setup.b.wIndex.w = ep_num;
phost->ctrlparam.setup.b.wLength.w = 0u;
return usb_host_ctrlreq(pdev, phost, 0u , 0u );
}
/**
*******************************************************************************
** \brief issue a comman to clear or disable a specific feature in the device.
** \param pdev : device instance
** \param phost: host state set
** \param ep_num: index of the endpoint
** \param hc_num: host channel index
** \retval status
******************************************************************************/
HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t ep_num,
uint8_t hc_num)
{
phost->ctrlparam.setup.b.bmRequestType = USB_H2D |
USB_REQ_RECIPIENT_ENDPOINT |
USB_REQ_TYPE_STANDARD;
phost->ctrlparam.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
phost->ctrlparam.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
phost->ctrlparam.setup.b.wIndex.w = ep_num;
phost->ctrlparam.setup.b.wLength.w = 0u;
if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H)
{
pdev->host.hc[hc_num].in_toggle = 0u;
}
else
{
pdev->host.hc[hc_num].out_toggle = 0u;
}
return usb_host_ctrlreq(pdev, phost, 0u , 0u );
}
/**
*******************************************************************************
** \brief parse the data frame of device descriptor
** \param dev_desc: the structure of the device descriptor
** \param buf: buffer where the source descriptor is save
** \param length: Length of the descriptor in byte
** \retval none
******************************************************************************/
void usb_host_parsedevdesc(usb_host_devdesc_typedef *dev_desc,
uint8_t *buf,
uint16_t length)
{
dev_desc->bLength = *(uint8_t *) (buf + 0u);
dev_desc->bDescriptorType = *(uint8_t *) (buf + 1u);
dev_desc->bcdUSB = SMALL_END(buf + 2u);
dev_desc->bDeviceClass = *(uint8_t *) (buf + 4u);
dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5u);
dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6u);
dev_desc->bMaxPacketSize0 = *(uint8_t *) (buf + 7u);
if (length > (uint16_t)8)
{
dev_desc->idVendor = SMALL_END(buf + 8u);
dev_desc->idProduct = SMALL_END(buf + 10u);
dev_desc->bcdDevice = SMALL_END(buf + 12u);
dev_desc->iManufacturer = *(uint8_t *) (buf + 14u);
dev_desc->iProduct = *(uint8_t *) (buf + 15u);
dev_desc->iSerialNumber = *(uint8_t *) (buf + 16u);
dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17u);
}
}
/**
*******************************************************************************
** \brief This function Parses the configuration descriptor from the received buffer
** \param cfg_desc: the structure of configuration descriptor
** \param itf_desc: the structure of interface descriptor
** \param ep_desc: the structure of endpoint descriptor
** \param buf: buffer where the source descriptor is save
** \param length: Length of the descriptor in byte
** \retval none
******************************************************************************/
void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc,
usb_host_itfdesc_typedef *itf_desc,
USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
uint8_t *buf,
uint16_t length)
{
usb_host_itfdesc_typedef *pif ;
usb_host_itfdesc_typedef temp_pif ;
USB_HOST_EPDesc_TypeDef *pep;
USB_HOST_DescHeader_TypeDef *pdesc = (USB_HOST_DescHeader_TypeDef *)buf;
uint16_t ptr;
int8_t if_ix = (int8_t)0;
int8_t ep_ix = (int8_t)0;
static uint16_t prev_ep_size = 0u;
static uint8_t prev_itf = 0u;
pdesc = (USB_HOST_DescHeader_TypeDef *)buf;
// Parse the configuration descriptor
cfg_desc->bLength = *(uint8_t *) (buf + 0u);
cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1u);
cfg_desc->wTotalLength = SMALL_END(buf + 2u);
cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4u);
cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5u);
cfg_desc->iConfiguration = *(uint8_t *) (buf + 6u);
cfg_desc->bmAttributes = *(uint8_t *) (buf + 7u);
cfg_desc->bMaxPower = *(uint8_t *) (buf + 8u);
if (length > USB_CONFIGURATION_DESC_SIZE)
{
ptr = USB_LEN_CFG_DESC;
if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES)
{
pif = (usb_host_itfdesc_typedef *)0u;
while (ptr < cfg_desc->wTotalLength )
{
pdesc = usb_host_getnextdesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
{
if_ix = (int8_t)*(((uint8_t *)pdesc ) + 2u);
pif = &itf_desc[if_ix];
if((*((uint8_t *)pdesc + 3u)) < 3u)
{
usb_host_parseitfdesc(&temp_pif, (uint8_t *)pdesc);
ep_ix = (int8_t)0;
// Parse Ep descriptors relative to the current interface
if(temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS)
{
while (ep_ix < (int8_t)temp_pif.bNumEndpoints)
{
pdesc = usb_host_getnextdesc((void* )pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
{
pep = &ep_desc[if_ix][ep_ix];
if(prev_itf != (uint8_t)if_ix)
{
prev_itf = (uint8_t)if_ix;
usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif);
}
else
{
if(prev_ep_size > SMALL_END((uint8_t *)pdesc + 4u))
{
break;
}
else
{
usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif);
}
}
usb_host_parseepdesc(pep, (uint8_t *)pdesc);
prev_ep_size = SMALL_END((uint8_t *)pdesc + 4u);
ep_ix++;
}
}
}
}
}
}
}
prev_ep_size = 0u;
prev_itf = 0u;
}
}
/**
*******************************************************************************
** \brief This function parses the interface descriptor from the received buffer.
** \param if_descriptor : structure of interface descriptor
** \param buf: buffer where the source descriptor is save
** \retval none
******************************************************************************/
void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf)
{
if_descriptor->bLength = *(uint8_t *) (buf + 0u);
if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1u);
if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2u);
if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3u);
if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4u);
if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5u);
if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6u);
if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7u);
if_descriptor->iInterface = *(uint8_t *) (buf + 8u);
}
/**
*******************************************************************************
** \brief This function parses the endpoint descriptor from the received buffer.
** \param ep_descriptor: the structure of endpoint descriptor.
** \param buf: buffer where the source descriptor is save
** \retval none
******************************************************************************/
void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf)
{
ep_descriptor->bLength = *(uint8_t *) (buf + 0u);
ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1u);
ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2u);
ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3u);
ep_descriptor->wMaxPacketSize = SMALL_END(buf + 4u);
ep_descriptor->bInterval = *(uint8_t *) (buf + 6u);
}
/**
*******************************************************************************
** \brief This function parses the string descriptor from the received buffer.
** \param psrc: source data
** \param pdest: destination data
** \param length: Length of the descriptor in byte
** \retval none
******************************************************************************/
void usb_host_parsestringdesc(uint8_t* psrc, uint8_t* pdest, uint16_t length)
{
uint16_t strlength;
uint16_t tmp_idx;
/*
The describ of String Desctipor refers to 9.6.8
psrc[0] = bLength bLength = N+2
psrc[1] = bDescriptorType STRING Descriptor Type
...
*/
if ( psrc[1] == USB_DESC_TYPE_STRING)
{
strlength = (( ((uint16_t)psrc[0])-2u) <= length) ? (((uint16_t)psrc[0])-2u) : length;
psrc += 2u;
for (tmp_idx = 0u; tmp_idx < strlength; tmp_idx+=2u )
{
*pdest = psrc[tmp_idx];
pdest++;
}
*pdest = 0u;
}
}
/**
*******************************************************************************
** \brief This function gets the header of next descriptor.
** \param buf: buffer where the configuration descriptor is contained.
** \param ptr: data popinter inside the cfg descriptor
** \retval header of next descriptor
******************************************************************************/
USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr)
{
USB_HOST_DescHeader_TypeDef *pnext;
*ptr += ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength;
pnext = (USB_HOST_DescHeader_TypeDef *)((uint8_t *)pbuf + ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength);
return(pnext);
}
/*******************************************************************************
* EOF
******************************************************************************/

View File

@@ -0,0 +1,122 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_host_stdreq.h
**
** A detailed description is available at
** @link Header file for usbh_stdreq.c @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_HOST_STDREQ_H__
#define __USB_HOST_STDREQ_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
#include "usb_host_driver.h"
#include "usb_host_core.h"
#include "usb_host_stddef.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
*******************************************************************************
** \brief USBH_STDREQ_Exported_Defines
**
******************************************************************************/
/*Standard Feature Selector for clear feature command*/
#define FEATURE_SELECTOR_ENDPOINT (0x00u)
#define FEATURE_SELECTOR_DEVICE (0x01u)
#define INTERFACE_DESC_TYPE (0x04u)
#define ENDPOINT_DESC_TYPE (0x05u)
#define INTERFACE_DESC_SIZE (0x09u)
#define USBH_HID_CLASS (0x03u)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
extern HOST_STATUS usb_host_getdesc(usb_core_instance *pdev,
USBH_HOST *phost,
uint8_t req_type,
uint16_t value_idx,
uint8_t *buff,
uint16_t length );
extern HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev, USBH_HOST *phost, uint8_t length);
extern HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev, USBH_HOST *phost, uint8_t string_index, uint8_t *buff, uint16_t length);
extern HOST_STATUS usb_host_setconfig(usb_core_instance *pdev, USBH_HOST *phost, uint16_t cfg_idx);
extern HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length);
extern HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev, USBH_HOST *phost, uint8_t DeviceAddress);
extern HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t hc_num);
extern HOST_STATUS usb_host_setintf(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t altSetting);
extern USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr);
#endif /* __USB_HOST_STDREQ_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,81 @@
/*****************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file USBH_conf.h
**
** A detailed description is available at
** @link General low level driver configuration @endlink
**
** - 2018-12-26 1.0 wangmin First version for USB demo.
**
******************************************************************************/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
/*******************************************************************************
* Include files
******************************************************************************/
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define USBH_MAX_NUM_ENDPOINTS (2u)
#define USBH_MAX_NUM_INTERFACES (2u)
#define USBH_MSC_MPS_SIZE (0x40u)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
#endif //__USBH_CONF__H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@@ -0,0 +1,86 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usbh_conf_template.h
**
** A detailed description is available at
** @link General USB Host library configuration @endlink
**
** - 2018-12-26 1.0 wangmin First version for USB demo.
**
******************************************************************************/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
/*******************************************************************************
* Include files
******************************************************************************/
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define USBH_MAX_NUM_ENDPOINTS (2u)
#define USBH_MAX_NUM_INTERFACES (2u)
#ifdef USE_USB_OTG_FS
#define USBH_MSC_MPS_SIZE (0x40)
#else
#define USBH_MSC_MPS_SIZE (0x200)
#endif
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
#endif //__USBH_CONF__H__
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,650 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_core_driver.h
**
**
** @link Header of the Core Layer Driver @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_CORE_DRIVER_H__
#define __USB_CORE_DRIVER_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
#include "usb_core_regs.h"
#include "usb_defines.h"
#include "hc32_common.h"
/*******************************************************************************
* GLOBAL #define
******************************************************************************/
#define USB_EP0_IDLE (0u)
#define USB_EP0_SETUP (1u)
#define USB_EP0_DATA_IN (2u)
#define USB_EP0_DATA_OUT (3u)
#define USB_EP0_STATUS_IN (4u)
#define USB_EP0_STATUS_OUT (5u)
#define USB_EP0_STALL (6u)
#define USB_EP_TX_DIS (0x0000u)
#define USB_EP_TX_STALL (0x0010u)
#define USB_EP_TX_NAK (0x0020u)
#define USB_EP_TX_VALID (0x0030u)
#define USB_EP_RX_DIS (0x0000u)
#define USB_EP_RX_STALL (0x1000u)
#define USB_EP_RX_NAK (0x2000u)
#define USB_EP_RX_VALID (0x3000u)
#define MAX_DATA_LENGTH (0x200u)
/*******************************************************************************
* typedef
******************************************************************************/
#define HD_USB_OK 0u
#define HD_USB_ERROR 1u
//status of the host channel
typedef enum {
HOST_CH_IDLE = 0u,
HOST_CH_XFERCOMPL,
HOST_CH_CHHLTD,
HOST_CH_NAK,
HOST_CH_NYET,
HOST_CH_STALL,
HOST_CH_XACTERR,
HOST_CH_BBLERR,
HOST_CH_DATATGLERR,
HOST_CH_AHBERR,
HOST_CH_FRMOVRUN,
HOST_CH_BNAINTR,
HOST_CH_XCS_XACT_ERR,
HOST_CH_DESC_LST_ROLLINTR
}HOST_CH_STATUS;
typedef enum {
HOST_CH_XFER_IDLE = 0u,
HOST_CH_XFER_DONE,
HOST_CH_XFER_UNREADY,
HOST_CH_XFER_ERROR,
HOST_CH_XFER_STALL
}HOST_CH_XFER_STATE;
typedef enum {
CTRL_START = 0u,
CTRL_XFRC,
CTRL_HALTED,
CTRL_NAK,
CTRL_STALL,
CTRL_XACTERR,
CTRL_BBLERR,
CTRL_DATATGLERR,
CTRL_FAIL
}CTRL_HANDLE_STATUS;
typedef struct
{
uint8_t dev_addr;
uint8_t ep_idx;
uint8_t is_epin;
uint8_t ch_speed;
uint8_t do_ping;
uint8_t ep_type;
uint16_t max_packet;
uint8_t pid_type;
uint8_t in_toggle;
uint8_t out_toggle;
/* transaction level variables*/
uint32_t dma_addr;
uint32_t xfer_len;
uint32_t xfer_count;
uint8_t *xfer_buff;
}USB_HOST_CH;
typedef struct
{
uint8_t epidx;
uint8_t ep_dir;
uint8_t trans_type;
uint8_t ep_stall;
uint8_t data_pid_start;
uint8_t datax_pid;
uint16_t tx_fifo_num;
uint32_t maxpacket;
/* Transfer level variables */
uint32_t rem_data_len;
uint32_t total_data_len;
uint32_t ctl_data_len;
/* transaction level variables*/
uint32_t dma_addr;
uint32_t xfer_len;
uint32_t xfer_count;
uint8_t *xfer_buff;
}USBD_EP;
typedef struct
{
uint8_t host_chnum;
uint8_t dev_epnum;
uint8_t dmaen;
uint8_t low_power;
} USB_CORE_BASIC_CFGS;
typedef struct
{
uint8_t bmRequest;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USB_SETUP_REQ;
typedef struct
{
uint8_t *(*get_dev_desc)(uint16_t *length);
uint8_t *(*get_dev_langiddesc)(uint16_t *length);
uint8_t *(*get_dev_manufacturerstr)(uint16_t *length);
uint8_t *(*get_dev_productstr)(uint16_t *length);
uint8_t *(*get_dev_serialstr)(uint16_t *length);
uint8_t *(*get_dev_configstr)(uint16_t *length);
uint8_t *(*get_dev_interfacestr)(uint16_t *length);
} usb_dev_desc_func;
typedef struct
{
uint8_t (*class_init) (void *pdev, uint8_t cfgidx);
uint8_t (*class_deinit) (void *pdev, uint8_t cfgidx);
/* Processing for Control Endpoints*/
uint8_t (*ep0_setup) (void *pdev, USB_SETUP_REQ *req);
uint8_t (*ep0_datain) (void *pdev);
uint8_t (*ep0_dataout) (void *pdev);
uint8_t *(*class_getconfigdesc) (uint16_t *length);
/* data processing for the class in other endpoints except control endpoint*/
uint8_t (*class_datain) (void *pdev, uint8_t epnum);
uint8_t (*class_dataout) (void *pdev, uint8_t epnum);
uint8_t (*class_sof) (void *pdev);
uint8_t (*class_syn_in_incomplt) (void *pdev);
uint8_t (*class_syn_out_incomplt) (void *pdev);
} usb_dev_class_func;
typedef struct
{
void (*user_init)(void);
void (*user_devrst)(void);
void (*user_devconfig)(void);
void (*user_devsusp)(void);
void (*user_devresume)(void);
void (*user_devconn)(void);
void (*user_devdisconn)(void);
}usb_dev_user_func;
typedef struct
{
uint8_t device_config;
uint8_t device_address;
uint8_t device_state;
uint8_t device_old_status;
uint8_t device_cur_status;
uint8_t connection_status;
uint8_t device_remote_wakeup;
uint8_t test_mode;
USBD_EP in_ep[USB_MAX_TX_FIFOS];
USBD_EP out_ep[USB_MAX_TX_FIFOS];
uint8_t setup_pkt_buf[24];
usb_dev_class_func *class_callback;
usb_dev_user_func *user_callback;
usb_dev_desc_func *desc_callback;
}USB_DEV_PARAM;
typedef struct
{
uint16_t channel[USB_MAX_TX_FIFOS];
USB_HOST_CH hc[USB_MAX_TX_FIFOS];
__IO uint32_t is_dev_connect;
uint8_t Rx_Buffer[MAX_DATA_LENGTH];
__IO uint32_t ErrCnt[USB_MAX_TX_FIFOS];
__IO uint32_t XferCnt[USB_MAX_TX_FIFOS];
__IO HOST_CH_STATUS HC_Status[USB_MAX_TX_FIFOS];
__IO HOST_CH_XFER_STATE URB_State[USB_MAX_TX_FIFOS];
}USB_HOST_PARAM;
typedef struct
{
USB_CORE_BASIC_CFGS basic_cfgs;
HD_USB_REGS regs;
#ifdef USE_DEVICE_MODE
USB_DEV_PARAM dev;
#endif
#ifdef USE_HOST_MODE
USB_HOST_PARAM host;
#endif
}usb_core_instance;
/*******************************************************************************
* inline functions
******************************************************************************/
/**
*******************************************************************************
** \brief get the current mode of the usb core from the corresponding register
** \param pdev : device instance
** \retval current mode \@=1: host mode \@=0: device mode
******************************************************************************/
static __INLINE uint8_t hd_usb_getcurmod(usb_core_instance *pdev)
{
uint8_t tmp;
USB_CORE_GINTSTS_TypeDef tmp_gintsts;
tmp_gintsts.d32 = HD_USB_RDREG32(&pdev->regs.GREGS->GINTSTS);
tmp = tmp_gintsts.b.curmode;
return tmp;
}
/**
*******************************************************************************
** \brief Initializes the normal interrupts
** \param pdev: device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_normalinten(usb_core_instance *pdev)
{
USB_CORE_GINTMSK_TypeDef tmp_gintmsk;
tmp_gintmsk.d32 = 0ul;
HD_USB_WRREG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFFul);
HD_USB_WRREG32( &pdev->regs.GREGS->GINTSTS, 0xBFFFFFFFul);
tmp_gintmsk.b.wkupintr = 1u;
tmp_gintmsk.b.usbsuspend = 1u;
HD_USB_WRREG32( &pdev->regs.GREGS->GINTMSK, tmp_gintmsk.d32);
}
/**
*******************************************************************************
** \brief clear all the pending device interrupt bits and mask the IN and OUT
** endpoint interrupts.
** \param pdev: device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_clrandmskepint(usb_core_instance *pdev)
{
HD_USB_WRREG32( &pdev->regs.DREGS->DIEPMSK, 0ul );
HD_USB_WRREG32( &pdev->regs.DREGS->DOEPMSK, 0ul );
HD_USB_WRREG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFFul );
HD_USB_WRREG32( &pdev->regs.DREGS->DAINTMSK, 0ul );
}
/**
*******************************************************************************
** \brief generate a device connect signal to the USB host
** \param pdev: device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_coreconn(usb_core_instance *pdev)
{
USB_CORE_DCTL_TypeDef tmp_dctl;
tmp_dctl.d32 = HD_USB_RDREG32(&pdev->regs.DREGS->DCTL);
tmp_dctl.b.sftdiscon = 0u;
HD_USB_WRREG32(&pdev->regs.DREGS->DCTL, tmp_dctl.d32);
}
/**
*******************************************************************************
** \brief test of mode processing
**
** \param pdev: device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_runtestmode(usb_core_instance *pdev, uint32_t reg)
{
HD_USB_WRREG32(&pdev->regs.DREGS->DCTL, reg);
}
/**
*******************************************************************************
** \brief Enables the controller's Global interrupts in the AHB Configuration
** registers.
** \param pdev : device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_ginten(usb_core_instance *pdev)
{
USB_CORE_GAHBCFG_TypeDef tmp_gahbcfg;
tmp_gahbcfg.d32 = 0ul;
tmp_gahbcfg.b.glblintrmsk = 1u;
HD_USB_MDFREG32(&pdev->regs.GREGS->GAHBCFG, 0ul, tmp_gahbcfg.d32);
}
/**
*******************************************************************************
** \brief Disable the controller's Global interrupt in the AHB Configuration
** register.
** \param pdev : device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_gintdis(usb_core_instance *pdev)
{
USB_CORE_GAHBCFG_TypeDef tmp_gahbcfg;
tmp_gahbcfg.d32 = 0ul;
tmp_gahbcfg.b.glblintrmsk = 1u;
HD_USB_MDFREG32(&pdev->regs.GREGS->GAHBCFG, tmp_gahbcfg.d32, 0ul);
}
/**
*******************************************************************************
** \brief Get the Core Interrupt bits from the interrupt register not including
** the bits that are masked.
** \param pdev : device instance
** \retval status[32bits]
******************************************************************************/
static __INLINE uint32_t hd_usb_getcoreintr(usb_core_instance *pdev)
{
uint32_t v = 0ul;
v = HD_USB_RDREG32(&pdev->regs.GREGS->GINTSTS);
v &= HD_USB_RDREG32(&pdev->regs.GREGS->GINTMSK);
return v;
}
/**
*******************************************************************************
** \brief Get the out endpoint interrupt bits from the all endpoint interrupt
** register not including the bits masked.
** \param pdev : device instance
** \retval The status that shows which OUT EP have interrupted.
******************************************************************************/
static __INLINE uint32_t hd_usb_getalloepintr(usb_core_instance *pdev)
{
uint32_t v;
v = HD_USB_RDREG32(&pdev->regs.DREGS->DAINT);
v &= HD_USB_RDREG32(&pdev->regs.DREGS->DAINTMSK);
return ((v & 0xffff0000ul) >> 16u);
}
/**
*******************************************************************************
** \brief Get the Device OUT EP Interrupt register(DOEPINT) not including the
** interrupt bits that are masked.
** \param pdev : device instance
** \param epnum: end point index
** \retval all the interrupt bits on DOEPINTn while n = epnum
******************************************************************************/
static __INLINE uint32_t hd_usb_getoepintbit(usb_core_instance *pdev , uint8_t epnum)
{
uint32_t v;
v = HD_USB_RDREG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT);
v &= HD_USB_RDREG32(&pdev->regs.DREGS->DOEPMSK);
return v;
}
/**
*******************************************************************************
** \brief Get the IN endpoint interrupt bits from the all endpoint interrupt
** register not including the bits masked.
** \param pdev : device instance
** \retval The status that shows which IN EP have interrupted.
******************************************************************************/
static __INLINE uint32_t hd_usb_getalliepintr(usb_core_instance *pdev)
{
uint32_t v;
v = HD_USB_RDREG32(&pdev->regs.DREGS->DAINT);
v &= HD_USB_RDREG32(&pdev->regs.DREGS->DAINTMSK);
return (v & 0xfffful);
}
/**
*******************************************************************************
** \brief Set the device a new address.
** \param pdev: device instance
** \param address: device address which will be set to the corresponding register.
** \retval none
******************************************************************************/
static __INLINE void hd_usb_devaddrset(usb_core_instance *pdev, uint8_t address)
{
USB_CORE_DCFG_TypeDef dcfg;
dcfg.d32 = 0ul;
dcfg.b.devaddr = address;
HD_USB_MDFREG32( &pdev->regs.DREGS->DCFG, 0ul, dcfg.d32);
}
#ifdef USE_HOST_MODE
/**
*******************************************************************************
** \brief Read the register HPRT and reset the following bits.
** \param pdev : device instance
** \retval value of HPRT
******************************************************************************/
static __INLINE uint32_t hd_usb_rdhprt(usb_core_instance *pdev)
{
USB_CORE_HPRT_TypeDef tmp_hprt;
tmp_hprt.d32 = HD_USB_RDREG32(pdev->regs.HPRT0);
tmp_hprt.b.prtena = 0u;
tmp_hprt.b.prtconndet = 0u;
tmp_hprt.b.prtenchng = 0u;
tmp_hprt.b.prtovrcurrchng = 0u;
return tmp_hprt.d32;
}
/**
*******************************************************************************
** \brief Issues a ping token
** \param pdev : device instance
** \param hc_num: the host channel index
** \retval none
******************************************************************************/
static __INLINE void hd_usb_pingtokenissue(usb_core_instance *pdev , uint8_t hc_num)
{
USB_CORE_HCCHAR_TypeDef tmp_hcchar;
USB_CORE_HCTSIZn_TypeDef tmp_hctsiz;
tmp_hctsiz.d32 = 0ul;
tmp_hctsiz.b.dopng = 1u;
tmp_hctsiz.b.pktcnt = 1u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, tmp_hctsiz.d32);
tmp_hcchar.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
tmp_hcchar.b.chen = 1u;
tmp_hcchar.b.chdis = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, tmp_hcchar.d32);
}
/**
** \brief This function returns the frame number for sof packet
** \param pdev : device instance
** \retval Frame number
******************************************************************************/
static __INLINE uint8_t hd_usb_ifevenframe (usb_core_instance *pdev)
{
return !(HD_USB_RDREG32(&pdev->regs.HREGS->HFNUM) & 0x1u);
}
/**
*******************************************************************************
** \brief Initializes the FSLSPClkSel field of the HCFG register on the PHY type
** \param pdev : device instance
** \param freq : clock frequency
** \retval none
******************************************************************************/
static __INLINE void hd_usb_fslspclkselset(usb_core_instance *pdev , uint8_t freq)
{
USB_CORE_HCFG_TypeDef tmp_hcfg;
tmp_hcfg.d32 = HD_USB_RDREG32(&pdev->regs.HREGS->HCFG);
tmp_hcfg.b.fslspclksel = freq;
HD_USB_WRREG32(&pdev->regs.HREGS->HCFG, tmp_hcfg.d32);
}
/**
*******************************************************************************
** \brief suspend the port
** \param pdev : device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_prtsusp(usb_core_instance *pdev)
{
USB_CORE_HPRT_TypeDef port0;
port0.d32 = hd_usb_rdhprt(pdev);
port0.b.prtsusp = 1u;
port0.b.prtres = 0u;
HD_USB_WRREG32(pdev->regs.HPRT0, port0.d32);
}
/**
*******************************************************************************
** \brief control the enumeration speed of the core, this function make sure that
** the maximum speed supperted by the connected device.
** \param pdev : device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_enumspeed(usb_core_instance *pdev)
{
USB_CORE_HCFG_TypeDef tmp_hcfg;
tmp_hcfg.d32 = HD_USB_RDREG32(&pdev->regs.HREGS->HCFG);
tmp_hcfg.b.fslssupp = 0u;
HD_USB_WRREG32(&pdev->regs.HREGS->HCFG, tmp_hcfg.d32);
}
/**
*******************************************************************************
** \brief set the TXFIFO and depth for non-periodic and periodic and RXFIFO size
** \param pdev : device instance
** \retval none
******************************************************************************/
static __INLINE void hd_usb_sethostfifo(usb_core_instance *pdev)
{
USB_CORE_FSIZ_TypeDef nptxfifosize;
USB_CORE_FSIZ_TypeDef ptxfifosize;
nptxfifosize.d32 = 0ul;
ptxfifosize.d32 = 0ul;
HD_USB_WRREG32(&pdev->regs.GREGS->GRXFSIZ, (uint32_t)RX_FIFO_FS_SIZE); //set the RxFIFO Depth
nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE; //non-periodic transmit RAM start address
nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ; //set the non-periodic TxFIFO depth
HD_USB_WRREG32(&pdev->regs.GREGS->GNPTXFSIZ, nptxfifosize.d32); //set the register-GNPTXFSIZ
ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ; //set the host periodic TxFIFO start address
ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ; //set the host periodic TxFIFO depth
HD_USB_WRREG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
}
/**
*******************************************************************************
** \brief Drives the Vbus signal through IO
** \param pdev : device instance
** \param state : VBUS states
** \retval None
******************************************************************************/
static __INLINE void hd_usb_drivevbus(usb_core_instance *pdev, uint8_t state)
{
USB_CORE_HPRT_TypeDef tmp_hprt;
tmp_hprt.d32 = hd_usb_rdhprt(pdev);
tmp_hprt.b.prtlnsts = state;
HD_USB_WRREG32(pdev->regs.HPRT0, tmp_hprt.d32);
}
/**
*******************************************************************************
** \brief reset the channel whose channel number is ch_idx
** \param pdev : device instance
** \param ch_idx: channel number
** \retval none
******************************************************************************/
static __INLINE void hd_usb_chrst(usb_core_instance *pdev, uint8_t ch_idx)
{
USB_CORE_HCCHAR_TypeDef hcchar;
hcchar.d32 = HD_USB_RDREG32(&pdev->regs.HC_REGS[ch_idx]->HCCHAR);
hcchar.b.chen = 0u;
hcchar.b.chdis = 1u;
hcchar.b.epdir = 0u;
HD_USB_WRREG32(&pdev->regs.HC_REGS[ch_idx]->HCCHAR, hcchar.d32);
}
#endif //end of USE_HOST_MODE
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
extern void hd_usb_initusbcore(usb_core_instance *pdev);
extern void hd_usb_setregaddr(usb_core_instance *pdev);
extern void hd_usb_rdpkt(usb_core_instance *pdev, uint8_t *dest, uint16_t len);
extern void hd_usb_wrpkt(usb_core_instance *pdev, uint8_t *src, uint8_t ch_ep_num, uint16_t len);
extern void hd_usb_txfifoflush(usb_core_instance *pdev , uint32_t num);
extern void hd_usb_rxfifoflush(usb_core_instance *pdev);
extern void hd_usb_modeset(usb_core_instance *pdev, uint8_t mode);
extern void hd_usb_ctrldevconnect(usb_core_instance *pdev, uint8_t link);
#ifdef USE_HOST_MODE
extern void hd_usb_hostmodeinit(usb_core_instance *pdev);
extern void hd_usb_hostinten(usb_core_instance *pdev);
extern uint8_t hd_usb_inithch(usb_core_instance *pdev, uint8_t hc_num);
extern void hd_usb_hchstop(usb_core_instance *pdev, uint8_t hc_num);
extern uint8_t hd_usb_hchtransbegin(usb_core_instance *pdev, uint8_t hc_num);
extern void hd_usb_hprtrst(usb_core_instance *pdev);
extern void hd_usb_vbusctrl(usb_core_instance *pdev, uint8_t state);
#endif
#ifdef USE_DEVICE_MODE
extern void hd_usb_devmodeinit(usb_core_instance *pdev);
extern void hd_usb_devinten(usb_core_instance *pdev);
extern void hd_usb_ep0activate(usb_core_instance *pdev);
extern void hd_usb_epactive(usb_core_instance *pdev, USBD_EP *ep);
extern void hd_usb_epdeactive(usb_core_instance *pdev, USBD_EP *ep);
extern void hd_usb_epntransbegin(usb_core_instance *pdev, USBD_EP *ep);
extern void hd_usb_ep0transbegin(usb_core_instance *pdev, USBD_EP *ep);
extern void hd_usb_setepstall(usb_core_instance *pdev, USBD_EP *ep);
extern void hd_usb_clearepstall(usb_core_instance *pdev, USBD_EP *ep);
extern uint8_t USBH_IsEvenFrame(usb_core_instance *pdev);
extern void hd_usb_ep0revcfg(usb_core_instance *pdev);
extern void hd_usb_remotewakeupen(usb_core_instance *pdev);
extern void hd_usb_epstatusset(usb_core_instance *pdev, USBD_EP *ep, uint32_t Status);
extern uint32_t hd_usb_epstatusget(usb_core_instance *pdev, USBD_EP *ep);
#endif
#endif // __USB_CORE_DRIVER_H__
/*******************************************************************************
* EOF
******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
/******************************************************************************
* Copyright (C) 2016, Huada Semiconductor Co.,Ltd. All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file usb_defines.h
**
** A detailed description is available at
** @link Header of the Core Layer @endlink
**
** - 2021-03-30 1.0 Linsq First version for USB demo.
**
******************************************************************************/
#ifndef __USB_DEF_H__
#define __USB_DEF_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "usb_conf.h"
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
*******************************************************************************
** \brief USB_DEFINES_Exported_Types
**
******************************************************************************/
/**
*******************************************************************************
** \brief ENUMERATION TYPE
**
******************************************************************************/
enum HD_USB_SPEED {
USB_SPEED_UNKNOWN = 0,
USB_SPEED_LOW,
USB_SPEED_FULL,
USB_SPEED_HIGH
};
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
*******************************************************************************
** \brief _GLOBAL_DEFINES_
**
******************************************************************************/
#define GRXSTS_PKTSTS_IN (2u)
#define GRXSTS_PKTSTS_IN_XFER_COMP (3u)
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR (5u)
#define GRXSTS_PKTSTS_CH_HALTED (7u)
#define SELF_POWERED (1u << 6u)
#define REMOTE_WAKEUP (1u << 5u)
/**
*******************************************************************************
** \brief _OnTheGo_DEFINES_
**
******************************************************************************/
#define DEVICE_MODE (0u)
#define HOST_MODE (1u)
/**
*******************************************************************************
** \brief __DEVICE_DEFINES_
**
******************************************************************************/
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0u)
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1u)
#define DSTS_ENUMSPD_LS_PHY_6MHZ (2u)
#define DSTS_ENUMSPD_FS_PHY_48MHZ (3u)
#define EP_TYPE_CTRL (0u)
#define EP_TYPE_ISOC (1u)
#define EP_TYPE_BULK (2u)
#define EP_TYPE_INTR (3u)
#define EP_TYPE_MSK (3u)
#define STS_GOUT_NAK (1u)
#define STS_DATA_UPDT (2u)
#define STS_XFER_COMP (3u)
#define STS_SETUP_COMP (4u)
#define STS_SETUP_UPDT (6u)
/**
*******************************************************************************
** \brief __HOST_DEFINES_
**
******************************************************************************/
#define PID_DATA0 (0u)
#define PID_DATA2 (1u)
#define PID_DATA1 (2u)
#define PID_SETUP (3u)
#define PRTSPD_FULL_SPEED (1u)
#define PRTSPD_LOW_SPEED (2u)
#define HCFG_30_60_MHZ (0u)
#define HCFG_48_MHZ (1u)
#define HCFG_6_MHZ (2u)
#define CTRL_TRANSFER (0u)
#define ISOC_TRANSFER (1u)
#define BULK_TRANSFER (2u)
#define INT_TRANSFER (3u)
#ifndef __MIN
#define __MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/**
*******************************************************************************
** \brief Internal_Macro
**
******************************************************************************/
#define HD_USB_RDREG32(reg) (*(__IO uint32_t *)(reg))
#define HD_USB_WRREG32(reg,value) (*(__IO uint32_t *)(reg) = (value))
#define HD_USB_MDFREG32(reg,clear_mask,set_mask) (HD_USB_WRREG32((reg), (((HD_USB_RDREG32((reg))) & ~(clear_mask)) | (set_mask))))
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
#endif //__USB_DEFINES__H__