From 64e0bb76b28533578f855c8698f8c29d3c559b59 Mon Sep 17 00:00:00 2001 From: David Barksdale Date: Tue, 2 Aug 2016 07:25:00 -0500 Subject: Adding USB files from KSDK for mass-storage class --- KSDK_1.2.0/usb/adapter/sources/adapter.h | 93 + KSDK_1.2.0/usb/adapter/sources/adapter_types.h | 67 + KSDK_1.2.0/usb/adapter/sources/sdk/adapter_cfg.h | 45 + KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.c | 502 +++++ KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.h | 115 + .../armgcc/usbd_sdk_frdmkl27z_bm/CMakeLists.txt | 138 ++ .../armgcc/usbd_sdk_frdmkl27z_bm/build_all.bat | 5 + .../armgcc/usbd_sdk_frdmkl27z_bm/build_all.sh | 5 + .../armgcc/usbd_sdk_frdmkl27z_bm/build_debug.bat | 3 + .../armgcc/usbd_sdk_frdmkl27z_bm/build_debug.sh | 3 + .../armgcc/usbd_sdk_frdmkl27z_bm/build_release.bat | 3 + .../armgcc/usbd_sdk_frdmkl27z_bm/build_release.sh | 3 + .../build/armgcc/usbd_sdk_frdmkl27z_bm/clean.bat | 3 + .../build/armgcc/usbd_sdk_frdmkl27z_bm/clean.sh | 3 + .../device/include/frdmkl27z/usb_device_config.h | 159 ++ .../device/include/usb_device_stack_interface.h | 618 ++++++ .../device/sources/bsp/frdmkl27z/usb_dev_bsp.c | 153 ++ .../device/sources/classes/common/usb_class.c | 376 ++++ .../sources/classes/common/usb_class_internal.h | 186 ++ .../classes/include/config/usb_msc_config.h | 54 + .../device/sources/classes/include/usb_class.h | 116 + .../device/sources/classes/include/usb_class_msc.h | 201 ++ .../usb_core/device/sources/classes/msd/usb_msc.c | 1580 +++++++++++++ .../usb_core/device/sources/classes/msd/usb_msc.h | 612 +++++ .../device/sources/classes/msd/usb_msc_scsi.c | 1467 ++++++++++++ .../device/sources/classes/msd/usb_msc_scsi.h | 309 +++ .../controller/khci/device_khci_interface.c | 75 + .../device/sources/controller/khci/khci_dev.c | 2339 ++++++++++++++++++++ .../device/sources/controller/khci/khci_dev.h | 75 + .../device/sources/controller/khci/khci_dev_misc.h | 146 ++ .../usb_core/device/sources/controller/usb_dev.c | 1560 +++++++++++++ .../usb_core/device/sources/controller/usb_dev.h | 136 ++ .../device/sources/controller/usb_framework.c | 1295 +++++++++++ .../device/sources/controller/usb_framework.h | 188 ++ KSDK_1.2.0/usb/usb_core/hal/fsl_usb_features.h | 126 ++ KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.c | 36 + KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.h | 1879 ++++++++++++++++ KSDK_1.2.0/usb/usb_core/include/compiler.h | 122 + KSDK_1.2.0/usb/usb_core/include/types.h | 84 + KSDK_1.2.0/usb/usb_core/include/usb.h | 40 + KSDK_1.2.0/usb/usb_core/include/usb_desc.h | 348 +++ KSDK_1.2.0/usb/usb_core/include/usb_error.h | 100 + KSDK_1.2.0/usb/usb_core/include/usb_misc.h | 193 ++ KSDK_1.2.0/usb/usb_core/include/usb_opt.h | 117 + KSDK_1.2.0/usb/usb_core/include/usb_pin_detect.h | 68 + KSDK_1.2.0/usb/usb_core/include/usb_types.h | 59 + 46 files changed, 15805 insertions(+) create mode 100644 KSDK_1.2.0/usb/adapter/sources/adapter.h create mode 100644 KSDK_1.2.0/usb/adapter/sources/adapter_types.h create mode 100644 KSDK_1.2.0/usb/adapter/sources/sdk/adapter_cfg.h create mode 100644 KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.c create mode 100644 KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/CMakeLists.txt create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.bat create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.sh create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.bat create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.sh create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.bat create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.sh create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.bat create mode 100755 KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.sh create mode 100644 KSDK_1.2.0/usb/usb_core/device/include/frdmkl27z/usb_device_config.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/include/usb_device_stack_interface.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/bsp/frdmkl27z/usb_dev_bsp.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class_internal.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/include/config/usb_msc_config.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class_msc.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/device_khci_interface.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev_misc.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.h create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.c create mode 100644 KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.h create mode 100644 KSDK_1.2.0/usb/usb_core/hal/fsl_usb_features.h create mode 100644 KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.c create mode 100644 KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/compiler.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/types.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_desc.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_error.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_misc.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_opt.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_pin_detect.h create mode 100644 KSDK_1.2.0/usb/usb_core/include/usb_types.h diff --git a/KSDK_1.2.0/usb/adapter/sources/adapter.h b/KSDK_1.2.0/usb/adapter/sources/adapter.h new file mode 100644 index 0000000..f67ddc6 --- /dev/null +++ b/KSDK_1.2.0/usb/adapter/sources/adapter.h @@ -0,0 +1,93 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: osadapter.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains OS adapter layer api header function. +* +*****************************************************************************/ + +#ifndef _USB_OSADAPTER_H +#define _USB_OSADAPTER_H 1 +#include "adapter_cfg.h" +#include "adapter_types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) /* USB stack running on MQX */ +#include "adapter_mqx.h" +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) /* USB stack running on BM */ +#include "adapter_bm.h" +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) /* USB stack running on SDK */ +#include "adapter_sdk.h" +#endif + +extern uint32_t OS_Task_create(task_start_t pstart, void* param, uint32_t pri, uint32_t stack_size, char* task_name, void* opt); +extern uint32_t OS_Task_delete(uint32_t task_id); +extern uint32_t OS_Task_suspend(uint32_t task_id); +extern uint32_t OS_Task_resume(uint32_t task_id); + +extern os_event_handle OS_Event_create(uint32_t flag); +extern uint32_t OS_Event_destroy(os_event_handle handle); +extern uint32_t OS_Event_set(os_event_handle handle, uint32_t bitmask); +extern uint32_t OS_Event_check_bit(os_event_handle handle, uint32_t bitmask); +//extern uint32_t OS_Event_set_auto_clear(os_event_handle event, uint32 bitmask); +extern uint32_t OS_Event_clear(os_event_handle handle, uint32_t bitmask); +extern uint32_t OS_Event_wait(os_event_handle handle, uint32_t bitmask, uint32_t flag, uint32_t timeout); +//extern OS_Event_get_value(a,b) _lwevent_get_value(a,b) +//#define OS_EVENT_WAIT_TIMEOUT 0x01 + + +extern os_msgq_handle OS_MsgQ_create(uint32_t max_msg_number, uint32_t msg_size); +extern uint32_t OS_MsgQ_send(os_msgq_handle msgq, void* msg, uint32_t flag); +extern uint32_t OS_MsgQ_recv(os_msgq_handle msgq, void* msg, uint32_t flag, uint32_t timeout); +extern uint32_t OS_MsgQ_destroy(os_msgq_handle msgq); + +extern os_gpio_handle OS_Gpio_init(uint32_t id, uint32_t dir, uint32_t value); +extern uint32_t OS_Gpio_set_functionality(os_gpio_handle handle, uint32_t function); +extern uint32_t OS_Gpio_set_value(os_gpio_handle handle, uint32_t value); + +extern os_mutex_handle OS_Mutex_create(void); +extern uint32_t OS_Mutex_lock(os_mutex_handle handle); +extern uint32_t OS_Mutex_unlock(os_mutex_handle handle); +extern uint32_t OS_Mutex_destroy(os_mutex_handle handle); + + +extern os_sem_handle OS_Sem_create(uint32_t initial_number); +extern uint32_t OS_Sem_post(os_sem_handle handle); +extern uint32_t OS_Sem_wait(os_sem_handle handle,uint32_t timeout); +extern uint32_t OS_Sem_destroy(os_sem_handle handle); + +#if defined(__cplusplus) +} +#endif + + +#endif + + diff --git a/KSDK_1.2.0/usb/adapter/sources/adapter_types.h b/KSDK_1.2.0/usb/adapter/sources/adapter_types.h new file mode 100644 index 0000000..17203f1 --- /dev/null +++ b/KSDK_1.2.0/usb/adapter/sources/adapter_types.h @@ -0,0 +1,67 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: osadapter_types.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains definition for OS adapter layer. +* +*****************************************************************************/ + +#ifndef _OSADAPTER_TYPES_H +#define _OSADAPTER_TYPES_H 1 + + +typedef void (* task_start_t)( void * param); +typedef void (* osa_int_isr_fptr)(void * param); +typedef void* os_event_handle; +typedef void* os_msgq_handle; +typedef void* os_gpio_handle; +typedef void* os_mutex_handle; +typedef void* os_sem_handle; + + +#define OS_TASK_OK (0) +#define OS_TASK_ERROR (-1) +#define OS_EVENT_OK (0) +#define OS_EVENT_ERROR (-1) +#define OS_EVENT_TIMEOUT (-2) +#define OS_MSGQ_OK (0) +#define OS_MSGQ_ERROR (-1) +#define OS_GPIO_OK (0) +#define OS_GPIO_ERROR (-1) +#define OS_MUTEX_OK (0) +#define OS_MUTEX_ERROR (-1) +#define OS_SEM_OK (0) +#define OS_SEM_ERROR (-1) +#define OS_SEM_TIMEOUT (-2) + +/* Block the reading task if msgq is empty */ +#define OS_MSGQ_RECEIVE_BLOCK_ON_EMPTY (0x04) + + +#endif + + diff --git a/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_cfg.h b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_cfg.h new file mode 100644 index 0000000..04418dd --- /dev/null +++ b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_cfg.h @@ -0,0 +1,45 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: osadapter_cfg.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains OS adapter configuration inf. +* +*****************************************************************************/ + +#ifndef _OSADAPTER_CFG_H +#define _OSADAPTER_CFG_H 1 + +#define OS_ADAPTER_MQX 1 +#define OS_ADAPTER_BM 2 +#define OS_ADAPTER_SDK 3 +#define OS_ADAPTER_UCOSIII 4 +/*#define OS_ADAPTER_ACTIVE_OS OS_ADAPTER_UCOSIII*/ +#define OS_ADAPTER_ACTIVE_OS OS_ADAPTER_SDK + +#endif + + diff --git a/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.c b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.c new file mode 100644 index 0000000..02dd9e9 --- /dev/null +++ b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.c @@ -0,0 +1,502 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2013 - 2014 Freescale Semiconductor; + * All Rights Reserved + * + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: osadapter_ucos.c$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file includes the implementation of OS adapter based on SDK OSA. + * + *****************************************************************************/ +#include "adapter_cfg.h" +#include "adapter_types.h" +#include "adapter_sdk.h" +#include "adapter.h" + +#include +#include +#include +#include "fsl_device_registers.h" + +uint8_t soc_get_usb_vector_number(uint8_t controller_id) +{ + if (controller_id == 0) + { + return USB0_IRQn; + } +#if defined (USBHS_BASE) + else if (controller_id == 2) + { + return USBHS_IRQn; + } +#endif + return 0; +} + +uint32_t soc_get_usb_base_address(uint8_t controller_id) +{ + if (controller_id == 0) + { + return (uint32_t) USB0_BASE; + } +#if defined (USBHS_BASE) + else if (controller_id == 2) + { + return (uint32_t)USBHS_BASE; + } +#endif + return (uint32_t) NULL; +} + +os_gpio_handle OS_Gpio_init(uint32_t id, uint32_t dir, uint32_t value) +{ + return (os_gpio_handle)(0x0000FFFF); +} + +uint32_t OS_Gpio_set_functionality(os_gpio_handle handle, uint32_t function) +{ + return OS_GPIO_OK; +} + +uint32_t OS_Gpio_set_value(os_gpio_handle handle, uint32_t value) +{ + return OS_GPIO_OK; +} + +uint32_t OS_Gpio_deinit(os_gpio_handle handle) +{ + return OS_GPIO_OK; +} + +/* Structure for uC/OS to manage the task stack and task handler. */ +#if ((defined (FSL_RTOS_UCOSII)) || (defined (FSL_RTOS_UCOSIII))) +typedef struct _usb_adapter_task_struct +{ + void *stack_mem; // Pointer to task stack. + task_handler_t handler;// Handler of task. +}usb_adapter_task_struct; +#endif + +uint32_t OS_Task_create(task_start_t pstart, void* param, uint32_t pri, uint32_t stack_size, char* task_name, void* opt) +{ + osa_status_t status; + /* + * For uC/OS, we should allocate memory for task stack. + */ +#if ((defined (FSL_RTOS_UCOSII)) || (defined (FSL_RTOS_UCOSIII))) + usb_adapter_task_struct* task_struct = OSA_MemAllocZero(sizeof(usb_adapter_task_struct)); + if (!task_struct) + { + return (uint32_t)OS_TASK_ERROR; + } + + task_struct->stack_mem = OSA_MemAlloc(stack_size); + if(!task_struct->stack_mem) + { + OSA_MemFree(task_struct); + return (uint32_t)OS_TASK_ERROR; + } + +#if defined (FSL_RTOS_UCOSIII) + task_struct->handler = OSA_MemAllocZero(sizeof(OS_TCB)); + if(!task_struct->handler) + { + OSA_MemFree(task_struct->stack_mem); + OSA_MemFree(task_struct); + return (uint32_t)OS_TASK_ERROR; + } +#endif + status = OSA_TaskCreate((task_t)pstart, (uint8_t*)task_name, stack_size, + task_struct->stack_mem, pri, (task_param_t)param, false, &task_struct->handler); + if (kStatus_OSA_Success == status) + { + return (uint32_t)task_struct; + } + else + { + return (uint32_t)OS_TASK_ERROR; + } + +#else //((defined (FSL_RTOS_UCOSII)) || (defined (FSL_RTOS_UCOSIII))) + task_handler_t task_handler; + status = OSA_TaskCreate((task_t) pstart, (uint8_t*) task_name, stack_size, NULL, pri, (task_param_t) param, false, &task_handler); + + if (kStatus_OSA_Success == status) + { + return (uint32_t) task_handler; + } + else + { + return (uint32_t) OS_TASK_ERROR; + } +#endif //((defined (FSL_RTOS_UCOSII)) || (defined (FSL_RTOS_UCOSIII))) +} + +uint32_t OS_Task_delete(uint32_t task_id) +{ +#if ((defined (FSL_RTOS_UCOSII)) || (defined (FSL_RTOS_UCOSIII))) + usb_adapter_task_struct* task_struct = (usb_adapter_task_struct*)task_id; + + if (kStatus_OSA_Success != OSA_TaskDestroy(task_struct->handler)) + { + return (uint32_t)OS_TASK_ERROR; + } +#if defined (FSL_RTOS_UCOSIII) + OSA_MemFree(task_struct->handler); // Free TCB +#endif + OSA_MemFree(task_struct->stack_mem); // Free stack memory + OSA_MemFree(task_struct); + return (uint32_t)OS_TASK_OK; +#else + return (kStatus_OSA_Success == OSA_TaskDestroy((task_handler_t) task_id)) ? (uint32_t) OS_TASK_OK : (uint32_t) OS_TASK_ERROR; +#endif +} + +/* Event create and destroy */ +os_event_handle OS_Event_create(uint32_t flag) +{ + event_t *p_event = (event_t *) OSA_MemAllocZero(sizeof(event_t)); + + if (!p_event) + { + return (os_event_handle) 0; + } + + if (kStatus_OSA_Success != OSA_EventCreate(p_event, flag ? kEventAutoClear : kEventManualClear)) + { + OSA_MemFree(p_event); + return (os_event_handle) 0; + } + return (os_event_handle) p_event; +} + +uint32_t OS_Event_destroy(os_event_handle handle) +{ + event_t* obj = (event_t*) handle; + + if (kStatus_OSA_Success == OSA_EventDestroy(obj)) + { + OSA_MemFree(handle); + return (uint32_t) OS_EVENT_OK; + } + else + { + return (uint32_t) OS_EVENT_ERROR; + } +} + +/* Message queue create and destroy */ +/* + * NOTE: The msg_size here is counted by words, not bytes! + */ +os_msgq_handle OS_MsgQ_create(uint32_t max_msg_number, uint32_t msg_size) +{ + os_msgq_handle ret; +#if defined (FSL_RTOS_UCOSII) + uint8_t *p_tmp; + uint32_t size = sizeof(msg_queue_t) + + (msg_size*sizeof(int32_t)+sizeof(void*))*max_msg_number; +#elif defined (FSL_RTOS_UCOSIII) + uint8_t *p_tmp; + uint32_t size = sizeof(msg_queue_t) + (msg_size*sizeof(int32_t))*max_msg_number; +#elif defined (FSL_RTOS_MQX) + uint32_t size = (SIZE_IN_MMT_UNITS(sizeof(LWMSGQ_STRUCT)) + + SIZE_IN_MMT_UNITS((msg_size*sizeof(int32_t))*(max_msg_number))) + * sizeof(_mqx_max_type); +#elif defined (FSL_RTOS_FREE_RTOS) +#else /* Bare metal by default. */ + uint8_t *p_tmp; + uint32_t size = sizeof(msg_queue_t) + sizeof(uint32_t) * max_msg_number * msg_size; +#endif + +#if defined (FSL_RTOS_FREE_RTOS) + msg_queue_t* msgq = NULL; +#else + msg_queue_t* msgq = (msg_queue_t*) OSA_MemAllocZero(size); + + if (!msgq) + { + return (msg_queue_handler_t) 0; + } +#endif + /* initialize the msg_queue_t */ +#if defined (FSL_RTOS_UCOSII) + p_tmp = (uint8_t*)msgq; + p_tmp += sizeof(msg_queue_t); + msgq->msgTbl = (void**)p_tmp; + p_tmp += max_msg_number*sizeof(void*); + msgq->msgs = (uint32_t*)p_tmp; +#elif defined (FSL_RTOS_UCOSIII) + p_tmp = (uint8_t*)msgq; + p_tmp += sizeof(msg_queue_t); + msgq->msgs = (void*)p_tmp; +#elif defined (FSL_RTOS_MQX) +#elif defined (FSL_RTOS_FREE_RTOS) +#else /* Bare metal by default. */ + p_tmp = (uint8_t*) msgq; + p_tmp += sizeof(msg_queue_t); + msgq->queueMem = (uint32_t*) p_tmp; +#endif + ret = OSA_MsgQCreate(msgq, max_msg_number, msg_size); +#if !defined (FSL_RTOS_FREE_RTOS) + if (!ret) + { + OSA_MemFree(msgq); + } +#endif + return ret; +} + +uint32_t OS_MsgQ_destroy(os_msgq_handle msgq) +{ + if (kStatus_OSA_Success == OSA_MsgQDestroy((msg_queue_handler_t) msgq)) + { +#if !defined (FSL_RTOS_FREE_RTOS) + OSA_MemFree(msgq); +#endif + return (uint32_t) OS_MSGQ_OK; + } + else + { + return (uint32_t) OS_MSGQ_ERROR; + } +} + +/* Mutex create and destroy */ +os_mutex_handle OS_Mutex_create(void) +{ + mutex_t *p_mutex = (mutex_t *) OSA_MemAllocZero(sizeof(mutex_t)); + + if (!p_mutex) + { + return (os_mutex_handle) 0; + } + if (kStatus_OSA_Success != OSA_MutexCreate(p_mutex)) + { + OSA_MemFree(p_mutex); + return (os_mutex_handle) 0; + } + + return (os_mutex_handle) p_mutex; +} + +uint32_t OS_Mutex_destroy(os_mutex_handle handle) +{ + if (kStatus_OSA_Success == OSA_MutexDestroy((mutex_t*) handle)) + { + OSA_MemFree(handle); + return (uint32_t) OS_MUTEX_OK; + } + else + { + return (uint32_t) OS_MUTEX_ERROR; + } +} + +/* Semaphore create and destroy */ +os_sem_handle OS_Sem_create(uint32_t initial_number) +{ + semaphore_t *p_sem = (semaphore_t *) OSA_MemAllocZero(sizeof(semaphore_t)); + + if (!p_sem) + { + return (os_sem_handle) 0; + } + + if (kStatus_OSA_Success != OSA_SemaCreate(p_sem, initial_number)) + { + OSA_MemFree(p_sem); + return (os_sem_handle) 0; + } + + return (os_sem_handle) p_sem; +} + +uint32_t OS_Sem_destroy(os_sem_handle handle) +{ + if (kStatus_OSA_Success == OSA_SemaDestroy((semaphore_t*) handle)) + { + OSA_MemFree(handle); + return (uint32_t) OS_SEM_OK; + } + else + { + return (uint32_t) OS_SEM_ERROR; + } +} + +/* Events */ +uint32_t OS_Event_check_bit(os_event_handle handle, uint32_t bitmask) +{ + event_t* event = (event_t*) handle; + return (((uint32_t) OSA_EventGetFlags(event)) & bitmask); +} + +uint32_t OS_Event_set(os_event_handle handle, uint32_t bitmask) +{ + return ((kStatus_OSA_Success == OSA_EventSet((event_t*) (handle), (bitmask))) ? OS_EVENT_OK : OS_EVENT_ERROR); +} + +uint32_t OS_Event_clear(os_event_handle handle, uint32_t bitmask) +{ + return ((kStatus_OSA_Success == OSA_EventClear((event_t*) (handle), (bitmask))) ? OS_EVENT_OK : OS_EVENT_ERROR); +} + +uint32_t OS_Event_wait(os_event_handle handle, uint32_t bitmask, uint32_t flag, uint32_t timeout) +{ + osa_status_t status = kStatus_OSA_Idle; + event_flags_t event_bit; + uint32_t re; + event_t* event = (event_t*) handle; + // flag will always be false, so wait any bits +#if (USE_RTOS) + if (0 == timeout) + { + timeout = OSA_WAIT_FOREVER; + } +#endif + // Block or timeout mode + do + { + status = OSA_EventWait(event, bitmask, flag, timeout, &event_bit); + } while (kStatus_OSA_Idle == status); + + switch(status) + { + case kStatus_OSA_Success: + re = (uint32_t) OS_EVENT_OK; + break; + case kStatus_OSA_Timeout: + re = (uint32_t) OS_EVENT_TIMEOUT; + break; + default: + re = (uint32_t) OS_EVENT_ERROR; + break; + } + return re; +} + +/* Semaphore */ +uint32_t OS_Sem_post(os_sem_handle handle) +{ + return ((kStatus_OSA_Success == OSA_SemaPost((semaphore_t*) (handle))) ? OS_SEM_OK : OS_SEM_ERROR); +} + +uint32_t OS_Sem_wait(os_sem_handle handle, uint32_t timeout) +{ + osa_status_t status = kStatus_OSA_Idle; + uint32_t re; +#if (USE_RTOS) + if (0==timeout) + { + timeout = OSA_WAIT_FOREVER; + } +#endif + do + { + status = OSA_SemaWait((semaphore_t*) handle, timeout); + } while (kStatus_OSA_Idle == status); + + switch(status) + { + case kStatus_OSA_Success: + re = (uint32_t) OS_SEM_OK; + break; + case kStatus_OSA_Timeout: + re = (uint32_t) OS_SEM_TIMEOUT; + break; + default: + re = (uint32_t) OS_SEM_ERROR; + break; + } + return re; +} + +/* Mutex */ +uint32_t OS_Mutex_lock(os_mutex_handle handle) +{ + osa_status_t status = kStatus_OSA_Idle; + uint32_t re; + +#if !(USE_RTOS) + status = OSA_MutexLock((mutex_t*) handle, 0); +#else + status = OSA_MutexLock((mutex_t*)handle, OSA_WAIT_FOREVER); +#endif + + switch(status) + { + case kStatus_OSA_Success: + re = (uint32_t) OS_MUTEX_OK; + break; + default: + re = (uint32_t) OS_MUTEX_ERROR; + break; + } + return re; +} + +uint32_t OS_Mutex_unlock(os_mutex_handle handle) +{ + return ((kStatus_OSA_Success == OSA_MutexUnlock((mutex_t*) (handle))) ? OS_MUTEX_OK : OS_MUTEX_ERROR); +} + +/* Message queue */ +uint32_t OS_MsgQ_recv(os_msgq_handle msgq, void* msg, uint32_t flag, uint32_t timeout) +{ + osa_status_t status; + uint32_t re; + + status = OSA_MsgQGet((msg_queue_handler_t)msgq, msg, + (!(OS_MSGQ_RECEIVE_BLOCK_ON_EMPTY & flag)) ? + 0u : + ((0==timeout) ? OSA_WAIT_FOREVER : timeout)); + + switch(status) + { + case kStatus_OSA_Success: + re = (uint32_t) OS_MSGQ_OK; + break; + case kStatus_OSA_Timeout: + re = (uint32_t) OS_MSGQ_TIMEOUT; + break; + default: + re = (uint32_t) OS_MSGQ_ERROR; + break; + } + return re; +} + +uint32_t OS_MsgQ_send(os_msgq_handle msgq, void* msg, uint32_t flag) +{ + return ((kStatus_OSA_Success == OSA_MsgQPut((msg_queue_handler_t)(msgq), + msg + )) ? OS_MSGQ_OK : OS_MSGQ_ERROR); +} + +uint32_t OS_MsgQ_Is_Empty(os_msgq_handle msgq, void* msg) +{ + return (kStatus_OSA_Success == OSA_MsgQGet((msg_queue_handler_t) msgq, msg, 0)) ? 0 : 1; +} + diff --git a/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.h b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.h new file mode 100644 index 0000000..7e62da2 --- /dev/null +++ b/KSDK_1.2.0/usb/adapter/sources/sdk/adapter_sdk.h @@ -0,0 +1,115 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: osadapter_ucos.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains the definition of OS adapter base-on SDK OSA. +* +*****************************************************************************/ + +#ifndef _USB_OSADAPTER_SDK_H +#define _USB_OSADAPTER_SDK_H 1 + +#include "fsl_os_abstraction.h" +#if !defined (FSL_RTOS_MQX) +#include "compiler.h" +#endif + +#include +#include +#include +#include "fsl_debug_console.h" + +#define BIG_ENDIAN 0 +#define LITTLE_ENDIAN 1 + +#define ENDIANNESS LITTLE_ENDIAN + +#define _CODE_PTR_ * + +#ifndef FALSE +#define FALSE ((bool)0) +#endif + +#ifndef TRUE +#define TRUE ((bool)1) +#endif + +#define UNUSED(x) (void)x; + +#define OS_MSGQ_TIMEOUT (-2) +//extern void * memset (void *, int32_t, unsigned); +//extern int32_t printf_kinetis (const char *fmt, ...); + +#define USB_PRINTF PRINTF +//#define OS_install_isr +#define OS_install_isr(num, isr, data) OSA_InstallIntHandler(num, isr) +#define OS_intr_init(num, prior, subprior, enable) \ +do { \ + NVIC_SetPriority(num, prior); \ + NVIC_EnableIRQ(num); \ +}while(0) + +#define TICKS_PER_SEC 1000 + +//#define TICKS_TO_MSEC(ticks) ((ticks)*1000uL/OS_TICKS_PER_SEC) + +#define OS_Lock() OSA_EnterCritical(kCriticalDisableInt) +#define OS_Unlock() OSA_ExitCritical(kCriticalDisableInt) + +/* Based on the targets it should be modified, for ColdFire it is MBYTES */ +#define OS_dcache_invalidate_mlines(p,n) +#define OS_dcache_flush_mlines(p,n) + + +#ifndef OS_Mem_alloc_uncached +#define OS_Mem_alloc_uncached OS_Mem_alloc +#endif + +#ifndef OS_Mem_alloc_uncached_zero +#define OS_Mem_alloc_uncached_zero OS_Mem_alloc_zero +#endif + +#define OS_Mem_alloc_zero(n) OSA_MemAllocZero(n) +#define OS_Mem_alloc(n) OSA_MemAlloc(n) +#define OS_Mem_free(ptr) OSA_MemFree(ptr) + +#define OS_Mem_zero(ptr,n) memset((ptr),(0),(n)) +#define OS_Mem_copy(src,dst,n) memcpy((dst),(src),(n)) +#if defined(__cplusplus) +extern "C"{ +#endif +extern uint32_t OS_MsgQ_Is_Empty(os_msgq_handle msgq, void* msg); + +#if defined(__cplusplus) +} +#endif +/* TimeDelay */ +#define OS_Time_delay OSA_TimeDelay + +#endif + + diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/CMakeLists.txt b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/CMakeLists.txt new file mode 100644 index 0000000..6e02997 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/CMakeLists.txt @@ -0,0 +1,138 @@ +INCLUDE(CMakeForceCompiler) + +# CROSS COMPILER SETTING +SET(CMAKE_SYSTEM_NAME Generic) +CMAKE_MINIMUM_REQUIRED (VERSION 2.6) + +# THE VERSION NUMBER +SET (Tutorial_VERSION_MAJOR 1) +SET (Tutorial_VERSION_MINOR 0) + +# ENABLE ASM +ENABLE_LANGUAGE(ASM) + +SET(CMAKE_STATIC_LIBRARY_PREFIX) +SET(CMAKE_STATIC_LIBRARY_SUFFIX) + +SET(CMAKE_EXECUTABLE_LIBRARY_PREFIX) +SET(CMAKE_EXECUTABLE_LIBRARY_SUFFIX) + + +# CURRENT DIRECTORY +SET(ProjDirPath ${CMAKE_CURRENT_SOURCE_DIR}) + +# DEBUG ASM FLAGS +SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -g -mcpu=cortex-m0plus -mthumb -Wall -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -Os -mapcs -std=gnu99 ") + +# DEBUG C FLAGS +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -Wno-format -fno-strict-aliasing -mcpu=cortex-m0plus -mthumb -MMD -MP -Wall -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -Os -mapcs -std=gnu99") + +# RELEASE ASM FLAGS +SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE} -mcpu=cortex-m0plus -mthumb -Wall -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -Os -mapcs -std=gnu99 ") + +# RELEASE C FLAGS +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-format -fno-strict-aliasing -mcpu=cortex-m0plus -mthumb -MMD -MP -Wall -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -Os -mapcs -std=gnu99") + +# ASM MACRO +SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -DDEBUG") + +# C MACRO +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG=1") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DCPU_MKL27Z256VLH4") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DFRDM_KL27Z") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DFREEDOM") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_DEBUG=0") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DCPU_MKL27Z256VLH4") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DFRDM_KL27Z") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DFREEDOM") + +# CXX MACRO + +# INCLUDE_DIRECTORIES +IF(CMAKE_BUILD_TYPE MATCHES Debug) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../adapter/sources) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../adapter/sources/sdk) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/common) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/include/config) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/msd) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/controller) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/controller/khci) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../hal) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/osa/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/utilities/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/CMSIS/Include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/system/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/hal/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/drivers/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../rtos) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4/include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4/startup) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../include/frdmkl27z) +ELSEIF(CMAKE_BUILD_TYPE MATCHES Release) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../adapter/sources) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../adapter/sources/sdk) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/common) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/include/config) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/classes/msd) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/controller) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../sources/controller/khci) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../hal) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/osa/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/utilities/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/CMSIS/Include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/system/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/hal/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/drivers/inc) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../rtos) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4/include) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4/startup) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../../../../platform/devices/MKL27Z4) + INCLUDE_DIRECTORIES(${ProjDirPath}/../../../include/frdmkl27z) +ENDIF() + +# ADD_LIBRARY +ADD_LIBRARY(KsdkUsbDevicePlatformLib STATIC + "${ProjDirPath}/../../../../../adapter/sources/adapter.h" + "${ProjDirPath}/../../../../../adapter/sources/adapter_types.h" + "${ProjDirPath}/../../../../../adapter/sources/sdk/adapter_cfg.h" + "${ProjDirPath}/../../../../../adapter/sources/sdk/adapter_sdk.c" + "${ProjDirPath}/../../../../../adapter/sources/sdk/adapter_sdk.h" + "${ProjDirPath}/../../../../include/compiler.h" + "${ProjDirPath}/../../../../include/types.h" + "${ProjDirPath}/../../../../include/usb.h" + "${ProjDirPath}/../../../../include/usb_desc.h" + "${ProjDirPath}/../../../../include/usb_error.h" + "${ProjDirPath}/../../../../include/usb_misc.h" + "${ProjDirPath}/../../../../include/usb_opt.h" + "${ProjDirPath}/../../../../include/usb_types.h" + "${ProjDirPath}/../../../include/usb_device_stack_interface.h" + "${ProjDirPath}/../../../sources/classes/include/usb_class.h" + "${ProjDirPath}/../../../sources/classes/include/usb_class_msc.h" + "${ProjDirPath}/../../../sources/classes/common/usb_class.c" + "${ProjDirPath}/../../../sources/classes/common/usb_class_internal.h" + "${ProjDirPath}/../../../sources/classes/msd/usb_msc.c" + "${ProjDirPath}/../../../sources/classes/msd/usb_msc.h" + "${ProjDirPath}/../../../sources/classes/msd/usb_msc_scsi.c" + "${ProjDirPath}/../../../sources/classes/msd/usb_msc_scsi.h" + "${ProjDirPath}/../../../sources/controller/usb_dev.c" + "${ProjDirPath}/../../../sources/controller/usb_dev.h" + "${ProjDirPath}/../../../sources/controller/usb_framework.c" + "${ProjDirPath}/../../../sources/controller/usb_framework.h" + "${ProjDirPath}/../../../sources/controller/khci/device_khci_interface.c" + "${ProjDirPath}/../../../sources/controller/khci/khci_dev.c" + "${ProjDirPath}/../../../sources/controller/khci/khci_dev.h" + "${ProjDirPath}/../../../sources/controller/khci/khci_dev_misc.h" + "${ProjDirPath}/../../../include/frdmkl27z/usb_device_config.h" + "${ProjDirPath}/../../../sources/bsp/frdmkl27z/usb_dev_bsp.c" +) + +SET_TARGET_PROPERTIES(KsdkUsbDevicePlatformLib PROPERTIES OUTPUT_NAME "libusbd_bm.a") diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.bat b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.bat new file mode 100755 index 0000000..fedfe7c --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.bat @@ -0,0 +1,5 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug . +mingw32-make -j4 +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release . +mingw32-make -j4 +pause diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.sh b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.sh new file mode 100755 index 0000000..3827529 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_all.sh @@ -0,0 +1,5 @@ +#!/bin/sh +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug . +make -j4 +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release . +make -j4 diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.bat b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.bat new file mode 100755 index 0000000..4f569ef --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.bat @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug . +mingw32-make -j4 +pause diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.sh b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.sh new file mode 100755 index 0000000..effd076 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_debug.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug . +make -j4 diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.bat b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.bat new file mode 100755 index 0000000..cc9d673 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.bat @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release . +mingw32-make -j4 +pause diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.sh b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.sh new file mode 100755 index 0000000..a12067d --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/build_release.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cmake -DCMAKE_TOOLCHAIN_FILE="../../../../../../tools/cmake_toolchain_files/armgcc.cmake" -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release . +make -j4 diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.bat b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.bat new file mode 100755 index 0000000..a3b733b --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.bat @@ -0,0 +1,3 @@ +RD /s /Q Debug Release CMakeFiles +DEL /s /Q /F Makefile cmake_install.cmake CMakeCache.txt +pause diff --git a/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.sh b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.sh new file mode 100755 index 0000000..795ad87 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/build/armgcc/usbd_sdk_frdmkl27z_bm/clean.sh @@ -0,0 +1,3 @@ +#!/bin/sh +rm -rf debug release CMakeFiles +rm -rf Makefile cmake_install.cmake CMakeCache.txt diff --git a/KSDK_1.2.0/usb/usb_core/device/include/frdmkl27z/usb_device_config.h b/KSDK_1.2.0/usb/usb_core/device/include/frdmkl27z/usb_device_config.h new file mode 100644 index 0000000..5ae49f8 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/include/frdmkl27z/usb_device_config.h @@ -0,0 +1,159 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 - 2015 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_device_config.h$ +* $Version : +* $Date : +* +* Comments: +* +* +* +*END************************************************************************/ + +#ifndef __usb_dev_config_h__ +#define __usb_dev_config_h__ + +/* if KHCI device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_KHCI 1 + +/* if EHCI device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_EHCI 0 + +/* how many device KHCI instance supported */ +#if USBCFG_DEV_KHCI +#define USBCFG_DEV_KHCI_NUM 1 +#else +#define USBCFG_DEV_KHCI_NUM 0 +#endif + +/* how many device EHCI instance supported */ +#if USBCFG_DEV_EHCI +#define USBCFG_DEV_EHCI_NUM 0 +#else +#define USBCFG_DEV_EHCI_NUM 0 +#endif + +/* how many device instance supported */ +#define USBCFG_DEV_NUM (USBCFG_DEV_KHCI_NUM + USBCFG_DEV_EHCI_NUM) + +/* if HID device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_HID 1 + +/* if PHDC device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_PHDC 1 + +/* if AUDIO device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_AUDIO 1 + +/* if CDC device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_CDC 1 + +/* if MSC device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_MSC 1 + +/* if composite device supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_COMPOSITE 0 + +/* if device is self powered + * 1 self power + * 0 bus power + */ +#define USBCFG_DEV_SELF_POWER 1 + +/* if device remote wakeup supported + * 1 supported + * 0 not supported + */ +#define USBCFG_DEV_REMOTE_WAKEUP 0 + +/* how many endpoints are supported */ +#define USBCFG_DEV_MAX_ENDPOINTS (6) + +/* how many XDs are supported at most */ +#define USBCFG_DEV_MAX_XDS (12) + +/* how many instance should be supported for one class type device */ +#define USBCFG_DEV_MAX_CLASS_OBJECT (1) + +#if USBCFG_DEV_KHCI + /* + ** Allow workaround for bug in the peripheral when unaligned buffer @4B address is used + */ + #define USBCFG_KHCI_4BYTE_ALIGN_FIX (1) + + #if USBCFG_KHCI_4BYTE_ALIGN_FIX + /* + ** The aligned buffer size for IN transactions, active when USBCFG_KHCI_4BYTE_ALIGN_FIX is defined + */ + #define USBCFG_DEV_KHCI_SWAP_BUF_MAX (64) + #endif + + #define USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING (0) +#endif + +/* if USB Keep Alive is enabled + * 1 enabled + * 0 not enabled + */ +#define USBCFG_DEV_KEEP_ALIVE_MODE (0) + +/* If the buffer provided by APP is cacheable +* 1 cacheable, buffer cache maintenance is needed +* 0 uncacheable, buffer cache maintenance is not needed +*/ +#define USBCFG_DEV_BUFF_PROPERTY_CACHEABLE (0) + +#define USBCFG_DEV_ADVANCED_SUSPEND_RESUME (0) + +#define USBCFG_DEV_ADVANCED_CANCEL_ENABLE (1) + +#define USBCFG_DEV_DETACH_ENABLE (0) + +#define USBCFG_DEV_IO_DETACH_ENABLE (0) + +#endif + diff --git a/KSDK_1.2.0/usb/usb_core/device/include/usb_device_stack_interface.h b/KSDK_1.2.0/usb/usb_core/device/include/usb_device_stack_interface.h new file mode 100644 index 0000000..ee2b1c9 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/include/usb_device_stack_interface.h @@ -0,0 +1,618 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_device_stack_interface.h$ + * $Version : + * $Date : + * + * Comments: + * + * + * + *END************************************************************************/ +/* Prototypes */ +#ifndef __usb_device_stack_interface_h__ +#define __usb_device_stack_interface_h__ + +#include "usb_types.h" + +/* Informational Request/Set Types */ +#define USB_STATUS_DEVICE_STATE (0x01) +#define USB_STATUS_INTERFACE (0x02) +#define USB_STATUS_ADDRESS (0x03) +#define USB_STATUS_CURRENT_CONFIG (0x04) +#define USB_STATUS_SOF_COUNT (0x05) +#define USB_STATUS_DEVICE (0x06) +#define USB_STATUS_TEST_MODE (0x07) +#define USB_STATUS_SPEED (0x08) + +#ifdef USBCFG_OTG +#define USB_STATUS_OTG (0x09) +#endif +#define USB_STATUS_ENDPOINT (0x10) +#define USB_STATUS_ENDPOINT_NUMBER_MASK (0x0F) + +#define USB_TEST_MODE_TEST_PACKET (0x0400) + +/* Available service types */ +/* Services 0 through 15 are reserved for endpoints */ +#define USB_SERVICE_EP0 (0x00) +#define USB_SERVICE_EP1 (0x01) +#define USB_SERVICE_EP2 (0x02) +#define USB_SERVICE_EP3 (0x03) +#define USB_SERVICE_BUS_RESET (0x10) +#define USB_SERVICE_SUSPEND (0x11) +//#define USB_SERVICE_SOF (0x12) +#define USB_SERVICE_RESUME (0x13) +#define USB_SERVICE_SLEEP (0x14) +#define USB_SERVICE_SPEED_DETECTION (0x15) +#define USB_SERVICE_ERROR (0x16) +//#define USB_SERVICE_STALL (0x17) +#define USB_SERVICE_REQUEST (0x18) +#define USB_SERVICE_DETACH (0x19) + +#define USB_CONTROL_ENDPOINT (0) +#define USB_SETUP_PKT_SIZE (8)/* Setup Packet Size */ +#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFF) + +#define USB_DEV_EVENT_BUS_RESET (0) +#define USB_DEV_EVENT_CONFIG_CHANGED (1) +#define USB_DEV_EVENT_INTERFACE_CHANGED (2) +#define USB_DEV_EVENT_ENUM_COMPLETE (3) +#define USB_DEV_EVENT_SEND_COMPLETE (4) +#define USB_DEV_EVENT_DATA_RECEIVED (5) +#define USB_DEV_EVENT_ERROR (6) +#define USB_DEV_EVENT_GET_DATA_BUFF (7) +#define USB_DEV_EVENT_EP_STALLED (8) +#define USB_DEV_EVENT_EP_UNSTALLED (9) +#define USB_DEV_EVENT_GET_TRANSFER_SIZE (0x10) +#define USB_DEV_EVENT_TYPE_SET_REMOTE_WAKEUP (0x11) +#define USB_DEV_EVENT_TYPE_CLR_REMOTE_WAKEUP (0x12) +#define USB_DEV_EVENT_TYPE_SET_EP_HALT (0x13) +#define USB_DEV_EVENT_TYPE_CLR_EP_HALT (0x14) +#define USB_DEV_EVENT_DETACH (0x15) + +/* Macros for description of class, configuration, interface */ +#define USB_DESC_INTERFACE(index, ep_cnt, ep) \ +{ \ + index, \ + { \ + ep_cnt, \ + ep \ + } \ +} +#define USB_DESC_CONFIGURATION(intf_cnt, intf) \ +{ \ + intf_cnt, \ + intf \ +} +#define USB_DESC_CLASS(type, config) \ +{ \ + type, \ + config, \ +} + +/* Go through each endpoint in class */ +#define for_each_ep_in_class_begin(epPtr, usbclassPtr, classtype) \ + for(uint32_t class_i = 0; usbclassPtr[class_i].type != USB_CLASS_INVALID; class_i++) \ + { \ + if((usbclassPtr[class_i].type == classtype) || (classtype == USB_CLASS_ALL)) \ + { \ + for(uint32_t intf_i = 0; intf_i < usbclassPtr[class_i].interfaces.count; intf_i++) \ + { \ + for(uint32_t ep_i = 0; \ + ((ep_i < usbclassPtr[class_i].interfaces.interface[intf_i].endpoints.count) && \ + ((epPtr = usbclassPtr[class_i].interfaces.interface[intf_i].endpoints.ep + ep_i) != NULL)); \ + ep_i++) \ + { +#define for_each_ep_in_class_end() }}}} + +/* Go through each interface in class */ +#define for_each_if_in_class_begin(ifPtr, usbclassPtr, classtype) \ + for(uint32_t class_i = 0; usbclassPtr[class_i].type != USB_CLASS_INVALID; class_i++) \ + { \ + if((usbclassPtr[class_i].type == classtype) || (classtype == USB_CLASS_ALL)) \ + { \ + for(uint32_t intf_i = 0; ((intf_i < usbclassPtr[class_i].interfaces.count) \ + && ((ifPtr = usbclassPtr[class_i].interfaces.interface + intf_i) != NULL)); \ + intf_i++) \ + { +#define for_each_if_in_class_end() }}} + +typedef enum +{ + USB_CLASS_INFO = 0, + USB_COMPOSITE_INFO, + USB_AUDIO_UNITS, + USB_RNDIS_INFO, + USB_PHDC_QOS_INFO, + USB_MSC_LBA_INFO, + USB_CLASS_INTERFACE_INDEX_INFO, +} entity_type; + +typedef enum +{ + USB_CLASS_HID = 0, + USB_CLASS_CDC, + USB_CLASS_MSC, + USB_CLASS_AUDIO, + USB_CLASS_PHDC, + USB_CLASS_ALL, + USB_CLASS_INVALID +} class_type; +/*! + * @brief Obtains the endpoint data structure. + * + * Define the endpoint data structure. + * + */ +typedef struct _usb_ep_struct +{ + uint8_t ep_num; /*!< endpoint number*/ + uint8_t type; /*!< type of endpoint*/ + uint8_t direction; /*!< direction of endpoint*/ + uint32_t size; /*!< maximum packet size of endpoint*/ +} usb_ep_struct_t; + +/*! + * @brief Obtains the endpoint group. + * + * Structure Representing Endpoints and number of endpoints user want. + * + */ +typedef struct _usb_endpoints +{ + uint8_t count; /*!< how many endpoints are described*/ + usb_ep_struct_t* ep; /*!< detailed information of each endpoint*/ +} usb_endpoints_t; + +/*! + * @brief Obtains the interface data structure. + * + * Structure Representing interface. + * + */ +typedef struct _usb_if_struct +{ + uint8_t index; /*!< interface index*/ + usb_endpoints_t endpoints; /*!< endpoints in this interface*/ +} usb_if_struct_t; + +/*! + * @brief Obtains the interface group. + * + * Structure Representing how many interfaces in one class type. + * + */ +typedef struct _usb_interfaces_struct +{ + uint8_t count; /*!< how many interfaces are described*/ + usb_if_struct_t* interface; /*!< detailed information of each interface*/ +} usb_interfaces_struct_t; + +/*! + * @brief Obtains the class data structure. + * + * Structure Representing class info. + * + */ +typedef struct _usb_class_struct +{ + class_type type; /*!< class type*/ + usb_interfaces_struct_t interfaces; /*!< interfaces in this class*/ +} usb_class_struct_t; + +/*! + * @brief Obtains the composite information data structure. + * + * Structure Representing composite info. + * + */ +typedef struct _usb_composite_info_struct +{ + uint8_t count; /*!< how many classes in the composite device*/ + usb_class_struct_t * class_handle; /*!< detailed information of each class*/ +} usb_composite_info_struct_t; + +/*! + * @brief Obtains the setup packet information data structure. + * + * Structure Representing setup packet. + * + */ +typedef struct _usb_setup_struct +{ + uint8_t request_type; /*!< type of request*/ + uint8_t request; /*!< id of request*/ + uint16_t value; /*!< value of request*/ + uint16_t index; /*!< interface index*/ + uint16_t length; /*!< data length of request*/ +} usb_setup_struct_t; + +/* USB Specs define CONTROL_MAX_PACKET_SIZE for High Speed device as only 64, + whereas for FS its allowed to be 8, 16, 32 or 64 */ +#define CONTROL_MAX_PACKET_SIZE (64) + +#if (USBCFG_DEV_EHCI && (CONTROL_MAX_PACKET_SIZE != 64)) +#error "For High Speed CONTROL_MAX_PACKET_SIZE should be 64" +#endif + +/*! + * @brief Obtains the event information. + * + * Structure Representing event for an endpoint. + * + */ +typedef struct _usb_event_struct +{ + usb_device_handle handle; /* controller device handle*/ + uint8_t* buffer_ptr; /* void* to buffer */ + uint32_t len; /* the buffer len had been done + * special case: 0xFFFFFFFF means transfer cancel + * 0xFFFFFFFE means tansfer error */ + uint8_t ep_num; /* endpoint number */ + uint8_t type; + bool setup; /* is setup packet */ + bool direction; /* direction of endpoint */ +} usb_event_struct_t; + +/* callback function pointer structure for Application to handle events */ +typedef void(_CODE_PTR_ usb_device_notify_t)(uint8_t event, void* val, void* arg); + +/* callback function pointer structure to handle USB framework request */ +typedef usb_status (_CODE_PTR_ usb_request_notify_t)(usb_setup_struct_t * setup, +uint8_t **data, +uint32_t *size,void* arg); + +typedef void(_CODE_PTR_ usb_event_service_t)(usb_event_struct_t* event, void* arg); + +/*! + * @brief Obtains the data structure of the descriptor related callback function. The application needs to implement them and passes it as the configuration parameter. + * + * Structure Representing the descriptor related callback function. + * + */ +typedef struct _usb_desc_request_notify_struct +{ +#ifdef USBCFG_OTG + uint32_t handle; +#endif + uint8_t (_CODE_PTR_ get_desc)(uint32_t class_handle,uint8_t type,uint8_t desc_index, + uint16_t index,uint8_t * *descriptor,uint32_t *size); /*!< to get the descriptor whose type is specified by the type*/ + uint8_t (_CODE_PTR_ get_desc_interface)(uint32_t class_handle,uint8_t interface, + uint8_t * alt_interface); /*!< to get the interface's alternate setting*/ + uint8_t (_CODE_PTR_ set_desc_interface)(uint32_t class_handle,uint8_t interface, + uint8_t alt_interface); /*!< to set the interface's alternate setting*/ + uint8_t (_CODE_PTR_ set_configuration)(uint32_t class_handle, uint8_t config); /*!< to inform the application whose configuration is active */ + uint8_t (_CODE_PTR_ get_desc_entity)(uint32_t class_handle, entity_type type, uint32_t * object); /*!< to get the descriptor/device related information*/ +} usb_desc_request_notify_struct_t; + +/*! + * @brief Obtains the callback for application. + * + * Structure Representing information for application callback. + * + */ +typedef struct usb_application_callback_struct +{ + usb_device_notify_t callback; /*!< application callback function*/ + void* arg; /*!< parameter for callback function*/ +}usb_application_callback_struct_t; + +/*! + * @brief Obtains the callback for vendor request. + * + * Structure Representing information for vendor request callback. + * + */ +typedef struct usb_vendor_req_callback_struct +{ + usb_request_notify_t callback; /*!< vendor request callback function*/ + void* arg; /*!< parameter for callback function*/ +}usb_vendor_req_callback_struct_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief Initializes the USB device controller. + * + * The function initializes the device controller specified by the controller_id and a device + * handle can be returned from the handle. + * + * @param controller_id controller ID, such as USB_CONTROLLER_KHCI_0 + * @param handle USB Device handle + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_init(uint8_t controller_id, usb_device_handle * handle); + +/*! + * @brief Un-initializes the USB device controller. + * + * The function un-initializes the device controller specified bcontroller_idy the handle. + * + * @param handle USB Device handle + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_deinit(usb_device_handle handle); + +/*! + * @brief Receives data from a specified endpoint. + * + * The function is used to receive data from a specified endpoint. + * + * @param handle USB Device handle + * @param ep_index endpoint index + * @param buff_ptr memory address to receive the data + * @param size length of the packet to be received + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_recv_data(usb_device_handle handle, uint8_t ep_num, uint8_t * buff_ptr, uint32_t size); + +/*! + * @brief Sends data from a specified endpoint. + * + * The function is used to send data to a specified endpoint. + * + * @param handle USB Device handle + * @param ep_index endpoint index + * @param buff_ptr memory address hold the data need to be sent + * @param size length of the packet to be sent + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_send_data(usb_device_handle handle, uint8_t ep_num, uint8_t * buff_ptr, uint32_t size); + +#if ((defined USBCFG_DEV_ADVANCED_CANCEL_ENABLE) && (USBCFG_DEV_ADVANCED_CANCEL_ENABLE)) +/*! + * @brief Cancels all the pending transfers in a specified endpoint. + * + * The function is used to cancel all the pending transfer in a specified endpoint which + * is determined by the endpoint index and the direction + * + * @param handle USB Device handle + * @param ep_index endpoint index + * @param direction direction of the endpoint + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_cancel_transfer(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + +#endif +/*! + * @brief Registers a callback function for one specified endpoint. + * + * The function is used to register a callback function for one specified endpoint. + * + * @param handle USB Device handle + * @param type service type, type & 0xF is the endpoint index + * @param service callback function + * @param arg second parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_register_service(usb_device_handle handle, uint8_t type, usb_event_service_t service, void* arg); + +/*! + * @brief Unregisters a callback function for one specified endpoint. + * + * The function is used to unregister a callback function for one specified endpoint. + * + * @param handle USB Device handle + * @param type service type, type & 0xF is the endpoint index + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_unregister_service(usb_device_handle handle, uint8_t type); + +#if ((defined USBCFG_DEV_ADVANCED_SUSPEND_RESUME) && (USBCFG_DEV_ADVANCED_SUSPEND_RESUME)) +/*! + * @brief Resume the process of usb. + * + * The function resumes the process of usb. + * + * @param handle USB Device handle + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_assert_resume(usb_device_handle handle); + +#endif +/*! + * @brief Initializes the specified endpoint. + * + * The function is used to initialize a specific endpoint which is determined by the ep_ptr. + * + * @param handle USB Device handle + * @param ep_ptr endpoint information + * @param flag whether the ZLT is enabled for this endpoint + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_init_endpoint(usb_device_handle handle, usb_ep_struct_t* ep_ptr, uint8_t flag); + +/*! + * @brief Stalls the specified endpoint. + * + * The function is used to stall a specific endpoint which is determined by the endpoint + * index and endpoint direction. + * + * @param handle USB Device handle + * @param ep_num endpoint index + * @param direction endpoint direction + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_stall_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + +/*! + * @brief Un-stalls the specified endpoint. + * + * The function is used to un-stall a specific endpoint which is determined by the endpoint + * index and endpoint direction + * + * @param handle USB Device handle + * @param ep_num endpoint index + * @param direction endpoint direction + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_unstall_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + +/*! + * @brief Un-initializes the specified endpoint. + * + * The function is used to un-initialize a specific endpoint which is determined by the endpoint + * index and endpoint direction. + * + * @param handle USB Device handle + * @param ep_num endpoint index + * @param direction endpoint direction + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_deinit_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + +/*! + * @brief Registers the callback function for the application related event. + * + * The function is used to register a callback function for the application related event. + * Currently the following events are supported: + * Event Description + * USB_DEV_EVENT_BUS_RESET A BUS reset is received. + * USB_DEV_EVENT_ENUM_COMPLETE The device enumerated process completes. + * USB_DEV_EVENT_CONFIG_CHANGED Host sends a set_configuration. + * USB_DEV_EVENT_ERROR Error. + * + * @param handle USB Device handle + * @param device_notify_callback callback function + * @param device_notify_param parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_register_application_notify(usb_device_handle handle, usb_device_notify_t device_notify_callback, void* device_notify_param); + +/*! + * @brief Registers the callback function for the vendor class related event. + * + * The function is used to register a callback function for the vendor class request related event. + * Currently the vendor class is not implemented, so both the request_notify_callback and + * request_notify_param can be set to NULL. + * + * @param handle USB Device handle + * @param request_notify_callback callback function + * @param request_notify_param parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_register_vendor_class_request_notify(usb_device_handle handle, usb_request_notify_t request_notify_callback, void* request_notify_param); + +/*! + * @brief Registers the callback functions for the device descriptor related request. + * + * The function is used to register a set of callback functions for the device descriptor related event. + * + * @param handle USB Device handle + * @param desc_request_notify_callback callback function + * @param desc_request_notify_param parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_register_desc_request_notify(usb_device_handle handle,usb_desc_request_notify_struct_t* desc_request_notify_callback, void* desc_request_notify_param); + +/*! + * @brief Gets the internal USB device state. + * + * The function is used to get the status of the specified component. The supported components include: + * USB_STATUS_DEVICE_STATE + * USB_STATUS_OTG + * USB_STATUS_DEVICE + * USB_STATUS_ENDPOINT, the LSB nibble carries the endpoint number + * + * @param handle USB Device handle + * @param component callback function + * @param status requested status + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_get_status(usb_device_handle handle, uint8_t component, uint16_t* error); + +/*! + * @brief Sets the internal USB device state. + * + * The function is used to set the status of the specified component. The supported components include: + * USB_STATUS_DEVICE_STATE + * USB_STATUS_OTG + * USB_STATUS_DEVICE + * + * @param handle USB Device handle + * @param component callback function + * @param status status to set + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_set_status(usb_device_handle handle, uint8_t component, uint16_t setting); + +/*! + * @brief Initializes the USB device controller. + * + * The function starts the initialization process that cannot be done in the usb_device_init() API. + * For example, the call back functions need to be registered after the device handle can be + * obtained from the usb_device_init() API. Therefore, the USB interrupt cannot be enabled in + * usb_device_init(); otherwise, the USB interrupt can be issued before the callback functions are + * registered. To avoid this issue, the USB interrupt will be enabled in the post initialization process. + * + * @param controller_id controller ID, such as USB_CONTROLLER_KHCI_0 + * @param handle USB Device handle + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_postinit(uint8_t controller_id, usb_device_handle handle); + +#ifdef USBCFG_OTG +/*! + * @brief Initializes the USB device OTG. + * + * The function initializes the device OTG specified by the device handle. + * + * @param handle USB Device handle + * @param otg_attributes Attributes used to initialize otg. Currently supported are + * OTG_SRP_SUPPORT OTG_HNP_SUPPORT + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_otg_init(usb_device_handle handle, uint8_t otg_attributes); + +/*! + * @brief Get the status of whether OTG hnp is supported. + * + * The function get the status of whether OTG hnp is supported. + * + * @param handle USB Device handle + * @param hnp_support_ptr TRUE-supported/FALSE-not supported + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_otg_get_hnp_support(usb_device_handle handle, uint8_t* hnp_support_ptr); + +/*! + * @brief Enable the OTG hnp. + * + * The function enable the OTG hnp feature. + * + * @param handle USB Device handle + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_otg_set_hnp_enable(usb_device_handle handle); + +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/bsp/frdmkl27z/usb_dev_bsp.c b/KSDK_1.2.0/usb/usb_core/device/sources/bsp/frdmkl27z/usb_dev_bsp.c new file mode 100644 index 0000000..0827537 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/bsp/frdmkl27z/usb_dev_bsp.c @@ -0,0 +1,153 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2013 - 2015 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* Comments: +* +*END************************************************************************/ +#include "adapter.h" +#include "usb.h" +#include "usb_device_config.h" +#include "usb_misc.h" +#include "fsl_usb_khci_hal.h" +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +#include +#include +#include +#include "fsl_device_registers.h" +#include "fsl_clock_manager.h" +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + #if (defined(CPU_MKL27Z64VLH4)) +#include "MKL27Z644/MKL27Z644_sim.h" +#include "MKL27Z644/MKL27Z644_usb.h" + #endif +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) +#include "MKL27Z644.h" +#endif +#include "usb_device_config.h" +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +#define BSP_USB_INT_LEVEL (4) +#define USB_CLK_RECOVER_IRC_EN (*(volatile unsigned char *)0x40072144) +#define BSPCFG_USB_USE_IRC48M (1) + +extern uint8_t soc_get_usb_vector_number(uint8_t controller_id); +extern uint32_t soc_get_usb_base_address(uint8_t controller_id); +#ifdef __cplusplus +extern "C" { +#endif +extern _WEAK_FUNCTION(usb_status bsp_usb_dev_board_init(uint8_t controller_id)); +#ifdef __cplusplus + } +#endif + +static usb_status bsp_usb_dev_soc_init +( + uint8_t controller_id +) +{ + int32_t ret = USB_OK; + uint8_t usb_instance = 0; + uint32_t base_addres = 0; + if (USB_CONTROLLER_KHCI_0==controller_id ) + { + usb_instance = controller_id - USB_CONTROLLER_KHCI_0; + base_addres = soc_get_usb_base_address(controller_id); +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +#if BSPCFG_USB_USE_IRC48M + /* IRC48MHz selected as CLK source */ + CLOCK_SYS_SetUsbfsSrc(usb_instance, kClockUsbfsSrcIrc48M); + /* USB Clock Gating */ + CLOCK_SYS_EnableUsbfsClock(usb_instance); + /* Enable IRC 48MHz for USB module, the regulator is always enabled on KL27 */ + USB_CLK_RECOVER_IRC_EN = USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK; +#else + /* USB_CLKIN selected as CLK source */ + CLOCK_SYS_SetUsbfsSrc(usb_instance, kClockUsbfsSrcExt); + + /* USB Clock Gating */ + CLOCK_SYS_EnableUsbfsClock(usb_instance); +#endif + + /* reset USB CTRL register */ + usb_hal_khci_reset_control_register(base_addres); +#if USBCFG_DEV_KEEP_ALIVE_MODE + USB0_CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; + USB0_KEEP_ALIVE_CTRL = USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK|USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK + |USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN_MASK|USB_KEEP_ALIVE_CTRL_AHB_DLY_EN_MASK + |USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK; + /* wake on out and setup transaction */ + USB0_KEEP_ALIVE_WKCTRL = 0x1; + MCG_MC |= MCG_MC_HIRCLPEN_MASK; + PMC_REGSC |= PMC_REGSC_BGEN_MASK|PMC_REGSC_VLPO_MASK; +#endif + + /* Enable internal pull-up resistor */ + usb_hal_khci_set_internal_pullup(base_addres); + usb_hal_khci_set_trc0(base_addres); /* Software must set this bit to 1 */ + + /* setup interrupt */ + OS_intr_init((IRQn_Type)soc_get_usb_vector_number(controller_id), BSP_USB_INT_LEVEL, 0, TRUE); + +#endif + } + else + { + ret = USBERR_BAD_STATUS; //unknow controller + } + + return ret; +} + +_WEAK_FUNCTION (usb_status bsp_usb_dev_board_init(uint8_t controller_id)) +{ + usb_status ret = USB_OK; + + controller_id = bsp_usb_dev_soc_init(controller_id); + if ( USB_CONTROLLER_KHCI_0==controller_id) + { +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) + +#else + +#endif + } + else + { + ret = USBERR_BAD_STATUS; + } + + return ret; +} +usb_status bsp_usb_dev_init(uint8_t controller_id) +{ + usb_status ret = USB_OK; + + ret = bsp_usb_dev_soc_init(controller_id); + if (ret == USB_OK) + { + ret = bsp_usb_dev_board_init(controller_id); + } + + return ret; +} + +#endif +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class.c b/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class.c new file mode 100644 index 0000000..6cb89ca --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class.c @@ -0,0 +1,376 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_class.c$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file contains USB stack Class module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device_stack_interface.h" +#include "usb_class_internal.h" + +#if USBCFG_DEV_HID || USBCFG_DEV_PHDC || USBCFG_DEV_AUDIO || USBCFG_DEV_CDC || USBCFG_DEV_MSC + +#include "usb_class_internal.h" +#include "usb_framework.h" + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +static usb_class_object_struct_t usb_class_object[USBCFG_DEV_MAX_CLASS_OBJECT]; +#if USBCFG_DEV_COMPOSITE +static class_handle_t s_class_handle = USB_UNINITIALIZED_VAL_32; +#endif +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ + +/***************************************************************************** + * Local Functions - None + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/*************************************************************************//*! + * + * @name USB_Class_Allocate_Handle + * + * @brief The function reserves entry in device array and returns the index. + * + * @param none. + * @return returns the reserved handle or if no entry found device busy. + * + *****************************************************************************/ +static usb_status USB_Class_Allocate_Handle(usb_class_object_struct_t** pclassobj) +{ + int32_t cnt = 0; + for (;cnt< USBCFG_DEV_MAX_CLASS_OBJECT;cnt++) + { + if (usb_class_object[cnt].controller_handle == NULL) + { + *pclassobj = &usb_class_object[cnt]; + return USB_OK; + } + } + return USBERR_DEVICE_BUSY; +} + +/*************************************************************************//*! + * + * @name USB_Class_Free_Handle + * + * @brief The function releases entry in device array . + * + * @param handle index in device array to be released.. + * @return returns and error code or USB_OK. + * + *****************************************************************************/ +static usb_status USB_Class_Free_Handle(usb_class_object_struct_t* handle) +{ + int32_t cnt = 0; + for (;cnt< USBCFG_DEV_MAX_CLASS_OBJECT;cnt++) + { + if (&usb_class_object[cnt] == handle) + { + usb_class_object[cnt].controller_handle = NULL; + usb_class_object[cnt].usb_fw_handle = 0; + usb_class_object[cnt].arg = NULL; + usb_class_object[cnt].class_callback = NULL; + return USB_OK; + } + } + + return USBERR_INVALID_PARAM; +} + +/**************************************************************************//*! + * + * @name USB_Class_Init + * + * @brief The function initializes the Class Module + * + * @param handle :handle to Identify the controller + * @param class_callback :event callback + * @param other_req_callback :call back for class/vendor specific requests on + * CONTROL ENDPOINT + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +class_handle_t USB_Class_Init +( +usb_device_handle handle, /* [IN] the USB device controller to initialize */ +usb_device_notify_t class_callback,/*[IN]*/ +usb_request_notify_t other_req_callback,/*[IN]*/ +void* user_arg,/*[IN]*/ +usb_desc_request_notify_struct_t* desc_callback_ptr/*[IN]*/ +) +{ + usb_class_object_struct_t* class_object_ptr = NULL; + usb_status ret; + + ret = USB_Class_Allocate_Handle(&class_object_ptr); + if (USBERR_DEVICE_BUSY == ret) + { + return USBERR_DEVICE_BUSY; + } + + class_object_ptr->controller_handle = handle; + class_object_ptr->class_callback = class_callback; + class_object_ptr->arg = user_arg; + + usb_device_register_application_notify(handle, class_callback, user_arg); + usb_device_register_vendor_class_request_notify(handle, other_req_callback, user_arg); + usb_device_register_desc_request_notify(handle, desc_callback_ptr, user_arg); + +#ifdef USBCFG_OTG + { + descriptor_union_t desc; + uint32_t config_size; + usb_status error; + uint8_t i; + uint8_t bm_attributes = 0; + error = desc_callback_ptr->get_desc(desc_callback_ptr->handle,USB_DESC_TYPE_CFG,0,0,(uint8_t **)&desc,&config_size); + if(error == USB_OK) + { + config_size = USB_SHORT_LE_TO_HOST(*(uint16_t*)&desc.cfig->wTotalLength[0]); + i= desc.cfig->bLength; + desc.word += desc.cfig->bLength; + while(ibDescriptorType == USB_DESC_TYPE_OTG) + { + /* Found the OTG descriptor */ + bm_attributes = desc.otg->bmAttributes; + break; + } /* Endif */ + i += desc.otg->bLength; + desc.word += desc.otg->bLength; + } + } + usb_device_otg_init(handle, bm_attributes); + } +#endif +#if USBCFG_DEV_COMPOSITE + /* Suppose only one class handle can be assigned */ + s_class_handle = (class_handle_t)class_object_ptr; +#endif + return (class_handle_t)class_object_ptr; +} + +/**************************************************************************//*! + * + * @name USB_Class_Deinit + * + * @brief The function initializes the Class Module + * + * @param handle :handle to Identify the controller + * @param class_handle :class handle + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Deinit +( +usb_device_handle handle, /* [IN] the USB device controller to initialize */ +class_handle_t class_handle +) +{ + usb_status error = USB_OK; + + error = USB_Class_Free_Handle((usb_class_object_struct_t*)class_handle); + +#if USBCFG_DEV_COMPOSITE + /* Suppose only one class handle can be assigned */ + s_class_handle = USB_UNINITIALIZED_VAL_32; +#endif + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Class_Send_Data + * + * @brief The function calls the device to send data upon receiving an IN token + * + * @param handle: handle to Identify the controller + * @param ep_num: The endpoint number + * @param buff_ptr: buffer to send + * @param size: length of transfer + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Send_Data +( +class_handle_t handle, /*[IN]*/ +uint8_t ep_num, /* [IN] the Endpoint number */ +uint8_t * buff_ptr, /* [IN] buffer to send */ +uint32_t size /* [IN] length of the transfer */ +) +{ + usb_status error = USB_OK; + //uint16_t state; + usb_class_object_struct_t* class_object_ptr = (usb_class_object_struct_t*)handle; + + if (NULL == class_object_ptr) + { + return USBERR_ERROR; + } + + error = usb_device_send_data(class_object_ptr->controller_handle, + ep_num,buff_ptr,size); + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Class_Get_Status + * + * @brief The funtion calls the device to send data upon recieving an IN token + * + * @param handle: handle to Identify the controller + * @param component: component code + * @param error_code: the requested error + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Get_Status +( +class_handle_t handle, /* [IN] */ +uint8_t component, /* [IN] component code */ +uint16_t * error_code /* [OUT] the requested error */ +) +{ + usb_status error = USB_OK; + usb_class_object_struct_t* class_object_ptr = (usb_class_object_struct_t*)handle; + + if (NULL == class_object_ptr) + { + return USBERR_ERROR; + } + + error = usb_device_get_status(class_object_ptr->controller_handle, + component,error_code); + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Class_Periodic_Task + * + * @brief The function calls for periodic tasks + * + * @param None + * + * @return None + * + *****************************************************************************/ +void USB_Class_Periodic_Task(void) +{ +#ifdef DELAYED_PROCESSING + USB_Framework_Periodic_Task(); +#endif +} + +#if USBCFG_DEV_COMPOSITE +/**************************************************************************//*! + * + * @name USB_Class_Get_Class_Handle + * + * @brief This function is called to return class handle. + * + * @return value: + * class handle + * + *****************************************************************************/ +class_handle_t USB_Class_Get_Class_Handle(void) +{ + return s_class_handle; +} + +/**************************************************************************//*! + * + * @name USB_Class_Get_Ctrler_Handle + * + * @brief This function is called to return controller handle. + * + * @return value: + * controller handle + * + *****************************************************************************/ +usb_device_handle USB_Class_Get_Ctrler_Handle(class_handle_t class_handle) +{ + usb_device_handle ret; + if(USB_UNINITIALIZED_VAL_32 != class_handle) + { + ret = ((usb_class_object_struct_t*)class_handle)->controller_handle; + } + else + { + ret = NULL; + } + return ret; +} +#endif + +#endif +/* EOF */ + diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class_internal.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class_internal.h new file mode 100644 index 0000000..e3cd99f --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/common/usb_class_internal.h @@ -0,0 +1,186 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_class_internal.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains USB stack class layer api header function. +* +*****************************************************************************/ + +#ifndef _USB_CLASS_INTERNAL_H +#define _USB_CLASS_INTERNAL_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_class.h" + + +/****************************************************************************** + * Global Variables + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ + +/****************************************************************************** + * Types + *****************************************************************************/ +/* Structure holding USB class object state*/ +typedef struct _usb_class_object +{ + uint32_t usb_fw_handle; + usb_device_handle controller_handle; + void* arg; + usb_device_notify_t class_callback; +} usb_class_object_struct_t; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Class_Init + * + * @brief The function initializes the Class Module + * + * @param handle :handle to Identify the controller + * @param class_callback :event callback + * @param other_req_callback :call back for class/vendor specific requests on + * CONTROL ENDPOINT + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +class_handle_t USB_Class_Init +( + usb_device_handle handle, /* [IN] the USB device controller to initialize */ + usb_device_notify_t class_callback, /*[IN]*/ + usb_request_notify_t other_req_callback,/*[IN]*/ + void* user_arg, /*[IN]*/ + usb_desc_request_notify_struct_t* desc_callback_ptr /*[IN]*/ +); + +/**************************************************************************//*! + * + * @name USB_Class_Deinit + * + * @brief The function initializes the Class Module + * + * @param handle :handle to Identify the controller + * @param class_handle :class handle + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Deinit +( + usb_device_handle handle, /* [IN] the USB device controller to initialize */ + class_handle_t class_handle + ); + /**************************************************************************//*! + * + * @name USB_Class_Send_Data + * + * @brief The function calls the device to send data upon receiving an IN token + * + * @param handle: handle to Identify the controller + * @param ep_num: The endpoint number + * @param buff_ptr: buffer to send + * @param size: length of transfer + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Send_Data +( + class_handle_t handle, /*[IN]*/ + uint8_t ep_num, /* [IN] the Endpoint number */ + uint8_t* buff_ptr, /* [IN] buffer to send */ + uint32_t size /* [IN] length of the transfer */ +); + +/**************************************************************************//*! + * + * @name USB_Class_Get_Status + * + * @brief The funtion calls the device to send data upon recieving an IN token + * + * @param handle: handle to Identify the controller + * @param component: component code + * @param error_code: the requested error + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + *****************************************************************************/ +usb_status USB_Class_Get_Status +( + class_handle_t handle, /* [IN] */ + uint8_t component, /* [IN] component code */ + uint16_t * error_code /* [OUT] the requested error */ +); + + +#ifdef USBCFG_DEV_COMPOSITE +/**************************************************************************//*! + * + * @name USB_Class_Get_Class_Handle + * + * @brief This function is called to return class handle. + * + * @return value: + * class handle + * + *****************************************************************************/ +class_handle_t USB_Class_Get_Class_Handle(void); + +/**************************************************************************//*! + * + * @name USB_Class_Get_Ctrler_Handle + * + * @brief This function is called to return controller handle. + * + * @return value: + * controller handle + * + *****************************************************************************/ +usb_device_handle USB_Class_Get_Ctrler_Handle(class_handle_t class_handle); +#endif + +#endif + +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/config/usb_msc_config.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/config/usb_msc_config.h new file mode 100644 index 0000000..3363cbb --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/config/usb_msc_config.h @@ -0,0 +1,54 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2014-2015 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_msc_config.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains USB stack MSC class layer api header function. +* +*****************************************************************************/ + +#ifndef _USB_MSC_CONFIG_H +#define _USB_MSC_CONFIG_H 1 + +/****************************************************************************** + * Macro's + *****************************************************************************/ + +/* If Implementing Disk Drive then configure the macro below as TRUE, + otherwise keep it False(say for Hard Disk)*/ +#define IMPLEMENTING_DISK_DRIVE (0) /*1: TRUE; 0:FALSE*/ + +#define MSD_RECV_MAX_TRANS_LENGTH (65536) +#define MSD_SEND_MAX_TRANS_LENGTH (65536) + +#define MAX_MSC_DEVICE (0x01) +#define MAX_MSC_SUPPORTED_INTERFACES (0x01) + + +#endif + diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class.h new file mode 100644 index 0000000..883c8e3 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class.h @@ -0,0 +1,116 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_class.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains USB stack class layer api header function. +* +*****************************************************************************/ + +#ifndef _USB_CLASS_H +#define _USB_CLASS_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "types.h" + +/****************************************************************************** + * Global Variables + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ + /*#define DELAYED_PROCESSING 1 This define is used to delay the control + processing and not have it executed as part + of the interrupt routine */ + +//#define UNINITIALISED_VAL (0xffffffff) +/* Events to the Application */ +/* +#define USB_APP_BUS_RESET (0) +#define USB_APP_CONFIG_CHANGED (1) +#define USB_APP_ENUM_COMPLETE (2) +#define USB_APP_SEND_COMPLETE (3) +#define USB_APP_DATA_RECEIVED (4) +#define USB_APP_ERROR (5) +#define USB_APP_GET_DATA_BUFF (6) +#define USB_APP_EP_STALLED (7) +#define USB_APP_EP_UNSTALLED (8) +#define USB_APP_GET_TRANSFER_SIZE (9) +*/ + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef uint32_t class_handle_t; + +/*callback function pointer structure for application to provide class params*/ +typedef uint8_t (_CODE_PTR_ usb_class_specific_handler_func)( + uint8_t event, + uint16_t value, + uint8_t **data, + uint32_t* size, + void* arg); + + +typedef struct usb_class_specific_handler_callback_struct +{ + usb_class_specific_handler_func callback; + void* arg; +}usb_class_specific_callback_struct_t; + + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +#if defined(__cplusplus) + extern "C" { +#endif +/**************************************************************************//*! + * + * @name USB_Class_Periodic_Task + * + * @brief The function calls for periodic tasks + * + * @param None + * + * @return None + * + *****************************************************************************/ +extern void USB_Class_Periodic_Task(void); + +#if defined(__cplusplus) + } +#endif + +#endif + +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class_msc.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class_msc.h new file mode 100644 index 0000000..3ada631 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/include/usb_class_msc.h @@ -0,0 +1,201 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_class_msc.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief +* +*****************************************************************************/ + +#ifndef _USB_CLASS_MSC_H +#define _USB_CLASS_MSC_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_class.h" +#include "usb_device_stack_interface.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_MSC_CLASS_EP_NUM 2 + +#define USB_MSC_DEVICE_READ_REQUEST (0x81) +#define USB_MSC_DEVICE_WRITE_REQUEST (0x82) +#define USB_MSC_DEVICE_FORMAT_COMPLETE (0x83) +#define USB_MSC_DEVICE_REMOVAL_REQUEST (0x84) +#define USB_MSC_DEVICE_GET_INFO (0x85) +#define USB_MSC_START_STOP_EJECT_MEDIA (0x86) +#define USB_MSC_DEVICE_GET_SEND_BUFF_INFO (0x87) +#define USB_MSC_DEVICE_GET_RECV_BUFF_INFO (0x88) + +/* macros for queuing */ + #define MSD_MAX_QUEUE_ELEMS (4) + + #define USB_REQ_VAL_INVALID (0xFFFF) + +typedef uint32_t msd_handle_t; + +/*! + * @brief MSC app data structure. + * + * Holds the information of msc app data struct + * + */ +typedef struct _msc_app_data_struct +{ + uint8_t* data_ptr; /*!< pointer to buffer */ + uint32_t data_size; /*!< buffer size of endpoint*/ +}msc_app_data_struct_t; + +/*! + * @brief MSC detailed information about the LAB structure. + * + * Holds the detailed information about the LAB + * + */ +typedef struct _device_lba_info_struct +{ + uint32_t total_lba_device_supports; /*!< blocks number */ + uint32_t length_of_each_lab_of_device; /*!< size of each block*/ + uint8_t num_lun_supported; /*!< number of LUN*/ +}device_lba_info_struct_t; + +/*! + * @brief MSC buffer information structure. + * + * Holds the detailed information about the buffer + * + */ +typedef struct _msd_buffers_info +{ + uint8_t* msc_bulk_in_ptr; /*!< pointer to bulk in buffer*/ + uint8_t* msc_bulk_out_ptr; /*!< pointer to bulk out buffer*/ + uint32_t msc_bulk_in_size; /*!< size of bulk in buffer*/ + uint32_t msc_bulk_out_size;/*!< size of bulk out buffer*/ +}msc_buff_info_t; + +/*! + * @brief MSD Configuration structure to be passed by APP + * + * Holds the detailed information about the MSC configuration + * + */ +typedef struct _msc_config_struct +{ + /* SCSI related initialization data. To be moved to SCSI layer.*/ + + usb_application_callback_struct_t msc_application_callback; /*!< application callback function to handle the Device status related event*/ + usb_vendor_req_callback_struct_t vendor_req_callback; /*!< application callback function to handle the vendor request related event, reserved for future use*/ + usb_class_specific_callback_struct_t class_specific_callback; /*!< application callback function to handle all the class related event*/ + usb_desc_request_notify_struct_t* desc_callback_ptr; /*!< descriptor related callback function data structure*/ +}msc_config_struct_t; + +/*! + * @brief MSC logical block access information structure. + * + * Holds the information used to perform the logical block access + * + */ +typedef struct _lba_app_struct +{ + uint32_t offset; /*!< offset of target block need to access*/ + uint32_t size; /*!< size need to access*/ + uint8_t* buff_ptr; /*!< used to save the content by access the target block*/ +}lba_app_struct_t; +//extern void USB_Class_Periodic_Task(void); +#define USB_MSC_Periodic_Task USB_Class_Periodic_Task +/****************************************************************************** + * Global Functions + *****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif +/*! +* @brief The function initializes the Device and Controller layer. +* +* The application calls this API function to initialize the MSD class, the underlying layers, and +* the controller hardware. +* +* @param controller_id controller ID, such as USB_CONTROLLER_KHCI_0 +* @param msd_config_ptr MSD configuration structure +* @param msd_handle pointer point to the initialized MSD class +* @return USB_OK-Success/Others-Fail +*/ +extern usb_status USB_Class_MSC_Init +( + uint8_t controller_id, + msc_config_struct_t* msd_config_ptr, + msd_handle_t * msd_handle +); + +/*! + * @brief The function De-initializes the Device and Controller layer. + * + * The application calls this API function to de-initialize the MSD class, the underlying layers, and + * the controller hardware. + * + * @param msd_handle MSC class handler + * @return USB_OK-Success/Others-Fail + */ +extern usb_status USB_Class_MSC_Deinit +( + msd_handle_t msd_handle +); + + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Get_Speed + * + * @brief This functions get speed from Host. + * + * @param handle : handle returned by USB_Class_MSC_Init + * @param speed : speed + * + * @return status + * USB_OK : When Successfull + * Others : Errors + *****************************************************************************/ +extern usb_status USB_Class_MSC_Get_Speed +( + msd_handle_t handle, + uint16_t * speed/* [OUT] the requested error */ +); +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.c b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.c new file mode 100644 index 0000000..e29bca8 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.c @@ -0,0 +1,1580 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_msc.c$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file contains USB stack MSC layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device_stack_interface.h" + +#if USBCFG_DEV_MSC +#include "usb_class_internal.h" +#include "usb_msc.h" +#include "usb_opt.h" +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +msc_device_struct_t g_msc_class[MAX_MSC_DEVICE]; + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK))) +cbw_t g_msc_class_cbw; +csw_t g_msc_class_csw; +#endif +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +usb_status process_mass_storage_command (msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr); + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +/*************************************************************************//*! + * + * @name USB_Msd_Allocate_Handle + * + * @brief The function reserves entry in device array and returns the index. + * + * @param none. + * @return returns the reserved handle or if no entry found device busy. + * + *****************************************************************************/ +static usb_status USB_Msd_Allocate_Handle(msc_device_struct_t** handle) +{ + uint32_t cnt = 0; + for (;cnt< MAX_MSC_DEVICE;cnt++) + { + if (g_msc_class[cnt].controller_handle == NULL) + { + *handle = (msc_device_struct_t*)&g_msc_class[cnt]; + return USB_OK; + } + } + return USBERR_DEVICE_BUSY; +} +/*************************************************************************//*! + * + * @name USB_Msd_Free_Handle + * + * @brief The function releases entry in device array . + * + * @param handle index in device array to be released.. + * @return returns and error code or USB_OK. + * + *****************************************************************************/ + +static usb_status USB_Msd_Free_Handle(msc_device_struct_t* handle) +{ + int32_t cnt = 0; + for (;cnt< MAX_MSC_DEVICE;cnt++) + { + if ((&g_msc_class[cnt]) == handle) + { + OS_Mem_zero((void*)handle, sizeof(msc_device_struct_t)); + return USB_OK; + } + } + return USBERR_INVALID_PARAM; +} + +/*************************************************************************//*! + * + * @name USB_Msd_Get_Device_Ptr + * + * @brief The function gets the device pointer from device array . + * + * @param handle index in device array. + * @return returns returns pointer to MSD device structure.. + * + *****************************************************************************/ +static msc_device_struct_t * USB_Msd_Get_Device_Ptr(msd_handle_t handle) +{ + return (msc_device_struct_t *)handle; +} + +/*************************************************************************//*! + * + * @name USB_Msd_Get_Desc_Info + * + * @brief The function gets the info of the descriptors. . + * + * @param handle index in device array. + * @param type descriptor type. + * @param object store the returned value. + * @return returns USB_OK if successful. + * + *****************************************************************************/ +static usb_status USB_Msd_Get_Desc_Info(msc_device_struct_t * msc_dev_ptr,USB_MSD_DESC_INFO_T type, uint32_t * object) +{ +#if USBCFG_DEV_COMPOSITE + uint32_t interface_index = 0xFF; +#endif + /* Get class info */ + + switch(type) + { + case USB_MSD_INTERFACE_COUNT: +#if USBCFG_DEV_COMPOSITE + *object = MAX_MSC_SUPPORTED_INTERFACES + 2; +#else + *object = MAX_MSC_SUPPORTED_INTERFACES; +#endif + break; +#if USBCFG_DEV_COMPOSITE + case USB_MSD_CLASS_INFO: + { + uint32_t class_i; + usb_composite_info_struct_t* usbcompinfoPtr; + /* Get class info */ + msc_dev_ptr->desc_callback.get_desc_entity((uint32_t)msc_dev_ptr->controller_handle, + USB_COMPOSITE_INFO, + (uint32_t *)&usbcompinfoPtr); + msc_dev_ptr->desc_callback.get_desc_entity((uint32_t)msc_dev_ptr, + USB_CLASS_INTERFACE_INDEX_INFO, + (uint32_t *)&interface_index); + *object = 0; + for (class_i = 0; class_i < usbcompinfoPtr->count; class_i++) + { + if ((USB_CLASS_MSC == usbcompinfoPtr->class_handle[class_i].type) && (class_i == interface_index)) + { + *object = (uint32_t)&(usbcompinfoPtr->class_handle[class_i]); + break; + } + } + } + break; +#endif + default : + break; + } + return USB_OK; +} + +/**************************************************************************//*! + * + * @name process_mass_storage_command + * + * @brief Process a Mass storage class command + * This function is added here to add more sub class specific commands) + * + * @param msc_device_struct_t * + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status process_mass_storage_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + usb_status error = USBERR_ERROR;/* initializing to error value */ + switch (cbw_ptr->command_block[0]) + { + /* commands to be supported by all devices */ + case INQUIRY_COMMAND : /*opcode : 0x12*/ + error = msc_inquiry_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case READ_10_COMMAND : /*opcode : 0x28 */ + case READ_12_COMMAND : /*opcode : 0xA8 */ + error = msc_read_command(msc_obj_ptr, + cbw_ptr,csw_residue_ptr,csw_status_ptr); + break; + case REQUEST_SENSE_COMMAND : /*opcode : 0x03*/ + error = msc_request_sense_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case TEST_UNIT_READY_COMMAND : /*opcode : 0x00 */ + error = msc_test_unit_ready_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case WRITE_10_COMMAND : /*opcode : 0x2A */ + case WRITE_12_COMMAND : /*opcode : 0xAA */ + error = msc_write_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case PREVENT_ALLOW_MEDIUM_REM_COMMAND : /*opcode :0x1E */ + error = msc_prevent_allow_medium_removal(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case FORMAT_UNIT_COMMAND : /*opcode : 0x04*/ + error = msc_format_unit_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case READ_CAPACITY_10_COMMAND : /*opcode : 0x25*/ + case READ_CAPACITY_16_COMMAND : /*opcode : 0x9E*/ + error = msc_read_capacity_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case MODE_SENSE_10_COMMAND : /* opcode :0x5A*/ + case MODE_SENSE_6_COMMAND : /* opcode : 0x1A */ + error = msc_mode_sense_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case MODE_SELECT_10_COMMAND : /*opcode : 0x55 */ + case MODE_SELECT_6_COMMAND : /*opcode : 0x15 */ + error = msc_mode_select_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case READ_FORMAT_CAPACITIES_COMMAND : /*opcode : 0x23 */ + error = msc_read_format_capacity_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case SEND_DIAGNOSTIC_COMMAND : /*opcode : 0x1D*/ + error = msc_send_diagnostic_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case VERIFY_COMMAND : /*opcode : 0x2F*/ + error = msc_verify_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + case START_STOP_UNIT_COMMAND : /*opcode : 0x1B*/ + error = msc_start_stop_unit_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + break; + default: /* for all unsupported commands */ + error = msc_unsupported_command(msc_obj_ptr, cbw_ptr,csw_residue_ptr, + csw_status_ptr); + msc_obj_ptr->out_flag = FALSE; + msc_obj_ptr->in_flag = FALSE; + msc_obj_ptr->out_stall_flag = FALSE; + msc_obj_ptr->in_stall_flag = FALSE; + msc_obj_ptr->need_out_stall_flag = FALSE; + msc_obj_ptr->need_in_stall_flag = FALSE; + break; + } + return error; +} + +/**************************************************************************//*! + * + * @name USB_Service_Bulk_In + * + * @brief The function is callback function of DIC Bulk In Endpoint + * + * @param event + * @param arg + * @return None + * + *****************************************************************************/ +void USB_Service_Bulk_In(usb_event_struct_t* event, void* arg) +{ + //uint8_t event_type; + csw_t * csw_ptr; + msc_device_struct_t * msc_obj_ptr; + + msc_obj_ptr = (msc_device_struct_t *)arg; + + if (NULL == msc_obj_ptr) + { +#if _DEBUG + USB_PRINTF("USB_Service_Bulk_In: msc_obj_ptr is NULL\n"); +#endif + return; + } + + if (event->len == 0xFFFFFFFF) + { + if((msc_obj_ptr->in_flag) && (msc_obj_ptr->class_specific_callback.callback != NULL) + && ((READ_10_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + || (READ_12_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]))) + { + lba_app_struct_t lba_data; + + lba_data.size = 0; + lba_data.buff_ptr = event->buffer_ptr; + lba_data.offset = 0; + msc_obj_ptr->class_specific_callback.callback(USB_DEV_EVENT_SEND_COMPLETE, + USB_REQ_VAL_INVALID, NULL, (uint32_t *)&lba_data, msc_obj_ptr->class_specific_callback.arg); + } + return; + } + + if(msc_obj_ptr->transfer_remaining >= event->len) + { /* decrement the global count */ + msc_obj_ptr->transfer_remaining -= event->len; + } + + /* check if there is need to stall BULK IN ENDPOINT And + there isn't any transfer in progress*/ + if( (msc_obj_ptr->need_in_stall_flag == TRUE)&& + (!msc_obj_ptr->transfer_remaining)) + { + msc_obj_ptr->need_in_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->in_stall_flag = TRUE; + msc_obj_ptr->in_flag = FALSE; /* clear send flag */ + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,event->ep_num,USB_SEND); + return; + } + + /* If its not a data phase on bulk endpoint */ + if ((!msc_obj_ptr->in_flag) && (event->len == MSC_CSW_LENGTH)) + { + csw_ptr = (csw_t *)(event->buffer_ptr); + } + + if(msc_obj_ptr->in_flag) /* bulk in transaction has occurred before CSW */ + { + if(msc_obj_ptr->class_specific_callback.callback != NULL) + { + lba_app_struct_t lba_data; + + lba_data.size = event->len; + lba_data.buff_ptr = event->buffer_ptr; + lba_data.offset = msc_obj_ptr->current_offset; + + if((READ_10_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + || (READ_12_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + ) + { + msc_obj_ptr->class_specific_callback.callback(USB_DEV_EVENT_SEND_COMPLETE, + USB_REQ_VAL_INVALID,NULL,(uint32_t *)&lba_data, msc_obj_ptr->class_specific_callback.arg); + } + + if(msc_obj_ptr->transfer_remaining) + { + msc_obj_ptr->current_offset += event->len; + lba_data.offset = msc_obj_ptr->current_offset; + lba_data.size = (msc_obj_ptr->msd_buff.msc_bulk_in_size > MSD_SEND_MAX_TRANS_LENGTH ? + MSD_SEND_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_in_size); /* whichever is smaller */ + lba_data.size = (msc_obj_ptr->transfer_remaining > lba_data.size ? + lba_data.size : msc_obj_ptr->transfer_remaining); /* whichever is smaller */ + + lba_data.buff_ptr = NULL; //msc_obj_ptr->msd_buff.msc_bulk_in_ptr; + + /* fetch data from MSD App(e.g)ram disk or Sd card, etc*/ + msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_READ_REQUEST, + USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_in_ptr,(uint32_t *)&lba_data, msc_obj_ptr->class_specific_callback.arg); + + lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_in_ptr; //msc_obj_ptr->msd_buff.msc_disk_buff_ptr + msc_obj_ptr->current_offset; + + if(msc_obj_ptr->current_offset < (msc_obj_ptr->device_info.total_lba_device_supports * msc_obj_ptr->device_info.length_of_each_lab_of_device)) + { + /* Send data on USB Bus */ + (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + (uint8_t *)lba_data.buff_ptr,lba_data.size); + } + else + { + msc_obj_ptr->need_in_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->in_stall_flag = TRUE; + msc_obj_ptr->in_flag = FALSE; /* clear send flag */ + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_in_endpoint,USB_SEND); + } + } + } + + if(!msc_obj_ptr->transfer_remaining) + { /* marks the end of data phase */ + msc_obj_ptr->in_flag = FALSE; /* clear the flag for next CBW */ + //if(msc_obj_ptr->csw_prime_flag == FALSE) + { + /* Send the command status information */ + (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + (uint8_t *)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH); + msc_obj_ptr->csw_prime_flag = TRUE; + } + } + } + else if ((event->len == MSC_CSW_LENGTH) /* CSW is 13 bytes in length */ + && (csw_ptr->signature == USB_DCSWSIGNATURE)) /*valid CSW signature*/ + { + /* this flag will now be set on reset or after CSW being sent */ + msc_obj_ptr->cbw_valid_flag = TRUE; + msc_obj_ptr->csw_prime_flag = FALSE; + /* prepare for next CBW */ + //if (msc_obj_ptr->cbw_prime_flag == FALSE) + { + (void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + (uint8_t*)msc_obj_ptr->cbw_ptr, MSC_CBW_LENGTH); + msc_obj_ptr->cbw_prime_flag = TRUE; + } + } +} + +/**************************************************************************//*! + * + * @name USB_Service_Bulk_Out + * + * @brief The function is callback function of DIC Bulk Out Endpoint + * + * @param event + * @param arg + * @return None + * + *****************************************************************************/ +void USB_Service_Bulk_Out(usb_event_struct_t* event,void* arg) +{ + //uint8_t event_type; + cbw_t * cbw_ptr = NULL; + uint8_t error; + msc_device_struct_t * msc_obj_ptr; + //uint32_t signature = USB_DCBWSIGNATURE; + //USB_PRINTF("\nsignature is :%x",signature); +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) && (!USE_RTOS)) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + uint8_t have_transfer = 0; +#endif + + msc_obj_ptr = (msc_device_struct_t *)arg; + + if (NULL == msc_obj_ptr) + { +#if _DEBUG + USB_PRINTF("USB_Service_Bulk_Out: msc_dev_ptr is NULL\n"); +#endif + return; + } + + if (event->len == 0xFFFFFFFF) + { + /* need to notify app that receives data Successfully and size is 0, app can release buffer */ + if ((msc_obj_ptr->out_flag) && (msc_obj_ptr->class_specific_callback.callback != NULL) + && ((WRITE_10_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + || (WRITE_12_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]))) + { + lba_app_struct_t lba_data1; + lba_data1.offset = 0; + lba_data1.size = 0; + lba_data1.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + msc_obj_ptr->class_specific_callback.callback(USB_DEV_EVENT_DATA_RECEIVED, + USB_REQ_VAL_INVALID,NULL,(uint32_t *)&lba_data1, msc_obj_ptr->class_specific_callback.arg); + } + return; + } + if(msc_obj_ptr->transfer_remaining >= event->len) + { /* decrement the global count */ + msc_obj_ptr->transfer_remaining -= event->len; + } + + /* check if there is need to stall BULK IN ENDPOINT */ + if( (msc_obj_ptr->need_out_stall_flag == TRUE)&& + (!msc_obj_ptr->transfer_remaining)) + { + //uint8_t component = (uint8_t)(event->ep_num | + // (USB_RECV<need_out_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */ + msc_obj_ptr->out_flag = FALSE; /* clear send flag */ + msc_obj_ptr->cbw_prime_flag = FALSE; + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,event->ep_num,USB_RECV); + return; + } + + /* If its not a data phase on bulk endpoint */ + if ((!msc_obj_ptr->out_flag) && (event->len == MSC_CBW_LENGTH)) + { + cbw_ptr = (cbw_t *)(event->buffer_ptr); + } + + if(msc_obj_ptr->out_flag) /* bulk out transaction has occurred after CBW */ + { +// if(msc_obj_ptr->transfer_remaining >= event->len) +// { /* decrement the global count */ +// msc_obj_ptr->transfer_remaining -= event->len; +// } + + if(msc_obj_ptr->class_specific_callback.callback != NULL) + { + lba_app_struct_t lba_data1; + + lba_data1.size = event->len; + lba_data1.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + lba_data1.offset = msc_obj_ptr->current_offset; + + if((WRITE_10_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + || (WRITE_12_COMMAND == msc_obj_ptr->cbw_ptr->command_block[0]) + ) + { +//#ifdef MUTILE_BUFFER +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) && (!USE_RTOS)) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + lba_app_struct_t lba_data2; + if (msc_obj_ptr->transfer_remaining) + { + msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_WRITE_REQUEST, + USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_out_ptr, NULL, msc_obj_ptr->class_specific_callback.arg); + if (msc_obj_ptr->msd_buff.msc_bulk_out_ptr != NULL) + { + have_transfer = 1; + msc_obj_ptr->current_offset += event->len; + lba_data2.offset = msc_obj_ptr->current_offset; + lba_data2.size = (msc_obj_ptr->msd_buff.msc_bulk_out_size > MSD_RECV_MAX_TRANS_LENGTH) ? + MSD_RECV_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_out_size; /* whichever is smaller */ + lba_data2.size = (msc_obj_ptr->transfer_remaining > lba_data2.size) ? + lba_data2.size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */ + + lba_data2.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + if(msc_obj_ptr->current_offset < (msc_obj_ptr->device_info.total_lba_device_supports * msc_obj_ptr->device_info.length_of_each_lab_of_device)) + { + (void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + lba_data2.buff_ptr,lba_data2.size); + } + else + { + msc_obj_ptr->need_out_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */ + msc_obj_ptr->out_flag = FALSE; /* clear send flag */ + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint,USB_RECV); + } + } + } +#endif + msc_obj_ptr->class_specific_callback.callback(USB_DEV_EVENT_DATA_RECEIVED, + USB_REQ_VAL_INVALID,NULL,(uint32_t *)&lba_data1, msc_obj_ptr->class_specific_callback.arg); + } +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) && (!USE_RTOS)) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + if((msc_obj_ptr->transfer_remaining) && (have_transfer == 0)) +#else + if(msc_obj_ptr->transfer_remaining) +#endif + { + + msc_obj_ptr->current_offset += event->len; + lba_data1.offset = msc_obj_ptr->current_offset; + lba_data1.size = (msc_obj_ptr->msd_buff.msc_bulk_out_size > MSD_RECV_MAX_TRANS_LENGTH) ? + MSD_RECV_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_out_size; /* whichever is smaller */ + lba_data1.size = (msc_obj_ptr->transfer_remaining > lba_data1.size) ? + lba_data1.size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */ + + lba_data1.buff_ptr = NULL; //msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + /* copy the data received on USB Bus, to MSD Disk + (e.g.) CD/DVD or SD Card, etc */ + msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_WRITE_REQUEST, + USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_out_ptr,(uint32_t *)&lba_data1, msc_obj_ptr->class_specific_callback.arg); + + lba_data1.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + if(msc_obj_ptr->current_offset < (msc_obj_ptr->device_info.total_lba_device_supports * msc_obj_ptr->device_info.length_of_each_lab_of_device)) + { + (void)USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + lba_data1.buff_ptr,lba_data1.size); + } + else + { + msc_obj_ptr->need_out_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */ + msc_obj_ptr->out_flag = FALSE; /* clear send flag */ + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint,USB_RECV); + } + } + } + +// if((msc_obj_ptr->need_out_stall_flag == TRUE)&& +// (!msc_obj_ptr->transfer_remaining)) +// { +// msc_obj_ptr->need_out_stall_flag = FALSE; /* clear the flag */ +// msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */ +// msc_obj_ptr->out_flag = FALSE; /* clear send flag */ +// usb_device_stall_endpoint(msc_obj_ptr->controller_handle,event->ep_num,USB_SEND); +// return; +// } + + if(!msc_obj_ptr->transfer_remaining) + { /* marks the end of data phase */ + msc_obj_ptr->out_flag = FALSE; /* clear the flag for next CBW */ + /* Send the command status information */ + //if(msc_obj_ptr->csw_prime_flag == FALSE) + { + (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + (uint8_t *)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH); + msc_obj_ptr->csw_prime_flag = TRUE; + } + } + } + else if(/* check for valid and meaningful CBW */ + /* CBW received after device had sent a CSW or after a reset */ + (msc_obj_ptr->cbw_valid_flag) + /* CBW is 31 bytes in length */ + && (event->len == MSC_CBW_LENGTH) + /* valid CBW signature*/ + && (cbw_ptr != NULL) && (cbw_ptr->signature == USB_DCBWSIGNATURE) + /* all reserved bits should be zero*/ + && (!((cbw_ptr->lun & 0xF0) || (cbw_ptr->cb_length & 0xE0))) + /* host should send command to valid LUN */ + && (cbw_ptr->lundevice_info.num_lun_supported) + /* valid cbwcb length*/ + && ((cbw_ptr->cb_length >= 0x01)&&(cbw_ptr->cb_length <= 0x10)) + ) + { + msc_obj_ptr->re_stall_flag = TRUE; + msc_obj_ptr->cbw_prime_flag = FALSE; + msc_obj_ptr->transfer_remaining = 0; + /* A valid CBW was received */ + msc_obj_ptr->csw_ptr->signature = USB_DCSWSIGNATURE; + msc_obj_ptr->csw_ptr->residue = 0; + msc_obj_ptr->csw_ptr->tag = cbw_ptr->tag; + /*this flag will now be set on reset or after CSW being sent */ + msc_obj_ptr->cbw_valid_flag = FALSE; + + cbw_ptr->data_length = USB_LONG_LE_TO_HOST(cbw_ptr->data_length); + + /* set flag if device is going to recv data in coming transaction */ + msc_obj_ptr->out_flag = (bool)(( (!(cbw_ptr->flag & USB_CBW_DIRECTION_BIT)) + && (cbw_ptr->data_length))?TRUE:FALSE); + /* set flag if send is going to send data in coming transaction */ + msc_obj_ptr->in_flag = (bool)(( (cbw_ptr->flag & USB_CBW_DIRECTION_BIT) + && (cbw_ptr->data_length))?TRUE:FALSE); + /* Process the command */ + error = process_mass_storage_command(msc_obj_ptr, cbw_ptr, + &(msc_obj_ptr->csw_ptr->residue), &(msc_obj_ptr->csw_ptr->csw_status)); + + if (error == USBERR_ENDPOINT_STALLED) + { + if (msc_obj_ptr->out_flag==TRUE) + { + if (msc_obj_ptr->out_stall_flag == FALSE) + { + msc_obj_ptr->need_out_stall_flag = TRUE; + } + msc_obj_ptr->out_flag = FALSE; /* so as to send status phase */ + } + else if (msc_obj_ptr->in_flag==TRUE) + { + if (msc_obj_ptr->in_stall_flag == FALSE) + { + msc_obj_ptr->need_in_stall_flag = TRUE; + } + msc_obj_ptr->in_flag = FALSE; + } + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + } + + /* if there is no data phase on bulk endpoints*/ + /* even if need_out_stall_flag or need_in_stall_flag */ + if(!((msc_obj_ptr->out_flag) || ((msc_obj_ptr->in_flag) || (msc_obj_ptr->need_in_stall_flag)))) + { + /* Send the command status information */ + (void)USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + (uint8_t *)msc_obj_ptr->csw_ptr, MSC_CSW_LENGTH); + msc_obj_ptr->csw_prime_flag = TRUE; + } + } + else /* Invalid/NMreceived */ + { + //uint8_t direction; + //uint8_t ep_num; + /* prepare the component to be sent in lower layer with + endpoint number and direction*/ + //uint8_t component; + //direction = USB_RECV; + //ep_num = msc_obj_ptr->bulk_out_endpoint; + //component = (uint8_t)(ep_num | (direction<controller_handle,msc_obj_ptr->bulk_out_endpoint,USB_RECV); + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_in_endpoint,USB_SEND); + msc_obj_ptr->cbw_valid_flag = FALSE; + msc_obj_ptr->out_stall_flag = TRUE; + msc_obj_ptr->in_stall_flag = TRUE; + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_CBW; + msc_obj_ptr->wait_for_reset_recovery = TRUE; + } +} + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Event + * + * @brief The function initializes MSC endpoints + * + * @param arg handle to Identify class object. + * @param event pointer to event structure + * @param val gives the configuration value + * + * @return None + * + *****************************************************************************/ +void USB_Class_MSC_Event(uint8_t event, void* val,void* arg) +{ + usb_class_struct_t* usbclassPtr; + msc_device_struct_t * msc_dev_ptr; + + usb_endpoints_t *usb_ep_data; + //uint8_t error; + + //USB_PRINTF("\n USB_Class_MSD_Event: event: 0x%x", event); + msc_dev_ptr = (msc_device_struct_t *)arg; + + if (NULL == msc_dev_ptr) + { +#if _DEBUG + USB_PRINTF("USB_Class_MSC_Event: msc_dev_ptr is NULL\n"); +#endif + return; + } + + if(event == USB_DEV_EVENT_CONFIG_CHANGED) + { + uint8_t count = 0; + + //USB_PRINTF("\n 000, count: 0x%x", count); + //USB_PRINTF("\nUSB_DEV_EVENT_CONFIG_CHANGED"); + + if (*(uint16_t*)val == 0) + { +#if _DEBUG + USB_PRINTF("only config change!\n"); +#endif + return; + } +#if USBCFG_DEV_COMPOSITE + /* Get class info */ + USB_Msd_Get_Desc_Info(msc_dev_ptr, USB_MSD_CLASS_INFO, (uint32_t *)&usbclassPtr); + USB_Msd_Get_Desc_Info(msc_dev_ptr, USB_MSD_INTERFACE_COUNT, &msc_dev_ptr->usb_max_suported_interfaces); +#else + msc_dev_ptr->desc_callback.get_desc_entity((uint32_t)msc_dev_ptr->controller_handle, + USB_CLASS_INFO, (uint32_t*)&usbclassPtr); + USB_Msd_Get_Desc_Info(msc_dev_ptr, USB_MSD_INTERFACE_COUNT, &msc_dev_ptr->usb_max_suported_interfaces); +#endif + if(usbclassPtr == NULL) + { + USB_PRINTF("not find msd interface\n"); + return; + } + + usb_ep_data = &(usbclassPtr[*(uint16_t*)val - 1].interfaces.interface[0].endpoints); + msc_dev_ptr->ep_desc_data = usb_ep_data; + msc_dev_ptr->msc_endpoint_data.count = usbclassPtr->interfaces.interface->endpoints.count; + + if (msc_dev_ptr->msc_endpoint_data.count > MAX_MSC_CLASS_EP_NUM) + { + USB_PRINTF("too many msc endpoint for the class driver\n"); + return; + } + + for (int epindex = 0; epindex < usbclassPtr->interfaces.interface->endpoints.count; ++epindex) + { + if (usbclassPtr->interfaces.interface->endpoints.ep[epindex].direction == USB_SEND) + { + msc_dev_ptr->bulk_in_endpoint = usbclassPtr->interfaces.interface->endpoints.ep[epindex].ep_num; + msc_dev_ptr->bulk_in_endpoint_packet_size = usbclassPtr->interfaces.interface->endpoints.ep[epindex].size; + } + else if (usbclassPtr->interfaces.interface->endpoints.ep[epindex].direction == USB_RECV) + { + msc_dev_ptr->bulk_out_endpoint = usbclassPtr->interfaces.interface->endpoints.ep[epindex].ep_num; + } + } + + /* initialize all non control endpoints */ + while(count < usb_ep_data->count) + { +#if _DEBUG + USB_PRINTF("\n 222, count: 0x%x", count); +#endif + usb_ep_struct_t* ep_struct_ptr= + (usb_ep_struct_t*) (&usb_ep_data->ep[count]); + + (void)usb_device_init_endpoint(msc_dev_ptr->controller_handle, + ep_struct_ptr, TRUE); + + /* register callback service for Non Control EndPoints */ + if(ep_struct_ptr->type == USB_BULK_PIPE) + { + if(ep_struct_ptr->direction == USB_RECV) + { + (void)usb_device_register_service(msc_dev_ptr->controller_handle, + (uint8_t)((uint8_t)(USB_SERVICE_EP0+ep_struct_ptr->ep_num) | ((uint8_t)(ep_struct_ptr->direction << 7))), + USB_Service_Bulk_Out,(void *)msc_dev_ptr); + } + else + { + (void)usb_device_register_service(msc_dev_ptr->controller_handle, + (uint8_t)((uint8_t)(USB_SERVICE_EP0+ep_struct_ptr->ep_num) | ((uint8_t)(ep_struct_ptr->direction << 7))), + USB_Service_Bulk_In,(void *)msc_dev_ptr); + } + } + count++; + + } + msc_dev_ptr->re_stall_flag = FALSE; + msc_dev_ptr->out_flag = FALSE; + msc_dev_ptr->in_flag = FALSE; + msc_dev_ptr->out_stall_flag = FALSE; + msc_dev_ptr->in_stall_flag = FALSE; + msc_dev_ptr->need_out_stall_flag = FALSE; + msc_dev_ptr->need_in_stall_flag = FALSE; + msc_dev_ptr->cbw_valid_flag = TRUE; /*making the first CBW valid */ + msc_dev_ptr->transfer_remaining = 0; + msc_dev_ptr->wait_for_reset_recovery = FALSE; + msc_dev_ptr->need_to_prepare_next = FALSE; + msc_dev_ptr->stall_status = 0; + } + else if(event == USB_DEV_EVENT_ENUM_COMPLETE) + { + /* To Do */ + if(NULL == msc_dev_ptr->cbw_ptr) + { + USB_PRINTF("msc cbw buff error\n"); + return; + } + //msc_dev_ptr->cbw_ptr = (cbw_t *)OS_Mem_alloc_uncached(MSC_CBW_LENGTH); + + if(msc_dev_ptr->cbw_prime_flag == TRUE) + { +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE + usb_device_cancel_transfer(msc_dev_ptr->controller_handle, msc_dev_ptr->bulk_out_endpoint, USB_RECV); +#endif + } + usb_device_recv_data(msc_dev_ptr->controller_handle, + msc_dev_ptr->bulk_out_endpoint, (uint8_t*)msc_dev_ptr->cbw_ptr, MSC_CBW_LENGTH); + msc_dev_ptr->cbw_prime_flag = TRUE; +#if _DEBUG + USB_PRINTF("\nUSB_MSC_Bulk_Recv_Data"); +#endif + //msc_dev_ptr->csw_ptr = (csw_t *)OS_mem_alloc_uncached(MSC_CSW_LENGTH); + //USB_Class_MSC_Send_Data(msc_dev_ptr->controller_handle,1,(uint8_t *)msc_dev_ptr->csw_ptr,MSC_CSW_LENGTH); + } + else if(event == USB_DEV_EVENT_BUS_RESET) + { + + } + else if(event == USB_DEV_EVENT_EP_UNSTALLED) + { + uint8_t value; + value = *((uint8_t *)val); + + if( (msc_dev_ptr->re_stall_flag == TRUE) + && + (((value & 0x0F) == msc_dev_ptr->bulk_in_endpoint) || + ((value & 0x0F) == msc_dev_ptr->bulk_out_endpoint))) + { /* For MASS Storage Class BULK ENDPOINTS have to be unstalled + only on receiving Bulk Only Reset. + Therefore, if Host sends clear feature to unstall these + endpoints, re-stall them + */ + usb_device_stall_endpoint(msc_dev_ptr->controller_handle,value & 0x0F, (uint8_t)(value & 0x80) >> 7); + } + } + else if(event == USB_DEV_EVENT_EP_STALLED) + { + /* Code to be added here, + if there is some action needed at app level */ + } + else if (event == USB_DEV_EVENT_TYPE_CLR_EP_HALT) + { + uint8_t value; + value = *((uint8_t *)val); + if (msc_dev_ptr->wait_for_reset_recovery != TRUE) + { + if (((value & 0x0F) == msc_dev_ptr->bulk_in_endpoint) && (msc_dev_ptr->in_stall_flag == TRUE)) + { + usb_device_unstall_endpoint(msc_dev_ptr->controller_handle,value & 0x0F, (uint8_t)(value & 0x80) >> 7); + msc_dev_ptr->in_stall_flag = FALSE; + } + if (((value & 0x0F) == msc_dev_ptr->bulk_out_endpoint) && (msc_dev_ptr->out_stall_flag == TRUE)) + { + usb_device_unstall_endpoint(msc_dev_ptr->controller_handle,value & 0x0F, (uint8_t)(value & 0x80) >> 7); + msc_dev_ptr->out_stall_flag = FALSE; + } + + if ((msc_dev_ptr->need_to_prepare_next != TRUE) && ((msc_dev_ptr->stall_status == STALL_IN_DATA_PHASE) || (msc_dev_ptr->stall_status == STALL_IN_CSW))) + { + if (msc_dev_ptr->csw_prime_flag == TRUE) + { +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE + usb_device_cancel_transfer(msc_dev_ptr->controller_handle, msc_dev_ptr->bulk_in_endpoint, USB_SEND); +#endif + } + /* Send the command status information */ + usb_device_send_data(msc_dev_ptr->controller_handle, + msc_dev_ptr->bulk_in_endpoint, (uint8_t*)msc_dev_ptr->csw_ptr, MSC_CSW_LENGTH); + msc_dev_ptr->csw_prime_flag = TRUE; + msc_dev_ptr->stall_status = 0; + } + + if ((msc_dev_ptr->need_to_prepare_next == TRUE) && (msc_dev_ptr->out_stall_flag == FALSE) && (msc_dev_ptr->in_stall_flag == FALSE)) + { + msc_dev_ptr->need_to_prepare_next = FALSE; + if (msc_dev_ptr->cbw_prime_flag == TRUE) + { +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE + usb_device_cancel_transfer(msc_dev_ptr->controller_handle, msc_dev_ptr->bulk_out_endpoint, USB_RECV); +#endif + } + usb_device_recv_data(msc_dev_ptr->controller_handle, + msc_dev_ptr->bulk_out_endpoint, (uint8_t*)msc_dev_ptr->cbw_ptr, MSC_CBW_LENGTH); + msc_dev_ptr->cbw_prime_flag = TRUE; + msc_dev_ptr->stall_status = 0; + } + } + } + else if(event == USB_DEV_EVENT_TYPE_SET_EP_HALT) + { + /* Code to be added here, + if there is some action needed at app level */ + uint8_t value; + value = *((uint8_t *)val); + if (((value & 0x0F) == msc_dev_ptr->bulk_in_endpoint)) + { + //usb_device_stall_endpoint(msc_dev_ptr->controller_handle,value & 0x0F, (value & 0x80) >> 7); + msc_dev_ptr->in_stall_flag = TRUE; + } + if (((value & 0x0F) == msc_dev_ptr->bulk_out_endpoint)) + { + //usb_device_stall_endpoint(msc_dev_ptr->controller_handle,value & 0x0F, (value & 0x80) >> 7); + msc_dev_ptr->out_stall_flag = TRUE; + } + } + + if(msc_dev_ptr->msc_application_callback.callback != NULL) + { + msc_dev_ptr->msc_application_callback.callback(event,val, + msc_dev_ptr->msc_application_callback.arg); + } +} + +/**************************************************************************//*! + * + * @name USB_MSC_Other_Requests + * + * @brief The function provides flexibility to add class and vendor specific + * requests + * + * @param arg + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +usb_status USB_MSC_Requests +( +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size, +void* arg +) +{ + msc_device_struct_t * msc_dev_ptr; + usb_status error = USBERR_INVALID_REQ_TYPE; + + msc_dev_ptr = (msc_device_struct_t *)arg; + //USB_PRINTF("\nsetup_packet->request: 0x%x", setup_packet->request); + + if (NULL == msc_dev_ptr) + { +#if _DEBUG + USB_PRINTF("USB_MSC_Other_Requests: msc_dev_ptr is NULL\n"); +#endif + return USBERR_ERROR; + } + + *size=0; + + if((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_POS) == + USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_CLASS) + { /* class request so handle it here */ + + error = USB_OK; + + /* call for class/subclass specific requests */ + switch(setup_packet->request) + { + case GET_MAX_LUN : + if((setup_packet->index < msc_dev_ptr->usb_max_suported_interfaces) && + (!setup_packet->value) && (setup_packet->length <= 0x0001) && + ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_DIR_IN) + ) + { + /* return the maximum number of logical units supported */ + *data = &msc_dev_ptr->lun; + *size= (uint32_t)setup_packet->length; + msc_dev_ptr->re_stall_flag = TRUE; + } + else + { /* for Get Max LUN request with invalid wIndex parameter, + host expects stall */ + error = USBERR_INVALID_REQ_TYPE; + } + break; + case BULK_ONLY_MASS_STORAGE_RESET : + /* Steps to be taken in this command : + 1) ready the device for the next CBW from the host + 2) preserve the value of its bulk data toggle bits + 3) preserve the value of its bulk endpoint STALL conditions + 4) device shall NAK the status stage of device request until + command is complete*/ + + if( (setup_packet->index < msc_dev_ptr->usb_max_suported_interfaces) && + (!setup_packet->value)&&(!setup_packet->length) && + ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_DIR_OUT) + ) + { + /* get the endpoints from the descriptor module */ + usb_endpoints_t *usb_ep_data = msc_dev_ptr->ep_desc_data; + uint8_t count = 0; + + /* de-initialize and initialize bulk endpoints */ + while(count < usb_ep_data->count) + { + usb_ep_struct_t* ep_struct_ptr= + (usb_ep_struct_t*) (&usb_ep_data->ep[count]); + + if(ep_struct_ptr->type == USB_BULK_PIPE) + { + (void)usb_device_deinit_endpoint(msc_dev_ptr->controller_handle, + ep_struct_ptr->ep_num, ep_struct_ptr->direction); + (void)usb_device_init_endpoint(msc_dev_ptr->controller_handle, + ep_struct_ptr, TRUE); + } + count++; + } + msc_dev_ptr->out_flag = FALSE; + msc_dev_ptr->in_flag = FALSE; + msc_dev_ptr->need_out_stall_flag = FALSE; + msc_dev_ptr->need_in_stall_flag = FALSE; + /*making the first CBW valid */ + msc_dev_ptr->cbw_valid_flag = TRUE; + msc_dev_ptr->re_stall_flag = FALSE; + msc_dev_ptr->transfer_remaining = 0; + msc_dev_ptr->wait_for_reset_recovery = FALSE; + msc_dev_ptr->cbw_prime_flag = FALSE; + msc_dev_ptr->csw_prime_flag = FALSE; + msc_dev_ptr->need_to_prepare_next = TRUE; +// usb_device_recv_data(msc_dev_ptr->controller_handle, +// msc_dev_ptr->bulk_out_endpoint, (uint8_t*)msc_dev_ptr->cbw_ptr, MSC_CBW_LENGTH); + } + else + { /* for Get Max LUN request with invalid wIndex parameter, + host expects stall */ + error = USBERR_INVALID_REQ_TYPE; + } + break; + default :break; + } + } + else if((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_POS) == + USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_VENDOR) + { /* vendor specific request */ + if(msc_dev_ptr->vendor_req_callback.callback != NULL) + { + error = msc_dev_ptr->vendor_req_callback.callback(setup_packet, + data,size,msc_dev_ptr->vendor_req_callback.arg); + } + } + + return error; +} + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Init + * + * @brief The function initializes the Device and Controller layer + * + * @param msd_config_ptr : Configuration parameter structure pointer + * passed by APP. + * @return status + * MSD Handle : When Successfully + * Others : Errors + ****************************************************************************** + * + *This function initializes the MSC Class layer and layers it is dependent on + ******************************************************************************/ +usb_status USB_Class_MSC_Init +( +uint8_t controller_id, +msc_config_struct_t* msd_config_ptr, +msd_handle_t * msd_handle + +) +{ +#if _DEBUG + USB_PRINTF("Enter USB_Class_MSC_Init\n"); +#endif + usb_status error = USBERR_ERROR; + uint32_t implementing_disk_drive = IMPLEMENTING_DISK_DRIVE; + msc_device_struct_t * devicePtr = NULL; + usb_class_specific_callback_struct_t* scsi_cb_ptr; + device_lba_info_struct_t* usb_msd_lba_info_ptr = NULL; + + if (msd_config_ptr == NULL) + { + return USBERR_ERROR; + } + + error = USB_Msd_Allocate_Handle(&devicePtr); + if (USB_OK != error) + { + return error; + } + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK))) + devicePtr->cbw_ptr = &g_msc_class_cbw; /* Initializing */ + devicePtr->csw_ptr = &g_msc_class_csw; +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + devicePtr->cbw_ptr = (cbw_t *)OS_Mem_alloc_uncached_align(sizeof(cbw_t), 32); + if (NULL == devicePtr->cbw_ptr) + { +#if _DEBUG + USB_PRINTF("6: USB_Class_MSC_Init: Memalloc failed\n"); +#endif + error = USBERR_ALLOC; + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } + *msd_handle = (unsigned long)0; + return error; + } + devicePtr->csw_ptr = (csw_t *)OS_Mem_alloc_uncached_align(sizeof(csw_t), 32); + if (NULL == devicePtr->csw_ptr) + { +#if _DEBUG + USB_PRINTF("7: USB_Class_MSC_Init: Memalloc failed\n"); +#endif + error = USBERR_ALLOC; + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } + *msd_handle = (unsigned long)0; + return error; + } +#endif + OS_Mem_zero(devicePtr->cbw_ptr, MSC_CBW_LENGTH); + OS_Mem_zero(devicePtr->csw_ptr, MSC_CSW_LENGTH); + + OS_Mem_copy(msd_config_ptr->desc_callback_ptr,&devicePtr->desc_callback,sizeof(usb_desc_request_notify_struct_t)); + + /* save the callback pointer */ + devicePtr->msc_application_callback.callback = msd_config_ptr->msc_application_callback.callback; + devicePtr->msc_application_callback.arg = msd_config_ptr->msc_application_callback.arg; + + /* save the callback pointer */ + devicePtr->vendor_req_callback.callback = + msd_config_ptr->vendor_req_callback.callback; + devicePtr->vendor_req_callback.arg = msd_config_ptr->vendor_req_callback.arg; + + /* save the callback pointer */ + devicePtr->class_specific_callback.callback = msd_config_ptr->class_specific_callback.callback; + devicePtr->class_specific_callback.arg = msd_config_ptr->class_specific_callback.arg; + + if(devicePtr->msc_application_callback.callback) + { + devicePtr->msc_application_callback.callback(USB_MSC_DEVICE_GET_SEND_BUFF_INFO, &devicePtr->msd_buff.msc_bulk_in_size , NULL); + devicePtr->msc_application_callback.callback(USB_MSC_DEVICE_GET_RECV_BUFF_INFO, &devicePtr->msd_buff.msc_bulk_out_size , NULL); + } +#if USBCFG_DEV_COMPOSITE + devicePtr->class_handle = USB_Class_Get_Class_Handle(); + + devicePtr->controller_handle = (usb_device_handle)USB_Class_Get_Ctrler_Handle(devicePtr->class_handle); + if(NULL == devicePtr->controller_handle) + { +#if _DEBUG + USB_PRINTF("4: USB_Class_MSC_Init: call USB_Class_Get_Ctrler_Handle failed\n"); +#endif +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } +#endif + *msd_handle = (unsigned long)0; + return error; + } +#else + /* Initialize the device layer*/ + error = usb_device_init(controller_id,(&devicePtr->controller_handle)); + /* +1 is for Control Endpoint */ + if(error != USB_OK) + { +#if _DEBUG + USB_PRINTF("4: USB_Class_MSC_Init: call usb_device_init failed\n"); +#endif +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } +#endif + *msd_handle = (unsigned long)0; + return error; + } + /* Initialize the generic class functions */ + devicePtr->class_handle = USB_Class_Init(devicePtr->controller_handle,USB_Class_MSC_Event, + USB_MSC_Requests,(void *)devicePtr,msd_config_ptr->desc_callback_ptr); +#endif + + devicePtr->desc_callback.get_desc_entity((uint32_t)devicePtr,USB_MSC_LBA_INFO, (uint32_t *)&usb_msd_lba_info_ptr); + if(NULL == usb_msd_lba_info_ptr) + { +#if _DEBUG + USB_PRINTF("9: USB_Class_MSC_Init: get msd lba info failed\n"); +#endif +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } +#endif + *msd_handle = (unsigned long)0; + return error; + } + devicePtr->device_info.length_of_each_lab_of_device = usb_msd_lba_info_ptr->length_of_each_lab_of_device; + devicePtr->device_info.num_lun_supported = usb_msd_lba_info_ptr->num_lun_supported; + devicePtr->device_info.total_lba_device_supports = usb_msd_lba_info_ptr->total_lba_device_supports; + + /* Initialize the scsi subclass functions */ + //scsi_cb.callback = USB_Class_MSC_Event; + scsi_cb_ptr = &msd_config_ptr->class_specific_callback; + //scsi_cb.arg = devicePtr; + error = USB_MSC_SCSI_Init(devicePtr,scsi_cb_ptr, &devicePtr->device_info, + implementing_disk_drive); + + if(error != USB_OK) + { +#if _DEBUG + USB_PRINTF("10: USB_Class_MSC_Init: call USB_MSC_SCSI_Init failed\n"); +#endif +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } +#endif + *msd_handle = (unsigned long)0; + return error; + } + + devicePtr->cbw_prime_flag = FALSE; + devicePtr->csw_prime_flag = FALSE; + + *msd_handle = (unsigned long)devicePtr; + devicePtr->msc_handle = *msd_handle; +#if !USBCFG_DEV_COMPOSITE + usb_device_postinit(controller_id,devicePtr->controller_handle); +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Deinit + * + * @brief The function initializes the Device and Controller layer + * + * @param cdc_handle + * + * @return status + * USB_OK : When Successfully + * Others : Errors + ****************************************************************************** + * + *This function initializes the MSC Class layer and layers it is dependent on + * + *****************************************************************************/ +usb_status USB_Class_MSC_Deinit +( +msd_handle_t msd_handle /*[IN]*/ +) +{ + usb_status error = USB_OK; + msc_device_struct_t * devicePtr = NULL; + + if (msd_handle == 0) + { + return USBERR_ERROR; + } + + devicePtr = USB_Msd_Get_Device_Ptr(msd_handle); + + if(error == USB_OK) + { + /* De-initialize the scsi subclass functions */ + error = USB_MSC_SCSI_Deinit(devicePtr); + } + +#if !USBCFG_DEV_COMPOSITE + if(error == USB_OK) + { + /* De-initialize the generic class functions */ + error = USB_Class_Deinit(devicePtr->controller_handle,devicePtr->class_handle); + } + if(error == USB_OK) + { + /* De-initialize the device layer*/ + error = usb_device_deinit(devicePtr->controller_handle); + } +#endif + if(error == USB_OK) + { +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if(NULL != devicePtr->csw_ptr) + { + OS_Mem_free(devicePtr->csw_ptr); + devicePtr->csw_ptr = NULL; + } + if(NULL != devicePtr->cbw_ptr) + { + OS_Mem_free(devicePtr->cbw_ptr); + devicePtr->cbw_ptr = NULL; + } +#endif + USB_Msd_Free_Handle(devicePtr); + } + return error; +} + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Send_Data + * + * @brief + * + * @param msc_handle : handle returned from USB_Class_MSC_Init + * @param ep_num : endpoint num + * @param app_buff : buffer to send + * @param size : length of the transfer + * + * @return status + * USB_OK : When Successfully + * Others : Errors + *****************************************************************************/ +usb_status USB_Class_MSC_Send_Data +( +msd_handle_t msc_handle, /*[IN]*/ +uint8_t ep_num, /*[IN]*/ +uint8_t * app_buff, /*[IN]*/ +uint32_t size /*[IN]*/ +) +{ + msc_device_struct_t * devicePtr; + usb_status error = USB_OK; + + devicePtr = USB_Msd_Get_Device_Ptr(msc_handle); + if (devicePtr == NULL) + { + return USBERR_ERROR; + } + + error = USB_Class_Send_Data(devicePtr->class_handle, + ep_num, app_buff,size); + + return error; +} + +/**************************************************************************//*! + * + * @name USB_MSC_LBA_Transfer + * + * @brief + * + * @param msc_device_struct_t * + * @param direction : transfer direction + * @param lba_info_ptr : buffer to send + * + * @return status + * USB_OK : When Successfully + * Others : Errors + *****************************************************************************/ +usb_status USB_MSC_LBA_Transfer +( +msc_device_struct_t * msc_obj_ptr, +bool direction, +lba_info_struct_t* lba_info_ptr +) +{ + usb_status error; + lba_app_struct_t lba_data; + +// if((!((lba_info_ptr->starting_lbadevice_info.total_lba_device_supports)&& +// (lba_info_ptr->lba_transfer_num <= (msc_obj_ptr->device_info.total_lba_device_supports - +// lba_info_ptr->starting_lba)))) || (msc_obj_ptr->class_specific_callback.callback == NULL)) +// { +// /* host trying to access region beyond MASS STORAGE SPACE +// Or no class_specific_callback is registered */ +// //return(uint8_t)((direction?USBERR_TX_FAILED:USBERR_RX_FAILED)); +// } + + msc_obj_ptr->transfer_remaining = lba_info_ptr->lba_transfer_num * + msc_obj_ptr->device_info.length_of_each_lab_of_device; + msc_obj_ptr->current_offset = lba_info_ptr->starting_lba * + msc_obj_ptr->device_info.length_of_each_lab_of_device; + + lba_data.offset = msc_obj_ptr->current_offset; + + if(direction == USB_SEND) + { + lba_data.size = (msc_obj_ptr->msd_buff.msc_bulk_in_size > MSD_SEND_MAX_TRANS_LENGTH) ? + MSD_SEND_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_in_size; /* whichever is smaller */ + lba_data.size = (msc_obj_ptr->transfer_remaining > lba_data.size) ? + lba_data.size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */ + + lba_data.buff_ptr = NULL; + msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_READ_REQUEST, + USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_in_ptr,(uint32_t *)&lba_data, msc_obj_ptr->class_specific_callback.arg); + + lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_in_ptr; + + if(lba_info_ptr->starting_lba < msc_obj_ptr->device_info.total_lba_device_supports) + { + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle,lba_data.buff_ptr,lba_data.size); + } + else + { + msc_obj_ptr->need_in_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->in_stall_flag = TRUE; /* clear the flag */ + msc_obj_ptr->in_flag = FALSE; /* clear send flag */ + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + error = usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_in_endpoint,USB_SEND); + } + } + else + { + lba_data.size = (msc_obj_ptr->msd_buff.msc_bulk_out_size > MSD_RECV_MAX_TRANS_LENGTH) ? + MSD_RECV_MAX_TRANS_LENGTH : msc_obj_ptr->msd_buff.msc_bulk_out_size; /* whichever is smaller */ + lba_data.size = (msc_obj_ptr->transfer_remaining > lba_data.size) ? + lba_data.size : msc_obj_ptr->transfer_remaining; /* whichever is smaller */ + + lba_data.buff_ptr = NULL; + msc_obj_ptr->class_specific_callback.callback(USB_MSC_DEVICE_WRITE_REQUEST, + USB_REQ_VAL_INVALID,&msc_obj_ptr->msd_buff.msc_bulk_out_ptr,(uint32_t *)&lba_data, msc_obj_ptr->class_specific_callback.arg); + + lba_data.buff_ptr = msc_obj_ptr->msd_buff.msc_bulk_out_ptr; + + if(lba_info_ptr->starting_lba < msc_obj_ptr->device_info.total_lba_device_supports) + { + error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle,lba_data.buff_ptr,lba_data.size); + } + else + { + msc_obj_ptr->need_out_stall_flag = FALSE; /* clear the flag */ + msc_obj_ptr->out_stall_flag = TRUE; /* clear the flag */ + msc_obj_ptr->out_flag = FALSE; /* clear send flag */ + msc_obj_ptr->stall_status = (uint8_t)STALL_IN_DATA_PHASE; + error = usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint,USB_RECV); + } + } + return error; +} + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Get_Speed + * + * @brief This functions get speed from Host. + * + * @param handle : handle returned by USB_Class_MSC_Init + * @param speed : speed + * + * @return status + * USB_OK : When Successfull + * Others : Errors + *****************************************************************************/ +usb_status USB_Class_MSC_Get_Speed +( +msd_handle_t handle, +uint16_t * speed/* [OUT] the requested error */ +) +{ + msc_device_struct_t * msd_obj_ptr; + usb_status error = USB_OK; + + msd_obj_ptr = (msc_device_struct_t *)handle; + if (NULL == msd_obj_ptr) + { + return USBERR_NO_DEVICE_CLASS; + } + error = USB_Class_Get_Status(msd_obj_ptr->class_handle, USB_STATUS_SPEED, speed); + + return error; +} + +#endif /*MSD_CONFIG*/ +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.h new file mode 100644 index 0000000..9c3d919 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc.h @@ -0,0 +1,612 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_msc.h$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file contains USB stack MSC class layer api header function. + * + *****************************************************************************/ + +#ifndef _USB_MSC_H +#define _USB_MSC_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_stack_interface.h" + +#include "usb_class.h" + +#include "usb_class_msc.h" + +#include "usb_msc_config.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ + +/* Class specific request Codes */ +#define BULK_ONLY_MASS_STORAGE_RESET (0xFF) +#define GET_MAX_LUN (0xFE) +#define PUT_REQUESTS (0xFD) +#define GET_REQUESTS (0xFC) + +/* Events to the Application *//* 0 to 4 are reserved for class events */ + +/* other macros */ +#define USB_DCBWSIGNATURE USB_LONG_BE_TO_HOST_CONST(0x55534243) +#define USB_DCSWSIGNATURE USB_LONG_BE_TO_HOST_CONST(0x55534253) +#define USB_CBW_DIRECTION_BIT (0x80) +#define USB_CBW_DIRECTION_SHIFT (7) +#define MSC_CBW_LENGTH (31) +#define MSC_CSW_LENGTH (13) + +#define COMMAND_PASSED (0x00) +#define COMMAND_FAILED (0x01) +#define PHASE_ERROR (0x02) + +/* MACROS FOR COMMANDS SUPPORTED */ +#define INQUIRY_COMMAND (0x12) +#define READ_10_COMMAND (0x28) +#define READ_12_COMMAND (0xA8) +#define REQUEST_SENSE_COMMAND (0x03) +#define TEST_UNIT_READY_COMMAND (0x00) +#define WRITE_10_COMMAND (0x2A) +#define WRITE_12_COMMAND (0xAA) +#define PREVENT_ALLOW_MEDIUM_REM_COMMAND (0x1E) +#define FORMAT_UNIT_COMMAND (0x04) +#define READ_CAPACITY_10_COMMAND (0x25) +#define READ_CAPACITY_16_COMMAND (0x9E) +#define READ_FORMAT_CAPACITIES_COMMAND (0x23) +#define MODE_SENSE_10_COMMAND (0x5A) +#define MODE_SENSE_6_COMMAND (0x1A) +#define MODE_SELECT_10_COMMAND (0x55) +#define MODE_SELECT_6_COMMAND (0x15) +#define SEND_DIAGNOSTIC_COMMAND (0x1D) +#define VERIFY_COMMAND (0x2F) +#define START_STOP_UNIT_COMMAND (0x1B) + +/***************************************************************************** + * Local Functions + *****************************************************************************/ +void USB_Service_Bulk_In(usb_event_struct_t* event, void* arg); +void USB_Service_Bulk_Out(usb_event_struct_t* event, void* arg); +void USB_Class_MSC_Event(uint8_t event, void* val, void* arg); +usb_status USB_MSC_Requests(usb_setup_struct_t * setup_packet, uint8_t * *data, uint32_t *size, void* arg); + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef enum +{ + USB_MSD_EP_COUNT = 1, + USB_MSD_INTERFACE_COUNT, + USB_MSD_CLASS_INFO, +} USB_MSD_DESC_INFO_T; + +typedef enum +{ + STALL_IN_CBW = 1, + STALL_IN_DATA_PHASE, + STALL_IN_CSW, +} STALL_TYPES_T; + +typedef struct _usb_msc_cbw /* Command Block Wrapper -- 31 bytes */ +{ + uint32_t signature; /*0-3 : dCBWSignature*/ + uint32_t tag; /*4-7 : dCBWTag*/ + uint32_t data_length; /*8-11 : dCBWDataTransferLength*/ + uint8_t flag; /*12 : bmCBWFlags*/ + uint8_t lun; /*13 : bCBWLUN(bits 3 to 0)*/ + uint8_t cb_length; /*14 : bCBWCBLength*/ + uint8_t command_block[16];/*15-30 : CBWCB*/ +}cbw_t; + +typedef struct _usb_msc_csw /* Command Status Wrapper -- 13 bytes */ +{ + uint32_t signature; /*0-3 : dCSWSignature*/ + uint32_t tag; /*4-7 : dCSWTag*/ + uint32_t residue; /*8-11 : dCSWDataResidue*/ + uint8_t csw_status; /*12 : bCSWStatus*/ +}csw_t; + +typedef struct _lba_info_struct +{ + uint32_t starting_lba;/* LBA to start transferring with */ + uint32_t lba_transfer_num;/* number of LBAs to transfer */ +} lba_info_struct_t; + +typedef struct _msc_thirteen_case_check +{ + usb_device_handle handle; + uint32_t host_expected_data_len; + uint32_t device_expected_data_len; + uint8_t* csw_status_ptr; + uint32_t* csw_residue_ptr; + uint8_t* buffer_ptr; + lba_info_struct_t lba_info; + bool lba_txrx_select; + uint8_t host_expected_direction; + uint8_t device_expected_direction; +} msc_thirteen_case_struct_t; + +/* USB class msc endpoint data */ +typedef struct _msc_endpoint_struct +{ + uint8_t endpoint; /* endpoint num */ + uint8_t type; /* type of endpoint (interrupt, bulk or isochronous) */ +} msc_endpoint_struct_t; + +typedef struct _msc_endpoint_data_struct +{ + uint8_t count; + msc_endpoint_struct_t ep[MAX_MSC_CLASS_EP_NUM]; +} msc_endpoint_data_struct_t; + +/* MSD Device Structure */ +typedef struct _msc_variable_struct +{ + usb_device_handle controller_handle; + uint32_t user_handle; + msd_handle_t msc_handle; + class_handle_t class_handle; + usb_endpoints_t* ep_desc_data; + usb_application_callback_struct_t msc_application_callback; + usb_vendor_req_callback_struct_t vendor_req_callback; + usb_class_specific_callback_struct_t class_specific_callback; + usb_desc_request_notify_struct_t desc_callback; + /* contains the endpoint info */ + /* Memory Allocation for endpoint done at App layer. Only App + Knows how many endpoints to allocate. + */ + void* scsi_object_ptr; + msc_endpoint_data_struct_t msc_endpoint_data; + /* macro configured by user*/ + /* global structure for command status wrapper */ + csw_t * csw_ptr; + /* global structure for command block wrapper */ + cbw_t * cbw_ptr; + device_lba_info_struct_t device_info; + msc_buff_info_t msd_buff; + /* following two macros are used to manage transfers involving read/write + on APPLICATION MASS STORAGE DEVICE */ + uint32_t transfer_remaining; + uint32_t current_offset; + uint32_t bulk_in_endpoint_packet_size; + uint32_t usb_max_suported_interfaces; + uint8_t bulk_in_endpoint; + uint8_t bulk_out_endpoint; + /* flag to track bulk out data processing after CBW if needed*/ + bool out_flag; + /* flag to track bulk in data processing before CSW if needed*/ + bool in_flag; + /* flag to track if there is stall BULK IN ENDPOINT because of BULK COMMAND*/ + bool in_stall_flag; + /* flag to track if there is stall BULK OUT ENDPOIN because of BULK COMMAND */ + bool out_stall_flag; + /* flag to validate CBW */ + bool cbw_valid_flag; + bool re_stall_flag; + bool wait_for_reset_recovery; + bool need_to_prepare_next; + /* flag to track if there is need to stall BULK IN ENDPOINT because of BULK COMMAND*/ + bool need_in_stall_flag; + /* flag to track if there is need to stall BULK OUT ENDPOIN because of BULK COMMAND */ + bool need_out_stall_flag; + bool cbw_prime_flag; + bool csw_prime_flag; + uint8_t stall_status; + /* LUN can have value only from 0 to 15 decimal */ + uint8_t lun; +}msc_device_struct_t; + +/**************************************************************************//*! + * + * @name USB_Class_MSC_Send_Data + * + * @brief + * + * @param msc_handle : handle returned from USB_Class_MSC_Init + * @param ep_num : endpoint num + * @param app_buff : buffer to send + * @param size : length of the transfer + * + * @return status + * USB_OK : When Successfull + * Others : Errors + *****************************************************************************/ +extern usb_status USB_Class_MSC_Send_Data +( + msd_handle_t msc_handle, + uint8_t ep_num, + uint8_t * app_buff, /* [IN] buffer to send */ + uint32_t size /* [IN] length of the transfer */ + ); + +/**************************************************************************//*! + * + * @name USB_MSC_LBA_Transfer + * + * @brief + * + * @param msc_device_struct_t * + * @param direction : transfer direction + * @param lba_info_ptr : buffer to send + * + * @return status + * USB_OK : When Successfully + * Others : Errors + *****************************************************************************/ +extern usb_status USB_MSC_LBA_Transfer +( + msc_device_struct_t * msc_obj_ptr, + bool direction, + lba_info_struct_t * lba_info_ptr + ); + +#define USB_MSC_Bulk_Send_Data(a,b,c) USB_Class_MSC_Send_Data(a,msc_obj_ptr->bulk_in_endpoint,b,c) +#define USB_MSC_Bulk_Recv_Data(a,b,c) usb_device_recv_data(a,msc_obj_ptr->bulk_out_endpoint,b,c) + +/* Sub Class Functions */ + +/**************************************************************************//*! + * + * @name USB_MSC_SCSI_Init + * + * @brief The function initializes the SCSI parameters and callbacks + * + * @param msc_obj_ptr MSD class object pointer. + * @param cb: event callback + * @param storage_disk Ramdisk Memory pointer. + * @param lb logical block + * @param lab_len length of each logical blocks + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +extern usb_status USB_MSC_SCSI_Init +( + msc_device_struct_t * msc_obj_ptr, + usb_class_specific_callback_struct_t* cb, + device_lba_info_struct_t* device_info_ptr, + uint32_t implementing_disk_drive + ); + +/**************************************************************************//*! + * + * @name USB_MSC_SCSI_Deinit + * + * @brief The function de-initializes the SCSI parameters and callbacks + * + * @param msc_obj_ptr MSD class object pointer. + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +extern usb_status USB_MSC_SCSI_Deinit +( + msc_device_struct_t * msc_obj_ptr + ); + +/**************************************************************************//*! + * + * @name msc_inquiry_command + * + * @brief It requests that information regarding parameters of the Device be + * sent to the Host Computer + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ + +extern usb_status msc_inquiry_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_read_command + * + * @brief command requests that device transfer data to the host computer + * (read (10) command) + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_read_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_request_sense_command + * + * @brief command instructs the Device to transfer sense data to host computer + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return NONE + * + *****************************************************************************/ +extern usb_status msc_request_sense_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_test_unit_ready_command + * + * @brief It provides a means to check if the device is ready + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_test_unit_ready_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_verify_command + * + * @brief requests that device verifies the data on medium + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_verify_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_mode_sense_command + * + * @brief command provides a means for a Device to report parameters to Host + * Computer.It is a complementary command to the MODE SELECT command. + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_mode_sense_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_mode_select_command + * + * @brief command provides a means for a Device to report parameters to Host + * Computer.It is a complementary command to the MODE SENSE command. + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_mode_select_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_read_capacity_command + * + * @brief command provides a means for the host computer to request information + * regarding the capacity of the installed medium of the device. + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_read_capacity_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_format_unit_command + * + * @brief host sends the FORMAT UNIT command to physically format a diskette + * according to selected options + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_format_unit_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_write_command + * + * @brief command requests that the Device write the data transferred by the + * Host Computer to the medium. + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_write_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_start_stop_unit_command + * + * @brief command instructs device to enable or disable media access operations + * + * @param controller_ID: To identify the controller + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_start_stop_unit_command +( + msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr + ); + +/**************************************************************************//*! + * + * @name msc_prevent_allow_medium_removal + * + * @brief command tells the UFI device to enable or disable the removal of the + * medium in the logical unit. + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_prevent_allow_medium_removal(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); +/**************************************************************************//*! + * + * @name msc_read_format_capacity_command + * + * @brief allows the host to request a list of the possible capacities that + * can be formatted on the currently installed medium + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_read_format_capacity_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); + +/**************************************************************************//*! + * + * @name msc_send_diagnostic_command + * + * @brief requests the device to perform self test + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_send_diagnostic_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); + +/**************************************************************************//*! + * + * @name msc_unsupported_command + * + * @brief Responds appropriately to unsupported commands + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +extern usb_status msc_unsupported_command(msc_device_struct_t * msc_obj_ptr, + cbw_t * cbw_ptr, + uint32_t* csw_residue_ptr, + uint8_t* csw_status_ptr); + +/* EOF */ +#endif + +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.c b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.c new file mode 100644 index 0000000..f30b5a3 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.c @@ -0,0 +1,1467 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_msc_scsi.c$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file contains USB Mass Storage SCSI command set. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device_stack_interface.h" + +#if USBCFG_DEV_MSC +#include "usb_class_internal.h" +#include "usb_msc_scsi.h" + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ +inquiry_data_struct_t inquiry_info = /* constant */ +{ + (PERIPHERAL_QUALIFIER << PERIPHERAL_QUALIFIER_SHIFT)|PERIPHERAL_DEVICE_TYPE, + (uint8_t)(REMOVABLE_MEDIUM_BIT << REMOVABLE_MEDIUM_BIT_SHIFT), + SPC_VERSION, 0x02, ADDITIONAL_LENGTH, 0x00,0x00,0x00, + { 'F', 'S', 'L', ' ', 'S', 'E', 'M', 'I'}, + { 'F','S','L',' ','M','A','S','S',' ','S','T','O','R','A','G','E'}, + { '0', '0', '0', '1'} +}; + +mode_parameter_header_struct_t mode_param_header = +{ + 0x0000,/*no following data available because of reason given below*/ + 0x00,/* 0x00 indicates current/default medium */ + 0x00,/* for write_protect and DPOFUA - no write protection available*/ + { 0x00,0x00,0x00,0x00} /* reserved bytes are always to be set to zero */ +}; + +/***************************************************************************** + * Global Functions Prototypes + *****************************************************************************/ +/**************************************************************************** + * Global Variables + ****************************************************************************/ +msc_scsi_struct_t g_msc_scsi[MAX_MSC_DEVICE]; +/* Add all the variables needed for usb_msc.c to this structure */ +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +usb_status msc_thirteen_cases_check(msc_device_struct_t * msc_obj_ptr,msc_thirteen_case_struct_t* msc_check_event); +/***************************************************************************** + * Local Variables + *****************************************************************************/ +//static read_capacity_data_struct_t read_capacity; +//static read_capacity16_data_struct_t read_capacity16; +//static uint8_t format_capacity_response_data[sizeof(capacity_list_header_struct_t) + sizeof(curr_max_capacity_desc_struct_t)+ +// sizeof(formattable_cap_desc_t) * 3]; +/***************************************************************************** + * Local Functions + *****************************************************************************/ +/*************************************************************************//*! + * + * @name USB_SCSI_Allocate_Handle + * + * @brief The funtion reserves entry in device array and returns the index. + * + * @param none. + * @return returns the reserved handle or if no entry found device busy. + * + *****************************************************************************/ +static usb_status USB_SCSI_Allocate_Handle(msc_scsi_struct_t** handle) +{ + uint32_t cnt = 0; + for (;cnt< MAX_MSC_DEVICE;cnt++) + { + if (g_msc_scsi[cnt].is_used == 0) + { + g_msc_scsi[cnt].is_used = 1; + *handle = (msc_scsi_struct_t*)&g_msc_scsi[cnt]; + return USB_OK; + } + } + return USBERR_DEVICE_BUSY; +} +/*************************************************************************//*! + * + * @name USB_SCSI_Free_Handle + * + * @brief The funtion releases entry in device array . + * + * @param handle index in device array to be released.. + * @return returns and error code or USB_OK. + * + *****************************************************************************/ + +static usb_status USB_SCSI_Free_Handle(msc_scsi_struct_t* handle) +{ + int32_t cnt = 0; + for (;cnt< MAX_MSC_DEVICE;cnt++) + { + if ((&g_msc_scsi[cnt]) == handle) + { + OS_Mem_zero((void*)handle, sizeof(msc_scsi_struct_t)); + return USB_OK; + } + } + return USBERR_INVALID_PARAM; +} +/**************************************************************************//*! + * + * @name msc_thirteen_cases_check + * + * @brief The funtion checks for thirteen error case of MSC and takes action + * appropriately + * + * @param scsi_ptr->thirteen_case: structure containing all necessary parameter to + * evaluate error scenarios + * + * @return error + * + *****************************************************************************/ +usb_status msc_thirteen_cases_check(msc_device_struct_t * msc_obj_ptr, +msc_thirteen_case_struct_t* msc_check_event +) +{ + usb_status error = USB_OK; + msc_scsi_struct_t* scsi_ptr; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + if(!msc_check_event->host_expected_data_len) + { /* host expects no data transfer */ + *(msc_check_event->csw_residue_ptr) = 0; + + if(!msc_check_event->device_expected_data_len) + { /* CASE 1: Device intends no data transfer : Thin Diagonal Case*/ + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { /* if(msc_check_event->device_expected_direction) : + CASE 2: Device intends to send data to host + else + CASE 3: Device intends to receive data from host */ + *(msc_check_event->csw_status_ptr) = PHASE_ERROR; + } + } + else if(msc_check_event->host_expected_direction) + { /* host expects to receive data from device (USB_SEND direction)*/ + if(!msc_check_event->device_expected_data_len) + { /* CASE 4: Device intends no data transfer */ + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len - + msc_check_event->device_expected_data_len; + /* sending zero bytes of data */ + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + msc_check_event->buffer_ptr, + msc_check_event->device_expected_data_len); + + if(error == USB_OK) + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR; + } + + /* BULK IN PIPE TO BE STALLED for status phase */ + error = USBERR_ENDPOINT_STALLED; + } + else if(msc_check_event->device_expected_direction) + { /* device intends to send data to host */ + if(msc_check_event->host_expected_data_len > + msc_check_event->device_expected_data_len) + { /* CASE 5: Host intends more data to receive than device + intends to send*/ + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len - + msc_check_event->device_expected_data_len; + + if(scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + msc_check_event->buffer_ptr, + msc_check_event->device_expected_data_len); + } + +// if ((READ_10_COMMAND != msc_obj_ptr->cbw_ptr->command_block[0]) && +// (READ_12_COMMAND != msc_obj_ptr->cbw_ptr->command_block[0]) && +// (msc_check_event->device_expected_data_len% +// msc_obj_ptr->bulk_in_endpoint_packet_size == 0)) +// { /* need to send zero bytes of data to tell host that device +// does not have any more data. This is needed only if the +// bytes send to host are integral multiple of max packet +// size of Bulk In endpoint */ +// error |= USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, +// msc_check_event->buffer_ptr,0); +// } + + if(error == USB_OK) + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR; + } + /* BULK IN PIPE TO BE STALLED for status phase */ + error = USBERR_ENDPOINT_STALLED; + } + else if(msc_check_event->host_expected_data_len == + msc_check_event->device_expected_data_len) + { /* CASE 6: Host intends exact amount of data to receive + as device intends to send : Thin Diagonal Case*/ + *(msc_check_event->csw_residue_ptr) = 0; + + if(scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + msc_check_event->buffer_ptr, + msc_check_event->device_expected_data_len); + } + + if(error == USB_OK) + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR; + } + } + else + { + /* CASE 7: Host intends less data to receive than device + intends to send*/ + *(msc_check_event->csw_residue_ptr) = 0; + + if (scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + msc_check_event->lba_info.lba_transfer_num = + msc_check_event->host_expected_data_len / + scsi_ptr->length_of_each_lab; + *(msc_check_event->csw_residue_ptr) = msc_check_event->host_expected_data_len - msc_check_event->lba_info.lba_transfer_num * scsi_ptr->length_of_each_lab; + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_SEND, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + msc_check_event->buffer_ptr, + msc_check_event->host_expected_data_len); + } + + if(error == USB_OK) + { + if (scsi_ptr->thirteen_case.lba_txrx_select == TRUE) /* READ_COMMAND OR WRITE_COMMAND */ + { + *(msc_check_event->csw_status_ptr) = PHASE_ERROR; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = UNRECOVERED_READ_ERROR; + } + } + } + else + { /* CASE 8: Device intends to receive data from host */ + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len; + /* device has no data to send */ + error = USB_MSC_Bulk_Send_Data(msc_obj_ptr->msc_handle, + msc_check_event->buffer_ptr,0); + *(msc_check_event->csw_status_ptr) = PHASE_ERROR; + /* BULK IN PIPE TO BE STALLED for status phase */ + error = USBERR_ENDPOINT_STALLED; + } + } + else + { /* host expects to send data to device (USB_RECV direction)*/ + if(!msc_check_event->device_expected_data_len) + { /* CASE 9: Device intends no data transfer */ + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint, USB_RECV); + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len; + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + /* BULK OUT PIPE STALLED */ + msc_obj_ptr->out_stall_flag = TRUE; + error = USBERR_ENDPOINT_STALLED; + } + else if(msc_check_event->device_expected_direction) + { /*CASE10: device intends to send data to host */ + usb_device_stall_endpoint(msc_obj_ptr->controller_handle,msc_obj_ptr->bulk_out_endpoint, USB_RECV); + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len; + *(msc_check_event->csw_status_ptr) = PHASE_ERROR; + /* BULK OUT PIPE STALLED */ + msc_obj_ptr->out_stall_flag = TRUE; + error = USBERR_ENDPOINT_STALLED; + } + else + { /*Device intends to receive data from host */ + if(msc_check_event->host_expected_data_len > + msc_check_event->device_expected_data_len) + { /* CASE 11: Host intends more data to send than device + intends to receive*/ + *(msc_check_event->csw_residue_ptr) = + msc_check_event->host_expected_data_len - + msc_check_event->device_expected_data_len; + + if(scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + msc_check_event->buffer_ptr, + msc_check_event->device_expected_data_len); + } + + if(error == USB_OK) + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = WRITE_FAULT; + } + /* BULK OUT PIPE TO BE STALLED for status phase */ + error = USBERR_ENDPOINT_STALLED; + } + else if(msc_check_event->host_expected_data_len == + msc_check_event->device_expected_data_len) + { /* CASE 12: Host intends exact amount of data to send + as device intends to receive : Thin Diagonal Case*/ + *(msc_check_event->csw_residue_ptr) = 0; + + if(scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + msc_check_event->buffer_ptr, + msc_check_event->device_expected_data_len); + } + + if(error == USB_OK) + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = WRITE_FAULT; + } + } + else + { + /* CASE 13: Host intends less data to send than device + intends to receive*/ + *(msc_check_event->csw_residue_ptr) = 0; + + if(scsi_ptr->thirteen_case.lba_txrx_select == TRUE) + { + msc_check_event->lba_info.lba_transfer_num = + msc_check_event->host_expected_data_len / + scsi_ptr->length_of_each_lab; + *(msc_check_event->csw_residue_ptr) = msc_check_event->host_expected_data_len - msc_check_event->lba_info.lba_transfer_num * scsi_ptr->length_of_each_lab; + error = USB_MSC_LBA_Transfer(msc_obj_ptr,USB_RECV, + &msc_check_event->lba_info); + } + else + { + error = USB_MSC_Bulk_Recv_Data(msc_obj_ptr->controller_handle, + msc_check_event->buffer_ptr, + msc_check_event->host_expected_data_len); + } + + if (error == USB_OK) + { + if (scsi_ptr->thirteen_case.lba_txrx_select == TRUE) /* READ_COMMAND OR WRITE_COMMAND */ + { + *(msc_check_event->csw_status_ptr) = PHASE_ERROR; + } + else + { + *(msc_check_event->csw_status_ptr) = COMMAND_PASSED; + } + } + else + { + scsi_ptr->request_sense.sense_key = MEDIUM_ERROR; + scsi_ptr->request_sense.add_sense_code = WRITE_FAULT; + } + } + } + } + return error; +} + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_MSC_SCSI_Init + * + * @brief The funtion initializes the SCSI parameters and callbacks + * + * @param msc_obj_ptr MSD class object pointer. + * @param cb: event callback + * @param device_info_ptr : Contains MSD device info like number of LBA, etc + * @return status + * USB_OK : When Successfull + * Others : Errors + * + *****************************************************************************/ +usb_status USB_MSC_SCSI_Init +( +msc_device_struct_t * msc_obj_ptr, +usb_class_specific_callback_struct_t* cb, +device_lba_info_struct_t* device_info_ptr, +uint32_t implementing_disk_drive +) +{ + msc_scsi_struct_t* scsi_ptr = NULL; + usb_status error = USBERR_ERROR; + /* initialize the Global Variable Structure */ + + error = USB_SCSI_Allocate_Handle(&scsi_ptr); + if (USB_OK != error) + { + return error; + } + + /* save input parameters */ + scsi_ptr->scsi_callback.callback = cb->callback; + scsi_ptr->scsi_callback.arg = cb->arg; + scsi_ptr->total_logical_add_block = + device_info_ptr->total_lba_device_supports; + scsi_ptr->length_of_each_lab = + device_info_ptr->length_of_each_lab_of_device; + scsi_ptr->implementing_disk_drive = implementing_disk_drive; + + /* no need to initialize other structure fields as g_resquest_sense has + been declared as static */ + scsi_ptr->request_sense.valid_error_code = REQ_SENSE_VALID_ERROR_CODE; + scsi_ptr->request_sense.add_sense_len = REQ_SENSE_ADDITIONAL_SENSE_LEN; + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + if(scsi_ptr->scsi_callback.callback != NULL) + { + scsi_ptr->scsi_callback.callback(USB_MSC_DEVICE_GET_INFO,USB_REQ_VAL_INVALID,NULL,(uint32_t *)device_info_ptr,NULL); + } + + scsi_ptr->total_logical_add_block = + device_info_ptr->total_lba_device_supports; + scsi_ptr->length_of_each_lab = + device_info_ptr->length_of_each_lab_of_device; + + scsi_ptr->read_capacity.last_logical_block_address = USB_LONG_BE_TO_HOST(scsi_ptr->total_logical_add_block -1); + scsi_ptr->read_capacity.block_size = USB_LONG_BE_TO_HOST((uint32_t) scsi_ptr->length_of_each_lab); + scsi_ptr->read_capacity16.last_logical_block_address1 = USB_LONG_BE_TO_HOST(scsi_ptr->total_logical_add_block -1); + scsi_ptr->read_capacity16.block_size = USB_LONG_BE_TO_HOST((uint32_t) scsi_ptr->length_of_each_lab); + + msc_obj_ptr->scsi_object_ptr = scsi_ptr; + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_MSC_SCSI_Deinit + * + * @brief The funtion deinitializes the SCSI parameters and callbacks + * + * @param msc_obj_ptr MSD class object pointer. + * @return status + * USB_OK : When Successfull + * Others : Errors + * + *****************************************************************************/ +usb_status USB_MSC_SCSI_Deinit +( +msc_device_struct_t * msc_obj_ptr +) +{ + if(NULL == msc_obj_ptr) + { + return USBERR_ERROR; + } + USB_SCSI_Free_Handle((msc_scsi_struct_t* )msc_obj_ptr->scsi_object_ptr); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name msc_request_sense_command + * + * @brief command instructs the Device to transfer sense data to host computer + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return NONE + * + *****************************************************************************/ +usb_status msc_request_sense_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + usb_status error; + msc_scsi_struct_t* scsi_ptr; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = REQ_SENSE_DATA_LENGTH; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&scsi_ptr->request_sense; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_inquiry_command + * + * @brief It requests that information regarding parameters of the Device be + * sent to the Host Computer + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_inquiry_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = INQUIRY_ALLOCATION_LENGTH; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&inquiry_info; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_read_command + * + * @brief command requests that device transfer data to the host computer + * (read (10) command) + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_read_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + uint32_t lba = 0; + uint32_t num_lba_tx = 0; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + lba = ((uint32_t)cbw_ptr->command_block[2] << 24); + lba |= ((uint32_t)cbw_ptr->command_block[3] << 16); + lba |= ((uint32_t)cbw_ptr->command_block[4] << 8); + lba |= ((uint32_t)cbw_ptr->command_block[5]); + + if(cbw_ptr->command_block[0] == READ_10_COMMAND) + { + num_lba_tx = (uint16_t)((uint16_t)cbw_ptr->command_block[7] << 8); + num_lba_tx |= (uint16_t)cbw_ptr->command_block[8]; + } + else if(cbw_ptr->command_block[0] == READ_12_COMMAND) + { + num_lba_tx = ((uint32_t)cbw_ptr->command_block[6] << 24); + num_lba_tx |= ((uint32_t)cbw_ptr->command_block[7] << 16); + num_lba_tx |= ((uint32_t)cbw_ptr->command_block[8] << 8); + num_lba_tx |= ((uint32_t)cbw_ptr->command_block[9]); + } + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + + scsi_ptr->thirteen_case.device_expected_data_len = + scsi_ptr->length_of_each_lab * num_lba_tx; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + + scsi_ptr->thirteen_case.lba_txrx_select = TRUE; + scsi_ptr->thirteen_case.lba_info.starting_lba = lba; + scsi_ptr->thirteen_case.lba_info.lba_transfer_num = num_lba_tx; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + return error; +} + +/**************************************************************************//*! + * + * @name msc_write_command + * + * @brief command requests that the Device write the data transferred by the + * Host Computer to the medium. + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_write_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + uint32_t lba = 0; + uint32_t num_lba_rx = 0; + usb_status error = USBERR_RX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + lba = ((uint32_t)cbw_ptr->command_block[2] << 24); + lba |= ((uint32_t)cbw_ptr->command_block[3] << 16); + lba |= ((uint32_t)cbw_ptr->command_block[4] << 8); + lba |= ((uint32_t)cbw_ptr->command_block[5]); + + if(cbw_ptr->command_block[0] == WRITE_10_COMMAND) + { + num_lba_rx = (uint16_t)((uint16_t)cbw_ptr->command_block[7] << 8); + num_lba_rx |= (uint16_t)cbw_ptr->command_block[8]; + } + else if(cbw_ptr->command_block[0] == WRITE_12_COMMAND) + { + num_lba_rx = ((uint32_t)cbw_ptr->command_block[6] << 24); + num_lba_rx |= ((uint32_t)cbw_ptr->command_block[7] << 16); + num_lba_rx |= ((uint32_t)cbw_ptr->command_block[8] << 8); + num_lba_rx |= ((uint32_t)cbw_ptr->command_block[9]); + } + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_direction = USB_RECV; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + + scsi_ptr->thirteen_case.buffer_ptr = NULL; + +#if 0 + if(usb_device_get_transfer_status(msc_obj_ptr->controller_handle, + BULK_OUT_ENDPOINT, USB_RECV) != USB_STATUS_IDLE) + { + (void)usb_device_cancel_transfer(msc_obj_ptr->controller_handle,BULK_OUT_ENDPOINT, + USB_RECV); + } +#endif + + scsi_ptr->thirteen_case.device_expected_data_len = + scsi_ptr->length_of_each_lab * num_lba_rx; + + scsi_ptr->thirteen_case.lba_txrx_select = TRUE; + scsi_ptr->thirteen_case.lba_info.starting_lba = lba; + scsi_ptr->thirteen_case.lba_info.lba_transfer_num = num_lba_rx; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_test_unit_ready_command + * + * @brief It provides a means to check if the device is ready + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_test_unit_ready_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_verify_command + * + * @brief requests that device verifies the data on medium + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_verify_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error; + /* Our Device has no mechanism to verify the blocks, + so just returning success status to host*/ + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_mode_sense_command + * + * @brief command provides a means for a Device to report parameters to Host + * Computer.It is a complementary command to the MODE SELECT command. + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_mode_sense_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + /* irrespective of DBD(Disable block descriptor) bit in Command Block + Wrapper we are not returning any block descriptors in the returned mode + sense data.Presently, we are just returning Mode Parameter Header */ + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = sizeof(mode_param_header); + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&mode_param_header; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_mode_select_command + * + * @brief command provides a means for a Device to report parameters to Host + * Computer.It is a complementary command to the MODE SENSE command. + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_mode_select_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + + scsi_ptr->thirteen_case.device_expected_data_len = sizeof(mode_param_header); + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&mode_param_header; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + if(cbw_ptr->command_block[1] & 0x01)/* checking Save Pages Bit in command*/ + { + scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST; + scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT; + /*logical unit does not implement save mode pages in our case*/ + } + return error; +} + +/**************************************************************************//*! + * + * @name msc_read_capacity_command + * + * @brief command provides a means for the host computer to request information + * regarding the capacity of the installed medium of the device. + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_read_capacity_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + if(cbw_ptr->command_block[0] == READ_CAPACITY_10_COMMAND) + { + scsi_ptr->thirteen_case.device_expected_data_len = READ_CAPACITY_DATA_LENGTH; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&(scsi_ptr->read_capacity); + } + else + { + scsi_ptr->thirteen_case.device_expected_data_len = READ_CAPACITY16_DATA_LENGTH; + scsi_ptr->thirteen_case.buffer_ptr = (uint8_t *)&(scsi_ptr->read_capacity16); + } + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_read_format_capacity_command + * + * @brief allows the host to request a list of the possible capacities that + * can be formatted on the currently installed medium + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_read_format_capacity_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + uint8_t num_formattable_cap_desc; + uint16_t allocation_length; + /* pointer to data to be sent in data phase for this command*/ + //uint8_t * response_data_ptr = NULL; + /* size of data to be sent in data phase for this command*/ + uint32_t response_size; + /* general variable for counting in loop */ + uint8_t i; + curr_max_capacity_desc_struct_t curr_max_cap_header; + uint8_t desc_code; + formattable_cap_desc_t formattable_cap_descriptor; + capacity_list_header_struct_t capacity_list_header= {{0x00,0x00,0x00},0x00}; + usb_status error = USBERR_TX_FAILED; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + allocation_length = (uint16_t)((uint8_t)(cbw_ptr->command_block[7] << 8) | + cbw_ptr->command_block[8]); + + num_formattable_cap_desc = (uint8_t)(scsi_ptr->formatted_disk ? + (scsi_ptr->implementing_disk_drive?0x02:0x03):0x00); + /* + * gives the number of Formattable Capacity Descriptor to be sent by device + * in response to read format capacities command + */ + + /* + * 0x03 is number of formattable capcity desc for HD while for DD its 2 if + * formatted drive is there + */ + + formattable_cap_descriptor.num_blocks = scsi_ptr->total_logical_add_block; + formattable_cap_descriptor.block_len = scsi_ptr->length_of_each_lab; + + desc_code = (uint8_t)(scsi_ptr->formatted_disk?FORMATTED_MEDIA:UNFORMATTED_MEDIA); + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + capacity_list_header.capacity_list_len = (uint8_t)(num_formattable_cap_desc * 8); + curr_max_cap_header.num_blocks = scsi_ptr->total_logical_add_block; + curr_max_cap_header.desc_code_and_block_len = (uint8_t)(desc_code << 24)| + scsi_ptr->length_of_each_lab; + response_size = sizeof(capacity_list_header) + sizeof(curr_max_cap_header)+ + sizeof(formattable_cap_descriptor) * num_formattable_cap_desc; + + if(response_size > allocation_length) + { /* comapring the length of data available with allocation length value + sent in CBW which indicates the length of buffer host has reserved + for data phase of this command */ + response_size = allocation_length; + } + + if(sizeof(scsi_ptr->format_capacity_response_data) < response_size) + { + USB_PRINTF("format_capacity_response_data buff size less than need\n"); + } + OS_Mem_zero(scsi_ptr->format_capacity_response_data, response_size); + + OS_Mem_copy(&capacity_list_header, scsi_ptr->format_capacity_response_data, + sizeof(capacity_list_header)); + OS_Mem_copy(&curr_max_cap_header, scsi_ptr->format_capacity_response_data + + sizeof(capacity_list_header),sizeof(curr_max_cap_header)); + + if(scsi_ptr->formatted_disk) + { + for(i = 0; i < num_formattable_cap_desc; i++) + { + OS_Mem_copy(&formattable_cap_descriptor, scsi_ptr->format_capacity_response_data + + sizeof(capacity_list_header) + sizeof(curr_max_cap_header)+ + sizeof(formattable_cap_descriptor) * i, + sizeof(formattable_cap_descriptor)); + } + } + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = response_size; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = scsi_ptr->format_capacity_response_data; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_format_unit_command + * + * @brief host sends the FORMAT UNIT command to physically format a diskette + * according to selected options + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_format_unit_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error; + *csw_residue_ptr = 0; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + if(*csw_status_ptr != PHASE_ERROR) + { + /* FmtData = 1, CmpList = 0, Defect List Format = 7 */ + if((cbw_ptr->command_block[1] & 0x1F) == 0x17) + { + *csw_status_ptr = COMMAND_PASSED; + } + else + { + *csw_status_ptr = COMMAND_FAILED; + scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST; + scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT; + } + } + return error; +} + +/**************************************************************************//*! + * + * @name msc_prevent_allow_medium_removal + * + * @brief command tells the UFI device to enable or disable the removal of the + * medium in the logical unit. + * + * @param handle + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_prevent_allow_medium_removal +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error; + uint8_t prevent_removal = 0; + /* masking to obtain value of last bit */ + prevent_removal = (uint8_t)(cbw_ptr->command_block[4] & + PREVENT_ALLOW_REMOVAL_MASK); + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + if(*csw_status_ptr != PHASE_ERROR) + { + if((!SUPPORT_DISK_LOCKING_MECHANISM)&&(prevent_removal)) + {/*there is no support for disk locking and removal of medium is disabled*/ + scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST; + scsi_ptr->request_sense.add_sense_code = INVALID_FIELD_IN_COMMAND_PKT; + *csw_status_ptr = COMMAND_FAILED; + } + } + + if(scsi_ptr->scsi_callback.callback != NULL) + { + scsi_ptr->scsi_callback.callback(USB_MSC_DEVICE_REMOVAL_REQUEST, + USB_REQ_VAL_INVALID,NULL,(uint32_t *)&prevent_removal, scsi_ptr->scsi_callback.arg); + } + + return error; +} + +/**************************************************************************//*! + * + * @name msc_send_diagnostic_command + * + * @brief requests the device to perform self test + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_send_diagnostic_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + /* No Self Test Procedure available */ + usb_status error; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + return error; +} + +/**************************************************************************//*! + * + * @name msc_start_stop_unit_command + * + * @brief command instructs device to enable or disable media access operations + * + * @param msc_obj_ptr: + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_start_stop_unit_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + usb_status error; + uint8_t load_eject_start; + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + /* masking to obtain value of last bit */ + load_eject_start = (uint8_t)(cbw_ptr->command_block[4] & + LOAD_EJECT_START_MASK); + /* initialize sense code values */ + scsi_ptr->request_sense.sense_key = NO_SENSE; + scsi_ptr->request_sense.add_sense_code = NO_SENSE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + scsi_ptr->thirteen_case.handle = msc_obj_ptr->controller_handle; + scsi_ptr->thirteen_case.host_expected_data_len = cbw_ptr->data_length; + scsi_ptr->thirteen_case.host_expected_direction = + (uint8_t)(cbw_ptr->flag >> USB_CBW_DIRECTION_SHIFT); + scsi_ptr->thirteen_case.device_expected_data_len = 0; + scsi_ptr->thirteen_case.device_expected_direction = USB_SEND; + scsi_ptr->thirteen_case.csw_status_ptr = csw_status_ptr; + scsi_ptr->thirteen_case.csw_residue_ptr = csw_residue_ptr; + scsi_ptr->thirteen_case.buffer_ptr = NULL; + scsi_ptr->thirteen_case.lba_txrx_select = FALSE; + + error = msc_thirteen_cases_check(msc_obj_ptr, &scsi_ptr->thirteen_case); + + if(*csw_status_ptr != PHASE_ERROR) + { + if(scsi_ptr->scsi_callback.callback != NULL) + { + scsi_ptr->scsi_callback.callback(USB_MSC_START_STOP_EJECT_MEDIA, + USB_REQ_VAL_INVALID,NULL,(uint32_t *)&load_eject_start, scsi_ptr->scsi_callback.arg); + } + } + return error; +} + +/**************************************************************************//*! + * + * @name msc_unsupported_command + * + * @brief Responds appropriately to unsupported commands + * + * @param msc_obj_ptr + * @param cbw_ptr : pointer to Command Block Wrapper sent by host + * @param csw_residue_ptr: pointer to dCSWDataResidue of Command Status Wrapper + * @param csw_status_ptr : pointer to bCSWStatus of Command Status Wrapper + * + * @return error + * + *****************************************************************************/ +usb_status msc_unsupported_command +( +msc_device_struct_t * msc_obj_ptr, +cbw_t * cbw_ptr, +uint32_t* csw_residue_ptr, +uint8_t* csw_status_ptr +) +{ + msc_scsi_struct_t* scsi_ptr; + + //UNUSED_ARGUMENT(cbw_ptr) + + scsi_ptr = (msc_scsi_struct_t*)msc_obj_ptr->scsi_object_ptr; + + *csw_residue_ptr = 0; + *csw_status_ptr = COMMAND_FAILED; + + scsi_ptr->request_sense.sense_key = ILLEGAL_REQUEST; + scsi_ptr->request_sense.add_sense_code = INVALID_COMMAND_OPCODE; + scsi_ptr->request_sense.add_sense_code_qual = NO_SENSE; + + return USB_OK; +} +#endif /*MSD_CONFIG*/ +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.h b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.h new file mode 100644 index 0000000..640aa33 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/classes/msd/usb_msc_scsi.h @@ -0,0 +1,309 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_msc_scsi.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains USB Mass Storage SCSI layer api header function +* +*****************************************************************************/ + +#ifndef _USB_MSC_SCSI_H +#define _USB_MSC_SCSI_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "usb_msc.h" +/****************************************************************************** + * Constants - None + *****************************************************************************/ + + +/****************************************************************************** + * Macro's + *****************************************************************************/ + /* macros for SENSE KEY Codes*/ +#define NO_SENSE (0x00) +#define RECOVERED_ERROR (0x01) +#define NOT_READY (0x02) +#define MEDIUM_ERROR (0x03) +#define HARDWARE_ERROR (0x04) +#define ILLEGAL_REQUEST (0x05) +#define UNIT_ATTENTION (0x06) +#define DATA_PROTECT (0x07) +#define BLANK_CHECK (0x08) +#define VENDOR_SPECIFIC_ERROR (0x09) +#define ABORTED_COMMAND (0x0B) +#define VOLUME_OVERFLOW (0x0D) +#define MISCOMPARE (0x0E) + +/* macros for ADDITIONAL SENSE Codes*/ +#define INVALID_COMMAND_OPCODE (0x20) +#define WRITE_FAULT (0x03) +#define UNRECOVERED_READ_ERROR (0x11) +#define UNKNOWN_ERROR (0xFF) +#define INVALID_FIELD_IN_COMMAND_PKT (0x24) +#define LBA_OUT_OF_RANGE (0x21) + +/* other macros */ +#define REQ_SENSE_VALID_ERROR_CODE (0x70) +#define REQ_SENSE_ADDITIONAL_SENSE_LEN (0x0A) +#define PREVENT_ALLOW_REMOVAL_MASK (0x01) +#define LOAD_EJECT_START_MASK (0x03) +#define FORMATTED_MEDIA (0x02) +#define UNFORMATTED_MEDIA (0x01) +#define NO_CARTRIDGE_IN_DRIVE (0x03) + +#define INQUIRY_ALLOCATION_LENGTH (0x24) +#define REQ_SENSE_DATA_LENGTH (18) +#define READ_CAPACITY_DATA_LENGTH (0x08) +#define READ_CAPACITY16_DATA_LENGTH (0x0C) + +#define PERIPHERAL_QUALIFIER (0) +#define PERIPHERAL_QUALIFIER_SHIFT (5) +#define SPC_VERSION (4)/*SPC3 is 5; SPC2 is 4*/ +#define PERIPHERAL_DEVICE_TYPE (0x00) +#define REMOVABLE_MEDIUM_BIT (1) +#define REMOVABLE_MEDIUM_BIT_SHIFT (7) +#define ADDITIONAL_LENGTH (0x20) +#define SUPPORT_DISK_LOCKING_MECHANISM (0) /*1: TRUE; 0:FALSE*/ + +#define BULK_OUT_ENDPOINT msc_obj_ptr->bulk_out_endpoint + +/* Forward Declaration */ +/****************************************************************************** + * Types + *****************************************************************************/ +/**** COMMAND STRUCTURES ******/ +typedef struct _inquiry_command +{ + uint8_t opcode; /* operation code : 0x12H*/ + uint8_t lun_evpd; /* Logical Unit Number: bits 7-5, EVPD: bit 0 */ + uint8_t page_code; + uint8_t reserved1; /* 1 bytes are reserved */ + uint8_t alloc_length; /* allocation length : 0x24H*/ + uint8_t reserved2[7];/* reserved and pad bits */ +}inquiry_command_struct_t, * PTR_INQUIRY_COMMAND_STRUCT; + +typedef struct _request_sense_command +{ + uint8_t opcode; /* operation code : 0x03H*/ + uint8_t lun; /* Logical Unit Number: bits 7-5, rest reserved */ + uint8_t reserved1[2]; /* 2 bytes are reserved */ + uint8_t alloc_length; /* specs say it to be 252 bytes, + but windows request only 18 bytes*/ + uint8_t reserved2[7];/* reserved and pad bits */ +}request_sense_command_struct_t; + +typedef struct _read_format_capacity_command +{ + uint8_t opcode; /* operation code : 0x23H*/ + uint8_t lun; /* LUN : bits 7-5*/ + uint8_t reserved1[5]; + uint16_t alloc_len; /*Allocation length (MSB) :byte 7; + Allocation length (LSB) :byte 8*/ + uint8_t reserved2[3]; +}read_format_capacity_command_struct_t; + +typedef struct _read_capacity_command +{ + uint8_t opcode; /* operation code : 0x25H*/ + uint8_t lun_adr; /* LUN : bits 7-5, RelAdr : bit 0*/ + uint32_t lba; /* Logical Block Address : 4 bytes */ + uint8_t reserved1[2]; /* 2 bytes are reserved */ + uint8_t pmi; /* always set to zero for UFI devices */ + uint8_t reserved2[3];/* 3 bytes are reserved */ +} read_capacity_command_struct_t; + +typedef struct _read_write_10_command +{ + uint8_t opcode; /* operation code : 0x28H(read), 0x2A(write)*/ + uint8_t lun_dpo_fua_adr;/*LUN:bits7-5, DPO:bit4, FUA:bit3, RelAdr:bit0*/ + uint32_t lba; + uint8_t reserved1; + uint8_t transfer_length_msb; + uint8_t transfer_length_lsb; + uint8_t reserved2[3]; +}read_write_10_command_struct_t; + + +/******* COMMAND RESPONSE DATA STRUCTURES */ +typedef struct _inquiry_data /* 36 bytes structure */ +{ + uint8_t peripheral;/*Bits 7..5: PERIPHERAL QUALIFIER (000 = a device is + connected to this logical unit) + Bits 4..0: PERIPHERAL DEVICE TYPE (PDT) */ + uint8_t rmb;/*Bit 7: RMB (0 = non-removable media; 1 = removable media) + Bits 6..0: reserved */ + uint8_t version;/*VERSION of SPC standard (5 = SPC-3; 4 = SPC-2) */ + uint8_t response_data_format;/*Bits 7..6: obsolete + Bit 5: NORMACA (normal ACA bit support) + Bit 4: HISUP(hierarchical addressing support) + Bits 3..0: response data format (must = 2) */ + uint8_t additional_length;/*the number of additional bytes in the response). + Equal to (response length - 4). Set to 20h if + returning 36 (24h) bytes. */ + uint8_t sccs;/*Bit 7: SCCS (0 = no embedded storage array controller + component present) + Bit 6: ACC (0 = no access controls coordinator present) + Bits 5..4: TPGS (0 = no support or vendor-specific support + for asymmetric logical unit access) + Bit 3: 3PC ((0 = no support for third-party copy commands) + Bits 2..1: reserved + Bit 0: PROTECT (0 = no support for protection information)*/ + uint8_t bque;/*Bit 7: BQUE (0 = no support for basic task management) + Bit 6: ENCSERV (0=no support for embedded enclosure services) + Bit 5: VS (vendor specific) + Bit 4: MULTIP (0 = device has a single port) + Bit 3: MCHNGR (0 = no support for media changer) + Bits 2..1: obsolete + Bit 0: ADDR16 (not used with USB interface) */ + uint8_t wbus;/*Bit 7..6: obsolete + Bit 5: WBUS16 (not used with USB interface) + Bit 4: SYNC (not used with USB interface) + Bit 3: LINKED (0 = no support for linked commands) + Bit 2: obsolete + Bit 1: CMDQUE (0 = no support for full task management) + Bit 0: VS (vendor specific)*/ + uint8_t vendor_info[8]; /*T10 VENDOR IDENTIFICATION, MSB first */ + uint8_t product_id[16]; /*PRODUCT IDENTIFICATION, MSB first*/ + uint8_t product_rev_level[4];/*PRODUCT REVISION LEVEL, MSB first*/ +}inquiry_data_struct_t; + +typedef struct _request_sense_data /* 18 bytes structure */ +{ + uint8_t valid_error_code;/*bit 7: VALID. Set to 1 if the INFORMATION field + contains valid information. + bits 6..0: RESPONSE CODE. Set to 70h for info on + current errors. Set to 71h for info on + deferred errors (used with commands + that use caching).*/ + uint8_t reserved1; /* obsolete */ + uint8_t sense_key;/*Bit7: FILEMARK. Used by streaming devices. + Bit6: EOM. End of medium. Used by streaming devices. + Bit5: ILI: Incorrect length indicator. Used with READ + LONG, WRITE LONG, and stream READ commands. + Bit4: Reserved + Bits3:0: SENSE KEY. Contains info describing the error*/ + uint8_t information[4];/*Device-specific or command-specific info*/ + uint8_t add_sense_len;/*number of additional sense bytes that follow this + field. Maximum is 244*/ + uint8_t command_specific_info[4]; + uint8_t add_sense_code;/*Provides additional information about the + error. Set to zero if unused */ + uint8_t add_sense_code_qual;/*Provides additional info related to additional + sense code. Set to zero if unused */ + uint8_t field_rep_uint_code;/*Identifies a failed component. Set to zero if + there is no component to identify */ + uint8_t sense_key_specific[3];/*If byte 15, bit7(SKSV) equals 1,remainder of + the field contains SENSE KEY SPECIFIC info*/ +}request_sense_data_struct_t; + +typedef struct _read_capacity_data /* 8 bytes structure */ +{ + uint32_t last_logical_block_address;/*last LBA number*/ + uint32_t block_size; /* in bytes */ +}read_capacity_data_struct_t; + +typedef struct _read_capacity16_data /* 8 bytes structure */ +{ + uint32_t last_logical_block_address0;/*last LBA number*/ + uint32_t last_logical_block_address1;/*last LBA number*/ + uint32_t block_size; /* in bytes */ +}read_capacity16_data_struct_t; + +typedef struct _capacity_list_header +{ + uint8_t reserved1[3]; + uint8_t capacity_list_len;/*specifies the length in bytes of the Capacity + Descriptor that follow. Each capacity descriptor + is eight bytes in length, making the capacity + list length equal to eight times the number of + descriptors */ +}capacity_list_header_struct_t; + +typedef struct _curr_max_capacity_desc +{ + uint32_t num_blocks; /*byte 0-3 = total number of addressable blocks for the + descriptor's media type */ + uint32_t desc_code_and_block_len; + /*byte 4: specifies the type of descriptor returned to host : + 01b : unformattable media - max formattable capacity for this cartridge + 10b : formatted media - current media capacity + 11b : no cartridge in drive - max formattable capacity for any cartridge*/ + /* byte 5-7 : specifies the length in bytes of each logical block + Note: byte 5 holds most significant byteS*/ +}curr_max_capacity_desc_struct_t; + +typedef struct _formattable_cap_desc +{ + uint32_t num_blocks;/*byte 0-3 : fields indicates the number of addressable + blocks for the given capacity descriptor*/ + uint32_t block_len;/*byte 4 : reserved; + byte5-7: specifies the length in bytes of each logical block for the given + capacity descriptor */ +}formattable_cap_desc_t; + +typedef struct _mode_parameter_header +{ + uint16_t mode_data_len;/*for MODE SELECT command, the mode data length field + should always be set to zero. + for MODE SENSE command, the mode data length field + specifies the length in bytes of the following data + that is available to be transfered(not including + itself)*/ + uint8_t medium_type_code;/*specifies the inserted medium type. The value in + this field are vendor specific. + default value should be 0x00*/ + uint8_t wp_dpofua;/* bit7:wp:write protect(ignored for mode select command) + bit4:dpofua; rest of the bits are reserved */ + uint8_t reserved1[4]; +}mode_parameter_header_struct_t; + +typedef struct _msc_scsi_variable_struct +{ + /* disk space reserved . This Disk Space is reserved by the App.*/ + uint32_t total_logical_add_block; + uint32_t length_of_each_lab; + uint32_t implementing_disk_drive; + /* structure to store request sense data for every + command received by device */ + request_sense_data_struct_t request_sense; + /* flag to track if the msd device is formatted or not */ + msc_thirteen_case_struct_t thirteen_case; + usb_class_specific_callback_struct_t scsi_callback; + read_capacity_data_struct_t read_capacity; + read_capacity16_data_struct_t read_capacity16; + uint8_t format_capacity_response_data[sizeof(capacity_list_header_struct_t) + sizeof(curr_max_capacity_desc_struct_t) + sizeof(formattable_cap_desc_t) * 3]; + bool formatted_disk; + uint8_t is_used; +}msc_scsi_struct_t; + +#endif + +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/device_khci_interface.c b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/device_khci_interface.c new file mode 100644 index 0000000..6cadcfa --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/device_khci_interface.c @@ -0,0 +1,75 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2009, 2013 Freescale Semiconductor; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: khci_interface.c$ + * $Version : + * $Date : + * + * Comments: + * + * + *END************************************************************************/ +#include "usb_device_config.h" +#if USBCFG_DEV_KHCI +//#include "types.h" +#include "adapter.h" +#include "adapter_cfg.h" +#include "usb_types.h" //USB error definitions +#include "compiler.h" +#include "usb_desc.h" //USB descriptor macros +#include "usb_misc.h" +#include "adapter_types.h" +#include "khci_dev.h" +#include "usb_device_stack_interface.h" +#include "usb_dev.h" +#if defined(__cplusplus) +extern const usb_dev_interface_functions_struct_t _usb_khci_dev_function_table = +#else +const usb_dev_interface_functions_struct_t _usb_khci_dev_function_table = +#endif +{ + usb_dci_khci_preinit, + usb_dci_khci_init, + usb_dci_khci_postinit, + usb_dci_khci_send, + usb_dci_khci_recv, +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE + usb_dci_khci_cancel, +#endif + usb_dci_khci_init_endpoint, + usb_dci_khci_deinit_endpoint, + usb_dci_khci_unstall_endpoint, + usb_dci_khci_get_endpoint_status, + usb_dci_khci_set_endpoint_status, + NULL, + usb_dci_khci_set_addr, + usb_dci_khci_shutdown, + NULL, +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME + usb_dci_khci_assert_resume, +#endif + usb_dci_khci_stall_endpoint, + usb_dci_khci_set_status, + usb_dci_khci_get_status, + usb_dci_khci_get_xd, + usb_dci_khci_reset, +}; +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.c b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.c new file mode 100644 index 0000000..fccd87f --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.c @@ -0,0 +1,2339 @@ +/**HEADER********************************************************************** + * + * Copyright (c) 2009, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + ******************************************************************************* + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: khci_dev.c$ + * $Version : + * $Date : + * + * Comments: + * + * This file contains the main usbfs USB Device Controller interface + * functions. + * + *END************************************************************************/ + +/****************************************************************************** + * BUFFER DISCRIPTOR TABLE (BDT) DISCRIPTION * + ******************************************************************************/ +/** + * The USB-FS implements a Buffer Descriptor Table (BDT) in system memory. The + * BDT resides on a 512 byte boundary in system memory and is pointed to by the + * BDT Page Registers. Every endpoint direction requires two eight-byte Buffer + * Descriptor entries.Therefore, a system with 16 fully bidirectional endpoints + * would require 512 bytes of system memory to implement the BDT.The two Buffer + * Descriptor (BD) entries allows for an EVEN BD and ODD BD entry for each + * endpoint direction. This allows the microprocessor to process one BD while + * the USB-FS is processing the other BD. Double buffering BDs in this way + * allows the USB-FS to easily transfer data at the maximum throughput provided + * by USB. + * + * Because the buffers are shared between the microprocessor and the USB-FS a + * simple semaphore mechanism is used to distinguish who is allowed to update + * the BDT and buffers in system memory. A semaphore bit, the OWN bit, is + * cleared to 0 when the BD entry is owned by the microprocessor. The + * microprocessor is allowed read and write access to the BD entry and the + * buffer in system memory when the OWN bit is 0. + * When the OWN bit is set to 1, the BD entry and the buffer in system memory + * are owned by the USB-FS. The USB-FS now has full read and write access and + * the microprocessor should not modify the BD or its corresponding data buffer. + * The BD also contains indirect address pointers to where the actual buffer + * resides in system memory. + ****************************************************************************** + * BUFFER DISCRIPTOR FORMAT DISCRIPTION + ****************************************************************************** + * The Buffer Descriptors have different meaning based on who is reading the BD + * in memory.The USB-FS Controller uses the data stored in BDs to determine: + * + * # Who owns the buffer in system memory + * # Data0 or Data1 PID + * # Release Own upon packet completion + * # No address increment (FIFO Mode) + * # Data toggle synchronization enable + * # How much data is to be transmitted or received + * # Where the buffer resides in system memory + * + * While the microprocessor uses the data stored in the BDs to determine: + * # Who owns the buffer in system memory + * # Data0 or Data1 PID + * # The received TOKEN PID + * # How much data was transmitted or received + * # Where the buffer resides in system memory + * + * ------ ------ ------ ------ -------- ---------- ---------- ---------- ---------- ---------- ---------- + * |31-26 |25-16 | 15-8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * |RSVD | BC | RSVD | OWN |DATA0/1 |TOK_PID[3]|TOK_PID[2]|TOK_PID[1]|TOK_PID[0]|TOK_PID[n]| reserved | + * ------ ------ ------ ------ -------- ---------- ---------- ---------- ---------- ---------- ---------- + * | ADDRESS[31--0] | + * | | + * ------------------------------------------------------------------------------------------------------- + * + * This Buffer Descriptor table is represented by the variable "BDT_BASE" + * defined in file usbfs_dev_main.h. Macros such as "BD_ADDR_RX" and + * "BD_ADDR_TX" is used to manipulate the address field and Macros such as + * BD_CTRL_RX and BD_CTRL_TX is used to manipulate the control fields. + */ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_config.h" +#if USBCFG_DEV_KHCI +#include "usb.h" +#include "usb_device_stack_interface.h" +#include "khci_dev.h" +#include "khci_dev_misc.h" +#include "fsl_usb_khci_hal.h" +#ifdef USBCFG_OTG +#include "usb_otg_main.h" +#include "usb_otg_private.h" +#endif + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +static uint8_t *bdt; + +#if (FSL_FEATURE_USB_KHCI_USB_RAM == 0) +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)) +#if defined( __ICCARM__ ) + #pragma data_alignment=512 + __no_init uint8_t g_khci_bdt_buffer[512]; +#elif defined (__CC_ARM) || defined(__GNUC__) + __attribute__((aligned(512))) uint8_t g_khci_bdt_buffer[512]; +#else + #error Unsupported compiler, please use IAR, Keil or arm gcc compiler and rebuild the project. +#endif +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + uint8_t* g_khci_bdt_ptr = NULL; +#endif +#endif + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)) + static usb_device_khci_data_t g_khci_data; +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + usb_device_khci_data_t* g_khci_data_ptr = NULL; +#endif + +static bool g_zero_pkt_send = FALSE; + +static usb_khci_dev_state_struct_t g_khci_dev[USBCFG_DEV_KHCI_NUM]; + +#if USBCFG_KHCI_4BYTE_ALIGN_FIX +static uint8_t *_usb_khci_dev_swap_buf_ptr = NULL; +#endif + +extern usb_status _usb_device_call_service(uint8_t type, usb_event_struct_t* event); +extern uint32_t soc_get_usb_base_address(uint8_t controller_id); + +#ifdef USBCFG_OTG +extern usb_otg_handle * g_usb_otg_handle; +#endif +extern uint8_t soc_get_usb_vector_number(uint8_t controller_id); +#if USBCFG_DEV_DETACH_ENABLE +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_dci_khci_detach + * Returned Value : void + * Comments : + * this function is called if device known it's detached. + * + *END*-----------------------------------------------------------------*/ +void usb_dci_khci_detach(void) +{ + usb_event_struct_t event; + usb_khci_dev_state_struct_t* state_ptr; + state_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[0]); + + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = 0; + event.setup = 0; + event.direction = 0; + + /* propagate control to upper layers for processing */ + _usb_device_call_service(USB_SERVICE_DETACH, &event); +} +#endif + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_dci_khci_free_xd + * Returned Value : void + * Comments : + * Enqueues a XD onto the free XD ring. + * + *END*-----------------------------------------------------------------*/ +void usb_dci_khci_free_xd +( + usb_device_handle handle, + /* [IN] the dTD to enqueue */ + xd_struct_t* xd_ptr +) +{ /* Body */ + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* + ** This function can be called from any context, and it needs mutual + ** exclusion with itself. + */ + OS_Lock(); + + /* + ** Add the XD to the free XD queue (linked via PRIVATE) and + ** increment the tail to the next descriptor + */ + if (usb_dev_ptr->xd_head == NULL) + { + usb_dev_ptr->xd_head = xd_ptr; + } + else + { + usb_dev_ptr->xd_tail->next = xd_ptr; + } + usb_dev_ptr->xd_tail = xd_ptr; + xd_ptr->next = NULL; + usb_dev_ptr->xd_entries++; + + OS_Unlock(); +} /* Endbody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_dci_khci_get_xd + * Returned Value : void + * Comments : + * get an XD from the free XD ring. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_dci_khci_get_xd +( + usb_device_handle handle, + /* [IN] the dTD to enqueue */ + xd_struct_t** xd_ptr_ptr +) +{ /* Body */ + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* This function can be called from any context, and it needs mutual + exclusion with itself.*/ + OS_Lock(); + + /* Get a transfer descriptor for the specified endpoint + ** and direction + */ + if (!usb_dev_ptr->xd_entries) + { + OS_Unlock(); + return USBERR_DEVICE_BUSY; + } + + *xd_ptr_ptr = usb_dev_ptr->xd_head; + if (usb_dev_ptr->xd_head) + { + usb_dev_ptr->xd_head = usb_dev_ptr->xd_head->next; + if (usb_dev_ptr->xd_head == NULL) + { + usb_dev_ptr->xd_tail = NULL; + } + } + usb_dev_ptr->xd_entries--; + OS_Unlock(); + + return USB_OK; +} /* Endbody */ + +/**************************************************************************//*! + * + * @name : usb_dci_khci_init_xd + * @brief : initialize the xd. + * @param handle: Handle to USB Device to be filled + * @return USB_OK on successful. + ******************************************************************************/ +usb_status usb_dci_khci_init_xd +( + /* [IN] the USB device handle */ + usb_device_handle handle +) +{ + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + xd_struct_t* xd_ptr; + uint32_t j; + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)) + usb_dev_ptr->setup_buff = (uint8_t *)(&g_khci_data.setup_packet); + usb_dev_ptr->xd_head = usb_dev_ptr->xd_base = (xd_struct_t*)(&g_khci_data.xd_base); +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + usb_dev_ptr->setup_buff = (uint8_t *) g_khci_data_ptr->setup_packet; + usb_dev_ptr->xd_head = usb_dev_ptr->xd_base = (xd_struct_t*) g_khci_data_ptr->xd_base; +#endif +#if FSL_FEATURE_USB_KHCI_USB_RAM + usb_dev_ptr->setup_buff = (uint8_t *)(usb_hal_khci_get_usbram_add(usb_dev_ptr->usbRegBase) + 480); +#endif + usb_dev_ptr->xd_entries = USBCFG_DEV_MAX_XDS; + + /* Enqueue all the XDs */ + xd_ptr = (xd_struct_t*)usb_dev_ptr->xd_base; + + for (j = 0; j < USBCFG_DEV_MAX_XDS - 1; j++) + { + xd_ptr->next = xd_ptr + 1; + //usb_dci_khci_free_xd(usb_dev_ptr, xd_ptr); + xd_ptr++; + } + xd_ptr->next = 0; + usb_dev_ptr->xd_tail = xd_ptr; + + return USB_OK; +} + +/***************************************************************************** + * Local Functions + *****************************************************************************/ +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +/****************************************************************************** + * + * @name _usb_khci_next_setup_token_prep + * + * @brief The function prepares for next setup token + * + * @param state_ptr: Device info Structure. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_next_setup_token_prep +( + usb_khci_dev_state_struct_t* state_ptr +) +{ + xd_struct_t* xd_ptr_temp; + usb_dci_khci_get_xd(state_ptr, &xd_ptr_temp); + /* prepare XD queue for RECV CONTROL ENDPOINT*/ + if (state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd == 0x0) + { + //BD_ADDR_RX(USB_CONTROL_ENDPOINT, state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)state_ptr->setup_buff); + usb_hal_khci_bdt_set_address((uint32_t )bdt, USB_CONTROL_ENDPOINT, USB_RECV, 0, (uint32_t )state_ptr->setup_buff); + xd_ptr_temp->wstartaddress = state_ptr->setup_buff; + } + else + { + //BD_ADDR_RX(USB_CONTROL_ENDPOINT, state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)state_ptr->setup_buff+ SETUP_PACKET_LENGTH); + usb_hal_khci_bdt_set_address((uint32_t )bdt, USB_CONTROL_ENDPOINT, USB_RECV, 1, (uint32_t)(state_ptr->setup_buff+SETUP_PACKET_LENGTH)); + xd_ptr_temp->wstartaddress = state_ptr->setup_buff + SETUP_PACKET_LENGTH; + } + xd_ptr_temp->ep_num = USB_CONTROL_ENDPOINT; + xd_ptr_temp->bdirection = USB_RECV; + xd_ptr_temp->wtotallength = ZERO_LENGTH; + xd_ptr_temp->ep_type = USB_CONTROL_PIPE; +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + xd_ptr_temp->internal_dma_align = TRUE; +#endif + //USB_XD_QUEUE_ENQUEUE(&state_ptr->ep_info[USB_CONTROL_ENDPOINT].xd_queue_recv, xd_ptr_temp); + state_ptr->ep_info[USB_CONTROL_ENDPOINT].recv_xd = xd_ptr_temp; + /* toggle send buffer */ + //state_ptr->ep_info[USB_CONTROL_ENDPOINT].tx_buf_odd ^= 1; + /* configure data pid for setup token and give control to SEI*/ + state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_data0 = 0; + usb_hal_khci_bdt_set_control((uint32_t )bdt, USB_CONTROL_ENDPOINT, USB_RECV, state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)((uint32_t)USB_BD_BC(SETUP_PACKET_LENGTH)| (uint32_t)USB_BD_OWN | (uint32_t)USB_BD_DTS | (uint32_t)USB_BD_DATA01(state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_data0)))); + //BD_CTRL_RX(USB_CONTROL_ENDPOINT, state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd) = + //USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(SETUP_PACKET_LENGTH)| + // USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_data0))); + //USB_PRINTF("ready to receive on EP0 setup\n"); + /* setup token is always on DATA0 PID */ + return; +} + +/**************************************************************************//*! + * + * @name _usb_khci_ep_read + * + * @brief The function reads the endpoint buffers + * + * @param state_ptr: Device info Structure. + * @param ep_num: endpoint number + * @param buf_ptr: buffer to receive in + * @param buf_num_bytes: number of bytes to read + * + * @return USB_OK When Successfully + *****************************************************************************/ +static usb_status _usb_khci_ep_read +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr, + /*[IN]*/ + uint8_t ep_num, + /*[OUT]*/ + uint8_t * buf_ptr, + /*[IN]*/ + uint32_t buf_num_bytes +) +{ + OS_Lock(); + + /* USB data is directly transferred to App Buffer to Avoid one level of + * memcpy. (i.e from Endpoint buffer to App buffer). So a hack here + * is been provided. This hack stores the current endpoint buffer + * address to a variable and programs the buffer address in the BDT + * as APP buffer. Later when TOKEN_DNE interrupt is received for this Token + * this buffer address saved is restored. Please note that at present + * App should not release the buffer passed till he gets a notification from + * interrupt handler. + */ + + usb_hal_khci_bdt_set_address((uint32_t )bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd, (uint32_t )buf_ptr); + //BD_ADDR_RX(ep_num, state_ptr->ep_info[ep_num].rx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)buf_ptr); + + /* Program number of bytes to be received and give + * the Control to the SEI + */ + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd, + USB_LONG_LE_TO_HOST(USB_BD_BC(buf_num_bytes) | USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->ep_info[ep_num].rx_data0))); + //BD_CTRL_RX(ep_num, state_ptr->ep_info[ep_num].rx_buf_odd) = + // USB_LONG_LE_TO_HOST(USB_BD_BC(buf_num_bytes) | + // USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->ep_info[ep_num].rx_data0)); + + OS_Unlock(); + + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_khci_ep_write + * + * @brief The function writes the endpoint buffers + * + * @param state_ptr: Device info Structure. + * @param ep_num: endpoint number + * @param buf_ptr: buffer to send from + * @param buf_num_bytes: number of bytes to write + * @param bytes_written_ptr: buffer that will contain Number of bytes written + * to device. + * + * @return USB_OK When Successfully + *****************************************************************************/ +static usb_status _usb_khci_ep_write +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t * buf_ptr, + /*[IN]*/ + uint32_t buf_num_bytes, + /*[OUT]*/ + uint32_t* bytes_written_ptr +) +{ + uint16_t max_packet_size; + + /* If the number of bytes to be sent is greater than the + * maximum data that can be sent on the USB bus, then split the + * transaction, into multiple transaction. + */ + max_packet_size = state_ptr->ep_info[ep_num].max_packet_size; + + if (buf_num_bytes > max_packet_size) + { + buf_num_bytes = max_packet_size; + } + + *bytes_written_ptr = buf_num_bytes; + + /* Program the endpoint buffer address in BDT + * from where DMA will pick the Data to be sent over USB bus. + */ + //BD_ADDR_TX(ep_num, state_ptr->ep_info[ep_num].tx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)buf_ptr); + usb_hal_khci_bdt_set_address((uint32_t )bdt, ep_num, USB_SEND, state_ptr->ep_info[ep_num].tx_buf_odd, (uint32_t )buf_ptr); + /* Program the number of bytes to be sent in BDT and Give + * the ownership to SEI + */ + //BD_CTRL_TX(ep_num, state_ptr->ep_info[ep_num].tx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(buf_num_bytes) | + // USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->ep_info[ep_num].tx_data0))); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_SEND, state_ptr->ep_info[ep_num].tx_buf_odd, + USB_LONG_LE_TO_HOST(USB_BD_BC(buf_num_bytes) | USB_BD_OWN | USB_BD_DTS | USB_BD_DATA01(state_ptr->ep_info[ep_num].tx_data0))); + + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_khci_reset_ep_state + * + * @brief This Function Resets all the parameters required for End Point + * Initialization + * + * @param state_ptr: Device info Structure. + * @return USB_OK When Successfully + *****************************************************************************/ +static usb_status _usb_khci_reset_ep_state +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + //volatile USB_MemMapPtr usb_ptr; + uint32_t ep; + + uint8_t interrupt_enable; + + /* Clear all the error Status register */ + usb_hal_khci_clr_all_error_interrupts(state_ptr->usbRegBase); + + /*Reset all ODD and Even BDTs to Zero */ + usb_hal_khci_set_oddrst(state_ptr->usbRegBase); + + /* Initialize the address as zero in the Address register of USB IP*/ + usb_hal_khci_set_device_addr(state_ptr->usbRegBase, 0); + + for (ep = 0; ep < USBCFG_DEV_MAX_ENDPOINTS; ep++) + { + /* Clearing all buffer descriptors for both ODD and even + * for Both Receive and Transmit direction + */ + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_RECV, 0, 0); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_RECV, 1, 0); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_SEND, 0, 0); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_SEND, 1, 0); + //BD_CTRL_RX(ep, EVEN_BUFF) = 0; + //BD_CTRL_RX(ep, ODD_BUFF) = 0; + + //BD_CTRL_TX(ep, EVEN_BUFF) = 0; + //BD_CTRL_TX(ep, ODD_BUFF) = 0; + + state_ptr->ep_info[ep].rx_buf_odd = EVEN_BUFF; + state_ptr->ep_info[ep].tx_buf_odd = EVEN_BUFF; + //state_ptr->ep_info[ep].data_buffer = NULL; +#if 0 + if(ep == USB_CONTROL_ENDPOINT) + { + state_ptr->ep_info[ep].tx_buf_odd = ODD_BUFF; + } +#endif + /* Initialize All End Point Control Registers with default value of 0*/ + usb_hal_khci_endpoint_shut_down(state_ptr->usbRegBase, ep); + } + + g_zero_pkt_send = FALSE; + + /* Clear Reset Interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_USBRST); + + usb_hal_khci_clr_oddrst(state_ptr->usbRegBase); + + /* initializing device address to default address + * value for USB in Device structure. + */ + state_ptr->device_address = 0; + + /* Set Default state of USB in Device Structure.*/ + state_ptr->usb_state = USB_STATE_DEFAULT; + + /* Set Default device status */ + state_ptr->usb_device_status = + (USBCFG_DEV_SELF_POWER << (USB_GET_STATUS_ATTRIBUTES_SELF_POWERED_SHIFT)) | + (USBCFG_DEV_REMOTE_WAKEUP << (USB_GET_STATUS_ATTRIBUTES_REMOTE_WAKEUP_SHIFT)); + + /* Enable All Error Interrupts */ + usb_hal_khci_enable_all_error_interrupts(state_ptr->usbRegBase); + + interrupt_enable = INTR_USBRST | INTR_SOFTOK | INTR_TOKDNE | INTR_STALL; + + /* Enable All Interrupts except RESUME */ +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME + interrupt_enable |= INTR_SLEEP; +#endif + +#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING + interrupt_enable |= INTR_ERROR; +#endif + usb_hal_khci_enable_interrupts(state_ptr->usbRegBase, interrupt_enable); + /* SEI if, has suspended packet transmission resume packet transmission by + * clearing TXD_SUSPEND in CTL register. + */ + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + + return USB_OK; +} + +#if 0 +/**************************************************************************//*! + * + * @name _usb_khci_process_transmit_request + * + * @brief : Service TOKEN DONE Interrupt when there is transmission of packet. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * @param ep_num: endpoint number + * @param buffer_ptr:Holds Data that is send to Host. + * @return USB_STATUS_TRANSFER_PENDING when there is split transaction or + * USB_OK. + *****************************************************************************/ +static usb_status _usb_khci_process_transmit_request +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr, + /*[IN]*/ + uint8_t ep_num, + /*[OUT]*/ + uint8_t** buffer_ptr +) +{ + xd_struct_t* xd_ptr = state_ptr->ep_info[ep_num].send_xd; + + //USB_XD_QUEUE_GET_HEAD(&state_ptr->ep_info[ep_num].xd_queue_send,&xd_ptr); + + //*buffer_ptr = (uint8_t *) USB_LONG_LE_TO_HOST(BD_ADDR_TX(ep_num, + // state_ptr->ep_info[ep_num].tx_buf_odd)); + + //*buffer_ptr = (uint8_t *)USB_LONG_LE_TO_HOST(usb_hal_khci_bdt_get_address(usb_dev_ptr->usbRegBase, (uint32_t)bdt, ep_num, USB_SEND, state_ptr->ep_info[ep_num].tx_buf_odd)); + + usb_dci_khci_send(state_ptr, xd_ptr); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_khci_process_receive_request + * + * @brief : Service TOKEN DONE Interrupt when there is receive packet scenario. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function + * OS_install_isr during ISR installation. + * @param ep_num: endpoint number + * @param stat: status of last transaction. + * @param buffer_ptr:buffer holding data received from Host. + * + * @return USB_STATUS_TRANSFER_PENDING when there is split transaction else + * USB_OK + *****************************************************************************/ +static usb_status _usb_khci_process_receive_request +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t stat, + /*[OUT]*/ + uint8_t** buffer_ptr +) +{ + xd_struct_t* xd_ptr = state_ptr->ep_info[ep_num].recv_xd; + + //*buffer_ptr = (uint8_t *) USB_LONG_LE_TO_HOST(BD_ADDR_RX(ep_num, + // state_ptr->ep_info[ep_num].rx_buf_odd)); + //*buffer_ptr = (uint8_t *)USB_LONG_LE_TO_HOST(usb_hal_khci_bdt_get_address(usb_dev_ptr->usbRegBase, (uint32_t)bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd)); + + usb_dci_khci_recv(state_ptr, xd_ptr); + return USB_OK; +} +#endif + +#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING +/**************************************************************************//*! + * + * @name _usb_khci_service_err_intr + * + * @brief : Service Error Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_err_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + uint8_t device_error = 0, stat, ep_num; + //volatile USB_MemMapPtr usb_ptr; + usb_event_struct_t event; + + stat = usb_hal_khci_get_transfer_status(state_ptr->usbRegBase); + + /* Clear the Error Interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_ERROR); + + /* Get the Endpoint number on which the transaction occurred. + * This is (7 - 5) [3:0] bit in STAT register. + */ + ep_num = usb_hal_khci_get_transfer_done_ep_number(state_ptr->usbRegBase); + + /* Read the ERRSTAT register to determine the source of the error + * It is Added with ERREN register to find out which of the + * Error was enabled and report only the enabled error to the App layer + */ + device_error = (uint8_t)(usb_hal_khci_get_error_interrupt_status(state_ptr->usbRegBase) & + usb_hal_khci_get_error_interrupt_enable_status(state_ptr->usbRegBase)); + +#if _DEBUG + USB_PRINTF("USB Err: 0x%x\n", device_error); +#endif + + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = FALSE; + event.direction = (bool)(stat >> 3 & 1); + event.buffer_ptr = (uint8_t*)device_error; + event.len = ZERO_LENGTH; + + /* Invoke Service Call */ + (void)_usb_device_call_service(USB_SERVICE_ERROR,&event); + + /*clear all errors*/ + usb_hal_khci_clr_all_error_interrupts(state_ptr->usbRegBase); +} +#endif + +/**************************************************************************//*! + * + * @name _usb_khci_service_reset_intr + * + * @brief : Service reset Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_reset_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + uint8_t ep_num; + //volatile USB_MemMapPtr usb_ptr; + usb_event_struct_t event; + + state_ptr->is_reseting = 1; + /* Clear Reset Interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_USBRST); + + /* Get the Endpoint number on which the transaction occurred. + * This is (7 - 5) [3:0] bit in STAT register. + */ + ep_num = usb_hal_khci_get_transfer_done_ep_number(state_ptr->usbRegBase); + + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = FALSE; + event.direction = USB_RECV; + event.buffer_ptr = (uint8_t*)NULL; + event.len = ZERO_LENGTH; + /* Inform Upper Layer of Reset Signal. + * Remember Upper layer i.e class driver invokes + * usb_dci_khci_init_endpoint() as part of reset callback + */ + (void)_usb_device_call_service(USB_SERVICE_BUS_RESET, &event); +} + +/**************************************************************************//*! + * + * @name _usb_khci_service_tk_dne_intr + * + * @brief : Service Error Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. It is the same + * structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_tk_dne_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + uint8_t ep_num, stat, dir, buf_odd, setup, token_pid; + uint32_t len = 0; + //usb_status error; + uint32_t buf_num_bytes; + //volatile USB_MemMapPtr usb_ptr; + xd_struct_t* xd_ptr; +// uint8_t * buffer_ptr = NULL; + uint32_t control = 0; +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + uint8_t *src, *dst = NULL; +#endif + usb_event_struct_t event; + + /* Get the status of previous transaction*/ + stat = usb_hal_khci_get_transfer_status(state_ptr->usbRegBase); + + /* Get the Endpoint number on which the transaction occurred. + * This is (7 - 5) [3:0] bit in STAT register. + */ + ep_num = usb_hal_khci_get_transfer_done_ep_number(state_ptr->usbRegBase); + + /* Get the Direction of transaction. (i.e the transaction was a receive + * operation or transaction was a Transmit operation).It is Bit [3] in STAT + * register. + */ + dir = usb_hal_khci_get_transfer_done_direction(state_ptr->usbRegBase); + + /* Get the last buffer transaction was in ODD buffer or Even Buffer*/ + buf_odd = usb_hal_khci_get_transfer_done_odd(state_ptr->usbRegBase); + + /* Clear TOKEN Done Interrupt. This clearing of TOKEN_DONE + * should happen after STAT register is read. This is because + * STAT register has four byte fifo and if TOKEN_DONE is cleared + * in INT_STAT then the content of STAT register is updated with + * the next value in the STAT fifo. + */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_TOKDNE); + + control = usb_hal_khci_bdt_get_control((uint32_t )bdt, ep_num, dir, buf_odd); + + /* Get length of Data transmitted or received in the last transaction. */ + len = (USB_HOST_TO_LE_LONG(control) >> 16) & 0x3ff; + + /* Get PID for this token */ + token_pid = (uint8_t)((USB_HOST_TO_LE_LONG(control) >> 2) & 0x0000000f); + + /* if token PID is a setup token */ + setup = (token_pid == USB_SETUP_TOKEN) ? TRUE : FALSE; + + //USB_PRINTF("23tk_dne ep %d dir %d len %d buff_odd %d\n", ep_num, dir, len, buf_odd); + if (dir) + { + /* direction is USB_SEND*/ + /* Get head of the send queue */ + //USB_XD_QUEUE_GET_HEAD(&state_ptr->ep_info[ep_num].xd_queue_send,&xd_ptr); + //USB_PRINTF("get send xd_ptr 0x%x\n", xd_ptr); + /* updating the WSOFAR field */ + xd_ptr = state_ptr->ep_info[ep_num].send_xd; + if (xd_ptr == NULL) + { + return; + } + xd_ptr->wsofar += len; + + buf_num_bytes = (uint32_t)(xd_ptr->wtotallength - xd_ptr->wsofar); + + /* dequeue if all bytes have been send or the last send transaction was + of length less then the max packet size length configured for + corresponding endpoint */ + state_ptr->ep_info[ep_num].tx_buf_odd ^= 1; + state_ptr->ep_info[ep_num].tx_data0 ^= 1; + if ((buf_num_bytes == 0) || (state_ptr->ep_info[ep_num].max_packet_size > len)) + { + event.len = xd_ptr->wsofar; + /* buffer address is updated for upper layer */ + event.buffer_ptr = xd_ptr->wstartaddress; + state_ptr->ep_info[ep_num].send_xd = NULL; + usb_dci_khci_free_xd(state_ptr, xd_ptr); + if ((len == state_ptr->ep_info[ep_num].max_packet_size) && + (ep_num == USB_CONTROL_ENDPOINT)) + { + g_zero_pkt_send = TRUE; + usb_device_send_data((usb_device_handle)state_ptr->upper_layer_handle, ep_num, NULL, 0); + return; + } + } + else + { + usb_dci_khci_send(state_ptr, xd_ptr); + //_usb_khci_process_transmit_request(state_ptr, ep_num, &buffer_ptr); + return;/*if above call returned USB_STATUS_TRANSFER_PENDING */ + } + } + else + { + + if ((ep_num == USB_CONTROL_ENDPOINT) && (!len)) + { + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = setup; + event.direction = (bool)(stat >> 3 & 1U); + + /* propagate control to upper layers for processing */ + _usb_device_call_service(ep_num, &event); + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + return; + } + /* direction is USB_RECV*/ + if (g_zero_pkt_send == TRUE) + { + g_zero_pkt_send = FALSE; + } + //USB_PRINTF("before ep %d : xd_head_ptr 0x%x xd_tail_ptr 0x%x\n", ep_num, + // state_ptr->EP_INFO[ep_num].xd_queue_recv.xd_head_ptr, + // state_ptr->EP_INFO[ep_num].xd_queue_recv.xd_tail_ptr); + /* Get head of the send queue */ + //USB_XD_QUEUE_GET_HEAD(&state_ptr->ep_info[ep_num].xd_queue_recv, &xd_ptr); + xd_ptr = state_ptr->ep_info[ep_num].recv_xd; + if (xd_ptr == NULL) + { + return; + } +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + if (!xd_ptr->internal_dma_align) + { + //src = (uint8_t *)USB_LONG_LE_TO_HOST(BD_ADDR_RX(ep_num, state_ptr->ep_info[ep_num].rx_buf_odd)); + src = (uint8_t*)USB_LONG_LE_TO_HOST(usb_hal_khci_bdt_get_address( (uint32_t)bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd)); + dst = xd_ptr->wstartaddress + xd_ptr->wsofar; + if (src != dst) + { + OS_Mem_copy(src, dst, len); + } + } +#endif + xd_ptr->wsofar += len;/* updating the WSOFAR field */ + + buf_num_bytes = (uint32_t)(xd_ptr->wtotallength - xd_ptr->wsofar); + + if ((ep_num == USB_CONTROL_ENDPOINT) && (token_pid == USB_SETUP_TOKEN)) + { + /* cancel any pending transfers in SEND QUEUE if present*/ + usb_dci_khci_cancel((usb_device_handle)state_ptr, ep_num, USB_SEND); + /* for first In/OUT after setup token DATA PID has to be always one */ + state_ptr->ep_info[ep_num].tx_data0 = 1; + state_ptr->ep_info[ep_num].rx_data0 = 1; + state_ptr->ep_info[ep_num].rx_buf_odd ^= 1; + //state_ptr->ep_info[ep_num].tx_buf_odd ^= 1; + } + else + { + /* set DATA PID and buffer for next recv transaction */ + state_ptr->ep_info[ep_num].rx_data0 ^= 1; + state_ptr->ep_info[ep_num].rx_buf_odd ^= 1; + } + + //USB_PRINTF("max packet size %d\n",state_ptr->EP_INFO[ep_num].max_packet_size); + /* dequeue if all bytes have been received or the last send transaction + was of length less then the max packet size length configured for + corresponding endpoint */ + if ((!xd_ptr->wtotallength) || (buf_num_bytes == 0) || + (state_ptr->ep_info[ep_num].max_packet_size > len)) + { + event.len = xd_ptr->wsofar; + /* buffer address is updated for upper layer */ + event.buffer_ptr = xd_ptr->wstartaddress; + state_ptr->ep_info[ep_num].recv_xd = NULL; + usb_dci_khci_free_xd(state_ptr, xd_ptr); + } + else + { + usb_dci_khci_recv(state_ptr, xd_ptr); + //_usb_khci_process_receive_request(state_ptr,ep_num, stat, &buffer_ptr); + return;/*if above call returned USB_STATUS_TRANSFER_PENDING */ + } + } + + /* prepare for next setup token if needed*/ + if ((ep_num == USB_CONTROL_ENDPOINT) && (!len) && (g_zero_pkt_send == FALSE)) + { + _usb_khci_next_setup_token_prep(state_ptr); + } + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = setup; + event.direction = (bool)(stat >> 3 & 1U); + + /* propagate control to upper layers for processing */ + _usb_device_call_service(ep_num, &event); + + //USB_PRINTF("_usb_khci_service_tk_dne_intr 3-- :%d \n",ep_num); + + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + +} + +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME +/**************************************************************************//*! + * + * @name _usb_khci_service_sleep_intr + * + * @brief : Service Sleep Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_sleep_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + //volatile USB_MemMapPtr usb_ptr; + usb_event_struct_t event; + + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_RESUME); + + /* clear suspend interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_SLEEP); + + state_ptr->usb_dev_state_b4_suspend = state_ptr->usb_state; + + state_ptr->usb_state = USB_STATE_SUSPEND; + + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = (uint8_t)USB_UNINITIALIZED_VAL_32; + event.setup = 0; + event.direction = 0; + event.buffer_ptr = (uint8_t*)NULL; + event.len = ZERO_LENGTH; + + /* Notify Device Layer of SLEEP Event */ + /* this callback need only handle and type - + all other arguments are redundant */ + (void)_usb_device_call_service(USB_SERVICE_SUSPEND, &event); + + /* Enable RESUME Interrupt */ + usb_hal_khci_enable_interrupts(state_ptr->usbRegBase, (INTR_RESUME)); +} + +/************************************************************************//*! + * + * @name _usb_khci_service_resume_intr + * + * @brief : Service resume Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_resume_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + usb_event_struct_t event; + + /* clear resume interrupt status bit */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_RESUME); + + state_ptr->usb_state = state_ptr->usb_dev_state_b4_suspend; + + /* Initialize the event structure to be passed to the upper layer*/ + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = (uint8_t)USB_UNINITIALIZED_VAL_32; + event.setup = 0; + event.direction = 0; + event.buffer_ptr = (uint8_t*)NULL; + event.len = ZERO_LENGTH; + + /* Notify Device Layer of RESUME Event */ + /* this callback need only handle and type - + all other arguments are redundant */ + (void)_usb_device_call_service(USB_SERVICE_RESUME,&event); + + /* Disable RESUME Interrupt */ + usb_hal_khci_disable_interrupts(state_ptr->usbRegBase, INTR_RESUME); +} +#endif +/***********************************************************************//*! + * + * @name _usb_khci_service_sof_token_intr + * + * @brief : Service SOF Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_sof_token_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + /* Clear SOF Interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_SOFTOK); + + state_ptr->usb_sof_count = usb_hal_khci_get_frame_number(state_ptr->usbRegBase); + + /* address of Lower byte of Frame number. + */ + //buffer_ptr = (uint8_t *)&(state_ptr->USB_SOF_COUNT); + /* clear resume interrupt status bit */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_RESUME); +} + +#if 0 +/**************************************************************************//*! + * + * @name _usb_khci_service_attach_intr + * + * @brief : Service attach Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_attach_intr +( +/*[IN]*/ +usb_khci_dev_state_struct_t* state_ptr +) +{ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_ATTACH); +} +#endif + +/************************************************************************//*! + * + * @name _usb_khci_service_stall_intr + * + * @brief : Service stall Interrupt. + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +static void _usb_khci_service_stall_intr +( + /*[IN]*/ + usb_khci_dev_state_struct_t* state_ptr +) +{ + + uint8_t ep; + + for (ep = 0; ep < USBCFG_DEV_MAX_ENDPOINTS; ep++) + { + if (state_ptr->ep_info[ep].endpoint_status == USB_STATUS_STALLED) + { + usb_hal_khci_endpoint_clr_stall(state_ptr->usbRegBase, ep); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_SEND, state_ptr->ep_info[ep].tx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep].max_packet_size)| USB_BD_DTS | USB_BD_DATA01(0)))); + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep, USB_RECV, state_ptr->ep_info[ep].rx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep].max_packet_size)| USB_BD_DTS | USB_BD_DATA01(0)))); + } + } + + /* Clear Stall Interrupt */ + usb_hal_khci_clr_interrupt(state_ptr->usbRegBase, INTR_STALL); + + /* check if the stall interrupt received was for CONTROL ENDPOINT */ + if (state_ptr->ep_info[USB_CONTROL_ENDPOINT].endpoint_status == USB_STATUS_STALLED) + { + state_ptr->ep_info[USB_CONTROL_ENDPOINT].endpoint_status = USB_STATUS_IDLE; + _usb_khci_next_setup_token_prep(state_ptr); + } + +} + +/**************************************************************************//*! + * + * @name _usb_khci_isr + * + * @brief : Service all the interrupts in the kirin usb hardware + * + * @param state_ptr: Device Structure Pointer Passed to ISR. The is the + * same structure which was passed in function OS_install_isr + * During ISR installation. + * + * @return NONE + *****************************************************************************/ +#ifdef USBCFG_OTG +void _usb_dev_khci_isr +( + usb_khci_dev_state_struct_t* state_ptr +) +{ + state_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[0]); +#else +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +static void _usb_khci_isr(void) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[0]); +#else +static void _usb_khci_isr(usb_khci_dev_state_struct_t* state_ptr) +{ + state_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[0]); +#endif +#endif + /* Get the USB IP base address in the controller */ + //error = (uint8_t)usb_hal_get_interrupt_status(state_ptr->usbRegBase); +#if FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED && USBCFG_DEV_KEEP_ALIVE_MODE +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) + if(usb_hal_khci_get_keepalive_wake_int_sts(state_ptr->usbRegBase)) + { + usb_hal_khci_clr_keepalive_wake_int_sts(state_ptr->usbRegBase); + } +#endif +#endif + /* This interrupt comes when any of the error conditions within + * the ERRSTAT register occur. The ColdFire core must + * then read the ERRSTAT register to determine the source of the error. + */ +#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_ERROR)) + { + _usb_khci_service_err_intr(state_ptr); + } +#endif + /* This TOKEN_DONE interrupt comes when the current token being processed + * has completed. The ColdFire core should immediately read the STAT register + * to determine the EndPoint and BD used for this token. Clearing this bit + * (by writing a one) causes the STAT register to be cleared or the + * STAT holding register to be loaded into the STAT register. + */ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_TOKDNE)) + { + // USB_PRINTF("done ++"); + _usb_khci_service_tk_dne_intr(state_ptr); + } + /* This reset interrupt comes when the USB Module has decoded a valid USB reset. + * This informs the Microprocessor that it should write 0x00 into the address + * register and enable endpoint 0. USB_RST bit is set after a USB reset has been + * detected for 2.5 microseconds. It is not asserted again until the USB reset + * condition has been removed and then re-asserted. + */ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_USBRST)) + { + _usb_khci_service_reset_intr(state_ptr); + } +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME + /* This sleep interrupt comes when the USB Module detects a constant idle + * on the USB bus for 3 milliseconds. + */ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_SLEEP)) + { + _usb_khci_service_sleep_intr(state_ptr); + } + + /* This interrupt comes depending upon the DP/DM signals, and can be used + * to signal remote wake-up signaling on the USB bus. When not in suspend + * mode this interrupt should be disabled + */ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_RESUME)) + { + _usb_khci_service_resume_intr(state_ptr); + } +#endif + /* This interrupt comes when the USB Module receives a Start Of Frame + * (SOF) token. + */ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_SOFTOK)) + { + _usb_khci_service_sof_token_intr(state_ptr); + } + +#if 0 + /* This interrupt comes when the USB Module detects an attach of a + * USB device. This signal is only valid if HOST_MODE_EN is true. + * This interrupt signifies that a peripheral is now present and must + * be configured. + */ + if(usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_ATTACH)) + { + _usb_khci_service_attach_intr(state_ptr); + } +#endif + /* In Target mode this interrupt comes when a STALL handshake is sent + by the SIE.*/ + if (usb_hal_khci_is_interrupt_issued(state_ptr->usbRegBase, INTR_STALL)) + { + _usb_khci_service_stall_intr(state_ptr); + } + + return; +} +/***************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name : usb_dci_khci_preinit + * @brief : Allocates space for the USB device controller. + * @param handle: Handle to USB Device to be filled + * @return USB_OK on successful. + ******************************************************************************/ +usb_status usb_dci_khci_preinit +( + /* [IN] the USB device handle */ + usb_device_handle upper_layer_handle, + + usb_device_handle * handle_ptr + ) +{ + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[0]); + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if (NULL == g_khci_data_ptr) + { + g_khci_data_ptr = OS_Mem_alloc_uncached(sizeof(usb_device_khci_data_t)); + } + +#if (FSL_FEATURE_USB_KHCI_USB_RAM == 0) + if (NULL == g_khci_bdt_ptr) + { + g_khci_bdt_ptr = OS_Mem_alloc_uncached_align(512, 512); + } +#endif + +#endif + + usb_dci_khci_init_xd((usb_device_handle)usb_dev_ptr); + +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) + _usb_khci_dev_swap_buf_ptr = g_khci_data.swap_buf; +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + _usb_khci_dev_swap_buf_ptr = g_khci_data_ptr->swap_buf; +#endif + +#endif + usb_dev_ptr->mutex = OS_Mutex_create(); + *handle_ptr = (usb_device_handle)usb_dev_ptr; + usb_dev_ptr->upper_layer_handle = upper_layer_handle; + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name : usb_dci_khci_init + * @brief : Initializes the USB device controller. + * @param handle: USB device handle. + * @param init_param: initialization parameters specific for device + * @return USB_OK on successful. + ******************************************************************************/ +usb_status usb_dci_khci_init +( + uint8_t controller_id, + /* [IN] the USB device handle */ + + usb_device_handle handle + ) +{ +#ifdef USBCFG_OTG + usb_otg_state_struct_t * usb_otg_struct_ptr = (usb_otg_state_struct_t *)g_usb_otg_handle; + usb_otg_status_t * otg_status_ptr = &usb_otg_struct_ptr->otg_status; +#endif + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + //volatile USB_MemMapPtr usb_ptr; + + usb_dev_ptr->dev_vec = soc_get_usb_vector_number(controller_id); + + usb_dev_ptr->is_reseting = 0; + + usb_dev_ptr->usbRegBase = soc_get_usb_base_address(controller_id); + /* Get the maximum number of endpoints supported by this USB controller */ + usb_dev_ptr->max_endpoints = KHCI_MAX_ENDPOINT; + usb_dev_ptr->speed = USB_SPEED_FULL; + + /* Clear all interrupts and bring it to finite + * state before device starts functioning. + */ + usb_hal_khci_clr_all_interrupts(usb_dev_ptr->usbRegBase); + usb_hal_khci_disable_dp_pull_up(usb_dev_ptr->usbRegBase); + +#ifndef USBCFG_OTG + /* Install the ISR + * Device Pointer is passed as an Argument when the + * ISR is invoked. + */ +#if (OS_ADAPTER_ACTIVE_OS != OS_ADAPTER_SDK) + if (!(OS_install_isr(usb_dev_ptr->dev_vec, (void (*)(void *))_usb_khci_isr, usb_dev_ptr))) + return USBERR_INSTALL_ISR; +#else + OS_install_isr(usb_dev_ptr->dev_vec, (void (*)(void) )_usb_khci_isr, usb_dev_ptr); +#endif +#endif + +#if FSL_FEATURE_USB_KHCI_USB_RAM + bdt = (uint8_t *)usb_hal_khci_get_usbram_add(usb_dev_ptr->usbRegBase); +#else + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)) + bdt = g_khci_bdt_buffer; +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + bdt = g_khci_bdt_ptr; +#endif + +#endif + + /* Initialize BDT Page register 1,2,3. The Buffer + * Descriptor Table Page Register 1 2,3 contains an + * 8-bit value used to compute the address where + * the current Buffer Descriptor Table (BDT) + * resides in system memory. + */ + usb_hal_khci_set_buffer_descriptor_table_addr(usb_dev_ptr->usbRegBase, (uint32_t)bdt); + + /* Initialize the end point state*/ + _usb_khci_reset_ep_state(usb_dev_ptr); + + //USB_PRINTF("11usb_dci_khci_init ++"); + /* Enable Sleep,Token Done,Error,USB Reset,Stall, + * Resume and SOF Interrupt. + */ + //usb_hal_khci_enable_interrupts(usb_dev_ptr->usbRegBase,(INTR_USBRST | INTR_ERROR | INTR_SOFTOK | INTR_TOKDNE | INTR_SLEEP | INTR_STALL)); +#ifdef USBCFG_OTG + usb_dev_ptr->otg_handle = g_usb_otg_handle; + otg_status_ptr->active_stack = USB_ACTIVE_STACK_DEVICE; + /* set otg status to 0 */ + usb_dci_khci_set_status(handle, USB_STATUS_OTG, 0); + /**/ +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name : usb_dci_khci_init + * @brief : Initializes the USB device controller. + * @param handle: USB device handle. + * @param init_param: initialization parameters specific for device + * @return USB_OK on successful. + ******************************************************************************/ +usb_status usb_dci_khci_postinit +( + uint8_t controller_id, + /* [IN] the USB device handle */ + + usb_device_handle handle + ) +{ + /* Enable D+ pull up register + * Note, that this D+ external resistor is not applicable for some devices + */ + usb_khci_dev_state_struct_t* usb_dev_ptr = (usb_khci_dev_state_struct_t*)(&g_khci_dev[controller_id - USB_CONTROLLER_KHCI_0]); + //usb_khci_dev_state_struct_t* state_ptr = *usb_dev_ptr; + + usb_hal_khci_enable_dp_pull_up(usb_dev_ptr->usbRegBase); + /* Enable USB module*/ + usb_hal_khci_enable_sof(usb_dev_ptr->usbRegBase); + + /* Remove suspend state */ + usb_hal_khci_clr_suspend(usb_dev_ptr->usbRegBase); + return USB_OK; +} + +/**************************************************************************//*! + * @name : usb_dci_khci_init_endpoint + * + * @brief : Initialize the Endpoint + * @param handle: Handle to USB Device. + * @param xd_ptr: Transaction Descriptor. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_init_endpoint +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + xd_struct_t* xd_ptr + ) +{ + //usb_status error = USB_OK; + uint16_t max_pkt_size = 0; + + /* Get the device pointer initialized in usb_dci_khci_init*/ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + //volatile USB_MemMapPtr usb_ptr; +#if 0 + if (state_ptr == NULL) + { + return USBERR_ERROR; + } + + if((xd_ptr->ep_type > USB_INTERRUPT_PIPE) || + (xd_ptr->bdirection > USB_SEND)) + { + return USBERR_EP_INIT_FAILED; + } +#endif + //USB_PRINTF("init ep %d dir %d\n", xd_ptr->EP_NUM, xd_ptr->BDIRECTION); + + /* mark this endpoint as initialized */ + state_ptr->ep_info[xd_ptr->ep_num].ep_init_flag[xd_ptr->bdirection] = TRUE; + + /*before initializing cancel all transfers on EP as there may be calls + for endpoint initialization more than once. This will free any allocated + queue*/ + + /* + * Since this is endpoint initialization section there will + * not be any pending transfers on this endpoint + */ + + /* The end point buffer size will be set as required by app. + * but if the size crosses MAX_EP_BUFFER_SIZE size then truncate the + * max packet size. + */ + if (xd_ptr->ep_type == USB_ISOCHRONOUS_PIPE) + { + max_pkt_size = (uint16_t)((xd_ptr->wmaxpacketsize > MAX_FS_ISO_EP_BUFFER_SIZE)? + MAX_FS_ISO_EP_BUFFER_SIZE:xd_ptr->wmaxpacketsize); + } + else + { + max_pkt_size = (uint16_t)((xd_ptr->wmaxpacketsize > MAX_FS_NON_ISO_EP_BUFFER_SIZE)? + MAX_FS_NON_ISO_EP_BUFFER_SIZE:xd_ptr->wmaxpacketsize); + } + + /* Initialize the End Point Information Structure which is part of device + * structure. It is done so that it can be used at later point of time + * like ISR handler, any other function call. + */ + state_ptr->ep_info[xd_ptr->ep_num].type = xd_ptr->ep_type; + state_ptr->ep_info[xd_ptr->ep_num].direction = xd_ptr->bdirection; + state_ptr->ep_info[xd_ptr->ep_num].max_packet_size = max_pkt_size; + state_ptr->ep_info[xd_ptr->ep_num].endpoint_status = USB_STATUS_IDLE; + state_ptr->ep_info[xd_ptr->ep_num].stall_flag = FALSE; + if (USB_RECV == xd_ptr->bdirection) + { + state_ptr->ep_info[xd_ptr->ep_num].rx_data0 = 0; + state_ptr->ep_info[xd_ptr->ep_num].recv_xd = NULL; + } + else + { + state_ptr->ep_info[xd_ptr->ep_num].tx_data0 = 0; + state_ptr->ep_info[xd_ptr->ep_num].send_xd = NULL; + } + + usb_hal_khci_endpoint_enable_handshake(state_ptr->usbRegBase, xd_ptr->ep_num, ((xd_ptr->ep_type != USB_ISOCHRONOUS_PIPE) ? 1 : 0)); + usb_hal_khci_endpoint_set_direction(state_ptr->usbRegBase, xd_ptr->ep_num, (xd_ptr->bdirection ? 1 : 0)); + if ((USB_RECV == xd_ptr->bdirection) && (xd_ptr->ep_num == USB_CONTROL_ENDPOINT)) + { + _usb_khci_next_setup_token_prep(state_ptr); + } +#if 0 + /* Write the initialized control values to end point control register*/ + //usb_hal_set_endpoint_ephshk(state_ptr->usbRegBase, xd_ptr->ep_num, (xd_ptr->ep_type != USB_ISOCHRONOUS_PIPE ? 1 : 0)); + /*Configure this endpoint for receive or Send direction as required by APP*/ + //usb_hal_set_endpoint_direction(state_ptr->usbRegBase, xd_ptr->ep_num, (xd_ptr->bdirection ? 1: 0)); + /* Set the BDT and buffer data pointer for Receive Direction*/ + if ((USB_RECV == xd_ptr->bdirection) && (xd_ptr->ep_num == USB_CONTROL_ENDPOINT) ) + { + const uint8_t control[2] = + { + USB_BD_DATA01(0) | USB_BD_DTS | USB_BD_OWN, + USB_BD_DATA01(1) | USB_BD_DTS + }; + + /* configure first start address for recv transaction */ + usb_dci_khci_get_xd (state_ptr, &xd_temp_ptr); + xd_temp_ptr->ep_num = xd_ptr->ep_num; + xd_temp_ptr->bdirection = xd_ptr->bdirection; + xd_temp_ptr->wtotallength =xd_ptr->wtotallength; +#if USBCFG_4BYTE_ALIGN_FIX + xd_temp_ptr->internal_dma_align = TRUE; +#endif + xd_temp_ptr->wsofar = xd_ptr->wsofar; + xd_temp_ptr->ep_type = xd_ptr->ep_type; + xd_temp_ptr->dont_zero_terminate = xd_ptr->dont_zero_terminate; + xd_temp_ptr->wstartaddress = (uint8_t *)USB_LONG_LE_TO_HOST((uint32_t)state_ptr->setup_buff); + USB_XD_QUEUE_ENQUEUE(&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_recv, xd_temp_ptr); + + /*Configure Even buff for the end point*/ + BD_ADDR_RX(xd_ptr->ep_num, state_ptr->ep_info[xd_ptr->ep_num].rx_buf_odd) = + USB_LONG_LE_TO_HOST((uint32_t)state_ptr->setup_buff); + + BD_CTRL_RX(xd_ptr->ep_num, state_ptr->ep_info[xd_ptr->ep_num].rx_buf_odd) = + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(SETUP_PACKET_LENGTH) | control[0])); + + /*Configure Even buff for odd end point*/ + BD_ADDR_RX(xd_ptr->ep_num, state_ptr->ep_info[xd_ptr->ep_num].rx_buf_odd ^ 1) = + USB_LONG_LE_TO_HOST((uint32_t) + (state_ptr->setup_buff + SETUP_PACKET_LENGTH)); + BD_CTRL_RX(xd_ptr->ep_num, state_ptr->ep_info[xd_ptr->ep_num].rx_buf_odd ^ 1) = + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(SETUP_PACKET_LENGTH) | control[1])); + } + else /* Set the BDT and buffer data pointer for Send direction */ + { + /* Initialize the DATA PID to DATA0*/ + //state_ptr->EP_INFO[xd_ptr->EP_NUM].tx_data0 = 0; + } +#endif + return USB_OK; +} + +/**************************************************************************//*! + * @name : usb_dci_khci_deinit_endpoint + * + * @brief : De-Initialize the Endpoint + * @param handle: Handle to USB Device. + * @param ep_num: End Point Number. + * @param direction: USB_SEND or USB_RECV. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_deinit_endpoint +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t direction +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + //volatile USB_MemMapPtr usb_ptr; + + /*before de-initializing cancel all transfers on EP */ + usb_dci_khci_cancel(handle, ep_num, direction); + + /*Disable the transmit or receive endpoint*/ + usb_hal_khci_endpoint_shut_down(state_ptr->usbRegBase, ep_num); + + /* un-initialize the structure for this endpoint */ + usb_hal_khci_bdt_set_address((uint32_t )bdt, ep_num, direction, EVEN_BUFF, USB_LONG_LE_TO_HOST_CONST((uint32_t)USB_UNINITIALIZED_VAL_32)); + usb_hal_khci_bdt_set_address((uint32_t )bdt, ep_num, direction, ODD_BUFF, USB_LONG_LE_TO_HOST_CONST((uint32_t)USB_UNINITIALIZED_VAL_32)); + //BD_ADDR(ep_num,direction,EVEN_BUFF) = + // USB_LONG_LE_TO_HOST_CONST((uint32_t)USB_UNINITIALIZED_VAL_32); + //BD_ADDR(ep_num,direction,ODD_BUFF) = + // USB_LONG_LE_TO_HOST_CONST((uint32_t)USB_UNINITIALIZED_VAL_32); + + state_ptr->ep_info[ep_num].max_packet_size = + (uint16_t)USB_UNINITIALIZED_VAL_32; + + /* mark this endpoint as de-initialized */ + state_ptr->ep_info[ep_num].ep_init_flag[direction] = FALSE; + + return USB_OK; +} + +/**************************************************************************//*! + * @name usb_dci_khci_send + * @brief : Sends data. Non-blocking. + * @param handle: Handle to USB Device. + * @param xd_ptr: Transaction Descriptor. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_send +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + xd_struct_t* xd_ptr + ) +{ + usb_status error = USBERR_TX_FAILED;/* initializing to failed value */ + uint32_t buf_num_bytes = (uint32_t)(xd_ptr->wtotallength - xd_ptr->wsofar); + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* Allocate XD structure from Free List maintained by Device structure, + * if it is not any split transaction. + */ + if (xd_ptr->wsofar == 0) + { + state_ptr->ep_info[xd_ptr->ep_num].send_xd = xd_ptr; + //USB_XD_QUEUE_ENQUEUE(&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_send, xd_ptr); + //USB_PRINTF("after send ep %d enqueue: xd_head_ptr 0x%x xd_tail_ptr 0x%x\n", xd_ptr->EP_NUM, + // state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_send.xd_head_ptr, + // state_ptr->EP_INFO[xd_ptr->EP_NUM].xd_queue_send.xd_tail_ptr); + + } + +#if 0 + /* Upper layer wants to send Zero Packet data + * Note that this situation will only come when + * Upper layer wants to send Zero packet data not + * in case of split transaction + */ + if (buf_num_bytes == 0) + { + error = _usb_khci_ep_write(state_ptr, xd_ptr->ep_num, + xd_ptr->wstartaddress, buf_num_bytes, (uint32_t*)&buf_num_bytes); + + if (error != USB_OK) + { + /* If write returns error release the XD pointer + * from Endpoint send queue and return it to Free list of XD pointers. + */ + xd_ptr->bstatus = USB_STATUS_IDLE; + //USB_XD_QUEUE_DEQUEUE (&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_send, &xd_ptr); + //if (xd_ptr != NULL) + // _usb_khci_free_XD(state_ptr, xd_ptr); + } + return error; + } +#endif + if (state_ptr->is_reseting == 0) + { + /* If not Zero Size packet send the data from here*/ + error = _usb_khci_ep_write(state_ptr, xd_ptr->ep_num, + (uint8_t *)xd_ptr->wstartaddress + xd_ptr->wsofar, buf_num_bytes, + (uint32_t*)&buf_num_bytes); + } + + if (error != USB_OK) + { + /* If write returns error release the XD pointer + * from Endpoint send queue and return it to Free list of XD pointers. + */ + //xd_ptr->bstatus = USB_STATUS_IDLE; + state_ptr->ep_info[xd_ptr->ep_num].send_xd = NULL; + //USB_XD_QUEUE_DEQUEUE (&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_send, &xd_ptr); + //if (xd_ptr != NULL) + usb_dci_khci_free_xd(state_ptr, xd_ptr); + } + return error; +} + +/**************************************************************************//*! + * @name : usb_dci_khci_recv + * @brief : Receives data. Non-blocking. + * @param handle: Handle to USB Device. + * @param xd_ptr: Transaction Descriptor. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_recv +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + xd_struct_t* xd_ptr +) +{ + usb_status error = USBERR_RX_FAILED;/* initializing to failed value */ + uint32_t buf_num_bytes; + uint8_t *buf_ptr; + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + buf_num_bytes = xd_ptr->wtotallength - xd_ptr->wsofar; + + /* Allocate XD structure from Free List maintained by Device structure, + * if it is not any split transaction. + */ + + if (xd_ptr->wsofar == 0) + { + //USB_XD_QUEUE_ENQUEUE(&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_recv, xd_ptr); + state_ptr->ep_info[xd_ptr->ep_num].recv_xd = xd_ptr; + } + + /* If the number of bytes to be received is greater than the + * maximum data that can be received on the USB bus, then split the + * transaction into multiple receive transaction. + */ + if (buf_num_bytes > state_ptr->ep_info[xd_ptr->ep_num].max_packet_size) + { + buf_num_bytes = state_ptr->ep_info[xd_ptr->ep_num].max_packet_size; + } + + /* Send the receive command to the device.*/ + buf_ptr = (uint8_t *)((uint32_t)xd_ptr->wstartaddress + (uint32_t)xd_ptr->wsofar); +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + if ((_usb_khci_dev_swap_buf_ptr) && ((buf_num_bytes & USB_DMA_ALIGN_MASK) || ((uint32_t)buf_ptr & USB_DMA_ALIGN_MASK))) + { + xd_ptr->internal_dma_align = FALSE; + buf_ptr = (uint8_t*)USB_DMA_ALIGN((int32_t)_usb_khci_dev_swap_buf_ptr); + } +#endif + if (state_ptr->is_reseting == 0) + { + error = _usb_khci_ep_read((usb_khci_dev_state_struct_t*)handle, xd_ptr->ep_num, buf_ptr, buf_num_bytes); + } + + if (error != USB_OK) + { + //USB_XD_QUEUE_DEQUEUE(&state_ptr->ep_info[xd_ptr->ep_num].xd_queue_recv, &xd_ptr); + //_usb_khci_free_XD(state_ptr, xd_ptr); + state_ptr->ep_info[xd_ptr->ep_num].recv_xd = NULL; + usb_dci_khci_free_xd(state_ptr, xd_ptr); + } + + if ((buf_num_bytes == 0) && (xd_ptr->ep_num == USB_CONTROL_ENDPOINT)) + { + usb_dci_khci_free_xd(state_ptr, xd_ptr); + + state_ptr->ep_info[USB_CONTROL_ENDPOINT].rx_buf_odd ^= 1; + _usb_khci_next_setup_token_prep(state_ptr); + // prime the next setup transaction here + } + return error; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_stall_endpoint + * @brief : Stalls the specified endpoint + * @param handle: Handle to USB Device. + * @param ep_num: End Point Number. + * @param direction: USB_SEND or USB_RECV. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_stall_endpoint +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t direction +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + //USB_MemMapPtr usb_ptr; + + /* set the stall flag in device structure to be true */ + state_ptr->ep_info[ep_num].stall_flag = TRUE; + state_ptr->ep_info[ep_num].endpoint_status = USB_STATUS_STALLED; + + /* retiring pending IRPs on stall detection */ + usb_dci_khci_cancel(handle, ep_num, direction); + + /* If Stall is for Send packet update Send BDT */ + if (direction) + { + /* USB_SEND */ + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_SEND, state_ptr->ep_info[ep_num].tx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size)| USB_BD_OWN | USB_BD_STALL | USB_BD_DTS))); + //BD_CTRL_TX(ep_num, state_ptr->ep_info[ep_num].tx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size)| USB_BD_OWN | USB_BD_STALL | USB_BD_DTS)); + } + else + { + /* USB_RECV */ + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size)| USB_BD_OWN | USB_BD_STALL | USB_BD_DTS))); + /* If Stall is for Receive transaction, Update Receive BDT*/ + //BD_CTRL_RX(ep_num, state_ptr->ep_info[ep_num].rx_buf_odd) = + // USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size) | USB_BD_OWN | USB_BD_STALL | USB_BD_DTS)); + } + + /* Continue Further processing as the IP stops on receiving + * Setup Token. + */ + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + + return USB_OK; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_unstall_endpoint + * @brief : Unstall the Endpoint in specific direction + * @param handle: Handle to USB Device. + * @param ep_num: End Point Number. + * @param direction: USB_SEND or USB_RECV. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_unstall_endpoint +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t direction +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + //USB_MemMapPtr usb_ptr; + + /* clear the stall flag in device structure */ + state_ptr->ep_info[ep_num].stall_flag = FALSE; + state_ptr->ep_info[ep_num].endpoint_status = USB_STATUS_IDLE; + + usb_hal_khci_endpoint_clr_stall(state_ptr->usbRegBase, ep_num); + + if (direction) + {/* USB_SEND */ + usb_hal_khci_endpoint_enable_handshake(state_ptr->usbRegBase, ep_num, 1); + usb_hal_khci_endpoint_set_direction(state_ptr->usbRegBase, ep_num, 1); + state_ptr->ep_info[ep_num].tx_data0 = 0; + /*BD_CTRL_TX(ep_num, state_ptr->ep_info[ep_num].tx_buf_odd) = + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size) | + USB_BD_DTS | USB_BD_DATA01(0)));*/ + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_SEND, state_ptr->ep_info[ep_num].tx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size)| USB_BD_DTS | USB_BD_DATA01(0)))); + } + else + {/* USB_RECV */ + usb_hal_khci_endpoint_enable_handshake(state_ptr->usbRegBase, ep_num, 1); + usb_hal_khci_endpoint_set_direction(state_ptr->usbRegBase, ep_num, 0); + state_ptr->ep_info[ep_num].rx_data0 = 0; + if (ep_num == USB_CONTROL_ENDPOINT) + { + /* something important need to do is toggle the tx buffer odd */ + //state_ptr->ep_info[USB_CONTROL_ENDPOINT].tx_buf_odd ^= 1; + _usb_khci_next_setup_token_prep(state_ptr); + } + else + { + usb_hal_khci_bdt_set_control((uint32_t )bdt, ep_num, USB_RECV, state_ptr->ep_info[ep_num].rx_buf_odd, + USB_LONG_LE_TO_HOST((uint32_t)(USB_BD_BC(state_ptr->ep_info[ep_num].max_packet_size)| USB_BD_DTS | USB_BD_DATA01(0)))); + } + } + + usb_hal_khci_clr_token_busy(state_ptr->usbRegBase); + return USB_OK; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_cancel + * @brief : Cancels all pending transfers on an endpoint. + * @param handle: Handle to USB Device. + * @param ep_num: End Point Number. + * @param direction: USB_SEND or USB_RECV. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_cancel +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t ep_num, + /*[IN]*/ + uint8_t direction +) +{ + usb_event_struct_t event; + xd_struct_t* xd_ptr = NULL; + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + if (direction == USB_RECV) + { + xd_ptr = state_ptr->ep_info[ep_num].recv_xd; + state_ptr->ep_info[ep_num].recv_xd = NULL; + } + else + { + xd_ptr = state_ptr->ep_info[ep_num].send_xd; + state_ptr->ep_info[ep_num].send_xd = NULL; + } + if (xd_ptr != NULL) + { + usb_dci_khci_free_xd(handle, xd_ptr); + event.len = 0xFFFFFFFF; + event.buffer_ptr = xd_ptr->wstartaddress; + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = FALSE; + event.direction = direction; + _usb_device_call_service(ep_num, &event); + } +#if 0 + if (direction) + { + tempQueue = &state_ptr->ep_info[ep_num].xd_queue_send; + } + else + { + tempQueue = &state_ptr->ep_info[ep_num].xd_queue_recv; + } + + /* Empty the queue and add the XD release structure to the Free list*/ + do + { + USB_XD_QUEUE_DEQUEUE(tempQueue, &xd_temp_ptr); + + if (xd_temp_ptr) + { + xd_temp_ptr->bstatus = USB_STATUS_IDLE; + event.len = 0xFFFFFFFF; + event.buffer_ptr = xd_temp_ptr->wstartaddress; + event.handle = (usb_device_handle)state_ptr->upper_layer_handle; + event.ep_num = ep_num; + event.setup = FALSE; + event.direction = direction; + _usb_khci_free_XD(state_ptr, xd_temp_ptr); + _usb_device_call_service(ep_num,&event); + } + } + while (xd_temp_ptr); +#endif + return USB_OK; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_set_addr + * @brief : Set device address. + * @param handle : Device handle. + * @param addr : Address to be set into Device Address register. + * @return : Returns USB_OK or error code. + ******************************************************************************/ +usb_status usb_dci_khci_set_addr +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t addr +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + //volatile USB_MemMapPtr usb_ptr; + + /* Update USB address in Device registers. This 7-bit value + * defines the USB address that the USB Module decodes + * in device mode + */ + usb_hal_khci_set_device_addr(state_ptr->usbRegBase, addr); + + /* Update the USB device address in Device Info structure for + * Future References. + */ + state_ptr->device_address = addr; + /* Set the Device Start as Address Assigned State.*/ + state_ptr->usb_state = USB_STATE_ADDRESS; + + return USB_OK; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_shutdown + * @brief : Shuts down the usbfs Device Controller + * Note: There is no function in MQX to uninstall ISR. + * Hence ISR is not Uninstalled here.However, installing + * ISR twice will not have any negative impact. + * @param handle : Device handle. + * @return : Returns USB_OK or error code. + ******************************************************************************/ +usb_status usb_dci_khci_shutdown +( + /*[IN]*/ + usb_device_handle handle + ) +{ +#ifdef USBCFG_OTG + usb_otg_state_struct_t * usb_otg_struct_ptr = (usb_otg_state_struct_t *)g_usb_otg_handle; + usb_otg_status_t * otg_status_ptr = &usb_otg_struct_ptr->otg_status; +#endif + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* Reset the Control Register */ + //usb_hal_khci_reset_controller(handle->usbRegBase);/* disables the USB MODULE */ + usb_hal_khci_disable_interrupts(state_ptr->usbRegBase, 0xFF); + usb_hal_khci_set_device_addr(state_ptr->usbRegBase, 0); + + usb_hal_khci_clear_control_register(state_ptr->usbRegBase); + + usb_hal_khci_enable_pull_down(state_ptr->usbRegBase); + usb_hal_khci_set_suspend(state_ptr->usbRegBase); + + state_ptr->usb_state = USB_STATE_UNKNOWN; + OS_Mutex_destroy(state_ptr->mutex); + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + if (NULL != g_khci_data_ptr) + { + OS_Mem_free(g_khci_data_ptr); + g_khci_data_ptr = NULL; + } + +#if (FSL_FEATURE_USB_KHCI_USB_RAM == 0) + if (NULL != g_khci_bdt_ptr) + { + OS_Mem_free(g_khci_bdt_ptr); + g_khci_bdt_ptr = NULL; + } +#endif + +#endif +#ifdef USBCFG_OTG + otg_status_ptr->active_stack = USB_ACTIVE_STACK_NONE; + usb_otg_struct_ptr->dev_inst_ptr = NULL; +#endif + return USB_OK; +} + +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME +/**************************************************************************//*!* + * @name : usb_dci_khci_assert_resume + * @brief : Resume signaling for remote wakeup + * @param handle: Handle to USB Device. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_assert_resume +( + /*[IN]*/ + usb_device_handle handle +) +{ + uint16_t delay_count; + //volatile USB_MemMapPtr usb_ptr; + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* clear resume FLAG*/ + usb_hal_khci_clr_interrupt(handle->usbRegBase, INTR_RESUME); + + /* Disable RESUME Interrupt */ +// usb_ptr->INTEN &= ~USB_INTEN_RESUME_EN_MASK; //already done in RESUME interrupt + /* continue processing */ + usb_hal_khci_clr_token_busy(handle->usbRegBase); + + /* Start RESUME signaling and make SUSPEND bit 0*/ + usb_hal_khci_start_resume(handle->usbRegBase); + + /* Set RESUME line for 1-15 ms*/ + delay_count = ASSERT_RESUME_DELAY_COUNT; + do + { + delay_count--; + }while (delay_count); + + /* Stop RESUME signaling */ + usb_hal_khci_stop_resume(handle->usbRegBase); + + return USB_OK; +} +#endif + +/**************************************************************************//*!* + * @name : usb_dci_khci_get_endpoint_status + * @brief : Get Endpoint Transfer Status + * @param handle: Handle to USB Device. + * @param component: End Point Number. + * @param endp_status: Variable containing endpint status.. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_get_endpoint_status +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t component, + /*[OUT]*/ + uint16_t* endp_status +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + + *endp_status = state_ptr->ep_info[component & USB_STATUS_ENDPOINT_NUMBER_MASK].endpoint_status; + return USB_OK; +} + +/**************************************************************************//*!* + * @name : usb_dci_khci_set_endpoint_status + * @brief : Set Endpoint Transfer Status + * @param handle: Handle to USB Device. + * @param component: End Point Number. + * @param setting: Variable containing new settings.. + * @return : USB_OK or error code + ******************************************************************************/ +usb_status usb_dci_khci_set_endpoint_status +( + /*[IN]*/ + usb_device_handle handle, + /*[IN]*/ + uint8_t component, + /*[IN]*/ + uint16_t setting +) +{ + usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle; + usb_status error = USBERR_ERROR;/* initializing */ + uint8_t ep_num = (uint8_t)(component & USB_STATUS_ENDPOINT_NUMBER_MASK); + /* direction is in most significant bit */ + uint8_t direction = (uint8_t)((component >> COMPONENT_PREPARE_SHIFT) & 1U); + + state_ptr->ep_info[ep_num].endpoint_status = setting; + + /* check if the setting was to halt endpoint or unhalt it*/ + if (setting == USB_STATUS_STALLED) + { /* stall the endpoint */ + error = usb_dci_khci_stall_endpoint(handle, ep_num, direction); + } + else if ((setting == USB_STATUS_IDLE) && (state_ptr->ep_info[ep_num].stall_flag)) + { + /* unstall the endpoint*/ + /* need to update the direction here for unstalling + (as it was not passed from above layers for unstall because the + STAT register doesn't get updated in STALL ISR and we need to unstall + directly from STALL_SERVICE for CONTROL ENDPOINT. Therefore, this + method of unstall was employed to make the structure generic)*/ + direction = state_ptr->ep_info[ep_num].direction; + error = usb_dci_khci_unstall_endpoint(handle, ep_num, direction); + } + + return error; +} + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_dci_khci_set_status + * Returned Value : USB_OK or error code + * Comments : + * Provides API to set internal state + * + *END*--------------------------------------------------------------------*/ +usb_status usb_dci_khci_set_status +( + /* [IN] Handle to the usb device */ + usb_device_handle handle, + + /* [IN] What to set the error of */ + uint8_t component, + + /* [IN] What to set the error to */ + uint16_t setting +) +{ + usb_khci_dev_state_struct_t* usb_dev_ptr; + uint8_t error = USB_OK; + + usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + OS_Mutex_lock(usb_dev_ptr->mutex); + + switch(component) + { + case USB_STATUS_DEVICE_STATE: + usb_dev_ptr->usb_state = setting; + break; + case USB_STATUS_DEVICE: + usb_dev_ptr->usb_device_status = setting; + break; + case USB_STATUS_INTERFACE: + break; + case USB_STATUS_CURRENT_CONFIG: + usb_dev_ptr->usb_curr_config = setting; + break; + case USB_STATUS_SOF_COUNT: + usb_dev_ptr->usb_sof_count = setting; + break; +#ifdef USBCFG_OTG + case USB_STATUS_OTG: + usb_dev_ptr->usb_otg_status = setting; + break; +#endif + default: + + break; + }/* Endswitch */ + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return error; +} /* EndBody */ + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_dci_khci_get_status + * Returned Value : USB_OK or error code + * Comments : + * Provides API to access the USB internal state. + * + *END*--------------------------------------------------------------------*/ +usb_status usb_dci_khci_get_status +( + /* [IN] Handle to the USB device */ + usb_device_handle handle, + + /* [IN] What to get the error of */ + uint8_t component, + + /* [OUT] The requested error */ + uint16_t* error +) +{ + usb_khci_dev_state_struct_t* usb_dev_ptr; + + usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + + OS_Mutex_lock(usb_dev_ptr->mutex); + switch(component) + { + case USB_STATUS_DEVICE_STATE: + *error = usb_dev_ptr->usb_state; + break; + + case USB_STATUS_DEVICE: + *error = usb_dev_ptr->usb_device_status; + break; + + case USB_STATUS_INTERFACE: + break; + + case USB_STATUS_ADDRESS: + *error = usb_dev_ptr->device_address; + break; + + case USB_STATUS_CURRENT_CONFIG: + *error = usb_dev_ptr->usb_curr_config; + break; + case USB_STATUS_SOF_COUNT: + *error = usb_dev_ptr->usb_sof_count; + break; + case USB_STATUS_SPEED: + *error = usb_dev_ptr->speed; + break; +#ifdef USBCFG_OTG + case USB_STATUS_OTG: + *error = usb_dev_ptr->usb_otg_status; + break; +#endif + default: + break; + } /* Endswitch */ + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USB_OK; +} + +usb_status usb_dci_khci_reset +( + /* [IN] Handle to the USB device */ + usb_device_handle handle +) +{ + usb_khci_dev_state_struct_t* usb_dev_ptr; + uint8_t cnt = 0; + + usb_dev_ptr = (usb_khci_dev_state_struct_t*)handle; + + /* De-Init All the End Point. */ + for (cnt = 0; cnt < USBCFG_DEV_MAX_ENDPOINTS; cnt++) + { + usb_dci_khci_deinit_endpoint(usb_dev_ptr, cnt, USB_RECV); + usb_dci_khci_deinit_endpoint(usb_dev_ptr, cnt, USB_SEND); + } + + /* Re-Initialize All the end point */ + _usb_khci_reset_ep_state((usb_khci_dev_state_struct_t*)usb_dev_ptr); + usb_dci_khci_init_xd((usb_device_handle)usb_dev_ptr); + usb_dev_ptr->is_reseting = 0; + return USB_OK; +} +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.h b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.h new file mode 100644 index 0000000..97f4f81 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev.h @@ -0,0 +1,75 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2009, 2015 Freescale Semiconductor; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: khci_dev.h$ + * $Version : + * $Date : + * + * Comments: + * + * This file contains the macros, function prototypes and data structure + * definitions required by the Full Speed USB Device Controller driver. + * + *END************************************************************************/ + +#ifndef __khci_dev_h__ +#define __khci_dev_h__ + +#define KHCI_MAX_ENDPOINT (16) + +/*************************************** + ** + ** Prototypes + **/ +#ifdef __cplusplus +extern "C" +{ +#endif + + usb_status usb_dci_khci_preinit(usb_device_handle upper_layer_handle, usb_device_handle *handle_ptr); + usb_status usb_dci_khci_postinit(uint8_t controller_id, usb_device_handle handle); + usb_status usb_dci_khci_init(uint8_t controller_id, usb_device_handle handle); + usb_status usb_dci_khci_send(usb_device_handle handle, xd_struct_t* xd_ptr); + usb_status usb_dci_khci_recv(usb_device_handle handle, xd_struct_t* xd_ptr); + usb_status usb_dci_khci_cancel(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + usb_status usb_dci_khci_set_addr(usb_device_handle handle, uint8_t addr); + usb_status usb_dci_khci_shutdown(usb_device_handle handle); +//usb_status usb_dci_khci_get_setup_data(usb_device_handle handle, uint8_t, uint8_t *); +#if ((defined USBCFG_DEV_ADVANCED_SUSPEND_RESUME) && (USBCFG_DEV_ADVANCED_SUSPEND_RESUME)) + usb_status usb_dci_khci_assert_resume(usb_device_handle handle); +#endif + usb_status usb_dci_khci_init_endpoint(usb_device_handle handle, xd_struct_t* xd_ptr); + usb_status usb_dci_khci_stall_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + usb_status usb_dci_khci_unstall_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + usb_status usb_dci_khci_deinit_endpoint(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + usb_status usb_dci_khci_get_endpoint_status(usb_device_handle handle, uint8_t component, uint16_t *endp_status); + usb_status usb_dci_khci_set_endpoint_status(usb_device_handle handle, uint8_t component, uint16_t setting); +//usb_status usb_dci_khci_get_transfer_status(usb_device_handle handle,uint8_t,uint8_t); + usb_status usb_dci_khci_get_status(usb_device_handle handle, uint8_t component, uint16_t *error); + usb_status usb_dci_khci_set_status(usb_device_handle handle, uint8_t component, uint16_t setting); + usb_status usb_dci_khci_get_xd(usb_device_handle handle, xd_struct_t** xd_ptr_ptr); + usb_status usb_dci_khci_reset(usb_device_handle handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev_misc.h b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev_misc.h new file mode 100644 index 0000000..e149332 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/khci/khci_dev_misc.h @@ -0,0 +1,146 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2009, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: khci_dev_misc.h$ +* $Version : +* $Date : +* +* Comments: +* +* This file contains the private defines, externs and data structure +* definitions required by the Full Speed USB Device driver. +* +*END************************************************************************/ + +#ifndef __khci_dev_misc_h__ +#define __khci_dev_misc_h__ 1 + +#define EP_DISABLE (0) +#define ASSERT_RESUME_DELAY_COUNT (8000)/* Delay for assert resume */ +#define BYTES_512 (512) +#define BYTES_1024 (1024) +#define ENDPOINT_NUMBER_SHIFT (4) /* endpoint shift & mask to */ +#define ENDPOINT_NUMBER_MASK (0xf0)/* use in setting and getting status */ +#define MAX_FS_NON_ISO_EP_BUFFER_SIZE (64) +#define MAX_FS_ISO_EP_BUFFER_SIZE (1023) +#define SETUP_PACKET_LENGTH (8) +#define COMPONENT_PREPARE_SHIFT (7) + +#define ZERO_LENGTH (0) +#define USB_SETUP_TOKEN (0x0d)/* Setup Token PID */ +#define FRAME_HIGH_BYTE_SHIFT (8) + +#define MAX_USB_DEVICES (1) +#define ODD_BUFF (1) +#define EVEN_BUFF (0) + +/* Define USB buffer descriptor definitions in case of their lack */ +#ifndef USB_BD_BC +# define USB_BD_BC(n) (((uint32_t)n & 0x3ff) << 16) +# define USB_BD_OWN 0x80 +# define USB_BD_DATA01(n) (((uint32_t)n & 1) << 6) +# define USB_BD_DATA0 USB_BD_DATA01(0) +# define USB_BD_DATA1 USB_BD_DATA01(1) +# define USB_BD_KEEP 0x20 +# define USB_BD_NINC 0x10 +# define USB_BD_DTS 0x08 +# define USB_BD_STALL 0x04 +# define USB_BD_PID(n) (((uint32_t)n & 0x0f) << 2) +#endif + +#ifndef USB_TOKEN_TOKENPID_SETUP +# define USB_TOKEN_TOKENPID_OUT USB_TOKEN_TOKENPID(0x1) +# define USB_TOKEN_TOKENPID_IN USB_TOKEN_TOKENPID(0x9) +# define USB_TOKEN_TOKENPID_SETUP USB_TOKEN_TOKENPID(0xD) +#endif + +typedef struct _usb_ep_info_struct +{ + //USB_XD_QUEUE xd_queue_send; /* FIFO queue for all XDs on this endpoint */ + //USB_XD_QUEUE xd_queue_recv; + struct xd_struct* send_xd; + struct xd_struct* recv_xd; + uint16_t max_packet_size; + uint8_t endpoint_status; + uint8_t stall_flag; + /* Endpoint initialization flag for both direction */ + uint8_t ep_init_flag[2]; + uint8_t type; + uint8_t direction; /* for usb_device_call_service */ + uint8_t tx_data0; + uint8_t rx_data0; + uint8_t tx_buf_odd; + uint8_t rx_buf_odd; /* next buffer is odd */ +} usb_ep_info_struct_t; + +/* The USB Device State Structure */ +typedef struct _usb_khci_device_state_struct +{ + uint32_t controller_id; /* Device controller ID */ + usb_device_handle upper_layer_handle; + void* dev_ptr; /* Device Controller Register base address */ + struct xd_struct* xd_base; + struct xd_struct* xd_head; /* Head Transaction descriptors */ + struct xd_struct* xd_tail; /* Tail Transaction descriptors */ + uint32_t xd_entries; + os_mutex_handle mutex; + uint32_t usbRegBase; + + /* These fields are kept only for USB_shutdown() */ + uint16_t usb_state; + uint16_t usb_device_status; + uint16_t usb_sof_count; + uint16_t errors; + uint16_t usb_dev_state_b4_suspend; + uint16_t usb_curr_config; + uint8_t dev_vec; /* Interrupt vector number for USB OTG */ + uint8_t speed; /* Low Speed, High Speed, Full Speed */ + uint8_t max_endpoints; /* Max endpoints supported by this device */ + uint8_t device_address; + uint8_t * setup_buff; + usb_ep_info_struct_t ep_info[USBCFG_DEV_MAX_ENDPOINTS]; +#ifdef USBCFG_OTG + uint16_t usb_otg_status; + usb_otg_handle otg_handle; + uint8_t otg_attr_srp; + uint8_t otg_attr_hnp; +#endif + uint8_t is_reseting; +} usb_khci_dev_state_struct_t; + +/*************************************** +** +** Prototypes +** +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.c b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.c new file mode 100644 index 0000000..c2d6979 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.c @@ -0,0 +1,1560 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_dev.c$ + * $Version : + * $Date : + * + * Comments: + * + * This file contains the main USB device API functions that will be + * used by most applications. + * + *END*********************************************************************/ +#include "usb_device_config.h" +#if USBCFG_DEV_KHCI || USBCFG_DEV_EHCI +#include "usb.h" +#include "usb_device_stack_interface.h" + +//#define USBCFG_DEV_USE_TASK (0) +#define USBCFG_DEV_SERVICE_MSG_CNT (8) +#define MSG_SIZE_IN_MAX_TYPE (1 + (sizeof(usb_event_struct_t) - 1) / sizeof(uint32_t)) + +#include "usb_dev.h" +#include "khci_dev_misc.h" +#ifdef USBCFG_OTG +#include "usb_otg_dev_api.h" +#endif + +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK))) + #if defined( __ICCARM__ ) + #pragma data_alignment=32 + __no_init usb_dev_data_t g_usb_dev_data[USBCFG_DEV_NUM]; + #elif defined (__CC_ARM) || defined(__GNUC__) + __attribute__((aligned(32))) usb_dev_data_t g_usb_dev_data[USBCFG_DEV_NUM]; + #else + #error Unsupported compiler, please use IAR, Keil or arm gcc compiler and rebuild the project. + #endif +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + usb_dev_data_t* g_usb_dev_data_ptr[USBCFG_DEV_NUM] = {NULL}; +#endif + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) +#define OS_Mutex_lock(_M_) OS_Lock() +#define OS_Mutex_unlock(_M_) OS_Unlock() +#endif +#define USB_DEV_HANDLE_OCCUPIED ((uint8_t)1) +#define USB_DEV_HANDLE_FREE ((uint8_t)0) + +#if USBCFG_DEV_USE_TASK +#define USB_DEVICE_TASK_TEMPLATE_INDEX 0 + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) /* USB stack running on MQX */ +#define USB_DEVICE_TASK_ADDRESS _usb_dev_task_stun + +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) /* USB stack running on BM */ +#define USB_DEVICE_TASK_ADDRESS _usb_dev_task + +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +#if USE_RTOS +#define USB_DEVICE_TASK_ADDRESS _usb_dev_task_stun +#else +#define USB_DEVICE_TASK_ADDRESS _usb_dev_task +#endif + +#endif + +#define USB_DEVICE_TASK_PRIORITY (6) +#define USB_DEVICE_TASK_STACKSIZE (3500) +#define USB_DEVICE_TASK_NAME "Device Task" +#define USB_DEVICE_TASK_ATTRIBUTES (0) +#define USB_DEVICE_TASK_CREATION_PARAMETER (0) +#define USB_DEVICE_TASK_DEFAULT_TIME_SLICE (0) + +#endif +extern usb_status bsp_usb_dev_init(uint8_t controller_id); +#ifdef USBCFG_OTG +extern usb_status bsp_usb_otg_dev_init(uint8_t controller_id); +#endif +#if USBCFG_DEV_KHCI && USBCFG_DEV_DETACH_ENABLE && USBCFG_DEV_IO_DETACH_ENABLE +extern int32_t bsp_usb_detach_init(uint8_t controller_id); +#endif +extern void USB_Control_Service (void* handle, usb_event_struct_t* event,void* arg); +extern void USB_Reset_Service(void* handle, usb_event_struct_t* event, void* arg); +extern void USB_Error_Service(void* handle, usb_event_struct_t* event, void* arg); +extern void USB_Suspend_Service(void* handle, usb_event_struct_t* event,void* arg); +extern void USB_Resume_Service(void* handle,usb_event_struct_t* event,void* arg ); + +static usb_dev_state_struct_t g_usb_dev[USBCFG_DEV_NUM] = {{0}}; +#if USBCFG_DEV_KHCI +extern const usb_dev_interface_functions_struct_t _usb_khci_dev_function_table; +#endif +#if USBCFG_DEV_EHCI +extern const usb_dev_interface_functions_struct_t _usb_ehci_dev_function_table; +#endif + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_device_get_handle + * Returned Value : NULL + * Comments : + * This function is used to get one unused device object + * + *END*-----------------------------------------------------------------*/ +static usb_dev_state_struct_t* _usb_device_get_handle +( + void +) +{ + uint8_t i = 0; + + for (; i < USBCFG_DEV_NUM; i++) + { + if (g_usb_dev[i].occupied != USB_DEV_HANDLE_OCCUPIED) + { + OS_Mem_zero(&g_usb_dev[i], sizeof(usb_dev_state_struct_t)); + g_usb_dev[i].occupied = USB_DEV_HANDLE_OCCUPIED; + g_usb_dev[i].dev_index = i; + return &g_usb_dev[i]; + } + } + return NULL; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_device_release_handle + * Returned Value : NULL + * Comments : + * This function is used to set one used device object to free + * + *END*-----------------------------------------------------------------*/ +static void _usb_device_release_handle +( +usb_dev_state_struct_t *usb_dev +) +{ + usb_dev->occupied = USB_DEV_HANDLE_FREE; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_device_get_DCI + * Returned Value : NULL + * Comments : + * This function is used to get the device controller's interface table pointer + * + *END*-----------------------------------------------------------------*/ +static void _usb_device_get_DCI +( + uint8_t controller_id, + const usb_dev_interface_functions_struct_t ** controller_if_ptr +) +{ +#if USBCFG_DEV_KHCI + if ((controller_id == USB_CONTROLLER_KHCI_0) || ((controller_id == USB_CONTROLLER_KHCI_1))) + { + *controller_if_ptr = (usb_dev_interface_functions_struct_t const*)&_usb_khci_dev_function_table; + } +#endif + +#if USBCFG_DEV_EHCI + if ((controller_id == USB_CONTROLLER_EHCI_0) || (controller_id == USB_CONTROLLER_EHCI_1)) + { + *controller_if_ptr = &_usb_ehci_dev_function_table; + } +#endif +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_device_shutdown + * Returned Value : USB_OK or error code + * Comments : + * Shutdown an initialized USB device + * + *END*-----------------------------------------------------------------*/ +static usb_status _usb_device_shutdown +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle +) +{ + usb_status error; + usb_dev_state_struct_t* usb_dev_ptr; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; +#if USBCFG_DEV_USE_TASK + + if (usb_dev_ptr->task_id != (uint32_t)OS_TASK_ERROR) + { + OS_Task_delete(usb_dev_ptr->task_id); + } + if (NULL != usb_dev_ptr->usb_dev_service_que) + { + OS_MsgQ_destroy(usb_dev_ptr->usb_dev_service_que); + } +#endif + if (usb_dev_ptr->usb_dev_interface->dev_shutdown != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_shutdown(usb_dev_ptr->controller_handle); + return error; + } + else + { +#if _DEBUG + USB_PRINTF("_usb_device_shutdown: DEV_SHUTDOWN is NULL\n"); +#endif + return USBERR_ERROR; + } +} /* EndBody */ + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_call_service + * Returned Value : USB_OK or error code + * Comments : + * Calls the appropriate service for the specified type, if one is + * registered. Used internally only. + * + *END*--------------------------------------------------------------------*/ +usb_status _usb_device_call_service_internal +( + /* [IN] pointer to usb device status structure */ + usb_dev_state_struct_t* usb_dev_ptr, + /* [IN] pointer to event structure */ + usb_event_struct_t* event +) +{ + service_struct_t* service_ptr = NULL; + uint32_t i; + + /* Needs mutual exclusion */ + //OS_Mutex_lock(usb_dev_ptr->mutex); + switch (event->type) + { + case USB_SERVICE_EP0: + USB_Control_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; + case USB_SERVICE_BUS_RESET: + USB_Reset_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME + case USB_SERVICE_SUSPEND: + USB_Suspend_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; + case USB_SERVICE_RESUME: + USB_Resume_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; +#endif +#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING + case USB_SERVICE_ERROR: + USB_Error_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; +#endif +#if USBCFG_DEV_DETACH_ENABLE + case USB_SERVICE_DETACH: + USB_Detach_Service(&usb_dev_ptr->usb_framework, event, NULL); + break; +#endif + default: + break; + } /* Endswitch */ + + /* Search for an existing entry for type */ + for (i = 0; i < MAX_DEVICE_SERVICE_NUMBER; i++) + { + service_ptr = &usb_dev_ptr->services[i]; + if (service_ptr->type == event->type) + { + service_ptr->service(event,service_ptr->arg); + //OS_Mutex_unlock(usb_dev_ptr->mutex); + return USB_OK; + } + } + + //OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_CLOSED_SERVICE; +} /* EndBody */ + +#if USBCFG_DEV_USE_TASK +static void _usb_dev_task +( + void* dev_inst_ptr +) +{ + usb_dev_state_struct_t* usb_dev_ptr = (usb_dev_state_struct_t*)dev_inst_ptr; + static usb_event_struct_t msg = {0}; + + //if (!OS_MsgQ_Is_Empty(usb_device_ptr->isr_que,&msg)) + while (!OS_MsgQ_recv(usb_dev_ptr->usb_dev_service_que, (uint32_t *) &msg, OS_MSGQ_RECEIVE_BLOCK_ON_EMPTY, 10)) + { + _usb_device_call_service_internal(usb_dev_ptr, &msg); + } +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_khci_task_stun + * Returned Value : none + * Comments : + * KHCI task + *END*-----------------------------------------------------------------*/ +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) && USE_RTOS) +static void _usb_dev_task_stun +( + void* dev_inst_ptr +) +{ + while (1) + { + _usb_dev_task(dev_inst_ptr); + } +} +#endif + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : _usb_task_create + * Returned Value : error or USB_OK + * Comments : + * Create device task + *END*-----------------------------------------------------------------*/ +static usb_status _usb_dev_task_create +( + usb_device_handle handle +) +{ + //USB_STATUS status; + //task_id = _task_create_blocked(0, 0, (uint32_t)&task_template); + usb_dev_state_struct_t* usb_dev_ptr; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + usb_dev_ptr->task_id = OS_Task_create(USB_DEVICE_TASK_ADDRESS, (void*)handle, (uint32_t)USB_DEVICE_TASK_PRIORITY, USB_DEVICE_TASK_STACKSIZE, USB_DEVICE_TASK_NAME, NULL); + + if (usb_dev_ptr->task_id == (uint32_t)OS_TASK_ERROR) + { + return USBERR_ERROR; + } + + //_task_ready(_task_get_td(task_id)); + //OS_Task_resume(task_id); + + return USB_OK; +} + +#endif + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_call_service + * Returned Value : USB_OK or error code + * Comments : + * Calls the appropriate service for the specified type, if one is + * registered. Used internally only. + * + *END*--------------------------------------------------------------------*/ +usb_status _usb_device_call_service +( + /* [IN] Type of service or endpoint */ + uint8_t type, + /* [IN] pointer to event structure */ + usb_event_struct_t* event +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_dev_ptr = (usb_dev_state_struct_t*)event->handle; + + event->type = type; + if((type & 0x7F) && ((type & 0x7F) < 0x10)) + { + event->type = (uint8_t)(((uint8_t)(event->direction << 7)) | (uint8_t)(type & 0x7F)); + } +#if USBCFG_DEV_USE_TASK + if (0 != OS_MsgQ_send(usb_dev_ptr->usb_dev_service_que, (void *)event, 0)) + { + return USBERR_ALLOC_STATE; + } + return USB_OK; +#else + return _usb_device_call_service_internal(usb_dev_ptr, event); +#endif + +} +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_set_address + * Returned Value : USB_OK or error code + * Comments : + * Sets the device address as assigned by the host during enumeration + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_set_address +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the USB address to be set in the hardware */ + uint8_t address +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + if ((usb_dev_ptr->usb_dev_interface)->dev_set_address != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_set_address(usb_dev_ptr->controller_handle, address); + return error; + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_set_address: DEV_SET_ADDRESS is NULL\n"); +#endif + return USBERR_ERROR; + } + +} + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_get_status + * Returned Value : USB_OK or error code + * Comments : + * Provides API to access the USB internal state. + * + *END*--------------------------------------------------------------------*/ +usb_status usb_device_get_status +( + /* [IN] Handle to the USB device */ + usb_device_handle handle, + /* [IN] What to get the error of */ + uint8_t component, + /* [OUT] The requested error */ + uint16_t* error +) +{ /* Body */ + usb_dev_state_struct_t* usb_dev_ptr; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + OS_Mutex_lock(usb_dev_ptr->mutex); + if (component & USB_STATUS_ENDPOINT) + { + if ((usb_dev_ptr->usb_dev_interface)->dev_get_endpoint_status != NULL) + { + (usb_dev_ptr->usb_dev_interface)->dev_get_endpoint_status(usb_dev_ptr->controller_handle, + (uint8_t)(component),error); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_get_status: DEV_GET_ENDPOINT_STATUS is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + } + else + { + if ((usb_dev_ptr->usb_dev_interface)->dev_get_device_status != NULL) + { + (usb_dev_ptr->usb_dev_interface)->dev_get_device_status(usb_dev_ptr->controller_handle, + (uint8_t)(component),error); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_get_status: DEV_GET_DEVICE_STATUS is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USB_OK; +} + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_set_status + * Returned Value : USB_OK or error code + * Comments : + * Provides API to set internal state + * + *END*--------------------------------------------------------------------*/ +usb_status usb_device_set_status +( +/* [IN] Handle to the usb device */ +usb_device_handle handle, +/* [IN] What to set the error of */ +uint8_t component, +/* [IN] What to set the error to */ +uint16_t setting +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + uint8_t error = USB_OK; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + OS_Mutex_lock(usb_dev_ptr->mutex); + if ((usb_dev_ptr->usb_dev_interface)->dev_set_device_status != NULL) + { + (usb_dev_ptr->usb_dev_interface)->dev_set_device_status(usb_dev_ptr->controller_handle, + (uint8_t)(component),setting); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_set_status: dev_set_device_status is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return error; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_init + * Returned Value : USB_OK or error code + * Comments : + * Initializes the USB device specific data structures and calls + * the low-level device controller chip initialization routine. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_init +( + /* [IN] the USB device controller to initialize */ + uint8_t controller_id, + /* [OUT] the USB_USB_dev_initialize state structure */ + usb_device_handle * handle +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + uint8_t i; + usb_status error = USB_OK; + const usb_dev_interface_functions_struct_t* dev_if = NULL; + usb_class_fw_object_struct_t* usb_fw_ptr = NULL; + + //OS_Lock(); + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + for(i = 0; i < USBCFG_DEV_NUM; i++) + { + if(NULL == g_usb_dev_data_ptr[i]) + { + g_usb_dev_data_ptr[i] = OS_Mem_alloc_uncached_align(sizeof(usb_dev_data_t), 32); + } + } +#endif + + usb_dev_ptr = _usb_device_get_handle(); + + if(usb_dev_ptr == NULL) + { + /* The interface does not support device functionality */ + //OS_Unlock(); + return USBERR_DEVICE_BUSY; + } + usb_dev_ptr->controller_id = controller_id; + usb_fw_ptr = &usb_dev_ptr->usb_framework; + usb_dev_ptr->mutex = OS_Mutex_create(); +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK))) + usb_fw_ptr->ext_req_to_host = (uint8_t*)(&g_usb_dev_data[usb_dev_ptr->dev_index].control_out); +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + usb_fw_ptr->ext_req_to_host = (uint8_t*)g_usb_dev_data_ptr[usb_dev_ptr->dev_index]->control_out; +#endif + + for (i= 0; i < MAX_DEVICE_SERVICE_NUMBER; i++) + { + usb_dev_ptr->services[i].type = (uint8_t)-1; + } + + _usb_device_get_DCI(controller_id, &dev_if); + + if(dev_if == NULL) + { + _usb_device_release_handle(usb_dev_ptr); + //OS_Unlock(); + return USBERR_DEVICE_NOT_FOUND; + } + + usb_dev_ptr->usb_dev_interface = dev_if; + +#if USBCFG_DEV_USE_TASK + /* The _lwmsgq_init accepts the size of ISR_MSG_STRUCT as a multiplier of sizeof(_mqx_max_type) */ + usb_dev_ptr->usb_dev_service_que = (os_msgq_handle)OS_MsgQ_create(USBCFG_DEV_SERVICE_MSG_CNT, MSG_SIZE_IN_MAX_TYPE); + _usb_dev_task_create(usb_dev_ptr); +#endif + + //OS_Unlock(); + /* Initialize the USB interface. */ + if (dev_if->dev_preint != NULL) + { + error = dev_if->dev_preint(usb_dev_ptr, (usb_device_handle *) (&usb_dev_ptr->controller_handle)); + } + + if (usb_dev_ptr->controller_handle == NULL) + { +#if _DEBUG + USB_PRINTF("1 memalloc failed in usb_device_init\n"); +#endif + return USBERR_ALLOC_STATE; + } /* Endif */ + usb_fw_ptr->controller_handle = usb_dev_ptr->controller_handle; + usb_fw_ptr->dev_handle = usb_dev_ptr; +#ifndef USBCFG_OTG + error = bsp_usb_dev_init(controller_id); +#if USBCFG_DEV_KHCI && USBCFG_DEV_DETACH_ENABLE && USBCFG_DEV_IO_DETACH_ENABLE + error = bsp_usb_detach_init(controller_id); +#endif +#else + error = bsp_usb_otg_dev_init(controller_id); +#endif + if (error != USB_OK) + { + if (dev_if->dev_shutdown != NULL) + { + dev_if->dev_shutdown(usb_dev_ptr->controller_handle); + } + return USBERR_UNKNOWN_ERROR; + } + + /* Initialize the USB controller chip */ + if (dev_if->dev_init != NULL) + { + error = dev_if->dev_init(controller_id,usb_dev_ptr->controller_handle); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_init: DEV_INIT is NULL\n"); +#endif + return USBERR_ERROR; + } + + if (error) + { + if (dev_if->dev_shutdown != NULL) + { + dev_if->dev_shutdown(usb_dev_ptr->controller_handle); + } + return USBERR_INIT_FAILED; + } /* Endif */ + + *handle = usb_dev_ptr; + return error; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_postinit + * Returned Value : USB_OK or error code + * Comments : + * Initializes the USB device specific data structures and calls + * the low-level device controller chip initialization routine. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_postinit +( + /* [IN] the USB device controller to initialize */ + uint8_t controller_id, + /* [OUT] the USB_USB_dev_initialize state structure */ + usb_device_handle handle +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error = 0; + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + if ((usb_dev_ptr->usb_dev_interface)->dev_postinit != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_postinit(controller_id, handle); + } + return error; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_deinit + * Returned Value : USB_OK or error code + * Comments : + * uninitializes the USB device specific data structures and calls + * the low-level device controller chip initialization routine. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_deinit +( + /* [OUT] the USB_USB_dev_initialize state structure */ + usb_device_handle handle +) +{ +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + uint32_t i; +#endif + usb_dev_state_struct_t* usb_dev_ptr; + //usb_class_fw_object_struct_t* usb_fw_ptr = NULL; + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("_usb_device_shutdowna: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + OS_Mutex_destroy(usb_dev_ptr->mutex); + _usb_device_shutdown(handle); + + _usb_device_release_handle(usb_dev_ptr); + +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + for(i = 0; i < USBCFG_DEV_NUM; i++) + { + if(NULL != g_usb_dev_data_ptr[i]) + { + OS_Mem_free(g_usb_dev_data_ptr[i]); + g_usb_dev_data_ptr[i] = NULL; + } + } +#endif + + return USB_OK; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_init_endpoint + * Returned Value : USB_OK or error code + * Comments : + * Initializes the endpoint and the data structures associated with the + * endpoint + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_init_endpoint +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the endpoint structure, include members such as endpoint number, + * endpoint type, endpoint direction and the max packet size + */ + usb_ep_struct_t* ep_ptr, + /* [IN] After all data is transfered, should we terminate the transfer + * with a zero length packet if the last packet size == MAX_PACKET_SIZE? + */ + uint8_t flag +) +{ + usb_status error = 0; + usb_dev_state_struct_t* usb_dev_ptr; + struct xd_struct xd; + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("_usb_device_shutdowna: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + /* Initialize the transfer descriptor */ + xd.ep_num = ep_ptr->ep_num; + xd.bdirection = ep_ptr->direction; + xd.wmaxpacketsize = (uint16_t)(ep_ptr->size & 0x0000FFFF); + xd.ep_type = ep_ptr->type; + xd.dont_zero_terminate = flag; + xd.wtotallength = 0; + xd.wsofar = 0; + + if ((usb_dev_ptr->usb_dev_interface)->dev_init_endoint != NULL) + { + error=(usb_dev_ptr->usb_dev_interface)->dev_init_endoint(usb_dev_ptr->controller_handle, &xd); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_init_endpoint: DEV_INIT_ENDPOINT is NULL\n"); +#endif + return USBERR_ERROR; + } + + return error; +} /* EndBody */ + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_register_service + * Returned Value : USB_OK or error code + * Comments : + * Registers a callback routine for a specified event or endpoint. + * + *END*--------------------------------------------------------------------*/ +usb_status usb_device_register_service +( + /* [IN] Handle to the USB device */ + usb_device_handle handle, + /* [IN] type of event or endpoint number to service */ + uint8_t type, + /* [IN] Pointer to the service's callback function */ + usb_event_service_t service, + /*[IN] User Argument to be passed to Services when invoked.*/ + void* arg +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + service_struct_t* service_ptr; + uint32_t i; + + if (handle == NULL) + { + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + OS_Mutex_lock(usb_dev_ptr->mutex); + + for (i = 0; i < MAX_DEVICE_SERVICE_NUMBER; i++) + { + service_ptr = &usb_dev_ptr->services[i]; + if (service_ptr->type == type) + { + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_OPEN_SERVICE; + } + } + + for (i = 0; i < MAX_DEVICE_SERVICE_NUMBER; i++) + { + service_ptr = &usb_dev_ptr->services[i]; + if (service_ptr->type == (uint8_t)-1) + { + service_ptr->type = type; + service_ptr->service = service; + service_ptr->arg = arg; + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USB_OK; + } + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ALLOC; +} /* EndBody */ + +/*FUNCTION*---------------------------------------------------------------- + * + * Function Name : usb_device_unregister_service + * Returned Value : USB_OK or error code + * Comments : + * Unregisters a callback routine for a specified event or endpoint. + * + *END*--------------------------------------------------------------------*/ +usb_status usb_device_unregister_service +( + /* [IN] Handle to the USB device */ + usb_device_handle handle, + /* [IN] type of event or endpoint number to service */ + uint8_t type +) +{ /* Body */ + usb_dev_state_struct_t* usb_dev_ptr; + service_struct_t* service_ptr; + uint32_t i; + + if (handle == NULL) + { + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + /* Needs mutual exclusion */ + OS_Mutex_lock(usb_dev_ptr->mutex); + + for (i = 0; i < MAX_DEVICE_SERVICE_NUMBER; i++) + { + service_ptr = &usb_dev_ptr->services[i]; + if (service_ptr->type == type) + { + service_ptr->type = (uint8_t)-1; + service_ptr->service = NULL; + service_ptr->arg = NULL; + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USB_OK; + } + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_CLOSED_SERVICE; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_deinit_endpoint + * Returned Value : USB_OK or error code + * Comments : + * Disables the endpoint and the data structures associated with the + * endpoint + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_deinit_endpoint +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] Direction */ + uint8_t direction +) +{ + uint8_t error = 0; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + OS_Mutex_lock(usb_dev_ptr->mutex); + + if ((usb_dev_ptr->usb_dev_interface)->dev_deinit_endoint != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_deinit_endoint(usb_dev_ptr->controller_handle, + ep_num, direction); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_deinit_endpoint: DEV_DEINIT_ENDPOINT is NULL\n"); +#endif + return USBERR_ERROR; + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_recv_data + * Returned Value : USB_OK or error code + * Comments : + * Receives data on a specified endpoint. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_recv_data +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] buffer to receive data */ + uint8_t * buff_ptr, + /* [IN] length of the transfer */ + uint32_t size +) +{ + usb_status error = USB_OK; + xd_struct_t* xd_ptr; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + if ((usb_dev_ptr->usb_dev_interface)->dev_get_xd != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_get_xd(usb_dev_ptr->controller_handle, &xd_ptr); + + if (USB_OK != error) + { +#if _DEBUG + USB_PRINTF("usb_device_recv_data: DEV_GET_XD failed\n"); +#endif + return USBERR_ERROR; + } + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_recv_data: DEV_GET_XD is NULL\n"); +#endif + return USBERR_ERROR; + } + + OS_Mutex_lock(usb_dev_ptr->mutex); + + /* Initialize the new transfer descriptor */ + xd_ptr->ep_num = ep_num; + xd_ptr->bdirection = USB_RECV; + xd_ptr->wtotallength = size; + xd_ptr->wstartaddress = buff_ptr; + xd_ptr->wsofar = 0; + xd_ptr->bstatus = USB_STATUS_TRANSFER_ACCEPTED; + + if ((usb_dev_ptr->usb_dev_interface)->dev_recv != NULL) + { + +#if (USBCFG_DEV_BUFF_PROPERTY_CACHEABLE) + if (size > 0) + { + OS_dcache_invalidate_mlines((void*)buff_ptr, size); + } +#endif + error = (usb_dev_ptr->usb_dev_interface)->dev_recv(usb_dev_ptr->controller_handle, xd_ptr); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_recv_data: DEV_RECV is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + if (error) + { + return USBERR_RX_FAILED; + } /* Endif */ + + return error; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_send_data + * Returned Value : USB_OK or error code + * Comments : + * Sends data on a specified endpoint. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_send_data +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] buffer to send */ + uint8_t * buff_ptr, + /* [IN] length of the transfer */ + uint32_t size +) +{ /* Body */ + usb_status error; + xd_struct_t* xd_ptr; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_send_data: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + if ((usb_dev_ptr->usb_dev_interface)->dev_get_xd != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_get_xd(usb_dev_ptr->controller_handle, &xd_ptr); + + if (USB_OK != error) + { +#if _DEBUG + USB_PRINTF("usb_device_send_data: DEV_GET_XD failed\n"); +#endif + return USBERR_ERROR; + } + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_send_data: DEV_GET_XD is NULL\n"); +#endif + return USBERR_ERROR; + } + + OS_Mutex_lock(usb_dev_ptr->mutex); + + /* Initialize the new transfer descriptor */ + xd_ptr->ep_num = ep_num; + xd_ptr->bdirection = USB_SEND; + xd_ptr->wtotallength = size; + xd_ptr->wstartaddress = buff_ptr; + xd_ptr->wsofar = 0; + xd_ptr->bstatus = USB_STATUS_TRANSFER_ACCEPTED; + + if ((usb_dev_ptr->usb_dev_interface)->dev_send != NULL) + { +#if (USBCFG_DEV_BUFF_PROPERTY_CACHEABLE) + if (size > 0) + { + /******************************************************** + If system has a data cache, it is assumed that buffer + passed to this routine will be aligned on a cache line + boundary. The following code will flush the + buffer before passing it to hardware driver. + ********************************************************/ + OS_dcache_flush_mlines((void*)buff_ptr, size); + } +#endif + error = (usb_dev_ptr->usb_dev_interface)->dev_send(usb_dev_ptr->controller_handle, xd_ptr); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_send_data: DEV_SEND is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + if (error) + { +#if _DEBUG + USB_PRINTF("usb_device_send_data, transfer failed\n"); +#endif + return USBERR_TX_FAILED; + } + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_unstall_endpoint + * Returned Value : USB_OK or error code + * Comments : + * Unstalls the endpoint in specified direction + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_unstall_endpoint +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] direction */ + uint8_t direction +) +{ + usb_status error = USB_OK; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_unstall_endpoint: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + OS_Mutex_lock(usb_dev_ptr->mutex); + + if ((usb_dev_ptr->usb_dev_interface)->dev_unstall_endpoint != NULL) + { + error= (usb_dev_ptr->usb_dev_interface)->dev_unstall_endpoint(usb_dev_ptr->controller_handle, ep_num, direction); + } + else + { + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + OS_Mutex_unlock(usb_dev_ptr->mutex); + return error; +} /* EndBody */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_stall_endpoint + * Returned Value : USB_OK or error code + * Comments : + * Stalls the endpoint. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_stall_endpoint +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] direction */ + uint8_t direction +) +{ + usb_status error = 0; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_stall_endpoint: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + if ((usb_dev_ptr->usb_dev_interface)->dev_stall_endpoint + != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_stall_endpoint(usb_dev_ptr->controller_handle, + ep_num, direction); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_stall_endpoint: DEV_STALL_ENDPOINT is NULL\n"); +#endif + error = USBERR_ERROR; + } + + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_register_application_notify + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_register_application_notify +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + usb_device_notify_t device_notify_callback, + void* device_notify_param +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error = USB_OK; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_register_application_notify: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + usb_dev_ptr->usb_framework.device_notify_callback = device_notify_callback; + usb_dev_ptr->usb_framework.device_notify_param = device_notify_param; + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_register_vendor_class_request_notify + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_register_vendor_class_request_notify +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + usb_request_notify_t request_notify_callback, + void* request_notify_param +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error = USB_OK; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_register_vendor_class_request_notify: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + usb_dev_ptr->usb_framework.request_notify_callback = request_notify_callback; + usb_dev_ptr->usb_framework.request_notify_param = request_notify_param; + + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_register_desc_request_notify + * Returned Value : USB_OK or error code + * Comments : + * + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_register_desc_request_notify +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + usb_desc_request_notify_struct_t* desc_request_notify_callback, + void* desc_request_notify_param +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error = USB_OK; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_register_desc_request_notify\n"); +#endif + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + usb_dev_ptr->usb_framework.desc_notify_callback = desc_request_notify_callback; + usb_dev_ptr->usb_framework.desc_notify_param = desc_request_notify_param; + + return error; +} +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_cancel_transfer + * Returned Value : USB_OK or error code + * Comments : + * returns the status of the transaction on the specified endpoint. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_cancel_transfer +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle, + /* [IN] the Endpoint number */ + uint8_t ep_num, + /* [IN] direction */ + uint8_t direction +) +{ + uint8_t error = USB_OK; + usb_dev_state_struct_t* usb_dev_ptr; + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("_usb_device_shutdowna: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + OS_Mutex_lock(usb_dev_ptr->mutex); + + /* Cancel transfer on the specified endpoint for the specified + ** direction + */ + if ((usb_dev_ptr->usb_dev_interface)->dev_cancel_transfer != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_cancel_transfer(usb_dev_ptr->controller_handle, + ep_num, direction); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_cancel_transfer: dev_cancel_transfer is NULL\n"); +#endif + OS_Mutex_unlock(usb_dev_ptr->mutex); + return USBERR_ERROR; + } + + OS_Mutex_unlock(usb_dev_ptr->mutex); + + return error; +} +#endif + +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_process_resume + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_assert_resume +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle +) +{ + usb_dev_state_struct_t* usb_dev_ptr; + usb_status error = USB_OK; + + if (handle == NULL) + { +#if _DEBUG + USB_PRINTF("usb_device_assert_resume: handle is NULL\n"); +#endif + return USBERR_ERROR; + } + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + if ((usb_dev_ptr->usb_dev_interface)->dev_assert_resume != NULL) + { + error= (usb_dev_ptr->usb_dev_interface)->dev_assert_resume(usb_dev_ptr->controller_handle); + } + else + { +#if _DEBUG + USB_PRINTF("usb_device_assert_resume: dev_assert_resume is NULL\n"); +#endif + error = USBERR_ERROR; + } + + return error; +} +#endif + +#ifdef USBCFG_OTG +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_otg_init + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_otg_init +( + usb_device_handle handle, + uint8_t otg_attributes +) +{ + usb_status error; + usb_khci_dev_state_struct_t* khci_dev_state_ptr; + if (handle == NULL) + { + return USBERR_ERROR; + } + khci_dev_state_ptr = (usb_khci_dev_state_struct_t*)((usb_dev_state_struct_t*)handle)->controller_handle; + khci_dev_state_ptr->otg_attr_srp = (otg_attributes & OTG_SRP_SUPPORT)?(TRUE):(FALSE); + khci_dev_state_ptr->otg_attr_hnp = (otg_attributes & OTG_HNP_SUPPORT)?(TRUE):(FALSE); + error = usb_otg_device_on_class_init(khci_dev_state_ptr->otg_handle, handle , otg_attributes ); + + return error; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_otg_get_hnp_support + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_otg_get_hnp_support +( + usb_device_handle handle, + uint8_t* hnp_support_ptr +) +{ + usb_khci_dev_state_struct_t* khci_dev_state_ptr; + + if (handle == NULL) + { + *hnp_support_ptr = 0; + return USBERR_ERROR; + } + khci_dev_state_ptr = (usb_khci_dev_state_struct_t*)((usb_dev_state_struct_t*)handle)->controller_handle; + *hnp_support_ptr = khci_dev_state_ptr->otg_attr_hnp; + return USB_OK; +} + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_otg_set_hnp_enable + * Returned Value : USB_OK or error code + * Comments : + * Process Resume event + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_otg_set_hnp_enable +( + usb_device_handle handle +) +{ + usb_khci_dev_state_struct_t* khci_dev_state_ptr; + if (handle == NULL) + { + return USBERR_ERROR; + } + khci_dev_state_ptr = (usb_khci_dev_state_struct_t*)((usb_dev_state_struct_t*)handle)->controller_handle; + return usb_otg_device_hnp_enable(khci_dev_state_ptr->otg_handle, TRUE); +} +#endif /* USBCFG_OTG */ + +/*FUNCTION*------------------------------------------------------------- + * + * Function Name : usb_device_reset + * Returned Value : USB_OK or error code + * Comments : + * reset device. + * + *END*-----------------------------------------------------------------*/ +usb_status usb_device_reset +( + /* [IN] the USB_USB_dev_initialize state structure */ + usb_device_handle handle +) +{ + usb_status error = USB_OK; + usb_dev_state_struct_t* usb_dev_ptr; + + if (handle == NULL) + { + return USBERR_ERROR; + } + + usb_dev_ptr = (usb_dev_state_struct_t*)handle; + + if ((usb_dev_ptr->usb_dev_interface)->dev_reset != NULL) + { + error = (usb_dev_ptr->usb_dev_interface)->dev_reset(usb_dev_ptr->controller_handle); + } + else + { +#if _DEBUG + //USB_PRINTF("usb_device_reset: dev_reset is NULL\n"); +#endif + return USBERR_ERROR; + } + + return error; +} /* EndBody */ +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.h b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.h new file mode 100644 index 0000000..254ca83 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_dev.h @@ -0,0 +1,136 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_dev.h$ +* $Version : +* $Date : +* +* Comments: +* +* This file contains the declarations specific to the USB Device API +* +*END*********************************************************************/ +#ifndef __USB_DEV_H__ +#define __USB_DEV_H__ 1 + +#include "usb_framework.h" +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + +#undef USBCFG_DEV_USE_TASK +#define USBCFG_DEV_USE_TASK 0 + +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + +#undef USBCFG_DEV_USE_TASK +#define USBCFG_DEV_USE_TASK 1 + +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) +#if USE_RTOS +#define USBCFG_DEV_USE_TASK 1 +#else +#define USBCFG_DEV_USE_TASK 0 +#endif + +#endif +#define MAX_DEVICE_SERVICE_NUMBER 8 + +/* Callback function storage structure */ +typedef struct service_struct +{ + usb_event_service_t service; + void* arg; + uint8_t type; +} service_struct_t; + +typedef struct usb_dev_interface_functions_struct +{ + /* The Host/Device init function */ + usb_status (_CODE_PTR_ dev_preint)(usb_device_handle upper_layer_handle, usb_device_handle *handle_ptr); + + /* The Host/Device init function */ + usb_status (_CODE_PTR_ dev_init)(uint8_t controller_id, usb_device_handle handle); + + /* The Host/Device init function */ + usb_status (_CODE_PTR_ dev_postinit)( uint8_t controller_id, usb_device_handle handle); + + /* The function to send data */ + usb_status (_CODE_PTR_ dev_send)(usb_device_handle handle, xd_struct_t* xd); + + /* The function to receive data */ + usb_status (_CODE_PTR_ dev_recv)(usb_device_handle handle, xd_struct_t* xd); +#if USBCFG_DEV_ADVANCED_CANCEL_ENABLE + /* The function to cancel the transfer */ + usb_status (_CODE_PTR_ dev_cancel_transfer)(usb_device_handle handle, uint8_t ep_num, uint8_t direction); +#endif + + usb_status (_CODE_PTR_ dev_init_endoint)(usb_device_handle handle, xd_struct_t* xd); + + usb_status (_CODE_PTR_ dev_deinit_endoint)(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + + usb_status (_CODE_PTR_ dev_unstall_endpoint)(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + + usb_status (_CODE_PTR_ dev_get_endpoint_status)(usb_device_handle handle, uint8_t component, uint16_t *endp_status); + + usb_status (_CODE_PTR_ dev_set_endpoint_status)(usb_device_handle handle, uint8_t component, uint16_t endp_status); + + usb_status (_CODE_PTR_ dev_get_transfer_status)(usb_device_handle handle, uint8_t component, uint8_t status); + + usb_status (_CODE_PTR_ dev_set_address)(usb_device_handle handle, uint8_t addr); + + usb_status (_CODE_PTR_ dev_shutdown)(usb_device_handle handle); + + usb_status (_CODE_PTR_ dev_get_setup_data)(usb_device_handle handle, uint8_t component, uint8_t *data); +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME + usb_status (_CODE_PTR_ dev_assert_resume)(usb_device_handle handle); +#endif + + usb_status (_CODE_PTR_ dev_stall_endpoint)(usb_device_handle handle, uint8_t ep_num, uint8_t direction); + + usb_status (_CODE_PTR_ dev_set_device_status)(usb_device_handle handle, uint8_t component, uint16_t setting); + + usb_status (_CODE_PTR_ dev_get_device_status)(usb_device_handle handle, uint8_t component, uint16_t *error); + + usb_status (_CODE_PTR_ dev_get_xd)(usb_device_handle handle, xd_struct_t** xd); + + usb_status (_CODE_PTR_ dev_reset)(usb_device_handle handle); +} usb_dev_interface_functions_struct_t; + +typedef struct usb_dev_state_struct +{ + usb_device_handle controller_handle; + const usb_dev_interface_functions_struct_t* usb_dev_interface; +#if USBCFG_DEV_USE_TASK + os_msgq_handle usb_dev_service_que; + uint32_t task_id; +#endif + usb_class_fw_object_struct_t usb_framework; + service_struct_t services[MAX_DEVICE_SERVICE_NUMBER]; + os_mutex_handle mutex; + uint8_t occupied; + uint8_t controller_id; /* Device controller ID */ + uint8_t dev_index; +} usb_dev_state_struct_t; + +#endif +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.c b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.c new file mode 100644 index 0000000..9017a11 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.c @@ -0,0 +1,1295 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 - 2015 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_framework.c$ + * $Version : + * $Date : + * + * Comments: + * + * @brief The file contains USB stack framework module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_device_config.h" +#if USBCFG_DEV_KHCI || USBCFG_DEV_EHCI +#include "usb.h" +#include "usb_device_stack_interface.h" +#include "usb_framework.h" + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +//usb_class_fw_object_struct_t* usb_class_fw_object[USB_MAX_CLASS_FW_OBJECT]; +#ifdef DELAYED_PROCESSING +usb_event_struct_t g_f_event; +bool g_control_pending=FALSE; +#endif +#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX)) +static bool g_validate_request[MAX_STRD_REQ][3] = +#else +static uint8_t g_validate_request[MAX_STRD_REQ][3] = +#endif + +{ + {1, 1, 0,}, /*USB_Strd_Req_Get_Status*/ + /* configured state: valid for existing interfaces/endpoints + address state : valid only for interface or endpoint 0 + default state : not specified + */ + {1, 1, 0,}, /* Clear Feature */ + /* configured state: valid only for device in configured state + address state : valid only for device (in address state), + interface and endpoint 0 + default state : not specified + */ + {0, 0, 0,}, /*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ +#ifdef USBCFG_OTG + {1, 1, 1,}, /* Set Feature */ + /* configured state: valid only for device in configured state + address state : valid only for interface or endpoint 0 + default state : not specified + */ +#else + {1, 1, 0,}, /* Set Feature */ + /* configured state: valid only for device in configured state + address state : valid only for interface or endpoint 0 + default state : not specified + */ +#endif + {0, 0, 0,},/*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {0, 1, 1,}, /*USB_Strd_Req_Set_Address*/ + /* configured state: not specified + address state : changes to default state if specified addr == 0, + but uses newly specified address + default state : changes to address state if specified addr != 0 + */ + {1, 1, 1,}, /*USB_Strd_Req_Get_Descriptor*/ + /* configured state: valid request + address state : valid request + default state : valid request + */ + {0, 0, 0,}, /*Set Descriptor*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {1, 1, 0,}, /*USB_Strd_Req_Get_Config*/ + /* configured state: bConfiguration Value of current config returned + address state : value zero must be returned + default state : not specified + */ + {1, 1, 0,}, /*USB_Strd_Req_Set_Config*/ + /* configured state: If the specified configuration value is zero, + then the device enters the Address state.If the + specified configuration value matches the + configuration value from a config descriptor, + then that config is selected and the device + remains in the Configured state. Otherwise, the + device responds with a Request Error. + + address state : If the specified configuration value is zero, + then the device remains in the Address state. If + the specified configuration value matches the + configuration value from a configuration + descriptor, then that configuration is selected + and the device enters the Configured state. + Otherwise,response is Request Error. + default state : not specified + */ + {1, 0, 0,}, /*USB_Strd_Req_Get_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {1, 0, 0,}, /*USB_Strd_Req_Set_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {1, 0, 0,}, /*USB_Strd_Req_Sync_Frame*/ + /* configured state: valid request + address state : request error + default state : not specified + */ +}; + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ +usb_class_fw_handle USB_Framework_Init( usb_device_handle handle, /*[IN]*/ +usb_device_notify_t class_callback,/*[IN]*/ +usb_request_notify_t other_req_callback,/*[IN]*/ +void* callback_data,/*[IN]*/ +int32_t data,/*[IN]*/ +usb_desc_request_notify_struct_t* desc_callback_ptr /*[IN]*/); +uint8_t USB_Framework_Deinit( usb_device_handle handle, /*[IN]*/ +usb_class_fw_handle fw_handle /*[IN]*/); +uint8_t USB_Framework_Reset(usb_device_handle handle); +void USB_Control_Service (void* handle, usb_event_struct_t* event,void* arg ); +void USB_Control_Service_Handler( usb_class_fw_object_struct_t* usb_fw_ptr, +uint8_t error, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); + +static uint8_t USB_Strd_Req_Get_Status(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Feature(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Set_Address(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Assign_Address(usb_class_fw_object_struct_t* usb_fw_ptr); +static uint8_t USB_Strd_Req_Get_Config(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Set_Config(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Get_Interface(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Set_Interface(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Sync_Frame(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); +static uint8_t USB_Strd_Req_Get_Descriptor(usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size); + +#ifdef DELAYED_PROCESSING +void USB_Control_Service_Callback( usb_event_struct_t* event,void* arg ); +#endif + +extern usb_status usb_device_set_address(usb_device_handle handle, uint8_t address); +extern usb_status usb_device_reset(usb_device_handle handle); + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +static USB_FW_REQ_FUNC g_standard_request[MAX_STRD_REQ] = +{ + USB_Strd_Req_Get_Status, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Set_Address, + USB_Strd_Req_Get_Descriptor, + NULL, + USB_Strd_Req_Get_Config, + USB_Strd_Req_Set_Config, + USB_Strd_Req_Get_Interface, + USB_Strd_Req_Set_Interface, + USB_Strd_Req_Sync_Frame +}; + +#ifdef DELAYED_PROCESSING +/**************************************************************************//*! + * + * @name USB_Framework_Periodic_Task + * + * @brief The function is called to respond to any control request + * + * @param None + * + * @return None + * + *****************************************************************************/ +static void USB_Framework_Periodic_Task +( +void +) +{ + /* if control request pending to be completed */ + if (g_control_pending==TRUE) + { /* handle pending control request */ + USB_Control_Service(&g_f_event); + g_control_pending=FALSE; + } +} + +/**************************************************************************//*! + * + * @name USB_Control_Service_Callback + * + * @brief The function can be used as a callback function to the service. + * + * @param event: from Service callback function + * + * @return None + * + *****************************************************************************/ +static void USB_Control_Service_Callback +( +usb_event_struct_t* event, +void* arg +) +{ + UNUSED_ARGUMENT(arg) + /* save the event parameters */ + g_f_event.buffer_ptr = event->buffer_ptr; + g_f_event.handle = event->handle; + g_f_event.ep_num = event->ep_num; + g_f_event.setup = event->setup; + g_f_event.len = event->len; + g_f_event.errors = event->errors; + + /* set the pending request flag */ + g_control_pending=TRUE; +} +#endif + +/**************************************************************************//*! + * + * @name USB_Framework_Reset + * + * @brief The function resets the framework + * + * @param handle: handle to Identify the controller + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +uint8_t USB_Framework_Reset +( +usb_device_handle handle +) +{ + //UNUSED_ARGUMENT(handle) + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Control_Service + * + * @brief Called upon a completed endpoint 0 (USB 1.1 Chapter 9) transfer + * + * @param event: from Service callback function + * + * @return None + * + *****************************************************************************/ +void USB_Control_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + uint16_t device_state = 0; + uint8_t error = USBERR_INVALID_REQ_TYPE; + uint8_t * data = NULL; + uint32_t size; + usb_class_fw_object_struct_t* usb_fw_ptr; + + usb_fw_ptr = (usb_class_fw_object_struct_t*)handle; + + /* get the device state */ + (void)usb_device_get_status(usb_fw_ptr->dev_handle, (uint8_t)USB_STATUS_DEVICE_STATE, + &device_state); + //USB_PRINTF("USB_Control_Service ++ \n"); + if (event->setup == TRUE) + { + OS_Mem_copy(event->buffer_ptr,&usb_fw_ptr->setup_packet,USB_SETUP_PKT_SIZE); + + /* take care of endianness of the 16 bit fields correctly */ + usb_fw_ptr->setup_packet.index = USB_SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.index); + usb_fw_ptr->setup_packet.value = USB_SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.value); + usb_fw_ptr->setup_packet.length = USB_SHORT_LE_TO_HOST(usb_fw_ptr->setup_packet.length); + // USB_PRINTF("00++ Enter ++ type:%d \n",usb_fw_ptr->setup_packet.request_type); + /* if the request is standard request */ + if ((usb_fw_ptr->setup_packet.request_type & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_POS) == + USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_STANDARD) + { + // USB_PRINTF("11++ Enter ++ :%d \n",usb_fw_ptr->setup_packet.request); + /* if callback is not NULL */ + if (g_standard_request[usb_fw_ptr->setup_packet.request] != NULL) + { + // USB_PRINTF("22++ Enter ++ :%d \n",usb_fw_ptr->setup_packet.request); + /* if the request is valid in this device state */ + if((device_state < USB_STATE_POWERED) && + (g_validate_request[usb_fw_ptr->setup_packet.request][device_state] + == (uint8_t)1)) + { + /* Standard Request function pointers */ + error = g_standard_request[usb_fw_ptr->setup_packet.request] + (usb_fw_ptr,&usb_fw_ptr->setup_packet,&data,&size); + } + } + } + else /* for Class/Vendor requests */ + { + /*get the length from the setup_request*/ + size = usb_fw_ptr->setup_packet.length; + + if( (size != 0) && + ((usb_fw_ptr->setup_packet.request_type & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_DIR_OUT) + ) + { + /* we have gone for one time memory allocation of ext_req_to_host + to avoid memory fragmentation, as there was memory crunch in + some of our Socs. */ + if((size + USB_SETUP_PKT_SIZE) > MAX_EXPECTED_CONTROL_OUT_SIZE) + { +#if _DEBUG + USB_PRINTF("MAX_EXPECTED_CONTROL_OUT_SIZE insufficient, needed %d\n", size + USB_SETUP_PKT_SIZE); + USB_PRINTF("Please change the macro!!!\n"); +#endif + usb_device_stall_endpoint(usb_fw_ptr->dev_handle,USB_CONTROL_ENDPOINT,USB_RECV); + return; + } + + /* copy setup token to ext_req_to_host */ + OS_Mem_copy(&usb_fw_ptr->setup_packet, usb_fw_ptr->ext_req_to_host, + USB_SETUP_PKT_SIZE); + /* expecting host to send data (OUT TRANSACTION)*/ + (void)usb_device_recv_data(event->handle, + USB_CONTROL_ENDPOINT,(usb_fw_ptr->ext_req_to_host+USB_SETUP_PKT_SIZE), + (uint32_t)(size)); + return; + } + /*call class/vendor request*/ + else if(usb_fw_ptr->request_notify_callback != NULL) + { + // USB_PRINTF("USB_Control_Service_Handler ++ #### \n"); + error = usb_fw_ptr->request_notify_callback( + &usb_fw_ptr->setup_packet,&data,&size,usb_fw_ptr->request_notify_param); + } + } + USB_Control_Service_Handler(usb_fw_ptr,error,&usb_fw_ptr->setup_packet, + &data,&size); + } + else if(device_state == USB_STATE_PENDING_ADDRESS) + { + /* Device state is PENDING_ADDRESS */ + /* Assign the new address to the Device */ + //USB_PRINTF("send ZLT done\n"); + (void)USB_Strd_Req_Assign_Address(usb_fw_ptr); + } + else if( ((usb_fw_ptr->setup_packet.request_type & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_DIR_OUT) && + (event->direction == USB_RECV) && + (usb_fw_ptr->setup_packet.length) + ) + { + /* execution enters Control Service because of + OUT transaction on USB_CONTROL_ENDPOINT*/ + if(usb_fw_ptr->request_notify_callback != NULL) + { + /* class or vendor request */ + size = event->len+USB_SETUP_PKT_SIZE; + error = usb_fw_ptr->request_notify_callback( + (usb_setup_struct_t*) usb_fw_ptr->ext_req_to_host, + &data,&size,usb_fw_ptr->request_notify_param); + } + /* if it is called by usb_dci_khci_cancel() in the reset procedure, there is no need to to prime the endpoint*/ + if(event->len != 0xFFFFFFFF) + { + USB_Control_Service_Handler(usb_fw_ptr,error,&usb_fw_ptr->setup_packet, + &data,&size); + } + } + return; +} + +/**************************************************************************//*! + * + * @name USB_Reset_Service + * + * @brief The function is called upon a bus reset event. + Initializes the control endpoint. + * + * @param event: for Service callback function + * + * @return None + *****************************************************************************/ +void USB_Reset_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + usb_ep_struct_t ep_struct; + volatile usb_class_fw_object_struct_t* usb_fw_ptr; + void* temp; + + usb_fw_ptr = (usb_class_fw_object_struct_t*)handle; + + usb_device_reset(usb_fw_ptr->dev_handle); + + /* Initialize the endpoint 0 in both directions */ + ep_struct.direction = USB_RECV; + ep_struct.ep_num = USB_CONTROL_ENDPOINT; + ep_struct.size = CONTROL_MAX_PACKET_SIZE; + ep_struct.type = USB_CONTROL_PIPE; + + usb_device_init_endpoint(event->handle, &ep_struct, TRUE); + + ep_struct.direction = USB_SEND; + usb_device_init_endpoint(event->handle, &ep_struct, TRUE); + temp = usb_fw_ptr->device_notify_param; + /* let the application know that bus reset has taken place */ + if (usb_fw_ptr->device_notify_callback != NULL) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_BUS_RESET,NULL,temp); + } + + return; +} + +#if USBCFG_DEV_DETACH_ENABLE +/**************************************************************************//*! + * + * @name USB_Detach_Service + * + * @brief The function is called upon a bus reset event. + Initializes the control endpoint. + * + * @param event: for Service callback function + * + * @return None + *****************************************************************************/ +void USB_Detach_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + volatile usb_class_fw_object_struct_t* usb_fw_ptr; + + usb_fw_ptr = (usb_class_fw_object_struct_t*)handle; + + usb_device_reset(usb_fw_ptr->dev_handle); + + /* let the application know that bus reset has taken place */ + if (usb_fw_ptr->device_notify_callback != NULL) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_DETACH, NULL, usb_fw_ptr->device_notify_param); + } + + return; +} +#endif + +#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING +/**************************************************************************//*! + * + * @name USB_Error_Service + * + * @brief The function is called when an error has been detected + * + * @param event: for Service callback function + * + * @return None + *****************************************************************************/ +void USB_Error_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + volatile usb_class_fw_object_struct_t* usb_fw_ptr; + + usb_fw_ptr = (usb_class_fw_object_struct_t*)handle; + + /* notify the application of the error */ + if (usb_fw_ptr->device_notify_callback != NULL) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_ERROR,event->buffer_ptr,usb_fw_ptr->device_notify_param); + } + return; +} +#endif + +#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME +/**************************************************************************//*! + * + * @name USB_Suspend_Service + * + * @brief The function is called when host suspends the USB port + * + * @param event: for Service callback function + * + * @return None + *****************************************************************************/ +void USB_Suspend_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + UNUSED_ARGUMENT(handle) + UNUSED_ARGUMENT(event) + UNUSED_ARGUMENT(arg) + return; +} + +/**************************************************************************//*! + * + * @name USB_Resume_Service + * + * @brief The function is called when host resumes the USB port + * + * @param event: for Service callback function + * + * @return None + *****************************************************************************/ +void USB_Resume_Service +( +void* handle, +usb_event_struct_t* event, +void* arg +) +{ + UNUSED_ARGUMENT(handle) + UNUSED_ARGUMENT(event) + UNUSED_ARGUMENT(arg) + return; +} +#endif + +/**************************************************************************//*! + * + * @name USB_Control_Service_Handler + * + * @brief The function is used to send a response to the Host based. + * + * @param status: status of Device e.g USB_OK,USBERR_INVALID_REQ_TYPE + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return None + * + *****************************************************************************/ +void USB_Control_Service_Handler +( +usb_class_fw_object_struct_t* usb_fw_ptr, +uint8_t error, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + if (error == USBERR_INVALID_REQ_TYPE) + { + uint8_t direction = USB_SEND; + uint8_t ep_num = USB_CONTROL_ENDPOINT; + + usb_device_stall_endpoint(usb_fw_ptr->dev_handle,ep_num,direction); + } + else /* Need to send Data to the USB Host */ + { + /* send the data prepared by the handlers.*/ + if (*size > setup_packet->length) + { + *size = setup_packet->length; + } + + /* send the data to the host */ + (void)usb_device_send_data(usb_fw_ptr->dev_handle,USB_CONTROL_ENDPOINT, *data, *size); + //USB_PRINTF("send %d to host\n", *size); + + if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_DIR_IN) + { + /* Request was to Get Data from device */ + /* setup recv to get status from host */ + (void)usb_device_recv_data(usb_fw_ptr->dev_handle, + USB_CONTROL_ENDPOINT,NULL,0); + //USB_PRINTF("ready to receive ZLT on EP0\n"); + } + } + return; +} +/*************************************************************************//*! + * + * @name USB_Strd_Req_Get_Status + * + * @brief This function is called in response to Get Status request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Get_Status +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + uint8_t endpoint; + uint8_t error = USBERR_ERROR; + + if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_DEVICE) + { /* request for Device */ +#ifdef USBCFG_OTG + if(setup_packet->index == USB_WINDEX_OTG_STATUS_SEL) + { + uint8_t hnp_support; + (void)usb_device_otg_get_hnp_support(usb_fw_ptr->dev_handle, &hnp_support); + if(hnp_support) + { + error = usb_device_get_status(usb_fw_ptr->dev_handle, + (uint8_t)USB_STATUS_OTG, &usb_fw_ptr->std_framework_data); + usb_fw_ptr->std_framework_data &= GET_STATUS_OTG_MASK; + usb_fw_ptr->std_framework_data = USB_SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data); + *size=OTG_STATUS_SIZE; + } + else + { + error = USBERR_INVALID_REQ_TYPE; + } + } + else +#endif + { + error = usb_device_get_status(usb_fw_ptr->dev_handle, + (uint8_t)USB_STATUS_DEVICE, &usb_fw_ptr->std_framework_data); + usb_fw_ptr->std_framework_data &= GET_STATUS_DEVICE_MASK; + usb_fw_ptr->std_framework_data = USB_SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data); + *size=DEVICE_STATUS_SIZE; + } + } + else if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_INTERFACE) + { /* request for Interface */ + usb_fw_ptr->std_framework_data = 0; + *size=INTERFACE_STATUS_SIZE; + } + else if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { /* request for Endpoint */ + endpoint =(uint8_t)(((uint8_t)setup_packet->index)|USB_STATUS_ENDPOINT); + error = usb_device_get_status(usb_fw_ptr->dev_handle, + (uint8_t)endpoint, + &usb_fw_ptr->std_framework_data); + usb_fw_ptr->std_framework_data = USB_SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data); + *size=ENDP_STATUS_SIZE; + } + + *data = (uint8_t *)&usb_fw_ptr->std_framework_data; + return error; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Feature + * + * @brief This function is called in response to Clear or Set Feature request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Feature +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + //uint16_t device_status; + uint16_t set_request; + uint8_t error=USBERR_INVALID_REQ_TYPE; + uint8_t epinfo; + uint8_t event; + uint8_t feature; +#if USBCFG_DEV_EHCI && USBCFG_DEV_EHCI_TEST_MODE + uint16_t ptc = 0; + volatile uint32_t loop = 10*1000*1000; +#endif + + //UNUSED_ARGUMENT(data) + *size=0; + /* find whether its a clear feature request or a set feature request */ + set_request = (uint16_t)((uint16_t)(setup_packet->request & USB_SET_REQUEST_MASK)>>1); + + if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_DEVICE) + { +#ifdef USBCFG_OTG + if (set_request) + { + if ((setup_packet->value == USB_DEV_REQ_STD_FEATURE_B_HNP_ENABLE) || (setup_packet->value == USB_DEV_REQ_STD_FEATURE_A_HNP_SUPPORT)) + { + uint8_t hnp_support; + (void)usb_device_otg_get_hnp_support(usb_fw_ptr->dev_handle, &hnp_support); + if (hnp_support) + { + error = USB_OK; + if (setup_packet->value == USB_DEV_REQ_STD_FEATURE_B_HNP_ENABLE) + { + (void)usb_device_otg_set_hnp_enable(usb_fw_ptr->dev_handle); + } + } + else + { + error = USBERR_INVALID_REQ_TYPE; + } + } + } +#endif + /* request for Device */ + feature = setup_packet->value & USB_DEV_REQ_STD_FEATURE_SELECTOR_MASK; + if (feature) + { + if (feature == USB_DEV_REQ_STD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP) + { + if (set_request == (uint16_t)TRUE) + { + event = USB_DEV_EVENT_TYPE_SET_REMOTE_WAKEUP; + } + else + { /* remove the request to be cleared from device_status */ + event = USB_DEV_EVENT_TYPE_CLR_REMOTE_WAKEUP; + } + error = USB_OK; + if (usb_fw_ptr->device_notify_callback) + { + usb_fw_ptr->device_notify_callback(event, NULL, usb_fw_ptr->request_notify_param); + } + } + else if (feature == USB_DEV_REQ_STD_FEATURE_SELECTOR_TEST_MODE) + { +#if USBCFG_DEV_EHCI && USBCFG_DEV_EHCI_TEST_MODE + (void)usb_device_send_data(usb_fw_ptr->dev_handle,USB_CONTROL_ENDPOINT, NULL, 0); + /* need add some delay to wait for zero length packet is sent complete */ + while(loop --) + { + ; + } + ptc = setup_packet->index >> 8; + usb_device_set_status(usb_fw_ptr->dev_handle, USB_STATUS_TEST_MODE, ptc); + error = USB_OK; +#endif + } + } + else + { + /* TODO */ + /* if the feature is 0, a request error need to be sent out*/ + + } + } + else if ((setup_packet->request_type & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS) == USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { + /* request for Endpoint */ + feature = setup_packet->value & USB_DEV_REQ_STD_FEATURE_SELECTOR_MASK; + if (feature == 0) + { + epinfo = (uint8_t)(setup_packet->index & 0x00FF); + if(set_request) + { + event = USB_DEV_EVENT_TYPE_SET_EP_HALT; + error = usb_device_stall_endpoint(usb_fw_ptr->dev_handle,epinfo & 0x0F, (uint8_t)(epinfo & 0x80) >> 7); + } + else + { + event = USB_DEV_EVENT_TYPE_CLR_EP_HALT; + if ((epinfo & 0x0f) == 0) + { + error = usb_device_unstall_endpoint(usb_fw_ptr->dev_handle,epinfo & 0x0F, (uint8_t)(epinfo & 0x80) >> 7); + } + } + if(usb_fw_ptr->device_notify_callback) + { + usb_fw_ptr->device_notify_callback(event, (void*)&epinfo, usb_fw_ptr->request_notify_param); + error = USB_OK; + } + } + else + { + /* TODO */ + /* if feature is not 0, request error need to be sent out */ + } + + } + return error; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Address + * + * @brief This function is called in response to Set Address request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Set_Address +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + //UNUSED_ARGUMENT(data) + *size=0; + /* update device state */ + (void)usb_device_set_status(usb_fw_ptr->dev_handle, + (uint8_t)USB_STATUS_DEVICE_STATE, + (uint16_t)USB_STATE_PENDING_ADDRESS); + /*store the address from setup_packet into assigned_address*/ + usb_fw_ptr->assigned_address = setup_packet->value; + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Assign_Address + * + * @brief This function assigns the address to the Device + * + * @param handle + * + * @return status + * USB_OK: Always + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Assign_Address +( +usb_class_fw_object_struct_t* usb_fw_ptr +) +{ + /* Set Device Address */ + (void)usb_device_set_address(usb_fw_ptr->dev_handle, + (uint8_t)(usb_fw_ptr->assigned_address&0x00FF)); + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Config + * + * @brief This function is called in response to Get Config request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : Always + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Get_Config +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + //UNUSED_ARGUMENT(setup_packet) + + *size = CONFIG_SIZE; + usb_fw_ptr->cur_config = USB_SHORT_LE_TO_HOST(usb_fw_ptr->cur_config); + *data = (uint8_t *)(&usb_fw_ptr->cur_config); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Config + * + * @brief This function is called in response to Set Config request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Set_Config +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + uint8_t error = USBERR_INVALID_REQ_TYPE; + uint16_t config_val; + + uint16_t device_state = USB_STATE_CONFIG; + //UNUSED_ARGUMENT(data) + *size=0; + error = USB_STATUS_ERROR; + config_val = setup_packet->value; + + if (!config_val) /* if config_val is 0 */ + { + device_state = USB_STATE_ADDRESS; + } + + error = usb_device_set_status(usb_fw_ptr->dev_handle, + (uint8_t)USB_STATUS_DEVICE_STATE, + (uint16_t)device_state); + + usb_fw_ptr->cur_config = config_val; + /* Set configuration according to config number*/ + if(NULL != usb_fw_ptr->desc_notify_callback->set_configuration) + { + usb_fw_ptr->desc_notify_callback->set_configuration((uint32_t)usb_fw_ptr->desc_notify_param,(uint8_t)config_val); + } + /* callback to the app. to let the application know about the new Config */ + if (usb_fw_ptr->device_notify_callback != NULL) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_CONFIG_CHANGED, + (void *)&config_val,usb_fw_ptr->device_notify_param); + if(config_val) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_ENUM_COMPLETE,NULL, + usb_fw_ptr->device_notify_param); + } + } + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Interface + * + * @brief This function is called in response to Get Interface request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Get_Interface +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + uint8_t error = USBERR_NULL_CALLBACK; + + *size = INTERFACE_STATUS_SIZE; + + if(!usb_fw_ptr->desc_notify_callback->get_desc_interface) + { + return error; + } + + error = usb_fw_ptr->desc_notify_callback->get_desc_interface((uint32_t)(usb_fw_ptr->desc_notify_param), + (uint8_t)setup_packet->index, (uint8_t *)&usb_fw_ptr->std_framework_data); + usb_fw_ptr->std_framework_data = USB_SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data); + *data = (uint8_t *)&usb_fw_ptr->std_framework_data; + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Interface + * + * @brief This function is called in response to Set Interface request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : Always + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Set_Interface +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + uint8_t error = USBERR_NULL_CALLBACK; + //UNUSED_ARGUMENT(data) + *size=0; + + /* Request type not for interface */ + if ((setup_packet->request_type & 0x03) != 0x01) + { + return USB_STATUS_ERROR; + } + + if(!usb_fw_ptr->desc_notify_callback->set_desc_interface) + { + return error; + } + + /* Get Interface and alternate interface from setup_packet */ + error = usb_fw_ptr->desc_notify_callback->set_desc_interface((uint32_t)(usb_fw_ptr->desc_notify_param), + (uint8_t)setup_packet->index, (uint8_t)setup_packet->value); + + if (usb_fw_ptr->device_notify_callback != NULL) + { + usb_fw_ptr->device_notify_callback(USB_DEV_EVENT_INTERFACE_CHANGED, + (void *)&setup_packet->value, usb_fw_ptr->device_notify_param); + } + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Sync_Frame + * + * @brief This function is called in response to Sync Frame request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Sync_Frame +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + uint8_t error; + //UNUSED_ARGUMENT(setup_packet) + + *size=FRAME_SIZE; + /* Get the frame number */ + error = usb_device_get_status(usb_fw_ptr->dev_handle, + (uint8_t)USB_STATUS_SOF_COUNT, + &usb_fw_ptr->std_framework_data); + usb_fw_ptr->std_framework_data = USB_SHORT_LE_TO_HOST(usb_fw_ptr->std_framework_data); + *data= (uint8_t *)&usb_fw_ptr->std_framework_data; + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Std_Req_Get_Descriptor + * + * @brief This function is called in response to Get Descriptor request + * + * @param setup_packet: setup packet received + * @param data: data to be send back + * @param size: size to be returned + * + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Strd_Req_Get_Descriptor +( +usb_class_fw_object_struct_t* usb_fw_ptr, +usb_setup_struct_t * setup_packet, +uint8_t * *data, +uint32_t *size +) +{ + /*g_setup_packet.hValue*/ + uint8_t type = (uint8_t)(setup_packet->value >> 8) & 0xFF; + uint16_t index = (uint8_t)USB_UNINITIALIZED_VAL_32; + uint8_t str_num = (uint8_t)USB_UNINITIALIZED_VAL_32; + uint8_t error = USBERR_NULL_CALLBACK; + + /* for string descriptor set the language and string number */ + index = setup_packet->index; + /*g_setup_packet.lValue*/ + str_num = setup_packet->value & 0xFF; + + if(!usb_fw_ptr->desc_notify_callback->get_desc) + { + return error; + } + /* Call descriptor class to get descriptor */ + error = usb_fw_ptr->desc_notify_callback->get_desc((uint32_t)(usb_fw_ptr->desc_notify_param), + type,str_num,index,data,size); + + return error; +} +#if 0 +/**************************************************************************//*! + * + * @name USB_Framework_GetDesc + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param in_buff buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Framework_GetDesc +( +usb_class_fw_handle handle, /*[IN]*/ +int32_t cmd,/*[IN]*/ +uint8_t in_data,/*[IN]*/ +uint8_t * * in_buff/*[OUT]*/ +) +{ + return 0; +} + +/**************************************************************************//*! + * + * @name USB_Framework_SetDesc + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param outBuf buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +static uint8_t USB_Framework_SetDesc +( +usb_class_fw_handle handle,/*[IN]*/ +int32_t cmd,/*[IN]*/ +uint8_t input_data,/*[IN]*/ +uint8_t * * outBuf/*[IN]*/ +) +{ + return 0; +} + +/**************************************************************************//*! + * + * @name USB_Framework_Remote_wakeup + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param in_buff buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +bool USB_Framework_Remote_wakeup +( +usb_class_fw_handle handle +) +{ + return 0; +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.h b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.h new file mode 100644 index 0000000..e4362e5 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/device/sources/controller/usb_framework.h @@ -0,0 +1,188 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_framework.h$ +* $Version : +* $Date : +* +* Comments: +* +* @brief The file contains USB Framework module api header function. +* +*****************************************************************************/ + +#ifndef _USB_FRAMEWORK_H +#define _USB_FRAMEWORK_H 1 + +/****************************************************************************** + * Includes + *****************************************************************************/ + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_STRD_REQ (13) /* Max value of standard request */ +/* size of data to be returned for various Get Desc calls */ +#define DEVICE_STATUS_SIZE (2) +#define INTERFACE_STATUS_SIZE (1) +#define CONFIG_SIZE (1) +#define FRAME_SIZE (2) +#define ENDP_STATUS_SIZE (2) +#define USB_SET_REQUEST_MASK (0x02) +/* wIndex values for GET_Status */ +#define USB_WINDEX_OTG_STATUS_SEL (0xF000) +#define GET_STATUS_OTG_MASK (0x0001) +#define OTG_STATUS_SIZE (1) +/****************************************************************************** + * Types + *****************************************************************************/ +typedef uint32_t usb_class_fw_handle; + +/* Strucutre holding USB state information and handles.*/ +typedef struct _usb_class_fw_object +{ + uint16_t std_framework_data; + uint16_t assigned_address; + usb_device_handle controller_handle; + usb_device_handle dev_handle; + usb_setup_struct_t setup_packet; + uint8_t* ext_req_to_host; + usb_device_notify_t device_notify_callback; + void* device_notify_param; + usb_request_notify_t request_notify_callback; + void* request_notify_param; + usb_desc_request_notify_struct_t* desc_notify_callback; + void* desc_notify_param; + uint16_t cur_config; +}usb_class_fw_object_struct_t; + + /* callback function pointer structure to handle USB framework request */ +typedef uint8_t (_CODE_PTR_ USB_FW_REQ_FUNC)(usb_class_fw_object_struct_t* usb_fw_ptr, + usb_setup_struct_t * setup_packet, + uint8_t * *data, + uint32_t *size); + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Framework_Periodic_Task + * + * @brief The function is called to respond to any control request + * + * @param None + * + * @return None + * + *****************************************************************************/ +#ifdef DELAYED_PROCESSING +extern void USB_Framework_Periodic_Task(void); +#endif +/**************************************************************************//*! + * + * @name USB_Framework_Reset + * + * @brief The function resets the framework + * + * @param handle: handle to Identify the controller + * + * @return status + * USB_OK : When Successfully + * Others : Errors + * + *****************************************************************************/ +extern uint8_t USB_Framework_Reset +( + usb_device_handle handle /*[IN] the USB device controller to initialize*/ +); + +/**************************************************************************//*! + * + * @name USB_Framework_GetDesc + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param in_buff buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +uint8_t USB_Framework_GetDesc(usb_class_fw_handle handle, /*[IN]*/ +int32_t cmd,/*[IN]*/ +uint8_t in_data,/*[IN]*/ +uint8_t * * in_buff/*[OUT]*/ +); + +/**************************************************************************//*! + * + * @name USB_Framework_SetDesc + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param outBuf buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +uint8_t USB_Framework_SetDesc(usb_class_fw_handle handle,/*[IN]*/ +int32_t cmd,/*[IN]*/ +uint8_t input_data,/*[IN]*/ +uint8_t * * outBuf/*[IN]*/ +); +/**************************************************************************//*! + * + * @name USB_Framework_Remote_wakeup + * + * @brief This function is called in to get the descriptor as specified in cmd. + * + * @param handle: USB framework handle. Received from + * USB_Framework_Init + * @param cmd: command for USB descriptor to get. + * @param in_data: input to the Application functions. + * @param in_buff buffer which will contain the descriptors. + * @return status: + * USB_OK : When Successfully + * Others : When Error + * + *****************************************************************************/ +bool USB_Framework_Remote_wakeup(usb_class_fw_handle handle/*[IN]*/); + +#endif + +/* EOF */ diff --git a/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_features.h b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_features.h new file mode 100644 index 0000000..998258a --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_features.h @@ -0,0 +1,126 @@ +/* +** ################################################################### +** Version: rev. 1.0, 2015-01-16 +** Build: b150116 +** +** Abstract: +** Chip specific module features. +** +** Copyright (c) 2015 Freescale Semiconductor, Inc. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** +** Revisions: +** - rev. 1.0 (2015-01-16) +** Initial version. +** +** ################################################################### +*/ + +#if !defined(__FSL_USB_FEATURES_H__) +#define __FSL_USB_FEATURES_H__ + +#if defined(CPU_MK20DN512VLK10) || defined(CPU_MK20DX256VLK10) || defined(CPU_MK20DN512VLL10) || defined(CPU_MK20DX256VLL10) || \ + defined(CPU_MK20DX128VLQ10) || defined(CPU_MK20DX256VLQ10) || defined(CPU_MK20DN512VLQ10) || defined(CPU_MK20DX256VMC10) || \ + defined(CPU_MK20DN512VMC10) || defined(CPU_MK20DX128VMD10) || defined(CPU_MK20DX256VMD10) || defined(CPU_MK20DN512VMD10) || \ + defined(CPU_MK21DX128AVLK5) || defined(CPU_MK21DX256AVLK5) || defined(CPU_MK21DN512AVLK5) || defined(CPU_MK21DX128AVMC5) || \ + defined(CPU_MK21DX256AVMC5) || defined(CPU_MK21DN512AVMC5) || defined(CPU_MK21FX512AVLQ12) || defined(CPU_MK21FN1M0AVLQ12) || \ + defined(CPU_MK21FX512AVMC12) || defined(CPU_MK21FN1M0AVMC12) || defined(CPU_MK21FX512AVMD12) || defined(CPU_MK21FN1M0AVMD12) || \ + defined(CPU_MK22FN128VDC10) || defined(CPU_MK22FN128VLH10) || defined(CPU_MK22FN128VLL10) || defined(CPU_MK22FN128VMP10) || \ + defined(CPU_MK22FN256CAH12) || defined(CPU_MK22FN128CAH12) || defined(CPU_MK22FN256VDC12) || defined(CPU_MK22FN256VLH12) || \ + defined(CPU_MK22FN256VLL12) || defined(CPU_MK22FN256VMP12) || defined(CPU_MK22FN512CAP12) || defined(CPU_MK22FN512VDC12) || \ + defined(CPU_MK22FN512VLH12) || defined(CPU_MK22FN512VLL12) || defined(CPU_MK22FN512VMP12) || defined(CPU_MK24FN1M0VDC12) || \ + defined(CPU_MK24FN1M0VLL12) || defined(CPU_MK24FN1M0VLQ12) || defined(CPU_MK24FN256VDC12) || defined(CPU_MK26FN2M0CAC18) || \ + defined(CPU_MK40DN512VLK10) || defined(CPU_MK40DN512VLL10) || defined(CPU_MK40DX128VLQ10) || defined(CPU_MK40DX256VLQ10) || \ + defined(CPU_MK40DN512VLQ10) || defined(CPU_MK40DN512VMC10) || defined(CPU_MK40DX128VMD10) || defined(CPU_MK40DX256VMD10) || \ + defined(CPU_MK40DN512VMD10) || defined(CPU_MK50DX256CLL10) || defined(CPU_MK50DN512CLL10) || defined(CPU_MK50DN512CLQ10) || \ + defined(CPU_MK50DX256CMC10) || defined(CPU_MK50DN512CMC10) || defined(CPU_MK50DN512CMD10) || defined(CPU_MK50DX256CMD10) || \ + defined(CPU_MK50DX256CLK10) || defined(CPU_MK51DX256CLL10) || defined(CPU_MK51DN512CLL10) || defined(CPU_MK51DN256CLQ10) || \ + defined(CPU_MK51DN512CLQ10) || defined(CPU_MK51DX256CMC10) || defined(CPU_MK51DN512CMC10) || defined(CPU_MK51DN256CMD10) || \ + defined(CPU_MK51DN512CMD10) || defined(CPU_MK51DX256CLK10) || defined(CPU_MK52DN512CLQ10) || defined(CPU_MK52DN512CMD10) || \ + defined(CPU_MK53DN512CLQ10) || defined(CPU_MK53DX256CLQ10) || defined(CPU_MK53DN512CMD10) || defined(CPU_MK53DX256CMD10) || \ + defined(CPU_MK60DN256VLL10) || defined(CPU_MK60DX256VLL10) || defined(CPU_MK60DN512VLL10) || defined(CPU_MK60DN256VLQ10) || \ + defined(CPU_MK60DX256VLQ10) || defined(CPU_MK60DN512VLQ10) || defined(CPU_MK60DN256VMC10) || defined(CPU_MK60DX256VMC10) || \ + defined(CPU_MK60DN512VMC10) || defined(CPU_MK60DN256VMD10) || defined(CPU_MK60DX256VMD10) || defined(CPU_MK60DN512VMD10) || \ + defined(CPU_MK63FN1M0VLQ12) || defined(CPU_MK63FN1M0VMD12) || defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FN1M0VDC12) || \ + defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FX512VMD12) || defined(CPU_MK64FN1M0VMD12) || defined(CPU_MK65FN2M0CAC18) || defined(CPU_MK65FX1M0CAC18) || \ + defined(CPU_MK65FN2M0VMI18) || defined(CPU_MK65FX1M0VMI18) || defined(CPU_MK66FN2M0VLQ18) || defined(CPU_MK66FX1M0VLQ18) || \ + defined(CPU_MK66FN2M0VMD18) || defined(CPU_MK66FX1M0VMD18) || defined(CPU_MKL24Z32VFM4) || defined(CPU_MKL24Z64VFM4) || \ + defined(CPU_MKL24Z32VFT4) || defined(CPU_MKL24Z64VFT4) || defined(CPU_MKL24Z32VLH4) || defined(CPU_MKL24Z64VLH4) || \ + defined(CPU_MKL24Z32VLK4) || defined(CPU_MKL24Z64VLK4) || defined(CPU_MKL25Z32VFM4) || defined(CPU_MKL25Z64VFM4) || \ + defined(CPU_MKL25Z128VFM4) || defined(CPU_MKL25Z32VFT4) || defined(CPU_MKL25Z64VFT4) || defined(CPU_MKL25Z128VFT4) || \ + defined(CPU_MKL25Z32VLH4) || defined(CPU_MKL25Z64VLH4) || defined(CPU_MKL25Z128VLH4) || defined(CPU_MKL25Z32VLK4) || \ + defined(CPU_MKL25Z64VLK4) || defined(CPU_MKL25Z128VLK4) || defined(CPU_MKL26Z128CAL4) || defined(CPU_MKL26Z32VFM4) || \ + defined(CPU_MKL26Z64VFM4) || defined(CPU_MKL26Z128VFM4) || defined(CPU_MKL26Z32VFT4) || defined(CPU_MKL26Z64VFT4) || \ + defined(CPU_MKL26Z128VFT4) || defined(CPU_MKL26Z32VLH4) || defined(CPU_MKL26Z64VLH4) || defined(CPU_MKL26Z128VLH4) || \ + defined(CPU_MKL26Z256VLH4) || defined(CPU_MKL26Z128VLL4) || defined(CPU_MKL26Z256VLL4) || defined(CPU_MKL26Z128VMC4) || \ + defined(CPU_MKL26Z256VMC4) || defined(CPU_MKL26Z256VMP4) || defined(CPU_MKL46Z128VLH4) || defined(CPU_MKL46Z256VLH4) || \ + defined(CPU_MKL46Z128VLL4) || defined(CPU_MKL46Z256VLL4) || defined(CPU_MKL46Z128VMC4) || defined(CPU_MKL46Z256VMC4) || \ + defined(CPU_MKL46Z256VMP4) || defined(CPU_MKW22D512VHA5) || defined(CPU_MKW24D512VHA5) + /* @brief HOST mode enabled */ + #define FSL_FEATURE_USB_KHCI_HOST_ENABLED (1) + /* @brief OTG mode enabled */ + #define FSL_FEATURE_USB_KHCI_OTG_ENABLED (1) + /* @brief Size of the USB dedicated RAM */ + #define FSL_FEATURE_USB_KHCI_USB_RAM (0) + /* @brief Has KEEP_ALIVE_CTRL register */ + #define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0) +#elif defined(CPU_MKL27Z128VFM4) || defined(CPU_MKL27Z256VFM4) || defined(CPU_MKL27Z128VFT4) || defined(CPU_MKL27Z256VFT4) || \ + defined(CPU_MKL27Z128VLH4) || defined(CPU_MKL27Z256VLH4) || defined(CPU_MKL27Z128VMP4) || defined(CPU_MKL27Z256VMP4) || \ + defined(CPU_MKL43Z128VLH4) || defined(CPU_MKL43Z256VLH4) || defined(CPU_MKL43Z128VMP4) || defined(CPU_MKL43Z256VMP4) + /* @brief HOST mode enabled */ + #define FSL_FEATURE_USB_KHCI_HOST_ENABLED (0) + /* @brief OTG mode enabled */ + #define FSL_FEATURE_USB_KHCI_OTG_ENABLED (0) + /* @brief Size of the USB dedicated RAM */ + #define FSL_FEATURE_USB_KHCI_USB_RAM (0) + /* @brief Has KEEP_ALIVE_CTRL register */ + #define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0) +#elif defined(CPU_MKL27Z32VDA4) || defined(CPU_MKL27Z64VDA4) || defined(CPU_MKL27Z32VFM4) || defined(CPU_MKL27Z64VFM4) || \ + defined(CPU_MKL27Z32VFT4) || defined(CPU_MKL27Z64VFT4) || defined(CPU_MKL27Z32VLH4) || defined(CPU_MKL27Z64VLH4) || \ + defined(CPU_MKL27Z32VMP4) || defined(CPU_MKL27Z64VMP4) + /* @brief HOST mode enabled */ + #define FSL_FEATURE_USB_KHCI_HOST_ENABLED (0) + /* @brief OTG mode enabled */ + #define FSL_FEATURE_USB_KHCI_OTG_ENABLED (0) + /* @brief Size of the USB dedicated RAM */ + #define FSL_FEATURE_USB_KHCI_USB_RAM (512) + /* @brief Has KEEP_ALIVE_CTRL register */ + #define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (1) +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_USB_FEATURES_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.c b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.c new file mode 100644 index 0000000..c2ac8c1 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_usb_khci_hal.h" +//#include "fsl_platform_common.h" + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + diff --git a/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.h b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.h new file mode 100644 index 0000000..7302bbe --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/hal/fsl_usb_khci_hal.h @@ -0,0 +1,1879 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_USB_KHCI_HAL_H__ +#define __FSL_USB_KHCI_HAL_H__ + +#include "adapter.h" +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK) + #include + #include + #include + #include "fsl_usb_features.h" + #include "fsl_device_registers.h" + #define NEW_USB_KHCI_HAL_ENABLE 1 +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) + #include "fsl_usb_features.h" + #if (defined(CPU_MK22F51212)) + #include "MK22F51212.h" + #include "MK22F51212_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MK22F12810)) + #include "MK22F12810.h" + #include "MK22F12810_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MK70F12)) + #include "MK70F12.h" + #include "MK70F12_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MKL25Z)) + #include "MKL25Z4.h" + #include "MKL25Z4_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MKL27Z64VLH4)) + #include "MKL27Z644.h" + #include "MKL27Z644_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MKL26Z)) + #include "MKL26Z4.h" + #include "MKL26Z4_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MK64F12)) + #include "MK64F12.h" + #include "MK64F12_usb.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #endif +#elif (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + #include "fsl_usb_features.h" + #if (defined(CPU_MK22F51212)) + #include "MK22F51212.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MK70F12)) + #include "MK70F12.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #elif (defined(CPU_MK64F12)) + #include "MK64F12.h" + #define NEW_USB_KHCI_HAL_ENABLE 0 + #endif +#endif + + +#define usb_hal_khci_bdt_set_address(bdt_base, ep, direction, odd, address) \ + *((uint32_t*)((bdt_base & 0xfffffe00) | (((uint32_t)ep & 0x0f) << 5) | (((uint32_t)direction & 1) << 4) | (((uint32_t)odd & 1) << 3)) + 1) = address + + +#define usb_hal_khci_bdt_set_control(bdt_base, ep, direction, odd, control) \ + *(uint32_t*)((bdt_base & 0xfffffe00) | (((uint32_t)ep & 0x0f) << 5) | (((uint32_t)direction & 1) << 4) | (((uint32_t)odd & 1) << 3)) = control + +#define usb_hal_khci_bdt_get_address(bdt_base, ep, direction, odd) \ + (*((uint32_t*)((bdt_base & 0xfffffe00) | (((uint32_t)ep & 0x0f) << 5) | (((uint32_t)direction & 1) << 4) | (((uint32_t)odd & 1) << 3)) + 1)) + + +#define usb_hal_khci_bdt_get_control(bdt_base, ep, direction, odd) \ + (*(uint32_t*)((bdt_base & 0xfffffe00) | (((uint32_t)ep & 0x0f) << 5) | (((uint32_t)direction & 1) << 4) | (((uint32_t)odd & 1) << 3))) + + + + +#if NEW_USB_KHCI_HAL_ENABLE +/*! + * @addtogroup usb_khci_hal + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) + extern "C" { +#endif + + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Init the BDT page register from the BDT table + * + * @param baseAddr USB baseAddr id + * @param bdtAddress the BDT address resides in memory + */ +static inline void usb_hal_khci_set_buffer_descriptor_table_addr(uint32_t baseAddr, uint32_t bdtAddress) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_BDTPAGE1(_baseAddr,(uint8_t)((uint32_t)bdtAddress >> 8)); + USB_WR_BDTPAGE2(_baseAddr,(uint8_t)((uint32_t)bdtAddress >> 16)); + USB_WR_BDTPAGE3(_baseAddr,(uint8_t)((uint32_t)bdtAddress >> 24)); +} + + +/*! + * @brief Enable the specific Interrupt + * + * @param baseAddr USB baseAddr id + * @param intrType specific interrupt type + */ +static inline void usb_hal_khci_enable_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_INTEN(_baseAddr,(uint8_t)intrType); +} + +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) +/*! + * @brief Enable the specific OTG Interrupt + * + * @param baseAddr USB baseAddr id + * @param specific interrupt type + * + */ +static inline void usb_hal_khci_enable_otg_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_OTGICR(_baseAddr,(uint8_t)intrType); +} +#endif + +/*! + * @brief Disable the specific Interrupt + * + * @param baseAddr USB baseAddr id + * @param intrType specific interrupt type + */ +static inline void usb_hal_khci_disable_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_INTEN(_baseAddr, intrType); +} + +/*! + * @brief Get the interrupt status + * + * @param baseAddr USB baseAddr id + * @return specific interrupt type + */ +static inline uint8_t usb_hal_khci_get_interrupt_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return (USB_RD_ISTAT(_baseAddr)); +} + +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) +/*! + * @brief Get the otg interrupt status + * + * @param baseAddr USB baseAddr id + * + */ +static inline uint8_t usb_hal_khci_get_otg_interrupt_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return (USB_RD_OTGISTAT(_baseAddr)); +} + +/*! +* @brief Clear the specific otg interrupt +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type +*/ +static inline void usb_hal_khci_clr_otg_interrupt(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_WR_OTGISTAT(_baseAddr,(uint8_t)intrType); +} + +/*! +* @brief Clear all the otg interrupts +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_otg_interrupts(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_WR_OTGISTAT(_baseAddr,0xFF); +} + +/*! + * @brief Check if controller is busy on transferring. + * + * @param baseAddr USB baseAddr id. + * @return the value of the TOKENBUSY bit from the control register + */ +static inline uint8_t usb_hal_khci_is_line_stable(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return ((USB_RD_OTGSTAT(_baseAddr) & USB_OTGSTAT_LINESTATESTABLE_MASK) ? 1:0); +} +#endif + +/*! + * @brief Get the interrupt enable status + * + * @param baseAddr USB baseAddr id + * @return current enabled interrupt types + */ +static inline uint8_t usb_hal_khci_get_interrupt_enable_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return (USB_RD_INTEN(_baseAddr)); +} + +/*! +* @brief Clear the specific interrupt +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type needs to be cleared +*/ +static inline void usb_hal_khci_clr_interrupt(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + + USB_WR_ISTAT(_baseAddr,(uint8_t)intrType); +} + +/*! +* @brief Clear all the interrupts +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_interrupts(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ISTAT(_baseAddr,0xff); +} + +/*! +* @brief Judge if an interrupt type happen +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type +* @return the current interrupt type is happen or not +*/ +static inline uint8_t usb_hal_khci_is_interrupt_issued(uint32_t baseAddr, uint32_t intrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + uint8_t temp = USB_RD_ISTAT(_baseAddr); + return ( temp & USB_RD_INTEN(_baseAddr) & (intrType)); +} + +/*! +* @brief Enable all the error interrupt +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_all_error_interrupts(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ERREN(_baseAddr,0xFF); +} + +/*! +* @brief Disable all the error interrupts +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_all_error_interrupts(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ERREN(_baseAddr,0); +} + +/*! +* @brief Enable the specific error interrupts +* @param baseAddr usb baseAddr id +* @param errIntrType the error interrupt type +*/ +static inline void usb_hal_khci_enable_error_interrupts(uint32_t baseAddr, uint32_t errIntrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_ERREN(_baseAddr,(uint8_t)errIntrType); +} + +/*! +* @brief Disable the specific error interrupt +* @param baseAddr usb baseAddr id +* @param errIntrType the error interrupt type +*/ +static inline void usb_hal_khci_disable_error_interrupts(uint32_t baseAddr, uint32_t errorIntrType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_ERREN(_baseAddr, errorIntrType); +} + +/*! +* @brief Get the error interrupt status +* +* @param baseAddr usb baseAddr id +* @return the error interrupt status +*/ +static inline uint8_t usb_hal_khci_get_error_interrupt_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return (USB_RD_ERRSTAT(_baseAddr)); +} + +/*! +* @brief Get the error interrupt enable status +* +* @param baseAddr usb baseAddr id +* @return the error interrupt enable status +*/ +static inline uint8_t usb_hal_khci_get_error_interrupt_enable_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return (USB_RD_ERREN(_baseAddr)); +} + +/*! +* @brief Clear all the error interrupt happened +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_error_interrupts(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ERRSTAT(_baseAddr,0xff); +} + +/*! +* @brief Check if the specific error happened +* +* @param baseAddr usb baseAddr id +* @return the ERRSTAT register together with the error interrupt +*/ +static inline uint8_t usb_hal_khci_is_error_happend(uint32_t baseAddr, uint32_t errorType) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return ( USB_RD_ERRSTAT(_baseAddr) & (uint8_t)errorType); +} + +/*! + * @brief Clear the TOKENBUSY flag. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_clr_token_busy(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_CLR_CTL(_baseAddr,USB_CTL_TXSUSPENDTOKENBUSY_MASK); +} + +/*! + * @brief Check if controller is busy on transferring. + * + * @param baseAddr USB baseAddr id. + * @return the value of the TOKENBUSY bit from the control register + */ +static inline uint8_t usb_hal_khci_is_token_busy(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return (uint8_t)(USB_RD_CTL(_baseAddr) & USB_CTL_TXSUSPENDTOKENBUSY_MASK); +} + +/*! + * @brief reset all the BDT odd ping/pong fields. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_set_oddrst(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_SET_CTL(_baseAddr,USB_CTL_ODDRST_MASK); +} + +/*! + * @brief clear the ODDRST flag. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_clr_oddrst(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_CLR_CTL(_baseAddr,USB_CTL_ODDRST_MASK); +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED) +/*! + * @brief Begin to issue RESET signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_start_bus_reset(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_CTL(_baseAddr,USB_CTL_RESET_MASK); +} + +/*! + * @brief Stop issuing RESET signal + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_stop_bus_reset(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_CTL(_baseAddr,USB_CTL_RESET_MASK); +} + +/*! + * @brief Start to issue resume signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_start_resume(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_CTL(_baseAddr,USB_CTL_RESUME_MASK); +} + +/*! + * @brief Stop issuing resume signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_stop_resume(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_CTL(_baseAddr,USB_CTL_RESUME_MASK); +} + +/*! + * @brief Set the USB controller to host mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_set_host_mode(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_CTL(_baseAddr,USB_CTL_HOSTMODEEN_MASK); +} + +/*! + * @brief Set the USB controller to device mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_set_device_mode(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_CTL(_baseAddr,USB_CTL_HOSTMODEEN_MASK); +} +#endif + +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) +/*! + * @brief Set the USB controller to host mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_enable_otg(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_SET_OTGCTL(_baseAddr,USB_OTGCTL_OTGEN_MASK); +} + +#endif + +/*! + * @brief Enable SOF. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_enable_sof(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_SET_CTL(_baseAddr,USB_CTL_USBENSOFEN_MASK); +} + +/*! + * @brief Disable the USB module. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_disable_sof(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_CLR_CTL(_baseAddr,USB_CTL_USBENSOFEN_MASK); +} + +/*! + * @brief Clear the USB controller register + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_clear_control_register(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_CLR_CTL(_baseAddr, 0xFFu); +} + +/*! + * @brief Get the speed of the USB module. + * + * @param baseAddr USB baseAddr id. + * @return the current line status of the USB module + */ +static inline uint8_t usb_hal_khci_get_line_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return ((USB_RD_CTL(_baseAddr) & USB_CTL_JSTATE_MASK) ? 0 : 1); +} + +/*! + * @brief + * + * @param baseAddr USB baseAddr id. + */ +static inline uint8_t usb_hal_khci_get_se0_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return ((USB_RD_CTL(_baseAddr) & USB_CTL_SE0_MASK) ? 1 : 0); +} + + +/*! +* @brief Get current status +* +* @param baseAddr usb baseAddr id +* @return current status +*/ +static inline uint8_t usb_hal_khci_get_transfer_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return USB_RD_STAT(_baseAddr); +} + +/*! +* @brief Get the endpoint number from STAT register +* +* @param baseAddr usb baseAddr id +* @return endpoint number +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_ep_number(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return ((uint8_t)(USB_RD_STAT(_baseAddr) & 0xf0) >> 4); +} + +/*! +* @brief Return the transmit dir from STAT register +* +* @param baseAddr usb baseAddr id +* @return transmit direction +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_direction(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return ((USB_RD_STAT(_baseAddr) & USB_STAT_TX_MASK) >>USB_STAT_TX_SHIFT); +} + +/*! +* @brief Return the even or odd bank from STAT register +* +* @param baseAddr usb baseAddr id +* @return the even or odd bank +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_odd(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + return ((USB_RD_STAT(_baseAddr) & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT); +} + +/*! +* @brief Returned the computed BDT address +* +* @param baseAddr usb baseAddr id +* @return the computed BDT address +*/ +static inline uint16_t usb_hal_khci_get_frame_number(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + uint16_t temp = (uint16_t)((uint16_t)(USB_RD_FRMNUMH(_baseAddr)) << 8); + return ( temp | USB_RD_FRMNUML(_baseAddr) ); +} + +/*! +* @brief Set the device address +* +* @param baseAddr usb baseAddr id +* @param addr the address used to set +*/ +static inline void usb_hal_khci_set_device_addr(uint32_t baseAddr, uint32_t addr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ADDR_ADDR(_baseAddr,addr); +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED == 1) +/*! +* @brief Set the transfer target +* +* @param baseAddr usb baseAddr id +* @param address the address used to set +* @param speed the speed used to set +*/ +static inline void usb_hal_khci_set_transfer_target(uint32_t baseAddr, uint32_t address, uint32_t speed) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ADDR(_baseAddr,(uint8_t)((speed == 0) ? (uint8_t)address : USB_ADDR_LSEN_MASK | (uint8_t)address)); +} +#endif + +/*! +* @brief Init the endpoint0 +* +* @param baseAddr usb baseAddr id +* @param isThoughHub endpoint0 is though hub or not +* @param isIsochPipe current pipe is iso or not +*/ +static inline void usb_hal_khci_endpoint0_init(uint32_t baseAddr, uint32_t isThoughHub, uint32_t isIsochPipe) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + uint8_t ep_ctl_val; +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED) + ep_ctl_val = (isThoughHub == 1 ? USB_ENDPT_HOSTWOHUB_MASK : 0)| USB_ENDPT_RETRYDIS_MASK | + USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK | (isIsochPipe == 1 ? 0 : USB_ENDPT_EPHSHK_MASK); +#else + ep_ctl_val = USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK | + (isIsochPipe == 1 ? 0 : USB_ENDPT_EPHSHK_MASK); +#endif + USB_WR_ENDPT(_baseAddr, 0, ep_ctl_val); +} + +/*! +* @brief Stop the endpoint +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_shut_down(uint32_t baseAddr, uint32_t epNumber) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_ENDPT(_baseAddr,epNumber,0); +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED) +/*! +* @brief Set the flag to indicate if the endpoint is communicating with controller through the hub +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_on_hub(uint32_t baseAddr, uint32_t epNumber) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + + USB_SET_ENDPT(_baseAddr, epNumber,USB_ENDPT_HOSTWOHUB_MASK); +} +#endif + +/*! +* @brief Set the endpoint in host mode which need handshake or not +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +* @param isEphshkSet needs handshake or not +*/ +static inline void usb_hal_khci_endpoint_enable_handshake(uint32_t baseAddr, uint32_t epNumber, uint32_t isEphshkSet) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_ENDPT(_baseAddr, epNumber,((isEphshkSet == 1) ? USB_ENDPT_EPHSHK_MASK : 0)); +} + +/*! +* @brief Set the endpoint in host mode which in TX or RX +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +* @param isEptxenSet in TX or RX +*/ +static inline void usb_hal_khci_endpoint_set_direction(uint32_t baseAddr, uint32_t epNumber, uint8_t isEptxenSet) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_ENDPT(_baseAddr, epNumber,((isEptxenSet == 1) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK)); +} + +/*! +* @brief Clear the stall status of the endpoint +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_clr_stall(uint32_t baseAddr, uint32_t epNumber) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_ENDPT(_baseAddr, epNumber, USB_ENDPT_EPSTALL_MASK); + +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED == 1) +/*! +* @brief Enable the support for low speed +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_low_speed_support(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_ADDR(_baseAddr, USB_ADDR_LSEN_MASK); +} + + +/*! +* @brief Disable the support for low speed +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_low_speed_support(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_ADDR(_baseAddr, USB_ADDR_LSEN_MASK); +} +#endif + +/*! +* @brief Enable the pull down +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_pull_down(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_USBCTRL(_baseAddr, USB_USBCTRL_PDE_MASK); +} + + +/*! +* @brief Disable the pull down +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_pull_down(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_USBCTRL(_baseAddr, USB_USBCTRL_PDE_MASK); +} + +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) +/*! +* @brief Enable the pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_pull_up(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_OTGCTL(_baseAddr, USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK |USB_OTGCTL_DMLOW_MASK |USB_OTGCTL_DPLOW_MASK); +} + +/*! +* @brief Disable the pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_pull_up(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_OTGCTL(_baseAddr, USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK |USB_OTGCTL_DMLOW_MASK |USB_OTGCTL_DPLOW_MASK); +} +#endif + +/*! +* @brief Enable the DP pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_dp_pull_up(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) + if (USB_RD_OTGCTL_OTGEN(_baseAddr)) + { + USB_SET_OTGCTL(_baseAddr, USB_OTGCTL_DPHIGH_MASK); + } + else + { + USB_SET_CONTROL(_baseAddr, USB_CONTROL_DPPULLUPNONOTG_MASK); + } +#else + USB_SET_CONTROL(_baseAddr, USB_CONTROL_DPPULLUPNONOTG_MASK); +#endif +} + +/*! +* @brief Disable the DP pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_dp_pull_up(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) + if (USB_RD_OTGCTL_OTGEN(_baseAddr)) + { + USB_CLR_OTGCTL(_baseAddr, USB_OTGCTL_DPHIGH_MASK); + } + else + { + USB_CLR_CONTROL(_baseAddr, USB_CONTROL_DPPULLUPNONOTG_MASK); + } +#else + USB_CLR_CONTROL(_baseAddr, USB_CONTROL_DPPULLUPNONOTG_MASK); +#endif +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED) +//TODO: +static inline uint8_t usb_hal_khci_set_pull_downs(uint32_t baseAddr, uint8_t bitfield ) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + USB_CLR_OTGCTL(_baseAddr,USB_OTGCTL_DMLOW_MASK | USB_OTGCTL_DPLOW_MASK); + if(bitfield & 0x01) + { + USB_SET_OTGCTL(_baseAddr,USB_OTGCTL_DPLOW_MASK); + } + + if(bitfield & 0x02) + { + USB_SET_OTGCTL(_baseAddr,USB_OTGCTL_DMLOW_MASK); + } + return USB_OK; +} +#endif + +//TODO: +static inline void usb_hal_khci_clr_usbtrc0(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_USBTRC0(_baseAddr, 0); +} + +#if (FSL_FEATURE_USB_KHCI_OTG_ENABLED) +/*! +* @brief Get OTG status +* @param baseAddr usb baseAddr id +*/ +static inline uint8_t usb_hal_khci_get_otg_status(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + return(USB_RD_OTGSTAT(_baseAddr)); +} +#endif + +/*! +* @brief Set the controller to the suspend state +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_set_suspend(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_USBCTRL(_baseAddr, USB_USBCTRL_SUSP_MASK); +} + + +/*! +* @brief Clear the suspend state of the controller +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_suspend(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_CLR_USBCTRL(_baseAddr, USB_USBCTRL_SUSP_MASK); +} + +#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED) +/*! +* @brief Set the sof threshold +* @param baseAddr usb baseAddr id +* @param value value used to set +*/ +static inline void usb_hal_khci_set_sof_theshold(uint32_t baseAddr, uint32_t value) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_SOFTHLD(_baseAddr, (uint8_t)value); +} + +static inline void usb_hal_khci_set_target_token(uint32_t baseAddr, uint8_t token, uint8_t endpoint_number) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_TOKEN(_baseAddr, (uint8_t)(USB_TOKEN_TOKENENDPT(endpoint_number) | token)); +} +#endif + +/*! +* @brief Set weak pull down +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_set_weak_pulldown(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_CTL(_baseAddr, USB_CTL_SE0_MASK); +} + +/*! +* @brief Reset control register +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_reset_control_register(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_CTL(_baseAddr, 0UL); +} + +/*! +* @brief Set internal pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_set_internal_pullup(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_WR_CONTROL(_baseAddr, USB_CONTROL_DPPULLUPNONOTG_MASK); +} + +/*! +* @brief Set trc0 +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_set_trc0(uint32_t baseAddr) +{ + USB_MemMapPtr _baseAddr = (USB_MemMapPtr)baseAddr; + + USB_SET_USBTRC0(_baseAddr, 0x40); +} + +#else +//#include +//#include +#include + + +//#include "fsl_usb_features.h" +//#include "device/fsl_device_registers.h" + +//! @addtogroup usb_hal +//! @{ + +//! @file + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// API +//////////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) +extern "C" { +#endif +#define HW_USB_INSTANCE_COUNT (1U) + +/*! + * @name Initialization + * @{ + */ + +/*! + * @brief Init the BDT page register from the BDT table + * + * @param baseAddr USB baseAddr id + * @param bdtAddress the BDT address resides in memory + * + */ +static inline void usb_hal_khci_set_buffer_descriptor_table_addr(uint32_t baseAddr, uint32_t bdtAddress) +{ + + USB0_BDTPAGE1 = (uint8_t)((uint32_t)bdtAddress >> 8); + USB0_BDTPAGE2 = (uint8_t)((uint32_t)bdtAddress >> 16); + USB0_BDTPAGE3 = (uint8_t)((uint32_t)bdtAddress >> 24); +} + + +/*! + * @brief Enable the specific Interrupt + * + * @param baseAddr USB baseAddr id + * @param intrType specific interrupt type + */ +static inline void usb_hal_khci_enable_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + + USB0_INTEN |= (uint8_t)intrType; +} +#if (FSL_USB_KHCI_OTG_ENABLED) +/*! + * @brief Enable the specific OTG Interrupt + * + * @param baseAddr USB baseAddr id + * @param specific interrupt type + * + */ +static inline void usb_hal_khci_enable_otg_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + + //HW_USB_OTGICR_SET((uint8_t)intrType); + USB0_OTGICR |= (uint8_t)intrType; +} +#endif + +/*! + * @brief Disable the specific Interrupt + * + * @param baseAddr USB baseAddr id + * @param intrType specific interrupt type + */ +static inline void usb_hal_khci_disable_interrupts(uint32_t baseAddr, uint32_t intrType) +{ + + USB0_INTEN &= ~(uint8_t)intrType; +} + +/*! + * @brief Get the interrupt status + * + * @param baseAddr USB baseAddr id + * @return specific interrupt type + */ +static inline uint8_t usb_hal_khci_get_interrupt_status(uint32_t baseAddr) +{ + + return (USB0_ISTAT); +} + +/*! + * @brief Get the otg interrupt status + * + * @param baseAddr USB baseAddr id + * + */ +#if (FSL_USB_KHCI_OTG_ENABLED) +static inline uint8_t usb_hal_khci_get_otg_interrupt_status(uint32_t baseAddr) +{ + //return (HW_USB_OTGISTAT_RD); + return (USB0_OTGISTAT); +} + +/*! +* @brief Clear the specific otg interrupt +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type +*/ +static inline void usb_hal_khci_clr_otg_interrupt(uint32_t baseAddr, uint32_t intrType) +{ + //HW_USB_OTGISTAT_WR((uint8_t)intrType); + USB0_OTGISTAT = (uint8_t)intrType; +} + +/*! +* @brief Clear all the otg interrupts +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_otg_interrupts(uint32_t baseAddr) +{ + //HW_USB_OTGISTAT_WR(0xFF); + USB0_OTGISTAT = 0xFF; +} + +/*! + * @brief Check if controller is busy on transferring. + * + * @param baseAddr USB baseAddr id. + * @return the value of the TOKENBUSY bit from the control register + */ +static inline uint8_t usb_hal_khci_is_line_stable(uint32_t baseAddr) +{ + //return ((HW_USB_OTGSTAT_RD & USB_OTGSTAT_LINESTATESTABLE_MASK) ? 1:0); + return ((USB0_OTGSTAT & USB_OTGSTAT_LINESTATESTABLE_MASK) ? 1:0); +} +#endif +/*! + * @brief Get the interrupt enable status + * + * @param baseAddr USB baseAddr id + * @return current enabled interrupt types + */ +static inline uint8_t usb_hal_khci_get_interrupt_enable_status(uint32_t baseAddr) +{ + + return (USB0_INTEN); +} + +/*! +* @brief Clear the specific interrupt +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type needs to be cleared +*/ +static inline void usb_hal_khci_clr_interrupt(uint32_t baseAddr, uint32_t intrType) +{ + + + USB0_ISTAT = (uint8_t)intrType; +} + +/*! +* @brief Clear all the interrupts +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_interrupts(uint32_t baseAddr) +{ + + USB0_ISTAT = 0xff; +} + +/*! +* @brief Judge if an interrupt type happen +* +* @param baseAddr usb baseAddr id +* @param intrType the interrupt type +* @return the current interrupt type is happen or not +*/ +static inline uint8_t usb_hal_khci_is_interrupt_issued(uint32_t baseAddr, uint32_t intrType) +{ + + return (USB0_ISTAT & USB0_INTEN & (uint8_t)(intrType)); +} + +/*! +* @brief Enable all the error interrupt +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_all_error_interrupts(uint32_t baseAddr) +{ + + USB0_ERREN = (uint8_t)0xFF; +} + + +/*! +* @brief Disable all the error interrupts +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_all_error_interrupts(uint32_t baseAddr) +{ + + USB0_ERREN = (uint8_t)0; +} + + +/*! +* @brief Enable error interrupts +* @param baseAddr usb baseAddr id +* @param errIntrType the error interrupt type +*/ +static inline void usb_hal_khci_enable_error_interrupts(uint32_t baseAddr, uint32_t errIntrType) +{ + + USB0_ERREN |= (uint8_t)errIntrType; +} + +/*! +* @brief Disable the specific error interrupt +* @param baseAddr usb baseAddr id +* @param errIntrType the error interrupt type +*/ +static inline void usb_hal_khci_disable_error_interrupts(uint32_t baseAddr, uint32_t errorIntrType) +{ + + USB0_ERREN &= ~(uint8_t)errorIntrType; +} + +/*! +* @brief Get the error interrupt status +* +* @param baseAddr usb baseAddr id +* @return the error interrupt status +*/ +static inline uint8_t usb_hal_khci_get_error_interrupt_status(uint32_t baseAddr) +{ + + return (USB0_ERRSTAT); +} + +/*! +* @brief Get the error interrupt enable status +* +* @param baseAddr usb baseAddr id +* @return the error interrupt enable status +*/ +static inline uint8_t usb_hal_khci_get_error_interrupt_enable_status(uint32_t baseAddr) +{ + + return (USB0_ERREN); +} + +/*! +* @brief Clear all the error interrupt happened +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_all_error_interrupts(uint32_t baseAddr) +{ + + USB0_ERRSTAT = 0xff; +} + +/*! +* @brief Check if the specific error happened +* +* @param baseAddr usb baseAddr id +* @return the ERRSTAT register together with the error interrupt +*/ +static inline uint8_t usb_hal_khci_is_error_happend(uint32_t baseAddr, uint32_t errorType) +{ + + return ( USB0_ERRSTAT & (uint8_t)errorType); +} + +/*! + * @brief Clear the TOKENBUSY flag. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_clr_token_busy(uint32_t baseAddr) +{ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; +} + +/*! + * @brief Check if controller is busy on transferring. + * + * @param baseAddr USB baseAddr id. + * @return the value of the TOKENBUSY bit from the control register + */ +static inline uint8_t usb_hal_khci_is_token_busy(uint32_t baseAddr) +{ + return (uint8_t)(USB0_CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK); +} + +/*! + * @brief reset all the BDT odd ping/pong fields. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_set_oddrst(uint32_t baseAddr) +{ + USB0_CTL |= USB_CTL_ODDRST_MASK; +} + +/*! + * @brief Clear the ODDRST flag. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_clr_oddrst(uint32_t baseAddr) +{ + USB0_CTL &= ~USB_CTL_ODDRST_MASK; +} + +#if (FSL_USB_KHCI_HOST_ENABLED) +/*! + * @brief Begin to issue RESET signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_start_bus_reset(uint32_t baseAddr) +{ + + USB0_CTL |= USB_CTL_RESET_MASK; +} + +/*! + * @brief Stop issuing RESET signal + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_stop_bus_reset(uint32_t baseAddr) +{ + + USB0_CTL &= ~USB_CTL_RESET_MASK; +} + +/*! + * @brief Start to issue resume signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_start_resume(uint32_t baseAddr) +{ + + USB0_CTL |= USB_CTL_RESUME_MASK; +} + +/*! + * @brief Stop issuing resume signal. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_stop_resume(uint32_t baseAddr) +{ + //HW_USB_CTL_CLR(USB_CTL_RESUME_MASK); + USB0_CTL &= ~USB_CTL_RESUME_MASK; +} + + +/*! + * @brief Set the USB controller to host mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_set_host_mode(uint32_t baseAddr) +{ + + USB0_CTL = USB_CTL_HOSTMODEEN_MASK; +} + +/*! + * @brief Set the USB controller to device mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_set_device_mode(uint32_t baseAddr) +{ + + + USB0_CTL &= ~USB_CTL_HOSTMODEEN_MASK; +} +#endif + +#if (FSL_USB_KHCI_OTG_ENABLED) +/*! + * @brief Set the USB controller to host mode + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_enable_otg(uint32_t baseAddr) +{ + //HW_USB_OTGCTL_SET(USB_OTGCTL_OTGEN_MASK); + USB0_OTGCTL |= USB_OTGCTL_OTGEN_MASK; +} +#endif + +/*! + * @brief Enable the USB module. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_enable_sof(uint32_t baseAddr) +{ + USB0_CTL |= USB_CTL_USBENSOFEN_MASK; +} + +/*! + * @brief Disable the USB module. + * + * @param baseAddr USB baseAddr id. + */ +static inline void usb_hal_khci_disable_sof(uint32_t baseAddr) +{ + USB0_CTL &= ~USB_CTL_USBENSOFEN_MASK; +} + +/*! + * @brief Clear the USB controller register + * + * @param baseAddr USB baseAddr id. + * + */ +static inline void usb_hal_khci_clear_control_register(uint32_t baseAddr) +{ + USB0_CTL = 0; +} + +/*! + * @brief Get the speed of the USB module. + * + * @param baseAddr USB baseAddr id. + * @return the current line status of the USB module + */ +static inline uint8_t usb_hal_khci_get_line_status(uint32_t baseAddr) +{ + return ((USB0_CTL & USB_CTL_JSTATE_MASK) ? 0 : 1); +} + +/*! + * @brief + * + * @param baseAddr USB baseAddr id. + */ +static inline uint8_t usb_hal_khci_get_se0_status(uint32_t baseAddr) +{ + return ((USB0_CTL & USB_CTL_SE0_MASK) ? 1 : 0); +} + +/*! +* @brief Get current status +* +* @param baseAddr usb baseAddr id +* @return current status +*/ +static inline uint8_t usb_hal_khci_get_transfer_status(uint32_t baseAddr) +{ + + return USB0_STAT; +} + +/*! +* @brief Get the endpoint number from STAT register +* +* @param baseAddr usb baseAddr id +* @return endpoint number +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_ep_number(uint32_t baseAddr) +{ + + return ((USB0_STAT & 0xf0) >> 4); +} + +/*! +* @brief Return the transmit dir from STAT register +* +* @param baseAddr usb baseAddr id +* @return transmit direction +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_direction(uint32_t baseAddr) +{ + + return ((USB0_STAT & USB_STAT_TX_MASK) >>USB_STAT_TX_SHIFT); +} + +/*! +* @brief Return the even or odd bank from STAT register +* +* @param baseAddr usb baseAddr id +* @return the even or odd bank +*/ +static inline uint8_t usb_hal_khci_get_transfer_done_odd(uint32_t baseAddr) +{ + + return ((USB0_STAT & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT); +} + + +/*! +* @brief Returned the computed BDT address +* +* @param baseAddr usb baseAddr id +* @return the computed BDT address +*/ +static inline uint16_t usb_hal_khci_get_frame_number(uint32_t baseAddr) +{ + + return ( USB0_FRMNUMH << 8 | USB0_FRMNUML); +} + +/*! +* @brief Set the device address +* +* @param baseAddr usb baseAddr id +* @param addr the address used to set +*/ +static inline void usb_hal_khci_set_device_addr(uint32_t baseAddr, uint32_t addr) +{ + + USB0_ADDR = (uint8_t)((USB0_ADDR & ~0x7F) | addr); +} + +#if (FSL_USB_KHCI_HOST_ENABLED == 1) +/*! +* @brief Set the transfer target +* +* @param baseAddr usb baseAddr id +* @param addr the address used to set +*/ +static inline void usb_hal_khci_set_transfer_target(uint32_t baseAddr, uint32_t address, uint32_t speed) +{ + + USB0_ADDR = (uint8_t)((speed == 0) ? (uint8_t)address : USB_ADDR_LSEN_MASK | (uint8_t)address); +} +#endif + +/*! +* @brief Init the endpoint0 +* +* @param baseAddr usb baseAddr id +* @param isThoughHub endpoint0 is though hub or not +* @param isIsochPipe current pipe is iso or not +*/ +static inline void usb_hal_khci_endpoint0_init(uint32_t baseAddr, uint32_t isThoughHub, uint32_t isIsochPipe) +{ +#if (FSL_USB_KHCI_HOST_ENABLED) + USB0_ENDPT0 = (isThoughHub == 1 ? USB_ENDPT_HOSTWOHUB_MASK : 0)| USB_ENDPT_RETRYDIS_MASK | + USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK | (isIsochPipe == 1 ? 0 : USB_ENDPT_EPHSHK_MASK); +#else + USB0_ENDPT0 = USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK | (isIsochPipe == 1 ? 0 : USB_ENDPT_EPHSHK_MASK); +#endif +} + +/*! +* @brief Stop the endpoint +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_shut_down(uint32_t baseAddr, uint32_t epNumber) +{ + + USB_ENDPT_REG(USB0_BASE_PTR, (uint8_t)epNumber) = 0; +} + +#if (FSL_USB_KHCI_HOST_ENABLED) +/*! +* @brief Set the flag to indicate if the endpoint is communicating with controller through the hub +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_on_hub(uint32_t baseAddr, uint32_t epNumber) +{ + + + USB_ENDPT_REG(USB0_BASE_PTR, (uint8_t)epNumber) |= USB_ENDPT_HOSTWOHUB_MASK; +} +#endif + +/*! +* @brief Set the endpoint in host mode which need handshake or not +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +* @param isEphshkSet needs handshake or not +*/ +static inline void usb_hal_khci_endpoint_enable_handshake(uint32_t baseAddr, uint32_t epNumber, uint32_t isEphshkSet) +{ + + USB_ENDPT_REG(USB0_BASE_PTR, (uint8_t)epNumber) |= ((isEphshkSet == 1) ? USB_ENDPT_EPHSHK_MASK : 0); + +} + +/*! +* @brief Set the endpoint in host mode which in TX or RX +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +* @param isEptxenSet in TX or RX +*/ +static inline void usb_hal_khci_endpoint_set_direction(uint32_t baseAddr, uint32_t epNumber, uint8_t isEptxenSet) +{ + + USB_ENDPT_REG(USB0_BASE_PTR, (uint8_t)epNumber) |= ((isEptxenSet == 1) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK); +} + +/*! +* @brief Clear the stall status of the endpoint +* +* @param baseAddr usb baseAddr id +* @param epNumber endpoint number +*/ +static inline void usb_hal_khci_endpoint_clr_stall(uint32_t baseAddr, uint32_t epNumber) +{ + + USB_ENDPT_REG(USB0_BASE_PTR, (uint8_t)epNumber) &= ~USB_ENDPT_EPSTALL_MASK; + +} + +#if (FSL_USB_KHCI_HOST_ENABLED == 1) +/*! +* @brief Enable the support for low speed +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_low_speed_support(uint32_t baseAddr) +{ + + USB0_ADDR |= USB_ADDR_LSEN_MASK; +} +#endif + +/*! +* @brief Disable the support for low speed +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_low_speed_support(uint32_t baseAddr) +{ + + USB0_ADDR &= ~USB_ADDR_LSEN_MASK; +} + + +/*! +* @brief Enable the pull down +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_pull_down(uint32_t baseAddr) +{ + + USB0_USBCTRL |= USB_USBCTRL_PDE_MASK; +} + + +/*! +* @brief Disable the pull down +* +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_pull_down(uint32_t baseAddr) +{ + + USB0_USBCTRL &= ~USB_USBCTRL_PDE_MASK; +} + +#if (FSL_USB_KHCI_OTG_ENABLED) +/*! +* @brief Enable the pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_pull_up(uint32_t baseAddr) +{ + + USB0_OTGCTL = USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK |USB_OTGCTL_DMLOW_MASK |USB_OTGCTL_DPLOW_MASK; +} + +/*! +* @brief Disable the pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_pull_up(uint32_t baseAddr) +{ + + USB0_OTGCTL &= ~(USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK |USB_OTGCTL_DMLOW_MASK |USB_OTGCTL_DPLOW_MASK); +} +#endif +/*! +* @brief Enable the DP pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_enable_dp_pull_up(uint32_t baseAddr) +{ +#if (FSL_USB_KHCI_OTG_ENABLED) + if ((USB0_OTGCTL & USB_OTGCTL_OTGEN_MASK) >> USB_OTGCTL_OTGEN_SHIFT) + { + USB0_OTGCTL |= USB_OTGCTL_DPHIGH_MASK; + } + else + { + USB0_CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; + } +#endif + USB0_CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; +} + +/*! +* @brief Disable the DP pull up +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_disable_dp_pull_up(uint32_t baseAddr) +{ +#if (FSL_USB_KHCI_OTG_ENABLED) + if ((USB0_OTGCTL & USB_OTGCTL_OTGEN_MASK) >> USB_OTGCTL_OTGEN_SHIFT) + { + USB0_OTGCTL &= ~ USB_OTGCTL_DPHIGH_MASK; + } + else + { + USB0_CONTROL &= ~ USB_CONTROL_DPPULLUPNONOTG_MASK; + } +#endif + USB0_CONTROL &= ~ USB_CONTROL_DPPULLUPNONOTG_MASK; +} + +#if (FSL_USB_KHCI_OTG_ENABLED) +//TODO: +static inline uint8_t usb_hal_khci_set_pull_downs(uint32_t baseAddr, uint8_t bitfield ) +{ + //HW_USB_OTGCTL_CLR(USB_OTGCTL_DMLOW_MASK | USB_OTGCTL_DPLOW_MASK); + USB0_OTGCTL &= ~(USB_OTGCTL_DMLOW_MASK | USB_OTGCTL_DPLOW_MASK); + if(bitfield & 0x01) + { + //HW_USB_OTGCTL_SET(USB_OTGCTL_DPLOW_MASK); + USB0_OTGCTL |= USB_OTGCTL_DPLOW_MASK; + } + + if(bitfield & 0x02) + { + //HW_USB_OTGCTL_SET(USB_OTGCTL_DMLOW_MASK); + USB0_OTGCTL |= USB_OTGCTL_DMLOW_MASK; + } + return USB_OK; +} +#endif + +//TODO: +static inline void usb_hal_khci_clr_usbtrc0(uint32_t baseAddr) +{ + + //HW_USB_USBTRC0_WR(0); + USB0_USBTRC0 = 0; +} + +#if (FSL_USB_KHCI_OTG_ENABLED) +/*! +* @brief Get OTG status +* @param baseAddr usb baseAddr id +*/ +static inline uint8_t usb_hal_khci_get_otg_status(uint32_t baseAddr) +{ + //return(HW_USB_OTGSTAT_RD); + return(USB0_OTGSTAT); +} +#endif + +/*! +* @brief Set the controller to the suspend state +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_set_suspend(uint32_t baseAddr) +{ + + USB0_USBCTRL |= USB_USBCTRL_SUSP_MASK; +} + + +/*! +* @brief Clear the suspend state of the controller +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_suspend(uint32_t baseAddr) +{ + + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; +} + +#if (FSL_USB_KHCI_HOST_ENABLED) +/*! +* @brief Set the sof threshold +* @param baseAddr usb baseAddr id +* @param value value used to set +*/ +static inline void usb_hal_khci_set_sof_theshold(uint32_t baseAddr, uint32_t value) +{ + + USB0_SOFTHLD = (uint8_t)value; +} + +static inline void usb_hal_khci_set_target_token(uint32_t baseAddr, uint8_t token, uint8_t endpoint_number) +{ + + USB0_TOKEN = (uint8_t)(USB_TOKEN_TOKENENDPT(endpoint_number) | token); +} +#endif + + + +#endif +#if (FSL_FEATURE_USB_KHCI_USB_RAM ) +#define USB_USBRAM_ADDRESS (0x400FE000) + +/*! +* @brief Get the USB Ram address of the ctrol +* @param baseAddr usb baseAddr id +*/ +static inline uint32_t usb_hal_khci_get_usbram_add(uint32_t baseAddr) +{ + return USB_USBRAM_ADDRESS; +} +#endif + +#if (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) +/*! +* @brief Clear the keep alive wake interrupt state of the controller +* @param baseAddr usb baseAddr id +*/ +static inline void usb_hal_khci_clr_keepalive_wake_int_sts(uint32_t baseAddr) +{ + USB0_KEEP_ALIVE_CTRL |= USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK; +} + +/*! +* @brief Getkeep alive wake interrupt status +* @param baseAddr usb baseAddr id +*/ +static inline uint8_t usb_hal_khci_get_keepalive_wake_int_sts(uint32_t baseAddr) +{ + return(USB0_KEEP_ALIVE_CTRL & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK); +} +#endif +#if defined(__cplusplus) + } +#endif +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/compiler.h b/KSDK_1.2.0/usb/usb_core/include/compiler.h new file mode 100644 index 0000000..3741e16 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/compiler.h @@ -0,0 +1,122 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2013 Freescale Semiconductor; + * All Rights Reserved + * + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: compiler.h$ + * $Version : + * $Date : + * + * Comments: + * + * This file defines compiler related MACRO + * + *END************************************************************************/ +#ifndef __compiler_h__ +#define __compiler_h__ 1 + +#ifdef __cplusplus +extern "C" +{ +#endif +#if ((defined __CWCC__)||(defined __GNUC__)) +#ifndef PACKED_STRUCT_BEGIN +#define PACKED_STRUCT_BEGIN +#endif + +#ifndef PACKED_STRUCT_END +#define PACKED_STRUCT_END __attribute__((__packed__)) +#endif + +#ifndef PACKED_UNION_BEGIN +#define PACKED_UNION_BEGIN +#endif + +#ifndef PACKED_UNION_END +#define PACKED_UNION_END __attribute__((__packed__)) +#endif + +#ifndef _WEAK_FUNCTION +#define _WEAK_FUNCTION(x) __attribute__((weak)) x +#endif + +#ifndef _WEAK_SYMBOL +#define _WEAK_SYMBOL(x) x __attribute__((weak)) +#endif + +#elif (defined __IAR_SYSTEMS_ICC__) + +#ifndef PACKED_STRUCT_BEGIN +#define PACKED_STRUCT_BEGIN __packed +#endif + +#ifndef PACKED_STRUCT_END +#define PACKED_STRUCT_END +#endif + +#ifndef PACKED_UNION_BEGIN +#define PACKED_UNION_BEGIN +#endif + +#ifndef PACKED_UNION_END +#define PACKED_UNION_END __packed +#endif + +#ifndef _WEAK_FUNCTION +#define _WEAK_FUNCTION(x) __weak x +#endif + +#ifndef _WEAK_SYMBOL +#define _WEAK_SYMBOL(x) __weak x +#endif + +#elif (defined __CC_ARM) + +#ifndef PACKED_STRUCT_BEGIN +#define PACKED_STRUCT_BEGIN _Pragma("pack(1)") +#endif + +#ifndef PACKED_STRUCT_END +#define PACKED_STRUCT_END _Pragma("pack()") +#endif + +#ifndef PACKED_UNION_BEGIN +#define PACKED_UNION_BEGIN _Pragma("pack()") +#endif + +#ifndef PACKED_UNION_END +#define PACKED_UNION_END _Pragma("pack()") +#endif + +#ifndef _WEAK_FUNCTION +#define _WEAK_FUNCTION(x) __weak x +#endif + +#ifndef _WEAK_SYMBOL +#define _WEAK_SYMBOL(x) __weak x +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/types.h b/KSDK_1.2.0/usb/usb_core/include/types.h new file mode 100644 index 0000000..33c075c --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/types.h @@ -0,0 +1,84 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2013 Freescale Semiconductor; + * All Rights Reserved + * + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: types.h$ + * $Version : + * $Date : + * + * Comments: + * + * + * + *END************************************************************************/ +#ifndef _types_h__ +#define _types_h__ + +/*--------------------------------------------------------------------------*/ +/* + ** STANDARD TYPES + */ + +/* + ** The following typedefs allow us to minimize portability problems + ** due to the various C compilers (even for the same processor) not + ** agreeing on the sizes of "int"s and "short int"s and "longs". + */ + +//#define * * +#define _CODE_PTR_ * + +typedef char * char_ptr; /* signed character */ + +typedef unsigned char uchar; /* unsigned character */ + +typedef signed char int8_t, *int_8_ptr; /* 8-bit signed integer */ +typedef unsigned char uint8_t; /* 8-bit signed integer */ + +typedef short int16_t, *int_16_ptr; /* 16-bit signed integer */ +typedef unsigned short uint16_t, *uint_16_ptr; /* 16-bit unsigned integer*/ + +typedef long int32_t, *int_32_ptr; /* 32-bit signed integer */ +typedef unsigned long uint32_t, *uint_32_ptr; /* 32-bit unsigned integer*/ + +typedef long long int_64, *int_64_ptr; /* 64-bit signed */ +typedef unsigned long long uint64_t, *uint_64_ptr; /* 64-bit unsigned */ + +#ifndef bool +typedef unsigned long bool; /* Machine representation of a bool */ +#endif + +//typedef void * void*; /* Machine representation of a pointer */ +//typedef unsigned char uint8_t; +//typedef unsigned short uint16_t; +//typedef unsigned long uint32_t; +#ifdef FALSE +#undef FALSE +#endif +#define FALSE ((uint8_t)0) + +#ifdef TRUE +#undef TRUE +#endif +#define TRUE ((uint8_t)1) + +#define UNUSED(x) (void)x; +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb.h b/KSDK_1.2.0/usb/usb_core/include/usb.h new file mode 100644 index 0000000..0fbfe4f --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb.h @@ -0,0 +1,40 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2013 Freescale Semiconductor; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb.h$ + * $Version : + * $Date : + * + * Comments: + * + * This file includes all the necessary head files. + * + *END************************************************************************/ +#ifndef __usb_h__ +#define __usb_h__ + +#include "adapter.h" +#include "usb_types.h" +#include "usb_desc.h" //USB descriptor macros +#include "usb_misc.h" +#include "usb_opt.h" +#include "usb_error.h" +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_desc.h b/KSDK_1.2.0/usb/usb_core/include/usb_desc.h new file mode 100644 index 0000000..143f9f4 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_desc.h @@ -0,0 +1,348 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_desc.h$ +* $Version : +* $Date : +* +* Comments: +* +* This file contains struct definitions for USB descriptors. +* +*END************************************************************************/ +#ifndef __usb_desc_h__ +#define __usb_desc_h__ + +//#include "compiler.h" + +/* USB Descriptor Endpoint types */ +#define USB_CONTROL_PIPE (0x00) +#define USB_ISOCHRONOUS_PIPE (0x01) +#define USB_BULK_PIPE (0x02) +#define USB_INTERRUPT_PIPE (0x03) + +/* USB Descriptor Direction constants */ +#define USB_RECV (0) +#define USB_SEND (1) + +/* USB Descriptor Lengths */ +#define USB_DESC_LEN_DEV (18) +#define USB_DESC_LEN_CFG (9) +#define USB_DESC_LEN_STR (2) /* minimum length */ +#define USB_DESC_LEN_IF (9) +#define USB_DESC_LEN_EP (7) +#define USB_DESC_LEN_DEV_QUALIFIER (10) +#define USB_DESC_LEN_OTHER_SPEED_CFG (USB_DESC_LEN_CFG) + +/* USB Descriptor Types */ +#define USB_DESC_TYPE_DEV (1) +#define USB_DESC_TYPE_CFG (2) +#define USB_DESC_TYPE_STR (3) +#define USB_DESC_TYPE_IF (4) +#define USB_DESC_TYPE_EP (5) +#define USB_DESC_TYPE_DEV_QUALIFIER (6) +#define USB_DESC_TYPE_OTHER_SPEED_CFG (7) +#define USB_DESC_TYPE_IF_POWER (8) +#define USB_DESC_TYPE_OTG (9) +#define USB_DESC_TYPE_HID (0x21) +#define USB_DESC_TYPE_REPORT (0x22) + +/* USB Functional Descriptor Types */ +#define USB_DESC_TYPE_CS_INTERFACE (0x24) +#define USB_DESC_TYPE_CS_ENDPOINT (0x25) + + +/* USB Standard Device Requests - bmRequestType */ +#define USB_DEV_REQ_STD_REQUEST_TYPE_DIR_MASK (0x1) +#define USB_DEV_REQ_STD_REQUEST_TYPE_DIR_SHIFT (7) +#define USB_DEV_REQ_STD_REQUEST_TYPE_DIR_POS (USB_DEV_REQ_STD_REQUEST_TYPE_DIR_MASK << USB_DEV_REQ_STD_REQUEST_TYPE_DIR_SHIFT) + +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_MASK (0x3) +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_SHIFT (5) +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_POS (USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_MASK << USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_SHIFT) + +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK (0x1F) +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT (0) +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_POS (USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK << USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT) + +#define USB_DEV_REQ_STD_REQUEST_TYPE_DIR_OUT ((0x0 & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_DIR_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_DIR_IN ((0x1 & USB_DEV_REQ_STD_REQUEST_TYPE_DIR_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_DIR_SHIFT) + +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_STANDARD ((0x0 & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_CLASS ((0x1 & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_VENDOR ((0x2 & USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_TYPE_SHIFT) + +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_DEVICE ((0x00 & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_INTERFACE ((0x01 & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_ENDPOINT ((0x02 & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT) +#define USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_OTHER ((0x03 & USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_MASK) << USB_DEV_REQ_STD_REQUEST_TYPE_RECIPIENT_SHIFT) + +/* USB Standard Request Codes - bRequest */ +#define USB_DEV_REQ_STD_REQUEST_GET_STATUS (0) +#define USB_DEV_REQ_STD_REQUEST_CLEAR_FEATURE (1) +#define USB_DEV_REQ_STD_REQUEST_SET_FEATURE (3) +#define USB_DEV_REQ_STD_REQUEST_SET_ADDRESS (5) +#define USB_DEV_REQ_STD_REQUEST_GET_DESCRIPTOR (6) +#define USB_DEV_REQ_STD_REQUEST_SET_DESCRIPTOR (7) +#define USB_DEV_REQ_STD_REQUEST_GET_CONFIGURATION (8) +#define USB_DEV_REQ_STD_REQUEST_SET_CONFIGURATION (9) +#define USB_DEV_REQ_STD_REQUEST_GET_INTERFACE (10) +#define USB_DEV_REQ_STD_REQUEST_SET_INTERFACE (11) +#define USB_DEV_REQ_STD_REQUEST_SYNCH_FRAME (12) + +#define GET_STATUS_DEVICE_MASK (0x0003) +#define REMOTE_WAKEUP_STATUS_MASK (0x0002) +/* identification values and masks to identify request types */ +//#define USB_REQUEST_CLASS_MASK (0x60) +//#define USB_REQUEST_CLASS_STRD (0x00) +//#define USB_REQUEST_CLASS_CLASS (0x20) +//#define USB_REQUEST_CLASS_VENDOR (0x40) +#define USB_GET_STATUS_ATTRIBUTES_SELF_POWERED_SHIFT (0) +#define USB_GET_STATUS_ATTRIBUTES_REMOTE_WAKEUP_SHIFT (1) +/* Configuration bmAttributes fields */ +#define USB_DESC_CFG_ATTRIBUTES_D7_MASK (0x1) +#define USB_DESC_CFG_ATTRIBUTES_D7_SHIFT (7) +#define USB_DESC_CFG_ATTRIBUTES_D7_POS (USB_DESC_CFG_ATTRIBUTES_D7_MASK << USB_DESC_CFG_ATTRIBUTES_D7_SHIFT) + +#define USB_DESC_CFG_ATTRIBUTES_SELF_POWERED_MASK (0x1) +#define USB_DESC_CFG_ATTRIBUTES_SELF_POWERED_SHIFT (6) +#define USB_DESC_CFG_ATTRIBUTES_SELF_POWERED_POS (USB_DESC_CFG_ATTRIBUTES_SELF_POWERED_MASK << USB_DESC_CFG_ATTRIBUTES_SELF_POWERED_SHIFT) + +#define USB_DESC_CFG_ATTRIBUTES_REMOTE_WAKEUP_MASK (0x1) +#define USB_DESC_CFG_ATTRIBUTES_REMOTE_WAKEUP_SHIFT (5) +#define USB_DESC_CFG_ATTRIBUTES_REMOTE_WAKEUP_POS (USB_DESC_CFG_ATTRIBUTES_REMOTE_WAKEUP_MASK << USB_DESC_CFG_ATTRIBUTES_REMOTE_WAKEUP_SHIFT) + +/* Endpoint bEndpointAddress fields */ +#define USB_DESC_EP_ENDPOINT_ADDRESS_DIR_MASK (0x1) +#define USB_DESC_EP_ENDPOINT_ADDRESS_DIR_SHIFT (7) +#define USB_DESC_EP_ENDPOINT_ADDRESS_DIR_POS (USB_DESC_EP_ENDPOINT_ADDRESS_DIR_MASK << USB_DESC_EP_ENDPOINT_ADDRESS_DIR_SHIFT) + +#define USB_DESC_EP_ENDPOINT_ADDRESS_EP_NUMBER_MASK (0xF) +#define USB_DESC_EP_ENDPOINT_ADDRESS_EP_NUMBER_SHIFT (0) +#define USB_DESC_EP_ENDPOINT_ADDRESS_EP_NUMBER_POS (USB_DESC_EP_ENDPOINT_ADDRESS_EP_NUMBER_MASK << USB_DESC_EP_ENDPOINT_ADDRESS_EP_NUMBER_SHIFT) + +#define USB_DESC_EP_ENDPOINT_ADDRESS_DIR_OUT ((0x0 & USB_DESC_EP_ENDPOINT_ADDRESS_DIR_MASK) << USB_DESC_EP_ENDPOINT_ADDRESS_DIR_SHIFT) +#define USB_DESC_EP_ENDPOINT_ADDRESS_DIR_IN ((0x1 & USB_DESC_EP_ENDPOINT_ADDRESS_DIR_MASK) << USB_DESC_EP_ENDPOINT_ADDRESS_DIR_SHIFT) + +/* Endpoint bmAttributes fields */ +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK (0x3) +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT (0) +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_POS (USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK << USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT) + +#define USB_DESC_EP_ATTRIBUTES_SYNC_TYPE_MASK (0x3) +#define USB_DESC_EP_ATTRIBUTES_SYNC_TYPE_SHIFT (2) +#define USB_DESC_EP_ATTRIBUTES_SYNC_TYPE_POS (USB_DESC_EP_ATTRIBUTES_SYNC_TYPE_MASK << USB_DESC_EP_ATTRIBUTES_SYNC_TYPE_SHIFT) + +#define USB_DESC_EP_ATTRIBUTES_USAGE_TYPE_MASK (0x3) +#define USB_DESC_EP_ATTRIBUTES_USAGE_TYPE_SHIFT (4) +#define USB_DESC_EP_ATTRIBUTES_USAGE_TYPE_POS (USB_DESC_EP_ATTRIBUTES_USAGE_TYPE_MASK << USB_DESC_EP_ATTRIBUTES_USAGE_TYPE_SHIFT) + +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_CONTROL ((0x0 & USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK) << USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT) +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_ISOCHRONOUS ((0x1 & USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK) << USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT) +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_BULK ((0x2 & USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK) << USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT) +#define USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_INTERRUPT ((0x3 & USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_MASK) << USB_DESC_EP_ATTRIBUTES_TRANSFER_TYPE_SHIFT) + +/* Standard Feature Selectors */ +#define USB_DEV_REQ_STD_FEATURE_SELECTOR_MASK (0x3) +#define USB_DEV_REQ_STD_FEATURE_SELECTOR_SHIFT (0x0) +#define USB_DEV_REQ_STD_FEATURE_SELECTOR_ENDPOINT_HALT (0) +#define USB_DEV_REQ_STD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1) +#define USB_DEV_REQ_STD_FEATURE_SELECTOR_TEST_MODE (2) + +#define USB_DEV_REQ_STD_FEATURE_B_HNP_ENABLE (0x0003) /* B HNP enable SET/CLEAR feature value */ +#define USB_DEV_REQ_STD_FEATURE_A_HNP_SUPPORT (0x0004) /* A HNP support SET/CLEAR feature value */ + + typedef struct _usb_language +{ + uint16_t language_id; + uint8_t ** lang_desc; + uint8_t * lang_desc_size; +} usb_language_t; + +typedef struct _usb_all_languages +{ + uint8_t *languages_supported_string; + uint8_t languages_supported_size; + uint8_t languages_number; + /*Allocate Memory In App Layer*/ + usb_language_t *usb_language; +} usb_all_languages_t; + +PACKED_STRUCT_BEGIN +struct usb_device_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 18 */ + uint8_t bDescriptorType; /* DEVICE descriptor type = 1 */ + uint8_t bcdUSD[2]; /* USB spec in BCD, e.g. 0x0200 */ + uint8_t bDeviceClass; /* Class code, if 0 see interface */ + uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */ + uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */ + uint8_t bMaxPacketSize; /* Endpoint 0 max. size */ + uint8_t idVendor[2]; /* Vendor ID per USB-IF */ + uint8_t idProduct[2]; /* Product ID per manufacturer */ + uint8_t bcdDevice[2]; /* Device release # in BCD */ + uint8_t iManufacturer; /* Index to manufacturer string */ + uint8_t iProduct; /* Index to product string */ + uint8_t iSerialNumber; /* Index to serial number string */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} PACKED_STRUCT_END; +typedef struct usb_device_descriptor device_descriptor_t; + +PACKED_STRUCT_BEGIN +struct usb_configuration_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 9 */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2 or 7 */ + uint8_t wTotalLength[2]; /* Length of concatenated descriptors */ + uint8_t bNumInterfaces; /* Number of interfaces, this config. */ + uint8_t bConfigurationValue; /* Value to set this config. */ + uint8_t iConfig; /* Index to configuration string */ + uint8_t bmAttributes; /* Config. characteristics */ + #define CONFIG_RES7 (0x80) /* Reserved, always = 1 */ + #define CONFIG_SELF_PWR (0x40) /* Self-powered device */ + #define CONFIG_WAKEUP (0x20) /* Remote wakeup */ + uint8_t bMaxPower; /* Max.power from bus, 2mA units */ +} PACKED_STRUCT_END; +typedef struct usb_configuration_descriptor usb_configuration_descriptor_t; + +PACKED_STRUCT_BEGIN +struct usb_interface_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 9 */ + uint8_t bDescriptorType; /* INTERFACE descriptor type = 4 */ + uint8_t bInterfaceNumber; /* Interface no.*/ + uint8_t bAlternateSetting; /* Value to select this IF */ + uint8_t bNumEndpoints; /* Number of endpoints excluding 0 */ + uint8_t bInterfaceClass; /* Class code, 0xFF = vendor */ + uint8_t bInterfaceSubClass; /* Sub-Class code, 0 if class = 0 */ + uint8_t bInterfaceProtocol; /* Protocol, 0xFF = vendor */ + uint8_t iInterface; /* Index to interface string */ +} PACKED_STRUCT_END; +typedef struct usb_interface_descriptor interface_descriptor_t; + +PACKED_STRUCT_BEGIN +struct usb_endpoint_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 7 */ + uint8_t bDescriptorType; /* ENDPOINT descriptor type = 5 */ + uint8_t bEndpointAddress; /* Endpoint # 0 - 15 | IN/OUT */ + #define IN_ENDPOINT (0x80) /* IN endpoint, device to host */ + #define OUT_ENDPOINT (0x00) /* OUT endpoint, host to device */ + #define ENDPOINT_MASK (0x0F) /* Mask endpoint # */ + uint8_t bmAttributes; /* Transfer type */ + #define CONTROL_ENDPOINT (0x00) /* Control transfers */ + #define ISOCH_ENDPOINT (0x01) /* Isochronous transfers */ + #define BULK_ENDPOINT (0x02) /* Bulk transfers */ + #define IRRPT_ENDPOINT (0x03) /* Interrupt transfers */ + #define EP_TYPE_MASK (0x03) /* Mask type bits */ + /* Following must be zero except for isochronous endpoints */ + #define ISOCH_NOSYNC (0x00) /* No synchronization */ + #define ISOCH_ASYNC (0x04) /* Asynchronous */ + #define ISOCH_ADAPT (0x08) /* Adaptive */ + #define ISOCH_SYNCH (0x0C) /* Synchronous */ + #define ISOCH_DATA (0x00) /* Data endpoint */ + #define ISOCH_FEEDBACK (0x10) /* Feedback endpoint */ + #define ISOCH_IMPLICIT (0x20) /* Implicit feedback */ + #define ISOCH_RESERVED (0x30) /* Reserved */ + uint8_t wMaxPacketSize[2]; /* Bits 10:0 = max. packet size */ + /* For high-speed interrupt or isochronous only, additional + ** transaction opportunities per microframe follow.*/ + #define PACKET_SIZE_MASK (0x7FFu) /* packet size bits */ + #define NO_ADDITONAL (0x0000) /* 1 / microframe */ + #define ONE_ADDITIONAL (0x0800) /* 2 / microframe */ + #define TWO_ADDITIONAL (0x1000) /* 3 / microframe */ + #define ADDITIONAL_MASK (ONE_ADDITIONAL | TWO_ADDITIONAL) + #define ADDITIONAL_POWER (11) + uint8_t iInterval; /* Polling interval in (micro) frames */ +} PACKED_STRUCT_END; +typedef struct usb_endpoint_descriptor endpoint_descriptor_t; + +PACKED_STRUCT_BEGIN +struct usb_qualifier_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 10 */ + uint8_t bDescriptorType; /* DEVICE QUALIFIER type = 6 */ + uint8_t bcdUSD[2]; /* USB spec in BCD, e.g. 0x0200 */ + uint8_t bDeviceClass; /* Class code, if 0 see interface */ + uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */ + uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */ + uint8_t bMaxPacketSize; /* Endpoint 0 max. size */ + uint8_t bNumConfigurations; /* Number of possible configurations */ + uint8_t bReserved; /* Reserved = 0 */ +} PACKED_STRUCT_END; +typedef struct usb_qualifier_descriptor qualifier_descriptor_t; + +/* Other-Config type 7 fields are identical to type 2 above */ + +/* Interface-Power descriptor type 8 not used in this version */ + +PACKED_STRUCT_BEGIN +struct usb_otg_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 9 */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2 or 7 */ + uint8_t bmAttributes; /* OTG characteristics */ + #define OTG_SRP_SUPPORT (0x01) /* Supports SRP */ + #define OTG_HNP_SUPPORT (0x02) /* Supports HNP */ +} PACKED_STRUCT_END; +typedef struct usb_otg_descriptor otg_descriptor_t; + +PACKED_STRUCT_BEGIN +struct usb_common_descriptor +{ + uint8_t bLength; /* Descriptor size in bytes = 9 */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2 or 7 */ +} PACKED_STRUCT_END; +typedef struct usb_common_descriptor common_descriptor_t; + + +typedef union descriptor_union +{ + uint32_t word; + uint8_t * bufr; + void* pntr; + device_descriptor_t dvic; + usb_configuration_descriptor_t* cfig; + interface_descriptor_t* intf; + endpoint_descriptor_t* ndpt; + qualifier_descriptor_t* qual; + otg_descriptor_t* otg; + common_descriptor_t* common; +} descriptor_union_t; + +#define USB_uint_16_low(x) ((x) & 0xFF) +#define USB_uint_16_high(x) ((uint8_t)((x) >> 8) & 0xFF) + + +/* Prototypes */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_error.h b/KSDK_1.2.0/usb/usb_core/include/usb_error.h new file mode 100644 index 0000000..e1184c8 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_error.h @@ -0,0 +1,100 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_error.h$ + * $Version : + * $Date : + * + * Comments: + * + * This file contains USB Device API defines for state and function + * returns. + * + *END************************************************************************/ +#ifndef __usb_error_h__ +#define __usb_error_h__ 1 + +/* Error codes */ +#define USB_OK (0x00) +#define USBERR_ALLOC (0x81) +#define USBERR_BAD_STATUS (0x82) +#define USBERR_CLOSED_SERVICE (0x83) +#define USBERR_OPEN_SERVICE (0x84) +#define USBERR_TRANSFER_IN_PROGRESS (0x85) +#define USBERR_ENDPOINT_STALLED (0x86) +#define USBERR_ALLOC_STATE (0x87) +#define USBERR_DRIVER_INSTALL_FAILED (0x88) +#define USBERR_DRIVER_NOT_INSTALLED (0x89) +#define USBERR_INSTALL_ISR (0x8A) +#define USBERR_INVALID_DEVICE_NUM (0x8B) +#define USBERR_ALLOC_SERVICE (0x8C) +#define USBERR_INIT_FAILED (0x8D) +#define USBERR_SHUTDOWN (0x8E) +#define USBERR_INVALID_PIPE_HANDLE (0x8F) +#define USBERR_OPEN_PIPE_FAILED (0x90) +#define USBERR_INIT_DATA (0x91) +#define USBERR_SRP_REQ_INVALID_STATE (0x92) +#define USBERR_TX_FAILED (0x93) +#define USBERR_RX_FAILED (0x94) +#define USBERR_EP_INIT_FAILED (0x95) +#define USBERR_EP_DEINIT_FAILED (0x96) +#define USBERR_TR_FAILED (0x97) +#define USBERR_BANDWIDTH_ALLOC_FAILED (0x98) +#define USBERR_INVALID_NUM_OF_ENDPOINTS (0x99) +#define USBERR_ADDRESS_ALLOC_FAILED (0x9A) +#define USBERR_PIPE_OPENED_FAILED (0x9B) +#define USBERR_NOT_FOUND (0x9C) +#define USBERR_HOST_BUSY (0x9D) +#define USBERR_INVALID_PARAM (0x9E) +#define USBERR_TR_RETRY_FAILED (0x9F) + +#define USBERR_DEVICE_NOT_FOUND (0xC0) +#define USBERR_DEVICE_BUSY (0xC1) +#define USBERR_NO_DEVICE_CLASS (0xC3) +#define USBERR_UNKNOWN_ERROR (0xC4) +#define USBERR_INVALID_BMREQ_TYPE (0xC5) +#define USBERR_GET_MEMORY_FAILED (0xC6) +#define USBERR_BAD_ALIGNMENT (0xC7) +#define USBERR_INVALID_MEM_TYPE (0xC8) +#define USBERR_NO_DESCRIPTOR (0xC9) +#define USBERR_NULL_CALLBACK (0xCA) +#define USBERR_NO_INTERFACE (0xCB) +#define USBERR_INVALID_CFIG_NUM (0xCC) +#define USBERR_INVALID_ANCHOR (0xCD) +#define USBERR_INVALID_REQ_TYPE (0xCE) +#define USBERR_DEVICE_DETACH (0xCF) +#define USBERR_INTERFACE_NOT_OPENED (0xD0) +#define USBERR_LACK_OF_SWAP_BUFFER (0xD1) +#define USBERR_LEAK_OF_SWAP_BUFFER (0xD2) + +#define USBERR_ERROR (0xFF) + +/* Error Codes for lower-layer */ +#define USBERR_ALLOC_EP_QUEUE_HEAD (0xA8) +#define USBERR_ALLOC_TR (0xA9) +#define USBERR_ALLOC_DTD_BASE (0xAA) +#define USBERR_CLASS_DRIVER_INSTALL (0xAB) +#define USBERR_TR_CANCEL (0xAC) + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_misc.h b/KSDK_1.2.0/usb/usb_core/include/usb_misc.h new file mode 100644 index 0000000..d6247e6 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_misc.h @@ -0,0 +1,193 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2008, 2013 - 2014 Freescale Semiconductor; +* All Rights Reserved +* +* Copyright (c) 1989-2008 ARC International; +* All Rights Reserved +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_misc.h$ +* $Version : +* $Date : +* +* Comments: +* +* This file contains USB Device API defines for state and function +* returns. +* +*END************************************************************************/ +#ifndef __usb_misc_h__ +#define __usb_misc_h__ 1 + +/* Host specific */ +#define USB_DEBOUNCE_DELAY (101) +#define USB_RESET_RECOVERY_DELAY (11) +#define USB_RESET_DELAY (10) + +/* USB device state- see USB 2.0 Documentation */ +#define USB_STATE_UNKNOWN (0xff) +#define USB_STATE_PENDING_ADDRESS (0x04) +#define USB_STATE_POWERED (0x03) +#define USB_STATE_DEFAULT (0x02) +#define USB_STATE_ADDRESS (0x01) +#define USB_STATE_CONFIG (0x00) +#define USB_STATE_SUSPEND (0x80) + +#define USB_STATUS_SELF_POWERED (0x01) +#define USB_STATUS_REMOTE_WAKEUP (0x02) + +/* Bus Control values */ +#define USB_NO_OPERATION (0x00) +#define USB_ASSERT_BUS_RESET (0x01) +#define USB_DEASSERT_BUS_RESET (0x02) +#define USB_ASSERT_RESUME (0x03) +#define USB_DEASSERT_RESUME (0x04) +#define USB_SUSPEND_SOF (0x05) +#define USB_RESUME_SOF (0x06) + +/* possible values of XD->bStatus */ +#define USB_STATUS_IDLE (0) +#define USB_STATUS_STALLED (1) +#define USB_STATUS_TRANSFER_PENDING (2) +#define USB_STATUS_TRANSFER_IN_PROGRESS (3) +#define USB_STATUS_ERROR (4) +#define USB_STATUS_DISABLED (5) +#define USB_STATUS_TRANSFER_ACCEPTED (6) +#define USB_STATUS_TRANSFER_QUEUED (7) +#define USB_STATUS_TRANSFER_DONE (8) + +#define USB_DEVICE_DONT_ZERO_TERMINATE (0x1) + +#define USB_SETUP_DATA_XFER_DIRECTION (0x80) + +/* Speed definitions */ +#define USB_SPEED_FULL (0) +#define USB_SPEED_LOW (1) +#define USB_SPEED_HIGH (2) + +#define USB_MAX_PKTS_PER_UFRAME (0x6) + +/* Event codes for attach/detach etc. callback */ +#define USB_ATTACH_EVENT (1) /* device attach */ +#define USB_DETACH_EVENT (2) /* device detach */ +#define USB_CONFIG_EVENT (3) /* device reconfigured */ +#define USB_INTF_OPENED_EVENT (4) /* device interface opened */ +#define USB_ATTACH_INTF_NOT_SUPPORT (5) /* device attach while some interfaces not supported */ +#define USB_ATTACH_DEVICE_NOT_SUPPORT (6) /* device attach while all interfaces not supported */ + +/* Alignment of buffer for DMA transfer, needed in some cases, +** USB DMA bus could not possibly be initializes properly and +** first data transfered is the one aligned at 4-byte boundary +*/ +#define USB_MEM4_ALIGN(n) ((uint32_t)(n) + ((uint32_t)(-(n)) & 3U)) +#define USB_DMA_ALIGN(n) USB_MEM4_ALIGN(n) +#define USB_DMA_ALIGN_MASK (0x03) +#define USB_SETUP_PKT_SIZE (8)/* Setup Packet Size */ +#define MAX_EXPECTED_CONTROL_OUT_SIZE (76 + USB_SETUP_PKT_SIZE) + +typedef struct xd_struct +{ + uint8_t ep_num; /* Endpoint number */ + uint8_t bdirection; /* Direction : Send/Receive */ + uint8_t ep_type; /* Type of the endpoint: Ctrl, Isoch, Bulk, Int */ + uint8_t bstatus; /* Current transfer status */ + uint8_t * wstartaddress; /* Address of first byte */ + uint32_t wtotallength; /* number of bytes to send/recv */ + uint32_t wsofar; /* number of bytes recv'd so far */ + struct xd_struct* next; + uint16_t wmaxpacketsize; /* max packet size */ + uint8_t dont_zero_terminate; +#if (defined USBCFG_KHCI_4BYTE_ALIGN_FIX && USBCFG_KHCI_4BYTE_ALIGN_FIX) + uint8_t internal_dma_align; +#endif + uint8_t max_pkts_per_uframe; +} xd_struct_t; + +typedef struct +{ + uint8_t* name; + uint8_t instance; +} usb_instance_t; + +#if (defined USBCFG_DEV_KHCI && USBCFG_DEV_KHCI) || (defined USBCFG_DEV_EHCI && USBCFG_DEV_EHCI) +typedef struct usb_dev_data +{ + uint8_t control_out[(((MAX_EXPECTED_CONTROL_OUT_SIZE-1)/32) + 1) * 32]; + /* control_out must be 32 byte align, + ** 96 = (((MAX_EXPECTED_CONTROL_OUT_SIZE-1)/32) + 1) * 32 + */ +} usb_dev_data_t; +#endif + +#if (defined USBCFG_DEV_KHCI && USBCFG_DEV_KHCI) +typedef struct usb_device_khci_data +{ + uint8_t setup_packet[16]; +#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_MQX) + uint8_t reserver1[16]; +#endif +#if USBCFG_KHCI_4BYTE_ALIGN_FIX + uint8_t swap_buf[USBCFG_DEV_KHCI_SWAP_BUF_MAX]; +#endif + uint8_t xd_base[USBCFG_DEV_MAX_XDS * sizeof(xd_struct_t)]; +}usb_device_khci_data_t; +#endif + +#if (defined USBCFG_DEV_EHCI && USBCFG_DEV_EHCI) +typedef struct usb_device_ehci_data +{ + uint8_t qh_base[USBCFG_DEV_EHCI_MAX_ENDPOINTS * 2 * 64]; + uint8_t dtd_base[USBCFG_DEV_EHCI_MAX_DTD * 32]; + uint8_t xd_base[USBCFG_DEV_MAX_XDS * sizeof(xd_struct_t)]; + uint8_t reserved[688]; /* each ehci data should be 2048B aligned */ +}usb_device_ehci_data_t; +#endif + +typedef enum +{ + INTR_USBRST = 0x01, + INTR_ERROR = 0x02, + INTR_SOFTOK = 0x04, + INTR_TOKDNE = 0x08, + INTR_SLEEP = 0x10, + INTR_RESUME = 0x20, + INTR_ATTACH = 0x40, + INTR_STALL = 0x80, +}INTR_TYPE; + +typedef enum +{ + ERROR_PIDERR = 0x01, + ERROR_CRC5EOF = 0x02, + ERROR_CRC16 = 0x04, + ERROR_DFN8 = 0x08, + ERROR_BTOERR = 0x10, + ERROR_DMAERR = 0x20, + ERROR_BTSERR = 0x80, +}ERROR_TYPE; + +typedef enum +{ + USB_CONTROLLER_KHCI_0 = 0x00, + USB_CONTROLLER_KHCI_1, + USB_CONTROLLER_EHCI_0, + USB_CONTROLLER_EHCI_1 +}CONTROLLER_INDEX; + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_opt.h b/KSDK_1.2.0/usb/usb_core/include/usb_opt.h new file mode 100644 index 0000000..507341a --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_opt.h @@ -0,0 +1,117 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 Freescale Semiconductor; + * All Rights Reserved + * + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_opt.h$ + * $Version : + * $Date : + * + * Comments: + * + * + * + *END************************************************************************/ +#ifndef __usb_opt_h__ +#define __usb_opt_h__ 1 + +#ifndef ENDIANNESS + +#error ENDIANNESS should be defined, and then rebulid the project. + +#endif + +#define SWAP2BYTE_CONST(n) ((((n) & 0x00FF) << 8) | (((n) & 0xFF00) >> 8)) +#define SWAP4BYTE_CONST(n) ((((n) & 0x000000FF) << 24) | (((n) & 0x0000FF00) << 8) | (((n) & 0x00FF0000) >> 8) | (((n) & 0xFF000000) >> 24)) + +#if (ENDIANNESS == BIG_ENDIAN) +#define USB_HOST_TO_BE_SHORT(n) (n) +#define USB_HOST_TO_BE_SHORT_CONST(n) (n) +#define USB_HOST_TO_LE_SHORT(n) SWAP2BYTE_CONST(n) +#define USB_HOST_TO_LE_SHORT_CONST(n) SWAP2BYTE_CONST(n) +#define USB_SHORT_BE_TO_HOST(n) (n) +#define USB_SHORT_BE_TO_HOST_CONST(n) (n) +#define USB_SHORT_LE_TO_HOST(n) SWAP2BYTE_CONST(n) +#define USB_SHORT_LE_TO_HOST_CONST(n) SWAP2BYTE_CONST(n) +#define USB_SHORT_UNALIGNED_LE_TO_HOST(n) ((n[1]<<8)|n[0]) + +#define USB_HOST_TO_BE_LONG(n) (n) +#define USB_HOST_TO_BE_LONG_CONST(n) (n) +#define USB_HOST_TO_BE_UNALIGNED_LONG(n, m) \ + { \ + m[0]=((n>>24) & 0xFF); \ + m[1]=((n>>16) & 0xFF); \ + m[2]=((n>>8) & 0xFF); \ + m[3]=(n & 0xFF); \ + } +#define USB_HOST_TO_LE_LONG(n) SWAP4BYTE_CONST(n) +#define USB_HOST_TO_LE_LONG_CONST(n) SWAP4BYTE_CONST(n) +#define USB_HOST_TO_LE_UNALIGNED_LONG(n, m) \ + { \ + m[0]=(n & 0xFF); \ + m[1]=((n>>8) & 0xFF); \ + m[2]=((n>>16) & 0xFF); \ + m[3]=((n>>24) & 0xFF); \ + } +#define USB_LONG_BE_TO_HOST(n) (n) +#define USB_LONG_BE_TO_HOST_CONST(n) (n) +#define USB_LONG_LE_TO_HOST(n) SWAP4BYTE_CONST(n) +#define USB_LONG_LE_TO_HOST_CONST(n) SWAP4BYTE_CONST(n) +#define USB_LONG_UNALIGNED_LE_TO_HOST(n) ((n[3]<<24)|(n[2]<<16)|(n[1]<<8)|n[0]) + +#else /* (PSP_ENDIAN == MQX_BIG_ENDIAN) */ + +#define USB_HOST_TO_BE_SHORT(n) SWAP2BYTE_CONST(n) +#define USB_HOST_TO_BE_SHORT_CONST(n) SWAP2BYTE_CONST(n) +#define USB_HOST_TO_LE_SHORT(n) (n) +#define USB_HOST_TO_LE_SHORT_CONST(n) (n) +#define USB_SHORT_BE_TO_HOST(n) SWAP2BYTE_CONST(n) +#define USB_SHORT_BE_TO_HOST_CONST(n) SWAP2BYTE_CONST(n) +#define USB_SHORT_LE_TO_HOST(n) (n) +#define USB_SHORT_LE_TO_HOST_CONST(n) (n) +#define USB_SHORT_UNALIGNED_LE_TO_HOST(n) ((uint16_t)((uint16_t)n[1]<<8)|n[0]) + +#define USB_HOST_TO_BE_LONG(n) SWAP4BYTE_CONST(n) +#define USB_HOST_TO_BE_LONG_CONST(n) SWAP4BYTE_CONST(n) +#define USB_HOST_TO_BE_UNALIGNED_LONG(n, m) \ + { \ + m[0]=((n>>24) & 0xFF); \ + m[1]=((n>>16) & 0xFF); \ + m[2]=((n>>8) & 0xFF); \ + m[3]=(n & 0xFF); \ + } +#define USB_HOST_TO_LE_LONG(n) (n) +#define USB_HOST_TO_LE_LONG_CONST(n) (n) +#define USB_HOST_TO_LE_UNALIGNED_LONG(n, m) \ + { \ + m[0]=(n & 0xFF); \ + m[1]=((n>>8) & 0xFF); \ + m[2]=((n>>16) & 0xFF); \ + m[3]=((n>>24) & 0xFF); \ + } + +#define USB_LONG_BE_TO_HOST(n) SWAP4BYTE_CONST(n) +#define USB_LONG_BE_TO_HOST_CONST(n) SWAP4BYTE_CONST(n) +#define USB_LONG_LE_TO_HOST(n) (n) +#define USB_LONG_LE_TO_HOST_CONST(n) (n) +#define USB_LONG_UNALIGNED_LE_TO_HOST(n) (((uint32_t)n[3]<<24) | ((uint32_t)n[2]<<16) | ((uint32_t)n[1]<<8) | (uint32_t)n[0]) +#endif /* (PSP_ENDIAN == MQX_BIG_ENDIAN) */ + +#endif diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_pin_detect.h b/KSDK_1.2.0/usb/usb_core/include/usb_pin_detect.h new file mode 100644 index 0000000..135c8b8 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_pin_detect.h @@ -0,0 +1,68 @@ +/**HEADER******************************************************************** +* +* Copyright (c) 2014 Freescale Semiconductor; +* All Rights Reserved +* +* +*************************************************************************** +* +* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +* +************************************************************************** +* +* $FileName: usb_pin_detect.h$ +* $Version : +* $Date : +* +* Comments: +* +* +* +*END************************************************************************/ + +#ifndef __usb_pin_detect_h__ +#define __usb_pin_detect_h__ + +typedef void(_CODE_PTR_ usb_pin_detect_service_t)(uint32_t event); + + +#define USB_DEVICE_ID_CHANGE (1) /* id change from device mode*/ +#define USB_HOST_ID_CHANGE (2) /* id change from host mode */ + +/*! + * @brief Registers a callback function for usb device pin detect + * + * The function is used to register a callback function for one specified endpoint. + * + * @param uint8_t USB controller id + * @param service callback function + * @param arg second parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_device_register_pin_detect_service(uint8_t controller_id, usb_pin_detect_service_t service, void* arg); + +/*! + * @brief Registers a callback function for usb host pin detect + * + * The function is used to register a callback function for one specified endpoint. + * + * @param uint8_t USB controller id + * @param service callback function + * @param arg second parameter for the callback function + * @return USB_OK-Success/Others-Fail + */ +extern usb_status usb_host_register_pin_detect_service(uint8_t controller_id, usb_pin_detect_service_t service, void* arg); + + +#endif + diff --git a/KSDK_1.2.0/usb/usb_core/include/usb_types.h b/KSDK_1.2.0/usb/usb_core/include/usb_types.h new file mode 100644 index 0000000..01dc026 --- /dev/null +++ b/KSDK_1.2.0/usb/usb_core/include/usb_types.h @@ -0,0 +1,59 @@ +/**HEADER******************************************************************** + * + * Copyright (c) 2008, 2013 Freescale Semiconductor; + * All Rights Reserved + * + * Copyright (c) 1989-2008 ARC International; + * All Rights Reserved + * + *************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************** + * + * $FileName: usb_types.h$ + * $Version : + * $Date : + * + * Comments: + * + * This file contains appropriate processor specific header file include. + * + *END************************************************************************/ +#ifndef __usb_types_h__ +#define __usb_types_h__ + +/*--------------------------------------------------------------------------*/ +/* + ** STANDARD TYPES + */ + +typedef uint32_t usb_status; +/* forward declarations */ +struct usb_interface_descriptor; +struct pipe_struct; +struct tr_struct; + +typedef void* usb_device_handle; /* device state struct */ +typedef void* usb_host_handle; /* host state struct */ +typedef void* usb_otg_handle; /* otg state struct */ + +typedef void* usb_device_instance_handle; /* item on host's list */ +typedef void* usb_interface_descriptor_handle; /* Chapter 9 interface descriptor */ +typedef void* usb_pipe_handle; /* pipe or pipe-bundle */ +typedef void* usb_class_intf_handle; /* interface state struct (general data + class driver specific data) */ + +#define UNUSED_ARGUMENT(x) (void)x; + +#endif -- cgit v1.2.3-18-g5258